Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ target/
!**/src/main/**/target/
!**/src/test/**/target/

### Generated scan output ###
cbom.json
maven_fast/
*.tokens
*.interp
generated-sources/
.antlr/

### IntelliJ IDEA ###
.idea
*.iws
Expand Down
63 changes: 63 additions & 0 deletions cxx/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.ibm</groupId>
<artifactId>sonar-cryptography</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>

<artifactId>cxx</artifactId>

<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>com.ibm</groupId>
<artifactId>engine</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.ibm</groupId>
<artifactId>output</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.ibm</groupId>
<artifactId>enricher</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.ibm</groupId>
<artifactId>rules</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.ibm</groupId>
<artifactId>common</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.ibm</groupId>
<artifactId>mapper</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>

<!-- Dependencies -->

<!-- Test dependencies -->
<dependency>
<groupId>org.sonarsource.analyzer-commons</groupId>
<artifactId>sonar-analyzer-test-commons</artifactId>
<version>2.18.0.3393</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>
133 changes: 133 additions & 0 deletions cxx/src/main/java/com/ibm/plugin/CryptoCxxSensor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* Sonar Cryptography Plugin
* Copyright (C) 2026 PQCA
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ibm.plugin;

import com.ibm.engine.language.cxx.CxxCheck;
import com.ibm.engine.language.cxx.CxxParserErrorListener;
import com.ibm.engine.language.cxx.CxxScanContext;
import com.ibm.engine.language.cxx.antlr.CPP14Lexer;
import com.ibm.engine.language.cxx.antlr.CPP14Parser;
import java.io.IOException;
import java.util.Collection;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.rule.CheckFactory;
import org.sonar.api.batch.sensor.Sensor;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.SensorDescriptor;

public class CryptoCxxSensor implements Sensor {

private static final Logger LOG = LoggerFactory.getLogger(CryptoCxxSensor.class);

private final Collection<CxxCheck> checks;

public CryptoCxxSensor(@Nonnull CheckFactory checkFactory) {
this.checks =
checkFactory
.<CxxCheck>create(CxxScannerRuleDefinition.REPOSITORY_KEY)
.addAnnotatedChecks(CxxRuleList.getChecks())
.all();
}

@Override
public void describe(@Nonnull SensorDescriptor descriptor) {
descriptor.onlyOnLanguage("cpp").name("Cryptography for C++");
}

@Override
public void execute(@Nonnull SensorContext context) {
if (checks.isEmpty()) {
return;
}

FileSystem fs = context.fileSystem();
Iterable<InputFile> cxxFiles =
fs.inputFiles(
fs.predicates()
.and(
fs.predicates().hasLanguage("cpp"),
fs.predicates().hasType(InputFile.Type.MAIN)));

for (InputFile inputFile : cxxFiles) {
if (context.isCancelled()) {
return;
}
analyzeFile(context, inputFile);
}
}

private void analyzeFile(@Nonnull SensorContext context, @Nonnull InputFile inputFile) {
String content;
try {
content = inputFile.contents();
} catch (IOException e) {
LOG.warn("Unable to read file: {}", inputFile, e);
return;
}

CPP14Parser.TranslationUnitContext parseTree = parseContent(content, inputFile);
if (parseTree == null) {
return;
}

CxxScanContext scanContext =
new CxxScanContext(context, inputFile, CxxScannerRuleDefinition.REPOSITORY_KEY);

for (CxxCheck check : checks) {
try {
check.scan(scanContext, parseTree);
} catch (RuntimeException e) {
LOG.warn(
"Error running check {} on {}: {}",
check.getClass().getSimpleName(),
inputFile,
e.getMessage(),
e);
}
}
}

@Nullable private CPP14Parser.TranslationUnitContext parseContent(
@Nonnull String content, @Nonnull InputFile inputFile) {
try {
CPP14Lexer lexer =
new CPP14Lexer(CharStreams.fromString(content, inputFile.toString()));
lexer.removeErrorListeners();
lexer.addErrorListener(new CxxParserErrorListener(inputFile));

CommonTokenStream tokens = new CommonTokenStream(lexer);
CPP14Parser parser = new CPP14Parser(tokens);
parser.removeErrorListeners();
parser.addErrorListener(new CxxParserErrorListener(inputFile));

return parser.translationUnit();
} catch (RuntimeException e) {
LOG.warn("Unable to parse file: {}", inputFile, e);
return null;
}
}
}
42 changes: 42 additions & 0 deletions cxx/src/main/java/com/ibm/plugin/CxxAggregator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Sonar Cryptography Plugin
* Copyright (C) 2026 PQCA
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ibm.plugin;

import com.ibm.mapper.model.INode;
import java.util.ArrayList;
import java.util.List;

public final class CxxAggregator {
private static final List<INode> nodes = new ArrayList<>();

private CxxAggregator() {}

public static List<INode> getDetectedNodes() {
return new ArrayList<>(nodes);
}

public static void addNode(INode node) {
nodes.add(node);
}

public static void reset() {
nodes.clear();
}
}
31 changes: 31 additions & 0 deletions cxx/src/main/java/com/ibm/plugin/CxxCheckRegistrar.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Sonar Cryptography Plugin
* Copyright (C) 2026 PQCA
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ibm.plugin;

import org.sonar.api.scanner.ScannerSide;

// TODO: Best effort Cxx Check Registrar. Depending on sonar-cxx API, this might need to implement a
// specific interface.
@ScannerSide
public class CxxCheckRegistrar {
public void register() {
// Implementation for registering custom Cxx rules
}
}
34 changes: 34 additions & 0 deletions cxx/src/main/java/com/ibm/plugin/CxxRuleList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Sonar Cryptography Plugin
* Copyright (C) 2026 PQCA
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ibm.plugin;

import com.ibm.plugin.rules.CxxInventoryRule;
import java.util.List;

public final class CxxRuleList {

private CxxRuleList() {
// nothing
}

public static List<Class<?>> getChecks() {
return List.of(CxxInventoryRule.class);
}
}
44 changes: 44 additions & 0 deletions cxx/src/main/java/com/ibm/plugin/CxxScannerRuleDefinition.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Sonar Cryptography Plugin
* Copyright (C) 2026 PQCA
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ibm.plugin;

import org.sonar.api.server.rule.RulesDefinition;

public class CxxScannerRuleDefinition implements RulesDefinition {
public static final String REPOSITORY_KEY = "cbomkit-cryptography-cxx";

@Override
public void define(Context context) {
NewRepository repository =
context.createRepository(REPOSITORY_KEY, "cpp")
.setName("CBOMkit Cryptography Repository");

// Use RuleMetadataLoader to load metadata from annotations and resources
// For C++, we might need to manually register if we don't have the resource files yet,
// but let's try to follow the pattern or at least register the class.
for (Class<?> checkClass : CxxRuleList.getChecks()) {
repository.createRule(checkClass.getAnnotation(org.sonar.check.Rule.class).key())
.setName(checkClass.getSimpleName())
.setHtmlDescription("Detection rule for C++ cryptographic assets.");
}

repository.done();
}
}
Loading