Skip to content

Commit 5811261

Browse files
cursoragentscript3r
andcommitted
Refactor: Improve algorithm deduplication and add libsodium support
This commit refactors the algorithm deduplication logic to correctly merge algorithms with varying parameter specificity. It also introduces support for detecting algorithms from the libsodium library by adding new patterns to `patterns.toml` and creating a new fixture `libsodium-modern`. Additionally, several other fixtures have been updated with new UUIDs and timestamps to reflect the changes. Co-authored-by: script3r <[email protected]>
1 parent aec7825 commit 5811261

File tree

19 files changed

+491
-545
lines changed

19 files changed

+491
-545
lines changed

crates/cbom-generator/src/algorithm_detector.rs

Lines changed: 49 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,7 @@ impl AlgorithmDetector {
4444
self.extract_algorithms_from_finding_with_registry(finding, registry)?
4545
{
4646
for asset in algorithm_assets {
47-
let key = format!(
48-
"{}:{}",
49-
asset.name.as_ref().unwrap_or(&"unknown".to_string()),
50-
asset.bom_ref
51-
);
47+
let key = self.create_deduplication_key(&asset);
5248
if seen_algorithms.insert(key) {
5349
algorithms.push(asset);
5450
}
@@ -60,11 +56,7 @@ impl AlgorithmDetector {
6056
let additional_algorithms =
6157
self.perform_deep_static_analysis_with_registry(scan_path, registry)?;
6258
for asset in additional_algorithms {
63-
let key = format!(
64-
"{}:{}",
65-
asset.name.as_ref().unwrap_or(&"unknown".to_string()),
66-
asset.bom_ref
67-
);
59+
let key = self.create_deduplication_key(&asset);
6860
if seen_algorithms.insert(key) {
6961
algorithms.push(asset);
7062
}
@@ -76,11 +68,7 @@ impl AlgorithmDetector {
7668
self.extract_algorithms_from_finding_fallback(finding)?
7769
{
7870
for asset in algorithm_assets {
79-
let key = format!(
80-
"{}:{}",
81-
asset.name.as_ref().unwrap_or(&"unknown".to_string()),
82-
asset.bom_ref
83-
);
71+
let key = self.create_deduplication_key(&asset);
8472
if seen_algorithms.insert(key) {
8573
algorithms.push(asset);
8674
}
@@ -89,7 +77,9 @@ impl AlgorithmDetector {
8977
}
9078
}
9179

92-
Ok(algorithms)
80+
// Merge duplicate algorithms with different parameter specificity
81+
let merged_algorithms = self.merge_algorithm_assets(algorithms);
82+
Ok(merged_algorithms)
9383
}
9484

9585
/// Extract algorithms from finding using pattern registry
@@ -326,6 +316,49 @@ impl AlgorithmDetector {
326316
Ok(algorithms)
327317
}
328318

319+
/// Create a proper deduplication key based on algorithm properties, not bom_ref
320+
fn create_deduplication_key(&self, asset: &CryptoAsset) -> String {
321+
match &asset.asset_properties {
322+
AssetProperties::Algorithm(props) => {
323+
// For deduplication, use algorithm name and primitive only
324+
// This will merge different parameter variations of the same algorithm
325+
format!("{}:{}",
326+
asset.name.as_ref().unwrap_or(&"unknown".to_string()),
327+
props.primitive as u8
328+
)
329+
}
330+
_ => format!("{}:{}",
331+
asset.name.as_ref().unwrap_or(&"unknown".to_string()),
332+
asset.bom_ref
333+
)
334+
}
335+
}
336+
337+
/// Merge algorithm assets with the same name/primitive but different parameters
338+
fn merge_algorithm_assets(&self, assets: Vec<CryptoAsset>) -> Vec<CryptoAsset> {
339+
let mut merged_map: HashMap<String, CryptoAsset> = HashMap::new();
340+
341+
for asset in assets {
342+
let key = self.create_deduplication_key(&asset);
343+
344+
if let Some(existing) = merged_map.get_mut(&key) {
345+
// Merge parameters if the new asset has more specific information
346+
if let (AssetProperties::Algorithm(existing_props), AssetProperties::Algorithm(new_props)) =
347+
(&mut existing.asset_properties, &asset.asset_properties) {
348+
349+
// If existing has no parameters but new one does, use the new parameters
350+
if existing_props.parameter_set.is_none() && new_props.parameter_set.is_some() {
351+
existing_props.parameter_set = new_props.parameter_set.clone();
352+
}
353+
}
354+
} else {
355+
merged_map.insert(key, asset);
356+
}
357+
}
358+
359+
merged_map.into_values().collect()
360+
}
361+
329362
// Essential helper methods for fallback scenarios
330363

331364
fn create_rsa_algorithm(&self, key_size: u32) -> CryptoAsset {

crates/cbom-generator/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ pub struct RelatedCryptoMaterialProperties {
144144
}
145145

146146
/// Classification of cryptographic primitives
147-
#[derive(Debug, Clone, Serialize, Deserialize)]
147+
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
148148
#[serde(rename_all = "lowercase")]
149149
pub enum CryptographicPrimitive {
150150
#[serde(rename = "pke")]
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"bomFormat": "MV-CBOM",
3+
"specVersion": "1.0",
4+
"serialNumber": "urn:uuid:470fe928-c629-4bc7-963f-7a023373c518",
5+
"version": 1,
6+
"metadata": {
7+
"component": {
8+
"name": "libsodium-modern",
9+
"path": "/workspace/fixtures/c/libsodium-modern"
10+
},
11+
"timestamp": "2025-09-15T19:35:58.450272085Z",
12+
"tools": [
13+
{
14+
"name": "cipherscope",
15+
"version": "0.1.0",
16+
"vendor": "CipherScope Contributors"
17+
}
18+
]
19+
},
20+
"cryptoAssets": [
21+
{
22+
"bom-ref": "16690765-56ee-4f2b-9e6e-fe748850c616",
23+
"assetType": "algorithm",
24+
"name": "X25519",
25+
"assetProperties": {
26+
"primitive": "kem",
27+
"nistQuantumSecurityLevel": 0
28+
}
29+
},
30+
{
31+
"bom-ref": "623fb39a-2f53-441f-94ec-08e8b54ca424",
32+
"assetType": "algorithm",
33+
"name": "BLAKE2b",
34+
"assetProperties": {
35+
"primitive": "hash",
36+
"nistQuantumSecurityLevel": 3
37+
}
38+
},
39+
{
40+
"bom-ref": "1e732469-0895-4854-93d1-fce78ae23345",
41+
"assetType": "algorithm",
42+
"name": "ChaCha20Poly1305",
43+
"assetProperties": {
44+
"primitive": "aead",
45+
"nistQuantumSecurityLevel": 3
46+
}
47+
},
48+
{
49+
"bom-ref": "0dd2d57e-101a-44c0-87cb-9027a2b7ac56",
50+
"assetType": "algorithm",
51+
"name": "Ed25519",
52+
"assetProperties": {
53+
"primitive": "signature",
54+
"nistQuantumSecurityLevel": 0
55+
}
56+
}
57+
],
58+
"dependencies": []
59+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"bomFormat": "MV-CBOM",
3+
"specVersion": "1.0",
4+
"serialNumber": "urn:uuid:9ae8429f-3631-4e2c-9a90-a0326818997d",
5+
"version": 1,
6+
"metadata": {
7+
"component": {
8+
"name": "makefile-crypto",
9+
"path": "/workspace/fixtures/c/makefile-crypto"
10+
},
11+
"timestamp": "2025-09-15T19:35:58.472153385Z",
12+
"tools": [
13+
{
14+
"name": "cipherscope",
15+
"version": "0.1.0",
16+
"vendor": "CipherScope Contributors"
17+
}
18+
]
19+
},
20+
"cryptoAssets": [
21+
{
22+
"bom-ref": "62aaec88-6e0c-45a5-a415-b8cfa87bc35e",
23+
"assetType": "algorithm",
24+
"name": "RSA",
25+
"assetProperties": {
26+
"primitive": "signature",
27+
"nistQuantumSecurityLevel": 0
28+
}
29+
}
30+
],
31+
"dependencies": [
32+
{
33+
"ref": "8f754482-fc81-4702-b3b7-25e67376b287",
34+
"dependsOn": [
35+
"62aaec88-6e0c-45a5-a415-b8cfa87bc35e"
36+
],
37+
"dependencyType": "implements"
38+
}
39+
]
40+
}

fixtures/c/openssl-mixed/mv-cbom.json

Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
{
22
"bomFormat": "MV-CBOM",
33
"specVersion": "1.0",
4-
"serialNumber": "urn:uuid:fc0dc0c3-dddc-4a08-9bb5-ec9e8c57513d",
4+
"serialNumber": "urn:uuid:807b91e0-f7ed-4066-b79c-28514ac1adb2",
55
"version": 1,
66
"metadata": {
77
"component": {
88
"name": "openssl-mixed",
99
"path": "/workspace/fixtures/c/openssl-mixed"
1010
},
11-
"timestamp": "2025-09-15T19:16:12.263741214Z",
11+
"timestamp": "2025-09-15T19:35:58.494965345Z",
1212
"tools": [
1313
{
1414
"name": "cipherscope",
@@ -19,34 +19,7 @@
1919
},
2020
"cryptoAssets": [
2121
{
22-
"bom-ref": "5da73c7c-874f-4a4a-bdd5-b788a4fd9828",
23-
"assetType": "algorithm",
24-
"name": "RSA",
25-
"assetProperties": {
26-
"primitive": "signature",
27-
"nistQuantumSecurityLevel": 0
28-
}
29-
},
30-
{
31-
"bom-ref": "949c682f-245a-48ac-929c-321883f113e5",
32-
"assetType": "algorithm",
33-
"name": "RSA",
34-
"assetProperties": {
35-
"primitive": "signature",
36-
"nistQuantumSecurityLevel": 0
37-
}
38-
},
39-
{
40-
"bom-ref": "21e6b5c1-a73c-4f06-9e65-2abb21dc7b8a",
41-
"assetType": "algorithm",
42-
"name": "RSA",
43-
"assetProperties": {
44-
"primitive": "signature",
45-
"nistQuantumSecurityLevel": 0
46-
}
47-
},
48-
{
49-
"bom-ref": "d9ad0e25-6a6a-4795-b6c6-6fe43df020d9",
22+
"bom-ref": "c266f971-0159-4e9e-b87e-c96ab6a04852",
5023
"assetType": "algorithm",
5124
"name": "ChaCha20Poly1305",
5225
"assetProperties": {
@@ -55,20 +28,20 @@
5528
}
5629
},
5730
{
58-
"bom-ref": "d17963d8-afc3-4d9d-9639-40207e59cba2",
31+
"bom-ref": "74d1ed1a-7841-4ccf-99e7-ae80f96df729",
5932
"assetType": "algorithm",
60-
"name": "ChaCha20Poly1305",
33+
"name": "RSA",
6134
"assetProperties": {
62-
"primitive": "aead",
63-
"nistQuantumSecurityLevel": 3
35+
"primitive": "signature",
36+
"nistQuantumSecurityLevel": 0
6437
}
6538
}
6639
],
6740
"dependencies": [
6841
{
69-
"ref": "9913e268-477a-44bd-b83c-e4507a13a864",
42+
"ref": "f2ce9aef-23b3-4df1-8030-4c8d0fc04054",
7043
"dependsOn": [
71-
"5da73c7c-874f-4a4a-bdd5-b788a4fd9828"
44+
"74d1ed1a-7841-4ccf-99e7-ae80f96df729"
7245
],
7346
"dependencyType": "implements"
7447
}

fixtures/certificates/x509-rsa-ecdsa/mv-cbom.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
{
22
"bomFormat": "MV-CBOM",
33
"specVersion": "1.0",
4-
"serialNumber": "urn:uuid:7eba9f44-8183-4dce-b2bd-6f6fad1fd26a",
4+
"serialNumber": "urn:uuid:ffb30bcc-15d8-4f2f-828d-5e7f09480a96",
55
"version": 1,
66
"metadata": {
77
"component": {
88
"name": "x509-rsa-ecdsa",
99
"path": "/workspace/fixtures/certificates/x509-rsa-ecdsa"
1010
},
11-
"timestamp": "2025-09-15T17:49:58.531299222Z",
11+
"timestamp": "2025-09-15T19:35:58.623962548Z",
1212
"tools": [
1313
{
1414
"name": "cipherscope",
@@ -19,34 +19,34 @@
1919
},
2020
"cryptoAssets": [
2121
{
22-
"bom-ref": "7a29490d-27fa-4d82-aa39-27ab91a0a9bc",
22+
"bom-ref": "18cec8f3-46fd-4392-88e1-b182a89e2348",
2323
"assetType": "certificate",
2424
"name": "ecdsa-example.com",
2525
"assetProperties": {
2626
"subjectName": "C=US, ST=CA, L=San Francisco, O=Test Corp, CN=ecdsa-example.com",
2727
"issuerName": "C=US, ST=CA, L=San Francisco, O=Test Corp, CN=ecdsa-example.com",
2828
"notValidAfter": "2026-09-15T17:49:42Z",
29-
"signatureAlgorithmRef": "903241ad-6fae-46f8-b395-fe93bd6f52c6"
29+
"signatureAlgorithmRef": "d6fd640e-eda2-4c32-98c3-79da61856e87"
3030
}
3131
},
3232
{
33-
"bom-ref": "1a7972ac-3422-4be1-a8d4-3fe8e41da29e",
33+
"bom-ref": "284ea65f-e698-4a74-9912-ce2bb6ba0c4d",
3434
"assetType": "certificate",
3535
"name": "rsa-example.com",
3636
"assetProperties": {
3737
"subjectName": "C=US, ST=CA, L=San Francisco, O=Test Corp, CN=rsa-example.com",
3838
"issuerName": "C=US, ST=CA, L=San Francisco, O=Test Corp, CN=rsa-example.com",
3939
"notValidAfter": "2026-09-15T17:49:26Z",
40-
"signatureAlgorithmRef": "a234cafc-99bb-4966-9f60-c38eca7bde88"
40+
"signatureAlgorithmRef": "f8473c88-dd07-4a2b-867d-52a0896747a5"
4141
}
4242
}
4343
],
4444
"dependencies": [
4545
{
46-
"ref": "279603a2-45e4-4c9a-870d-4d03165ebb97",
46+
"ref": "3ab8a56c-fef7-46af-b957-1e48116db024",
4747
"dependsOn": [
48-
"7a29490d-27fa-4d82-aa39-27ab91a0a9bc",
49-
"1a7972ac-3422-4be1-a8d4-3fe8e41da29e"
48+
"284ea65f-e698-4a74-9912-ce2bb6ba0c4d",
49+
"18cec8f3-46fd-4392-88e1-b182a89e2348"
5050
],
5151
"dependencyType": "uses"
5252
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"bomFormat": "MV-CBOM",
3+
"specVersion": "1.0",
4+
"serialNumber": "urn:uuid:c1deb27e-4d9b-4ad1-8b73-7fa82adfbdfd",
5+
"version": 1,
6+
"metadata": {
7+
"component": {
8+
"name": "stdlib-crypto-fixture",
9+
"version": "1.19",
10+
"path": "/workspace/fixtures/go/stdlib-crypto"
11+
},
12+
"timestamp": "2025-09-15T19:35:58.516104704Z",
13+
"tools": [
14+
{
15+
"name": "cipherscope",
16+
"version": "0.1.0",
17+
"vendor": "CipherScope Contributors"
18+
}
19+
]
20+
},
21+
"cryptoAssets": [
22+
{
23+
"bom-ref": "28113262-9793-4a1a-8f06-4c2d655e6319",
24+
"assetType": "algorithm",
25+
"name": "RSA",
26+
"assetProperties": {
27+
"primitive": "signature",
28+
"nistQuantumSecurityLevel": 0
29+
}
30+
}
31+
],
32+
"dependencies": []
33+
}

0 commit comments

Comments
 (0)