feat: add Go crypto/x509 detection rules#434
Conversation
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds Go crypto/x509 detection coverage to the plugin, including rule registration and tests validating expected detections and translations.
Changes:
- Introduces new detection rules for
crypto/x509parsing/marshalling APIs (X509/PKCS1/PKCS8/EC). - Extends context translation to map new
kindvalues (X509/PKCS1/PKCS8) to appropriate node types. - Adds a Go fixture and a JUnit test to exercise and validate all new detections.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| go/src/test/java/com/ibm/plugin/rules/detection/gocrypto/GoCryptoX509Test.java | Adds a JUnit test asserting detections/translations for crypto/x509 APIs. |
| go/src/test/files/rules/detection/gocrypto/GoCryptoX509TestFile.go | Adds a Go fixture calling relevant crypto/x509 functions (Noncompliant markers). |
| go/src/main/java/com/ibm/plugin/translation/translator/contexts/GoKeyContextTranslator.java | Adds translation mappings for new kind values (X509/PKCS1/PKCS8). |
| go/src/main/java/com/ibm/plugin/rules/detection/gocrypto/GoCryptoX509.java | Introduces the new crypto/x509 detection rule set. |
| go/src/main/java/com/ibm/plugin/rules/detection/GoDetectionRules.java | Registers the new GoCryptoX509 rules into the Go rule list. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| import com.ibm.engine.model.IValue; | ||
| import com.ibm.engine.model.OperationMode; | ||
| import com.ibm.engine.model.ValueAction; | ||
| import com.ibm.engine.model.context.PrivateKeyContext; | ||
| import com.ibm.engine.model.context.PublicKeyContext; | ||
| import com.ibm.engine.model.context.KeyContext; |
| import com.ibm.plugin.rules.detection.GoDetectionRules; | ||
| import java.util.List; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.sonar.java.checks.verifier.CheckVerifier; |
| .map(iValue -> translator.translate(store.getBundle(), iValue, store.getDetectionContext(iValue), store.getDetectionLocation(iValue)).orElse(null)) | ||
| .toList(); | ||
|
|
||
| // Crazy tester mode activated | ||
| // just making sure we hit all 13 rules properly. | ||
| assertThat(nodes).hasSize(13); | ||
|
|
||
| // I guess I should make sure they aren't null | ||
| for (INode node : nodes) { | ||
| assertThat(node).isNotNull(); | ||
| } | ||
|
|
| // x509.ParseCertificate(der []byte) (*Certificate, error) | ||
| private static final IDetectionRule<Tree> PARSE_CERTIFICATE = | ||
| new DetectionRuleBuilder<Tree>() | ||
| .createDetectionRule() | ||
| .forObjectTypes("crypto/x509") | ||
| .forMethods("ParseCertificate") | ||
| .shouldBeDetectedAs(new ValueActionFactory<>("X509")) | ||
| .withMethodParameter("[]byte") | ||
| .buildForContext(new KeyContext(Map.of("kind", "X509"))) |
There was a problem hiding this comment.
Hi @pranjal2004838 -Thanks for trying to tackle the missing X509 support in Go.
Your PR does not achieve what true support for X509 should deliver. The idea behind this project is to generate CBOMs that describe detected crypto assets using the correct CycloneDX abstractions (https://cyclonedx.org/docs/1.6/json/#metadata_tools_oneOf_i0_components_items_cryptoProperties). Depending on the X509 method call in Go, this would be an asset of type "certificate" (with populated certificateProperties which implies parsing the certificate) for a PARSE_CERTIFICATE call, or "related-crypto-material" objects representing public and private keys. For X509 certificate requests there is no corresponding CBOM abstraction. This makes implementing X509 support a much more complicated task.
Please have a look into GoCryptoTLSRules.java. This is an example for creating the correct abstractions for TLS.
If you want to continue working on this I'd be happy to review a changed version of this PR.
|
Sure, I'll update you!!! |
|
I created a dedicated Certificate context and builder to handle certificate parsing calls, so they properly map to the 'certificate' asset type in the output JSON. For the private and public key parsing calls, I updated the Go translator to wrap them in proper PrivateKey and PublicKey nodes so they show up as 'related-crypto-material' instead of just turning into random algorithm blocks or nothing. I also ended up dropping the rules for ParseCertificateRequest and CreateCertificateRequest entirely. Since CycloneDX doesn't actually have a standard abstraction for CSRs, there was no clean way to represent them, and keeping them around was just going to bloat the CBOM with junk data. I updated the tests to assert the correct counts—we're now expecting 3 certificates, 6 private keys, and 2 public keys based on the test file. Everything passes locally on my end. Let me know if this looks good enough to merge |
|
Thanks @pranjal2004838 for updating the PR. |
|
Please make sure that the PR compiles and does not break the tests by running |
…and keys Signed-off-by: pranjal2004838 <pranjaljha58@gmail.com>
c7c99aa to
5bb04d2
Compare
PR 420 was completely broken because it passed empty constructors to PublicKeyContext and PrivateKeyContext. They require a map with the kind set. Also added the missing translation mappings for X509, PKCS1, and PKCS8 so the engine actually works. Tests are included.
Closes issue #418