|
1 | 1 | use std::process::Command; |
2 | 2 |
|
3 | | -fn main() { |
4 | | - // Check if the "fips" feature is enabled |
5 | | - let fips_enabled = std::env::var("CARGO_FEATURE_FIPS").is_ok(); |
| 3 | +/// Checks if a specific dependency is present in the dependency tree when FIPS is enabled |
| 4 | +fn check_forbidden_dependency(dependency_name: &str) -> Result<(), String> { |
| 5 | + println!( |
| 6 | + "cargo:warning=Checking for {} dependency...", |
| 7 | + dependency_name |
| 8 | + ); |
6 | 9 |
|
7 | | - if fips_enabled { |
8 | | - println!("cargo:warning=FIPS feature is enabled, checking for ring dependency..."); |
| 10 | + // First run cargo tree to get dependency with detailed info |
| 11 | + let output = Command::new("cargo") |
| 12 | + .args([ |
| 13 | + "tree", |
| 14 | + "-i", |
| 15 | + dependency_name, |
| 16 | + "--format={p} {f}", |
| 17 | + "--prefix-depth", |
| 18 | + "--features=fips", |
| 19 | + "--no-default-features", |
| 20 | + ]) |
| 21 | + .output() |
| 22 | + .expect(&format!( |
| 23 | + "Failed to execute cargo tree command for {}", |
| 24 | + dependency_name |
| 25 | + )); |
9 | 26 |
|
10 | | - // First run cargo tree to get dependency on ring with detailed info |
11 | | - let output = Command::new("cargo") |
12 | | - .args([ |
13 | | - "tree", |
14 | | - "-i", |
15 | | - "ring", |
16 | | - "--format={p} {f}", |
17 | | - "--prefix-depth", |
18 | | - "--features=fips", |
19 | | - "--no-default-features", |
20 | | - ]) |
21 | | - .output() |
22 | | - .expect("Failed to execute cargo tree command"); |
| 27 | + // Also get the complete dependency path to help debugging |
| 28 | + let path_output = Command::new("cargo") |
| 29 | + .args([ |
| 30 | + "tree", |
| 31 | + "-i", |
| 32 | + dependency_name, |
| 33 | + "--features=fips", |
| 34 | + "--no-default-features", |
| 35 | + ]) |
| 36 | + .output() |
| 37 | + .expect(&format!( |
| 38 | + "Failed to execute detailed cargo tree command for {}", |
| 39 | + dependency_name |
| 40 | + )); |
23 | 41 |
|
24 | | - // Also get the complete dependency path to help debugging |
25 | | - let path_output = Command::new("cargo") |
26 | | - .args([ |
27 | | - "tree", |
28 | | - "-i", |
29 | | - "ring", |
30 | | - "--features=fips", |
31 | | - "--no-default-features", |
32 | | - ]) |
33 | | - .output() |
34 | | - .expect("Failed to execute detailed cargo tree command"); |
| 42 | + let output_str = String::from_utf8_lossy(&output.stdout); |
| 43 | + let dependency_pattern = format!("{} v", dependency_name); |
35 | 44 |
|
36 | | - let output_str = String::from_utf8_lossy(&output.stdout); |
| 45 | + // Check if the dependency is in the dependency tree |
| 46 | + if output_str.contains(&dependency_pattern) { |
| 47 | + // Get the dependency paths |
| 48 | + let deps: Vec<&str> = output_str |
| 49 | + .lines() |
| 50 | + .filter(|line| line.contains(&dependency_pattern)) |
| 51 | + .collect(); |
37 | 52 |
|
38 | | - // Check if ring is in the dependency tree |
39 | | - if output_str.contains("ring v") { |
40 | | - // Get the dependency paths to ring |
41 | | - let ring_deps: Vec<&str> = output_str |
42 | | - .lines() |
43 | | - .filter(|line| line.contains("ring v")) |
44 | | - .collect(); |
| 53 | + // Get the detailed dependency path |
| 54 | + let path_str = String::from_utf8_lossy(&path_output.stdout); |
45 | 55 |
|
46 | | - // Get the detailed dependency path |
47 | | - let path_str = String::from_utf8_lossy(&path_output.stdout); |
| 56 | + // Create detailed error message with dependency paths |
| 57 | + let error_msg = format!( |
| 58 | + "\n\nERROR: {} dependency detected with FIPS feature enabled!\n\ |
| 59 | + FIPS compliance requires eliminating this dependency.\n\ |
| 60 | + \n\ |
| 61 | + {} dependency versions and features:\n{}\n\ |
| 62 | + \n\ |
| 63 | + Detailed dependency paths to {}:\n{}\n\ |
| 64 | + \n\ |
| 65 | + Ensure all dependencies use aws-lc-rs instead of non-FIPS compliant cryptographic libraries.\n\ |
| 66 | + Consider updating the following in your Cargo.toml:\n\ |
| 67 | + 1. Ensure all dependencies that use rustls have the 'aws-lc-rs' feature\n\ |
| 68 | + 2. Check transitive dependencies in reqwest, hyper-rustls, etc.\n\ |
| 69 | + 3. Update your dependencies to versions that support FIPS mode\n", |
| 70 | + dependency_name, |
| 71 | + dependency_name, |
| 72 | + deps.join("\n"), |
| 73 | + dependency_name, |
| 74 | + path_str |
| 75 | + ); |
48 | 76 |
|
49 | | - // Print detailed error message with dependency paths |
50 | | - let error_msg = format!( |
51 | | - "\n\nERROR: ring dependency detected with FIPS feature enabled!\n\ |
52 | | - FIPS compliance requires eliminating all ring dependencies.\n\ |
53 | | - \n\ |
54 | | - Ring dependency versions and features:\n{}\n\ |
55 | | - \n\ |
56 | | - Detailed dependency paths to ring:\n{}\n\ |
57 | | - \n\ |
58 | | - Ensure all dependencies use aws-lc-rs instead of ring.\n\ |
59 | | - Consider updating the following in your Cargo.toml:\n\ |
60 | | - 1. Ensure all dependencies that use rustls have the 'aws-lc-rs' feature\n\ |
61 | | - 2. Check transitive dependencies in reqwest, hyper-rustls, etc.\n\ |
62 | | - 3. Update your dependencies to versions that support FIPS mode\n", |
63 | | - ring_deps.join("\n"), |
64 | | - path_str |
65 | | - ); |
| 77 | + Err(error_msg) |
| 78 | + } else { |
| 79 | + println!("cargo:warning=No {} dependency found. FIPS compliance check passed for this dependency!", dependency_name); |
| 80 | + Ok(()) |
| 81 | + } |
| 82 | +} |
66 | 83 |
|
67 | | - panic!("{}", error_msg); |
68 | | - } else { |
69 | | - println!("cargo:warning=No ring dependency found. FIPS compliance check passed!"); |
| 84 | +fn main() { |
| 85 | + // Check if the "fips" feature is enabled |
| 86 | + let fips_enabled = std::env::var("CARGO_FEATURE_FIPS").is_ok(); |
| 87 | + |
| 88 | + if fips_enabled { |
| 89 | + println!("cargo:warning=FIPS feature is enabled, checking for forbidden dependencies..."); |
| 90 | + |
| 91 | + // List of dependencies that are not FIPS compliant |
| 92 | + let forbidden_dependencies = vec!["ring", "openssl", "boringssl"]; |
| 93 | + |
| 94 | + // Check each forbidden dependency |
| 95 | + for dependency in &forbidden_dependencies { |
| 96 | + if let Err(error_msg) = check_forbidden_dependency(dependency) { |
| 97 | + panic!("{}", error_msg); |
| 98 | + } |
70 | 99 | } |
| 100 | + |
| 101 | + println!("cargo:warning=All dependency checks passed. No forbidden dependencies found!"); |
71 | 102 | } else { |
72 | | - println!("cargo:warning=FIPS feature is not enabled, skipping ring dependency check."); |
| 103 | + println!("cargo:warning=FIPS feature is not enabled, skipping dependency checks."); |
73 | 104 | } |
74 | 105 | } |
0 commit comments