Skip to content

feat: experimental crypto behavior taxonomy in CBOM (Part A + B)#475

Draft
n1ckl0sk0rtge wants to merge 46 commits into
mainfrom
feature/crypto-behavior-taxonomy
Draft

feat: experimental crypto behavior taxonomy in CBOM (Part A + B)#475
n1ckl0sk0rtge wants to merge 46 commits into
mainfrom
feature/crypto-behavior-taxonomy

Conversation

@n1ckl0sk0rtge

@n1ckl0sk0rtge n1ckl0sk0rtge commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary (experimental)

Adds experimental CycloneDX 2.0-dev cryptographic-behavior information to the generated CBOM. The scanned software's crypto behaviors are aggregated across all detected assets and emitted once as a single cbomkit:crypto:behavior property on metadata.component. The behavior taxonomy is a draft (CycloneDX 2.0-dev-threatmodeling), so a local snapshot is bundled and the value is a namespaced, non-standard property.

Delivered in two parts (both in this PR).

Part A — behavior mapping + CBOM output (output module)

  • crypto-behavior-taxonomy.json — local verbatim snapshot of the draft security:cryptography:* taxonomy.
  • CryptoBehavior enum (14 emitted identifiers), fullId()security:cryptography:<leaf>; enum↔JSON sync test.
  • CryptoBehaviorMapper — pure/total map(INode): operation-first mapping (Functionality children + exact primitive kind) with a primitive-kind fallback; emits operational (encryptsData, signsData, …) + security-goal (ensuresConfidentiality/Integrity/NonRepudiation, authenticates) behaviors.
  • CBOMOutputFile — accumulates behaviors across the whole scan (incl. protocol/cipher-suite constituents) and emits the sorted, comma-joined union on a metadata.component (type APPLICATION); none when no crypto is detected.

Part B — curated detection (so more behaviors fire on real code)

  • wrapsKey: detect Cipher.unwrapDecapsulate (new CipherAction.UNWRAP); treat KeyWrap-kind ciphers (AESWrap/DESedeWrap) as ciphers in the mapper.
  • generatesRandomValue: generic PRNG model + JcaPRNGMapper DRBG names; register the previously-orphaned Random detection bundle; detect SecureRandom.getInstance(String) / getInstanceStrong() / no-arg new SecureRandom(); JavaPRNGContextTranslator attaches a Generate functionality to the PRNG node.

⚠️ Design note: no-arg new SecureRandom() detection is broad — it emits a PRNG component + generatesRandomValue for essentially every project that instantiates one (including as key-gen scaffolding). This is accurate for a CBOM but notably increases output; ~25 sample test files had incidental new SecureRandom() scaffolding removed to keep unrelated detection tests focused.

Known taxonomy gaps (documented)

  • MAC has no operational verb → goal-level authenticates + ensuresIntegrity.
  • Generic (non-password) KDF has no "deriveKey" → approximated as generatesKey.

Docs

  • Spec: docs/superpowers/specs/2026-07-03-crypto-behavior-taxonomy-design.md
  • Plans: docs/superpowers/plans/2026-07-03-crypto-behavior-taxonomy.md (Part A), …-part-b.md (Part B)

Deferred (spec §8)

Data-context (*DataAtRest/InTransit/Disk), KeyStore lifecycle, PKI/cert behaviors.

Testing

Full multi-module mvn test — BUILD SUCCESS (all modules green). Additive: existing CBOM component/dependency output is unchanged.

Signed-off-by: Nicklas Körtge <Nicklas.Koertge1@ibm.com>
…olish

FIX 1: Move behaviour accumulation from add() forEach into createAlgorithmComponent()
so TLS/cipher-suite constituent algorithms (reached via direct calls) now contribute
their behaviours to metadata.component; add regression test (RED→GREEN).
FIX 2: Relocate CryptoBehaviorTaxonomyTest to correctly-spelled cyclonedx package
(git mv); add CryptoBehavior import now required from different package.
FIX 3: Extend CryptoBehaviorMapperTest with 11 new cases covering Decrypt/Verify/
Digest/Tag/KeyGeneration operations, GenericKDF, AE/PKE/KEM/PRNG fallbacks, and
non-Algorithm empty-return.
FIX 4: Reference CryptoBehaviorMapper.BEHAVIOR_PROPERTY_NAME constant instead of
inline string literal in CryptoBehaviorMetadataTest.
FIX 5: Document METADATA_COMPONENT_NAME intentional simplification (spec §4.4).
…unwrap-test comments

- Add CryptoBehaviorMapperTest.decapsulateOnKeyWrapCipherYieldsWrapsKey() to verify Decapsulate
  functionality yields wrapsKey behavior on KeyWrap ciphers
- Add clarifying comment on SECURE_RANDOM_NO_ARG probe key indirection (maps to generic PRNG)
- Add comment on JcaCipherUnwrapTest scope noting end-to-end behavior validated elsewhere
@n1ckl0sk0rtge n1ckl0sk0rtge changed the title feat(output): experimental crypto behavior taxonomy in CBOM (Part A) feat: experimental crypto behavior taxonomy in CBOM (Part A + B) Jul 4, 2026
The SecureRandom key-generation scaffolding removed from detection tests
in this branch is restored, now that new SecureRandom()/getInstance is
itself detected as a PRNG asset.

Each restored construct is annotated with the expected PRNG finding, and
every affected asserts() gains a PRNGContext guard so the extra finding
is accounted for without disturbing the existing cipher assertions.
findingId-keyed tests are renumbered for the interleaved PRNG findings.

All 25 affected tests pass; full java suite green (162 tests, 7 skipped).
Follow the BouncyCastleJars convention: hand the analyzer a curated,
version-pinned set of API jars from src/test/resources/test-jars via
AuthInterfaceJars, instead of reflecting the whole JUnit runtime
classpath. Type resolution is now deterministic and self-contained.
The pom test deps are retained solely for IDE linting of the detection
test files.
Emit crypto behaviors as a plain, comma-joined list of ids instead of a
confidence-suffixed one. BehaviorInferenceEngine.infer now returns a
Set<CryptoBehavior> rather than Map<CryptoBehavior, Confidence>, and the
cbomkit:crypto:behavior property value drops the =high/=medium suffix.

The two-tier gating model is unchanged: a MAC alone still does not assert
authenticates, and auth-interface primaries still unlock authenticates/
validatesToken/usesIdentity.

Delete the Confidence enum and its test; update the design docs and plans
to match.
The BouncyCastle detection rules expand into a ~520k-object in-memory
graph, which can exhaust the forked Scanner Engine heap during rule
construction (OutOfMemoryError in MethodMatcher.<init>). Document the
-Dsonar.scanner.javaOpts=-Xmx2g workaround in the scan guide.

Permanent fix (rule-graph memoization) tracked in #476.
The mvn sonar:sonar path runs the scanner engine inside the Maven JVM,
so -Dsonar.scanner.javaOpts / SONAR_SCANNER_JAVA_OPTS are ignored (those
only affect the standalone sonar-scanner CLI). Set MAVEN_OPTS=-Xmx4g
instead; document both knobs and bump to 4g for headroom.
…ven 5.0+

Scanner-for-Maven 5.0+ (bundled with recent SonarQube) forks the Scanner
Engine into its own JVM (ScannerMain), whose heap is set by
SONAR_SCANNER_JAVA_OPTS, not MAVEN_OPTS. MAVEN_OPTS only applied to
scanner <= 4.x where the engine ran in-process. Prior commit had this
backwards.
…est`

Signed-off-by: Nicklas Körtge <Nicklas.Koertge1@ibm.com>
…or-taxonomy

# Conflicts:
#	java/src/main/java/com/ibm/plugin/rules/detection/jca/cipher/JcaCipherWrap.java
#	java/src/main/java/com/ibm/plugin/rules/detection/random/SecureRandomGetInstance.java
@n1ckl0sk0rtge

Copy link
Copy Markdown
Contributor Author

Example CBOM output for Keycloak

cbom.json

@n1ckl0sk0rtge n1ckl0sk0rtge self-assigned this Jul 5, 2026
@n1ckl0sk0rtge n1ckl0sk0rtge added the enhancement New feature or request label Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant