@@ -180,6 +180,7 @@ impl SbomGenerator {
180
180
component. scope = Some ( Scope :: Required ) ;
181
181
component. external_references = Self :: get_external_references ( package) ;
182
182
component. licenses = self . get_licenses ( package) ;
183
+ component. hashes = self . get_hashes ( package) ;
183
184
184
185
component. description = package
185
186
. description
@@ -414,6 +415,19 @@ impl SbomGenerator {
414
415
Some ( Licenses ( licenses) )
415
416
}
416
417
418
+ fn get_hashes ( & self , package : & Package ) -> Option < cyclonedx_bom:: models:: hash:: Hashes > {
419
+ match self . crate_hashes . get ( & package. id ) {
420
+ Some ( hash) => Some ( cyclonedx_bom:: models:: hash:: Hashes ( vec ! [ to_bom_hash( hash) ] ) ) ,
421
+ None => {
422
+ log:: debug!(
423
+ "Hash for package ID {} not found in Cargo.lock" ,
424
+ & package. id
425
+ ) ;
426
+ None
427
+ }
428
+ }
429
+ }
430
+
417
431
fn create_metadata ( & self , package : & Package ) -> Result < Metadata , GeneratorError > {
418
432
let authors = Self :: create_authors ( package) ;
419
433
@@ -821,6 +835,22 @@ fn pkgid(pkg: &cargo_lock::Package) -> String {
821
835
}
822
836
}
823
837
838
+ /// Converts a checksum from the `cargo-lock` crate format to `cyclonedx-bom` crate format
839
+ fn to_bom_hash ( hash : & Checksum ) -> cyclonedx_bom:: models:: hash:: Hash {
840
+ use cyclonedx_bom:: models:: hash:: { Hash , HashAlgorithm , HashValue } ;
841
+ // use a match statement to get a compile-time error
842
+ // if/when more variants are added
843
+ match hash {
844
+ Checksum :: Sha256 ( _) => {
845
+ Hash {
846
+ alg : HashAlgorithm :: SHA256 ,
847
+ // {:x} means "format as lowercase hex"
848
+ content : HashValue ( format ! ( "{hash:x}" ) ) ,
849
+ }
850
+ }
851
+ }
852
+ }
853
+
824
854
#[ derive( Error , Debug ) ]
825
855
pub enum SbomWriterError {
826
856
#[ error( "I/O error" ) ]
0 commit comments