Skip to content

Support for C/C++ Language and OpenSSL library - #377

Open
chmodshubham wants to merge 29 commits into
cbomkit:mainfrom
chmodshubham:cpp-support
Open

Support for C/C++ Language and OpenSSL library#377
chmodshubham wants to merge 29 commits into
cbomkit:mainfrom
chmodshubham:cpp-support

Conversation

@chmodshubham

Copy link
Copy Markdown

For detailed reference, follow Issue: #374.

Signed-off-by: Shubham Kumar chmodshubham@gmail.com

@chmodshubham
chmodshubham requested a review from a team as a code owner March 16, 2026 12:42
@chmodshubham

Copy link
Copy Markdown
Author

Hi @n1ckl0sk0rtge, I have a questtion regarding adding sonar-cxx plugin in parent pom.xml file. Unlike other sonar language plugins, sonar-cxx is not hosted on central maven repository. And currently, I am referencing the plugin from my local maven cache. So, can you suggest what should be the right way to reference here? Should I/cbomkit host the artifacts on github packages and then reference it in pom.xml or add instructions in readme to download the sonar-cxx plugin locally?

@chmodshubham
chmodshubham marked this pull request as draft March 16, 2026 12:56
@n1ckl0sk0rtge

Copy link
Copy Markdown
Contributor

Hi @chmodshubham, thanks for the question! I looked a bit around and think JitPack could be a good solution. JitPack builds and serves Maven artifacts directly from GitHub repositories on demand.

Something like that should work:

Add the JitPack repository to the parent pom.xml:

  <repository>    
      <id>jitpack.io</id>                                                                                                            
      <url>https://jitpack.io</url>
  </repository>          

Reference the sonar-cxx dependency using the GitHub coordinates:

  <dependency>                                                                                                                       
      <groupId>com.github.SonarOpenCommunity</groupId>
      <artifactId>sonar-cxx</artifactId>                                                                                             
      <version>{commit-hash-or-tag}</version>
  </dependency>

The first time someone builds, JitPack fetches the source from GitHub, builds it, and caches the artifact. After that it's served like any normal Maven dependency.

This avoids both the manual local install step for every contributor and the maintenance burden of hosting/re-publishing artifacts ourselves. What do you think?

@chmodshubham

Copy link
Copy Markdown
Author

Hi @n1ckl0sk0rtge,

Ohh, nice, this tool is good. It will definitely solve this hosting problem.

Btw, I have also raised the same issue in sonar-cxx, SonarOpenCommunity/sonar-cxx#3037, in the hope that they may host it like other sonar language plugins. Will look how it will resolve, and if it goes well, will not have to put effort on this; otherwise, will do it.

Though this doesn’t look like much work. Good finding. Thanks

@chmodshubham

Copy link
Copy Markdown
Author

Hi @n1ckl0sk0rtge, I have added the jitpack-based artifact build support, and it's working too. And I guess it will take a while to come to a resolution for sonar-cxx on whether to have a gh-pkg hosting or not, so it’s better to keep it this way. We can modify it once it is hosted; until then, we can use this approach.

@chmodshubham
chmodshubham marked this pull request as ready for review April 2, 2026 06:04
@san-zrl

san-zrl commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

Hi @chmodshubham,

Thank you very much for adding C/C++ language supportm to CBOMkit. This is a long-wanted feature and we greatly appreciate your contributions.

I had a look into the PR and could easily build the code. @n1ckl0sk0rtge - very good idea to use jitpack. I saw that although there is infrastructure for tests in the cpp module, there are no real test cases yet. Could you add test cases for the rules in cpp/src/main/java/com/ibm/plugin/rules?

@chmodshubham

Copy link
Copy Markdown
Author

Could you add test cases for the rules in cpp/src/main/java/com/ibm/plugin/rules?

Hi @san-zrl,

Thanks for the review.

I plan to add the tests by the end of this month or next month. Apologies for the delay. If that's fine, I can raise a separate PR for it so this one doesn't get held up. Let me know if this works.

@san-zrl

san-zrl commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Hi @chmodshubham - no problem. We will start merging when the tests are available. I'll keep this PR open until then.

@chmodshubham

Copy link
Copy Markdown
Author

Ok, sure. That will work.

@chmodshubham

Copy link
Copy Markdown
Author

Hi there,

Apologies for late following up.

I have a quick question: currently, sonar-cxx builds the AST tree after preprocessing, which causes the macros to be expanded to the underlying functions.

For example, SSL_CTX_set_min_proto_version are actually macros that expand to underlying functions like SSL_CTX_ctrl (ref). Therefore, in the detection rule, instead of matching SSL_CTX_set_min_proto_version, I had to match SSL_CTX_ctrl with the appropriate constant (123 / SSL_CTRL_SET_MIN_PROTO_VERSION).

So, does this work, or do I need to find a workaround for it?

@san-zrl

san-zrl commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Hi @chmodshubham - I think this should work. The only challenge I see is when you have macros that expand to multiple lines. In this case the location reporting would break. Don't know if this is an issue for SSL macros.

@chmodshubham

Copy link
Copy Markdown
Author

Hi @san-zrl,

I checked the sonar-cxx code to see how it handles macro expansion, specifically for multi-line macros.

So basically, sonar-cxx doesn't care whether a macro is defined on one line or spread across multiple lines. It reassembles the macro body into one logical line of text. the raw line layout in the header file doesn't matter at all.

For example,
When sonar-cxx finds SSL_CTX_set_min_proto_version in the code, it records its call site location. Then it expands the macro body and creates a new set of tokens for SSL_CTX_ctrl, (, ctx, etc. These new tokens don't hold any meaningful position at the start, not even point to ssl.h. But later, it then overwrites these new token's position with the call site's position. The AST is built from these re-stamped tokens, and that's what the detection rules run on.

So, yes, I also think sticking with writing the detection rules based on the macro expansion should be fine for now.

Moving forward with this!

chmodshubham and others added 26 commits July 28, 2026 13:15
Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
…yAction mappings

Changes over PR cbomkit#428: return the KeyAction switch result (original discarded it and always returned empty); use top-level imports to match sibling translators.

Signed-off-by: Divyateja2709 <indrakantidivyateja@gmail.com>
Co-Authored-By: Shubham Kumar <chmodshubham@gmail.com>
Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
…arnings

- Fix SSLv3/DTLS methods being incorrectly wrapped as TLS nodes in
  CxxProtocolContextTranslator; strings not starting with tls now
  emit generic Protocol nodes instead
- Add recursion into child stores in cpp TestBase.getStoresOfValueType
  so nested detection findings are correctly surfaced in tests
- Replace deprecated KeyContext(Kind)/SignatureContext(Kind) constructors
  with no-arg equivalents across all OpenSSL legacy detection rules
- Fix redundant double .stream().toList() call in CxxTranslationProcess
- Pin maven-resources-plugin version in cpp/pom.xml to silence build warning
- Fix @nonnull placement on generic method in output/Utils.java (Java 21
  rejects annotation between type parameter and return type)
- Suppress unchecked varargs warning in CxxVerifier caused by sonar-cxx
  API accepting SquidAstVisitor<Grammar>... varargs
- Add descriptive @disabled reason to JcaPRNGMapperTest documenting that
  NativePRNGBlocking mapping is not yet implemented
- Set sonar-cxx dependencies to provided scope in root pom.xml
- Remove Java 17 version override from sonar-cryptography-plugin pom.xml

Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Detection matches literal OpenSSL calls, no header expansion needed.
Also unify JRE target to 21 and use sonar-cxx fork's groupId/version.

Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
ArgSnapshot and IDetachedIssueReporter were Java-specific (hardcoded
DetachedSyntaxToken). Parameterize both over T so other languages can
supply their own AST-free location type for cross-file detachment.

Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Add CxxDetachedAstNode/CxxDetachedIssueReporter and wire them through
CxxDetectionEngine/CxxLanguageSupport/CxxSemantic, mirroring the Java
detachment path now that the engine types are language-generic.

CxxBaseDetectionRule also runs CxxSymbolResolverVisitor ahead of
detection in visitFile (it otherwise only populates on visit/leaveNode,
too late for this class's own traversal) and detaches recorded calls
in leaveFile so a finished file's AST can be garbage-collected.

Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
With CxxSymbolResolverVisitor now populated before detection, numeric
NID codes, EVP fetch algorithm names, params, and key-size bits can be
read from resolved symbols instead of literal string/int matches.

Introduces OpenSSLNidLookupFactory, OpenSSLParamsScannerFactory,
OpenSSLKeygenBitsFactory, OpenSSLNameCanonicalizerFactory, and
OpenSSLCipherFetchFactory, and updates the cipher/kdf/keygen/digest/
legacy/mac/rand/signature/keyagreement rules plus the context
translators to consume the resulting Algorithm values. ANSIX942 also
gains a MessageDigest child to carry the resolved hash.

Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
TLS version now resolved from the *_method() call, replacing the old
version lookup table. Also detect set1_groups_list/set1_sigalgs_list
via new OpenSslGroupMapper/OpenSslSignatureMapper.

Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Map TLS 1.3's ASCONAEAD128 to the new AsconAead128 model.

Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
The ciphersuites.info API leaves enc/hash empty for some TLS 1.3
suites since there's no negotiable kex/auth to split on. Recover them
from the suite name instead, matched against known hash suffixes
(longest first, so SHA3_256 isn't mis-split). Regenerate
JsonCipherSuites from the corrected data.

Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
…pher calls

Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
… multiple modules

Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
…assignment)

Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
…pper

Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
Signed-off-by: Shubham Kumar <chmodshubham@gmail.com>
@chmodshubham

Copy link
Copy Markdown
Author

Hi, thanks for pointing out such issues. I have resolved all of them; here are explanations for some points:

9. Build-time OpenSSL download. Every clean cpp build downloads the OpenSSL 3.6.2 tarball from GitHub and runs perl Configure (cpp/pom.xml), which makes CI flaky and offline builds impossible. A cached download with a checksum, or a committed pruned header subset, would be more robust. (Side note: ${openssl.skip.configure} is defined — the Copilot flag on that was stale.)

I have removed the OpenSSL headers completely from the build. Initially, I was not including these headers in the final jar file (was only testing with the test suite), due to which the sonar-cxx preprocessor was not able to expand the macros properly during scanning. Later, I included them in the jar file, and it worked completely fine during scanning. However, I realized that in the future, as support for more libraries gets added, more headers will need to be included in the jar file, which will keep increasing the final artifact size.

So I checked how other languages are dealing with this, and noticed that they don't include their headers/classpaths at all - yet they're still able to discover findings. The other language libs define the raw APIs (not expanded macros) in the rules and don't include the classpath at all, and are still able to detect the crypto primitives. The only side effect is that the debug logs show something like "preprocessor can't find that path/file" and skip expanding it, which seems fine as long as we're still able to detect the crypto assets. On top of that, this means we no longer need to worry about expanded forms at all.

Let me know your thoughts.

7. No fixture exercises symbol resolution. Every algorithm argument in the fixtures is a direct string literal, so the sonar-cxx 2.3.0 Symbol support you upstreamed (the headline feature of #374) never actually runs in tests. One fixture along the lines of const char* alg = "AES-128-GCM"; EVP_CIPHER_fetch(NULL, alg, NULL); would cover it.

Thanks for pointing this out. On checking sonar-cxx, I realized the symbol resolution API (Symbol/SymbolTable interfaces, accessor methods) was added by me, but nothing actually populated the table — there was no visitor walking the AST to resolve declarations. So I raised another PR on sonar-cxx adding that visitor along with the concrete implementation (such as Symbol/TypeSymbol/VariableSymbol/FunctionSymbol) behind it.

For now, I'm temporarily pointing at my local fork of sonar-cxx so others can test it. Once it's merged upstream, I'll update the pom file to the sonar-cxx repo's commit.

Ready for review again.

@chmodshubham
chmodshubham marked this pull request as ready for review August 4, 2026 19:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants