Skip to content

Commit 25fbfae

Browse files
committed
refactor (wolfcrypt-rs):
- refactor(build.rs): unravel nested if/else in build.rs Split build script into modular functions with proper error handling. Add documentation and extract constants for better maintainability. - refactor(lib): minimize unsafe blocks in RSA encryption test
1 parent 55e5e78 commit 25fbfae

File tree

2 files changed

+244
-167
lines changed

2 files changed

+244
-167
lines changed

wolfcrypt-rs/build.rs

Lines changed: 187 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,54 @@ extern crate bindgen;
22

33
use std::env;
44
use std::fs;
5+
use std::io::{self, Result};
56
use std::path::Path;
67
use std::path::PathBuf;
78
use std::process::Command;
89

10+
/// Version-related constants for WolfSSL
11+
const WOLFSSL_DIR: &str = "wolfssl-5.7.4-stable";
12+
const WOLFSSL_ZIP: &str = "wolfssl-5.7.4-stable.zip";
13+
const WOLFSSL_URL: &str = "https://github.com/wolfSSL/wolfssl/archive/refs/tags/v5.7.4-stable.zip";
14+
15+
/// Entry point for the build script.
16+
/// Handles the main build process and exits with an error code if anything fails.
917
fn main() {
10-
// We check if the release was already fetched, if not,
11-
// we fetch it and setup it.
12-
if fs::metadata("wolfssl-5.7.6-stable").is_err() {
13-
setup_wolfssl();
18+
if let Err(e) = run_build() {
19+
eprintln!("Build failed: {}", e);
20+
std::process::exit(1);
1421
}
22+
}
23+
24+
/// Orchestrates the entire build process.
25+
///
26+
/// This function:
27+
/// 1. Checks if WolfSSL needs to be set up
28+
/// 2. Sets up WolfSSL if necessary
29+
/// 3. Generates Rust bindings for the WolfSSL library
30+
///
31+
/// Returns `Ok(())` if successful, or an error if any step fails.
32+
fn run_build() -> Result<()> {
33+
if fs::metadata(WOLFSSL_DIR).is_err() {
34+
setup_wolfssl()?;
35+
}
36+
37+
generate_bindings()?;
38+
Ok(())
39+
}
1540

16-
let wolfssl_lib_dir = Path::new(&"/opt/wolfssl-rs/lib/");
17-
let wolfssl_include_dir = Path::new(&"/opt/wolfssl-rs/include/");
41+
/// Generates Rust bindings for the WolfSSL library using bindgen.
42+
///
43+
/// This function:
44+
/// 1. Sets up the library and include paths
45+
/// 2. Configures the build environment
46+
/// 3. Generates Rust bindings using bindgen
47+
/// 4. Writes the bindings to a file
48+
///
49+
/// Returns `Ok(())` if successful, or an error if binding generation fails.
50+
fn generate_bindings() -> Result<()> {
51+
let wolfssl_lib_dir = Path::new("/opt/wolfssl-rs/lib/");
52+
let wolfssl_include_dir = Path::new("/opt/wolfssl-rs/include/");
1853

1954
println!(
2055
"cargo:rustc-link-search={}",
@@ -27,130 +62,163 @@ fn main() {
2762
.clang_arg(format!("-I{}/", wolfssl_include_dir.to_str().unwrap()))
2863
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
2964
.generate()
30-
.expect("Unable to generate bindings");
65+
.map_err(|_| io::Error::new(io::ErrorKind::Other, "Failed to generate bindings"))?;
3166

3267
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
3368
bindings
3469
.write_to_file(out_path.join("bindings.rs"))
35-
.expect("Couldn't write bindings!");
70+
.map_err(|e| {
71+
io::Error::new(
72+
io::ErrorKind::Other,
73+
format!("Couldn't write bindings: {}", e),
74+
)
75+
})
76+
}
77+
78+
/// Coordinates the complete setup process for WolfSSL.
79+
///
80+
/// This function executes all necessary steps in sequence:
81+
/// 1. Downloads the WolfSSL source
82+
/// 2. Extracts the archive
83+
/// 3. Removes the downloaded archive
84+
/// 4. Builds WolfSSL from source
85+
/// 5. Returns to the original directory
86+
///
87+
/// Returns `Ok(())` if all steps complete successfully, or an error if any step fails.
88+
fn setup_wolfssl() -> Result<()> {
89+
download_wolfssl()?;
90+
unzip_wolfssl()?;
91+
remove_zip()?;
92+
build_wolfssl()?;
93+
change_back_to_root()?;
94+
Ok(())
3695
}
3796

38-
fn setup_wolfssl() {
39-
// Step 1: Download the ZIP file using curl
97+
/// Downloads the WolfSSL source code archive using curl.
98+
///
99+
/// Uses curl to download the specified version of WolfSSL from the official repository.
100+
/// The download URL and filename are defined in the constants.
101+
///
102+
/// Returns `Ok(())` if the download succeeds, or an error if the download fails.
103+
fn download_wolfssl() -> Result<()> {
40104
let output = Command::new("curl")
41105
.arg("-L")
42106
.arg("-o")
43-
.arg("wolfssl-5.7.6-stable.zip")
44-
.arg("https://github.com/wolfSSL/wolfssl/archive/refs/tags/v5.7.6-stable.zip")
45-
.output()
46-
.expect("Failed to execute curl command");
47-
48-
if output.status.success() {
49-
println!("Download completed successfully.");
50-
51-
// Step 2: Unzip the downloaded file
52-
let output = Command::new("unzip")
53-
.arg("wolfssl-5.7.6-stable.zip")
54-
.output()
55-
.expect("Failed to execute unzip command");
56-
57-
if output.status.success() {
58-
println!("Unzipping completed successfully.");
59-
60-
// Step 3: Remove the ZIP file
61-
if let Err(e) = fs::remove_file("wolfssl-5.7.6-stable.zip") {
62-
eprintln!("Error removing ZIP file: {}", e);
63-
} else {
64-
println!("Removed ZIP file successfully.");
65-
}
66-
67-
// Step 4: Change the current working directory to the unzipped folder
68-
if let Err(e) = env::set_current_dir("wolfssl-5.7.6-stable") {
69-
eprintln!("Error changing directory: {}", e);
70-
} else {
71-
println!("Changed directory to wolfssl-5.7.6-stable.");
72-
73-
// Step 5: Execute ./autogen.sh
74-
let output = Command::new("./autogen.sh")
75-
.output()
76-
.expect("Failed to execute ./autogen.sh");
77-
78-
if output.status.success() {
79-
println!("./autogen.sh completed successfully.");
80-
81-
// Step 6: Execute ./configure
82-
let output = Command::new("./configure")
83-
.arg("--enable-all")
84-
.arg("--enable-all-crypto")
85-
.arg("--enable-debug")
86-
.arg("--disable-shared")
87-
.arg("--prefix=/opt/wolfssl-rs/")
88-
.output()
89-
.expect("Failed to execute ./configure");
90-
91-
if output.status.success() {
92-
println!("./configure completed successfully.");
93-
94-
// Step 7: Execute make
95-
let output = Command::new("make")
96-
.output()
97-
.expect("Failed to execute make");
98-
99-
if output.status.success() {
100-
println!("make completed successfully.");
101-
102-
// Step 8: Execute sudo make install
103-
let output = Command::new("sudo")
104-
.arg("make")
105-
.arg("install")
106-
.output()
107-
.expect("Failed to execute sudo make install");
108-
109-
if output.status.success() {
110-
println!("sudo make install completed successfully.");
111-
} else {
112-
eprintln!(
113-
"Error executing sudo make install: {}",
114-
String::from_utf8_lossy(&output.stderr)
115-
);
116-
}
117-
} else {
118-
eprintln!(
119-
"Error executing make: {}",
120-
String::from_utf8_lossy(&output.stderr)
121-
);
122-
}
123-
} else {
124-
eprintln!(
125-
"Error executing ./configure: {}",
126-
String::from_utf8_lossy(&output.stderr)
127-
);
128-
}
129-
} else {
130-
eprintln!(
131-
"Error executing ./autogen.sh: {}",
132-
String::from_utf8_lossy(&output.stderr)
133-
);
134-
}
135-
}
136-
} else {
137-
eprintln!(
138-
"Error unzipping file: {}",
107+
.arg(WOLFSSL_ZIP)
108+
.arg(WOLFSSL_URL)
109+
.output()?;
110+
111+
if !output.status.success() {
112+
return Err(io::Error::new(
113+
io::ErrorKind::Other,
114+
format!(
115+
"Failed to download: {}",
116+
String::from_utf8_lossy(&output.stderr)
117+
),
118+
));
119+
}
120+
println!("Download completed successfully.");
121+
Ok(())
122+
}
123+
124+
/// Extracts the downloaded WolfSSL archive.
125+
///
126+
/// Uses the unzip command to extract the contents of the downloaded ZIP file.
127+
/// The archive name is defined in the constants.
128+
///
129+
/// Returns `Ok(())` if extraction succeeds, or an error if it fails.
130+
fn unzip_wolfssl() -> Result<()> {
131+
let output = Command::new("unzip").arg(WOLFSSL_ZIP).output()?;
132+
133+
if !output.status.success() {
134+
return Err(io::Error::new(
135+
io::ErrorKind::Other,
136+
format!(
137+
"Failed to unzip: {}",
139138
String::from_utf8_lossy(&output.stderr)
140-
);
141-
}
142-
} else {
143-
eprintln!(
144-
"Error downloading file: {}",
145-
String::from_utf8_lossy(&output.stderr)
146-
);
139+
),
140+
));
147141
}
142+
println!("Unzipping completed successfully.");
143+
Ok(())
144+
}
145+
146+
/// Removes the downloaded ZIP file after extraction.
147+
///
148+
/// This cleanup step removes the ZIP file to save disk space.
149+
///
150+
/// Returns `Ok(())` if removal succeeds, or an error if it fails.
151+
fn remove_zip() -> Result<()> {
152+
fs::remove_file(WOLFSSL_ZIP)?;
153+
println!("Removed ZIP file successfully.");
154+
Ok(())
155+
}
148156

149-
// Final step: we change the directory back to the root directory
150-
// to finally generate the bindings.
151-
if let Err(e) = env::set_current_dir("../") {
152-
eprintln!("Error changing directory: {}", e);
153-
} else {
154-
println!("Changed directory to wolfssl-5.7.6-stable.");
157+
/// Builds WolfSSL from source.
158+
///
159+
/// This function:
160+
/// 1. Changes to the source directory
161+
/// 2. Runs autogen.sh to generate build files
162+
/// 3. Configures the build with specific options
163+
/// 4. Builds the library
164+
/// 5. Installs the library system-wide
165+
///
166+
/// Returns `Ok(())` if all build steps succeed, or an error if any step fails.
167+
fn build_wolfssl() -> Result<()> {
168+
env::set_current_dir(WOLFSSL_DIR)?;
169+
println!("Changed directory to {}.", WOLFSSL_DIR);
170+
171+
run_command("./autogen.sh", &[])?;
172+
run_command(
173+
"./configure",
174+
&[
175+
"--enable-all",
176+
"--enable-all-crypto",
177+
"--enable-debug",
178+
"--disable-shared",
179+
"--prefix=/opt/wolfssl-rs/",
180+
],
181+
)?;
182+
run_command("make", &[])?;
183+
run_command("sudo", &["make", "install"])?;
184+
185+
Ok(())
186+
}
187+
188+
/// Helper function to execute shell commands.
189+
///
190+
/// Executes a command with given arguments and handles the output appropriately.
191+
///
192+
/// # Arguments
193+
/// * `cmd` - The command to execute
194+
/// * `args` - Array of arguments for the command
195+
///
196+
/// Returns `Ok(())` if the command executes successfully, or an error if it fails.
197+
fn run_command(cmd: &str, args: &[&str]) -> Result<()> {
198+
let output = Command::new(cmd).args(args).output()?;
199+
200+
if !output.status.success() {
201+
return Err(io::Error::new(
202+
io::ErrorKind::Other,
203+
format!(
204+
"Failed to execute {}: {}",
205+
cmd,
206+
String::from_utf8_lossy(&output.stderr)
207+
),
208+
));
155209
}
210+
println!("{} completed successfully.", cmd);
211+
Ok(())
212+
}
213+
214+
/// Changes the working directory back to the root directory.
215+
///
216+
/// This function is called after building WolfSSL to return to the original
217+
/// working directory for the rest of the build process.
218+
///
219+
/// Returns `Ok(())` if the directory change succeeds, or an error if it fails.
220+
fn change_back_to_root() -> Result<()> {
221+
env::set_current_dir("../")?;
222+
println!("Changed directory back to root.");
223+
Ok(())
156224
}

0 commit comments

Comments
 (0)