diff --git a/cargo-cyclonedx/src/generator.rs b/cargo-cyclonedx/src/generator.rs index 945ce317..fc00bc69 100644 --- a/cargo-cyclonedx/src/generator.rs +++ b/cargo-cyclonedx/src/generator.rs @@ -180,6 +180,7 @@ impl SbomGenerator { component.scope = Some(Scope::Required); component.external_references = Self::get_external_references(package); component.licenses = self.get_licenses(package); + component.hashes = self.get_hashes(package); component.description = package .description @@ -414,6 +415,19 @@ impl SbomGenerator { Some(Licenses(licenses)) } + fn get_hashes(&self, package: &Package) -> Option { + match self.crate_hashes.get(&package.id) { + Some(hash) => Some(cyclonedx_bom::models::hash::Hashes(vec![to_bom_hash(hash)])), + None => { + log::debug!( + "Hash for package ID {} not found in Cargo.lock", + &package.id + ); + None + } + } + } + fn create_metadata(&self, package: &Package) -> Result { let authors = Self::create_authors(package); @@ -821,6 +835,22 @@ fn pkgid(pkg: &cargo_lock::Package) -> String { } } +/// Converts a checksum from the `cargo-lock` crate format to `cyclonedx-bom` crate format +fn to_bom_hash(hash: &Checksum) -> cyclonedx_bom::models::hash::Hash { + use cyclonedx_bom::models::hash::{Hash, HashAlgorithm, HashValue}; + // use a match statement to get a compile-time error + // if/when more variants are added + match hash { + Checksum::Sha256(_) => { + Hash { + alg: HashAlgorithm::SHA256, + // {:x} means "format as lowercase hex" + content: HashValue(format!("{hash:x}")), + } + } + } +} + #[derive(Error, Debug)] pub enum SbomWriterError { #[error("I/O error")]