diff --git a/pom.xml b/pom.xml index 711ae28..3a768cf 100644 --- a/pom.xml +++ b/pom.xml @@ -13,7 +13,7 @@ 21 UTF-8 - 1.5.1 + 2.0.0-SNAPSHOT 13.4.3.4290 25.8.0.112029 diff --git a/src/main/java/org/pqca/indexing/csharp/CSharpBuildType.java b/src/main/java/org/pqca/indexing/csharp/CSharpBuildType.java new file mode 100644 index 0000000..0b31547 --- /dev/null +++ b/src/main/java/org/pqca/indexing/csharp/CSharpBuildType.java @@ -0,0 +1,26 @@ +/* + * CBOMkit-lib + * Copyright (C) 2025 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 + * + * https://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 org.pqca.indexing.csharp; + +import org.pqca.indexing.IBuildType; + +public enum CSharpBuildType implements IBuildType { + CSPROJ +} diff --git a/src/main/java/org/pqca/indexing/csharp/CSharpIndexService.java b/src/main/java/org/pqca/indexing/csharp/CSharpIndexService.java new file mode 100644 index 0000000..541aebf --- /dev/null +++ b/src/main/java/org/pqca/indexing/csharp/CSharpIndexService.java @@ -0,0 +1,72 @@ +/* + * CBOMkit-lib + * Copyright (C) 2024 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 + * + * https://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 org.pqca.indexing.csharp; + +import jakarta.annotation.Nonnull; +import java.io.File; +import java.util.List; +import javax.annotation.Nullable; +import org.pqca.indexing.IBuildType; +import org.pqca.indexing.IndexingService; +import org.pqca.progress.IProgressDispatcher; + +public final class CSharpIndexService extends IndexingService { + + public CSharpIndexService(@Nonnull File baseDirectory) { + this(null, baseDirectory); + } + + public CSharpIndexService( + @Nullable IProgressDispatcher progressDispatcher, @Nonnull File baseDirectory) { + super(progressDispatcher, baseDirectory, "cs", ".cs"); + this.setExcludePatterns(null); + } + + public void setExcludePatterns(@Nullable List patterns) { + if (patterns == null) { + super.setExcludePatterns(List.of("tests/", "Tests$")); + } else { + super.setExcludePatterns(patterns); + } + } + + @Override + public boolean isModule(@Nonnull File directory) { + if (!directory.isDirectory()) { + return false; + } + + final File file = new File(directory, directory.getName() + ".csproj"); + return file.exists() && file.isFile(); + } + + @Override + @Nullable public IBuildType getMainBuildTypeFromModuleDirectory(@Nonnull File directory) { + if (!directory.isDirectory()) { + return null; + } + // csproj + final File csProjFile = new File(directory, directory.getName() + ".csproj"); + if (csProjFile.exists() && csProjFile.isFile()) { + return CSharpBuildType.CSPROJ; + } + return null; + } +} diff --git a/src/main/java/org/pqca/scanning/Language.java b/src/main/java/org/pqca/scanning/Language.java index e335af3..84dc8cb 100644 --- a/src/main/java/org/pqca/scanning/Language.java +++ b/src/main/java/org/pqca/scanning/Language.java @@ -22,5 +22,6 @@ public enum Language { JAVA, PYTHON, - GO + GO, + CSHARP } diff --git a/src/main/java/org/pqca/scanning/csharp/CSharpDetectionCollectionRule.java b/src/main/java/org/pqca/scanning/csharp/CSharpDetectionCollectionRule.java new file mode 100644 index 0000000..532a682 --- /dev/null +++ b/src/main/java/org/pqca/scanning/csharp/CSharpDetectionCollectionRule.java @@ -0,0 +1,47 @@ +/* + * CBOMkit-lib + * Copyright (C) 2024 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 + * + * https://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 org.pqca.scanning.csharp; + +import com.ibm.engine.detection.Finding; +import com.ibm.engine.language.csharp.CSharpCheck; +import com.ibm.engine.language.csharp.CSharpScanContext; +import com.ibm.engine.language.csharp.CSharpSymbol; +import com.ibm.engine.language.csharp.tree.CSharpTree; +import com.ibm.mapper.model.INode; +import com.ibm.plugin.rules.CSharpInventoryRule; +import jakarta.annotation.Nonnull; +import java.util.List; +import java.util.function.Consumer; + +public class CSharpDetectionCollectionRule extends CSharpInventoryRule { + private final Consumer> handler; + + public CSharpDetectionCollectionRule(@Nonnull Consumer> findingConsumer) { + this.handler = findingConsumer; + } + + @Override + public void update( + @Nonnull Finding finding) { + super.update(finding); + final List nodes = csharpTranslationProcess.initiate(finding.detectionStore()); + handler.accept(nodes); + } +} diff --git a/src/main/java/org/pqca/scanning/csharp/CSharpScannerService.java b/src/main/java/org/pqca/scanning/csharp/CSharpScannerService.java new file mode 100644 index 0000000..7a5d9d8 --- /dev/null +++ b/src/main/java/org/pqca/scanning/csharp/CSharpScannerService.java @@ -0,0 +1,95 @@ +/* + * CBOMkit-lib + * 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 + * + * https://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 org.pqca.scanning.csharp; + +import com.ibm.engine.language.csharp.CSharpCheck; +import com.ibm.plugin.CryptoCSharpSensor; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; +import java.io.File; +import java.util.Collection; +import java.util.List; +import org.pqca.errors.ClientDisconnected; +import org.pqca.indexing.ProjectModule; +import org.pqca.progress.IProgressDispatcher; +import org.pqca.progress.ProgressMessage; +import org.pqca.progress.ProgressMessageType; +import org.pqca.scanning.CBOM; +import org.pqca.scanning.ScanResultDTO; +import org.pqca.scanning.ScannerService; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.internal.SensorContextTester; + +public final class CSharpScannerService extends ScannerService { + + public CSharpScannerService(@Nonnull File projectDirectory) { + this(null, projectDirectory); + } + + public CSharpScannerService( + @Nullable IProgressDispatcher progressDispatcher, @Nonnull File projectDirectory) { + super(progressDispatcher, projectDirectory); + } + + @Override + public @Nonnull ScanResultDTO scan(@Nonnull List index) + throws ClientDisconnected { + LOGGER.info("Start scanning {} C# projects", index.size()); + + long scanTimeStart = System.currentTimeMillis(); + int counter = 1; + int numberOfScannedLines = 0; + int numberOfScannedFiles = 0; + + CSharpCheck visitor = new CSharpDetectionCollectionRule(this); + Collection checks = List.of(visitor); + final SensorContextTester sensorContext = SensorContextTester.create(projectDirectory); + // C# scanner (CryptoCSharpSensor) reads files from context + index.forEach(project -> project.inputFileList().forEach(sensorContext.fileSystem()::add)); + + for (ProjectModule project : index) { + numberOfScannedFiles += project.inputFileList().size(); + numberOfScannedLines += + project.inputFileList().stream().mapToInt(InputFile::lines).sum(); + + final String projectStr = + project.identifier() + " (" + counter + "/" + index.size() + ")"; + if (this.progressDispatcher != null) { + this.progressDispatcher.send( + new ProgressMessage( + ProgressMessageType.LABEL, "Scanning C# project " + projectStr)); + } + LOGGER.info("Scanning C# project {}", projectStr); + + CryptoCSharpSensor.execute((SensorContext) sensorContext, checks); + + counter += 1; + } + LOGGER.info("Scanned {} C# projects", index.size()); + + return new ScanResultDTO( + scanTimeStart, + System.currentTimeMillis(), + numberOfScannedLines, + numberOfScannedFiles, + this.getBOM().map(CBOM::new).orElse(null)); + } +} diff --git a/src/main/java/org/pqca/scanning/go/GoScannerService.java b/src/main/java/org/pqca/scanning/go/GoScannerService.java index 29b5a3d..42f374e 100644 --- a/src/main/java/org/pqca/scanning/go/GoScannerService.java +++ b/src/main/java/org/pqca/scanning/go/GoScannerService.java @@ -134,7 +134,6 @@ public List all() { return this.checks; } - @SuppressWarnings("null") public RuleKey ruleKey(GoCheck check) { return RuleKey.of("sonar-cryptography", "go-rule"); } diff --git a/src/test/java/org/pqca/indexing/CSharpIndexServiceTest.java b/src/test/java/org/pqca/indexing/CSharpIndexServiceTest.java new file mode 100644 index 0000000..df57b28 --- /dev/null +++ b/src/test/java/org/pqca/indexing/CSharpIndexServiceTest.java @@ -0,0 +1,52 @@ +/* + * CBOMkit-lib + * Copyright (C) 2025 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 + * + * https://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 org.pqca.indexing; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertThat; + +import java.io.File; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.pqca.errors.ClientDisconnected; +import org.pqca.indexing.csharp.CSharpIndexService; + +class CSharpIndexServiceTest { + @Test + void testDefaultExclusion() throws ClientDisconnected { + final CSharpIndexService csharpIndexService = + new CSharpIndexService(new File("src/test/testdata/csharp/dotnet")); + final List projectModules = csharpIndexService.index(null); + assertThat(projectModules).hasSize(1); + assertThat(projectModules.getFirst().identifier()).isEqualTo(""); + assertThat(projectModules.getFirst().inputFileList()).hasSize(12); + } + + @Test + void testExclusion() throws ClientDisconnected { + final CSharpIndexService csharpIndexService = + new CSharpIndexService(new File("src/test/testdata/csharp/dotnet")); + csharpIndexService.setExcludePatterns(List.of("AES")); + final List projectModules = csharpIndexService.index(null); + assertThat(projectModules).hasSize(1); + assertThat(projectModules.getFirst().identifier()).isEqualTo(""); + assertThat(projectModules.getFirst().inputFileList()).hasSize(10); + } +} diff --git a/src/test/java/org/pqca/indexing/GoIndexServiceTest.java b/src/test/java/org/pqca/indexing/GoIndexServiceTest.java index 3611860..5cb7f30 100644 --- a/src/test/java/org/pqca/indexing/GoIndexServiceTest.java +++ b/src/test/java/org/pqca/indexing/GoIndexServiceTest.java @@ -32,11 +32,21 @@ class GoIndexServiceTest { @Test void testDefaultExclusion() throws ClientDisconnected { final GoIndexService goIndexService = - new GoIndexService(new File("src/test/testdata/go/simple")); + new GoIndexService(new File("src/test/testdata/go/gocrypto")); final List projectModules = goIndexService.index(null); assertThat(projectModules).hasSize(1); - assertThat(projectModules.getFirst().inputFileList()) - .extracting(Object::toString) - .containsExactlyInAnyOrder("go.mod", "module1/file.go"); + assertThat(projectModules.getFirst().identifier()).isEqualTo(""); + assertThat(projectModules.getFirst().inputFileList()).hasSize(36); + } + + @Test + void testCustomExclusion() throws ClientDisconnected { + final GoIndexService goIndexService = + new GoIndexService(new File("src/test/testdata/go/gocrypto")); + goIndexService.setExcludePatterns(List.of("RSA")); + final List projectModules = goIndexService.index(null); + assertThat(projectModules).hasSize(1); + assertThat(projectModules.getFirst().identifier()).isEqualTo(""); + assertThat(projectModules.getFirst().inputFileList()).hasSize(31); } } diff --git a/src/test/java/org/pqca/scanning/CSharpScannerServiceTest.java b/src/test/java/org/pqca/scanning/CSharpScannerServiceTest.java new file mode 100644 index 0000000..0a2c471 --- /dev/null +++ b/src/test/java/org/pqca/scanning/CSharpScannerServiceTest.java @@ -0,0 +1,84 @@ +/* + * CBOMkit-lib + * Copyright (C) 2025 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 + * + * https://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 org.pqca.scanning; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.pqca.errors.ClientDisconnected; +import org.pqca.indexing.ProjectModule; +import org.pqca.indexing.csharp.CSharpIndexService; +import org.pqca.scanning.csharp.CSharpScannerService; +import org.pqca.utils.AssertableCBOM; + +class CSharpScannerServiceTest { + + @Test + void test() throws ClientDisconnected { + // indexing + final File projectDirectory = + new File("/Users/san/oss/sonar-cryptography/csharp/src/test/files"); + final CSharpIndexService cSharpIndexService = new CSharpIndexService(projectDirectory); + final List cSharpModules = cSharpIndexService.index(null); + assertThat(cSharpModules).hasSize(1); + final ProjectModule projectModule = cSharpModules.getFirst(); + assertThat(projectModule.inputFileList()).hasSize(12); + // scanning + final CSharpScannerService cSharpScannerService = + new CSharpScannerService(projectDirectory); + ScanResultDTO scanResult = cSharpScannerService.scan(cSharpModules); + + // check - 21 unique cryptographic assets with 27 total occurrences + AssertableCBOM assertableCBOM = new AssertableCBOM(scanResult.cbom()); + assertThat(scanResult.cbom().cycloneDXbom().getComponents()).hasSize(21); + assertableCBOM.hasNumberOfDetections(27); + + assertThat( + assertableCBOM.hasDetectionWithNameAt( + "SHA256", "rules/detection/dotnet/DotNetSHATestFile.cs", 4)) + .isTrue(); + + assertThat( + assertableCBOM.hasDetectionWithNameAt( + "AES256-CBC-PKCS7", + "rules/detection/dotnet/DotNetAESPropertyTestFile.cs", + 7)) + .isTrue(); + + assertThat( + assertableCBOM.hasDetectionWithNameAt( + "HMAC-SHA256", "rules/detection/dotnet/DotNetHMACTestFile.cs", 4)) + .isTrue(); + + assertThat( + assertableCBOM.hasDetectionWithNameAt( + "RSA", "rules/detection/dotnet/DotNetRSATestFile.cs", 3)) + .isTrue(); + + assertThat( + assertableCBOM.hasDetectionWithNameAt( + "PBKDF2", + "rules/detection/dotnet/DotNetRfc2898DeriveBytesTestFile.cs", + 4)) + .isTrue(); + } +} diff --git a/src/test/java/org/pqca/scanning/GoScannerServiceTest.java b/src/test/java/org/pqca/scanning/GoScannerServiceTest.java new file mode 100644 index 0000000..010e436 --- /dev/null +++ b/src/test/java/org/pqca/scanning/GoScannerServiceTest.java @@ -0,0 +1,90 @@ +/* + * CBOMkit-lib + * Copyright (C) 2025 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 + * + * https://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 org.pqca.scanning; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.pqca.errors.ClientDisconnected; +import org.pqca.indexing.ProjectModule; +import org.pqca.indexing.go.GoIndexService; +import org.pqca.scanning.go.GoScannerService; +import org.pqca.utils.AssertableCBOM; + +class GoScannerServiceTest { + + @Test + void test() throws ClientDisconnected { + // indexing + final File projectDirectory = new File("src/test/testdata/go/gocrypto"); + final GoIndexService goIndexService = new GoIndexService(projectDirectory); + final List goModules = goIndexService.index(null); + assertThat(goModules).hasSize(1); + final ProjectModule projectModule = goModules.getFirst(); + assertThat(projectModule.inputFileList()).isNotEmpty(); + // scanning + final GoScannerService goScannerService = new GoScannerService(projectDirectory); + ScanResultDTO scanResult = goScannerService.scan(goModules); + + // check - verify cryptographic assets are detected + AssertableCBOM assertableCBOM = new AssertableCBOM(scanResult.cbom()); + assertThat(scanResult.cbom().cycloneDXbom().getComponents()).hasSize(27); + assertableCBOM.hasNumberOfDetections(69); + + assertThat( + assertableCBOM.hasDetectionWithNameAt( + "SHA256", + "src/test/testdata/go/gocrypto/GoCryptoSHA256TestFile.go", + 10)) + .isTrue(); + + assertThat( + assertableCBOM.hasDetectionWithNameAt( + "AES-GCM", + "src/test/testdata/go/gocrypto/GoCryptoAESTestFile.go", + 18)) + .isTrue(); + + assertThat( + assertableCBOM.hasDetectionWithNameAt( + "RSA-2048", + "src/test/testdata/go/gocrypto/GoCryptoRSATestFile.go", + 10)) + .isTrue(); + + assertThat( + assertableCBOM.hasDetectionWithNameAt( + "HMAC-SHA256", + "src/test/testdata/go/gocrypto/GoCryptoHMACTestFile.go", + 11)) + .isTrue(); + + assertThat( + assertableCBOM.hasDetectionWithNameAt( + "PBKDF2", + "src/test/testdata/go/gocrypto/GoCryptoPBKDF2TestFile.go", + 15)) + .isTrue(); + } +} + +// Made with Bob diff --git a/src/test/testdata/csharp/dotnet/DotNetAESPropertyTestFile.cs b/src/test/testdata/csharp/dotnet/DotNetAESPropertyTestFile.cs new file mode 100644 index 0000000..a97e1ad --- /dev/null +++ b/src/test/testdata/csharp/dotnet/DotNetAESPropertyTestFile.cs @@ -0,0 +1,19 @@ +using System.Security.Cryptography; + +public class DotNetAESPropertyTest +{ + public void TestAesWithProperties() + { + var aes = Aes.Create(); + aes.Mode = CipherMode.CBC; + aes.KeySize = 256; + aes.Padding = PaddingMode.PKCS7; + } + + public void TestAesManagedWithMode() + { + var aes = new AesManaged(); + aes.Mode = CipherMode.ECB; + aes.KeySize = 128; + } +} diff --git a/src/test/testdata/csharp/dotnet/DotNetAESTestFile.cs b/src/test/testdata/csharp/dotnet/DotNetAESTestFile.cs new file mode 100755 index 0000000..6f24227 --- /dev/null +++ b/src/test/testdata/csharp/dotnet/DotNetAESTestFile.cs @@ -0,0 +1,14 @@ +using System.Security.Cryptography; + +public class DotNetAESTest +{ + public void TestAesCreate() + { + var aes = Aes.Create(); // Noncompliant + } + + public void TestAesManaged() + { + var aes = new AesManaged(); // Noncompliant + } +} diff --git a/src/test/testdata/csharp/dotnet/DotNetDESTestFile.cs b/src/test/testdata/csharp/dotnet/DotNetDESTestFile.cs new file mode 100755 index 0000000..7e53f08 --- /dev/null +++ b/src/test/testdata/csharp/dotnet/DotNetDESTestFile.cs @@ -0,0 +1,4 @@ +using System.Security.Cryptography; +public class DotNetDESTest { + public void TestDesCreate() { var des = DES.Create(); } // Noncompliant +} diff --git a/src/test/testdata/csharp/dotnet/DotNetDSATestFile.cs b/src/test/testdata/csharp/dotnet/DotNetDSATestFile.cs new file mode 100755 index 0000000..63e24c9 --- /dev/null +++ b/src/test/testdata/csharp/dotnet/DotNetDSATestFile.cs @@ -0,0 +1,4 @@ +using System.Security.Cryptography; +public class DotNetDSATest { + public void TestDsaCreate() { var dsa = DSA.Create(); } // Noncompliant +} diff --git a/src/test/testdata/csharp/dotnet/DotNetECDiffieHellmanTestFile.cs b/src/test/testdata/csharp/dotnet/DotNetECDiffieHellmanTestFile.cs new file mode 100755 index 0000000..2c91853 --- /dev/null +++ b/src/test/testdata/csharp/dotnet/DotNetECDiffieHellmanTestFile.cs @@ -0,0 +1,4 @@ +using System.Security.Cryptography; +public class DotNetECDiffieHellmanTest { + public void TestECDHCreate() { var ecdh = ECDiffieHellman.Create(); } // Noncompliant +} diff --git a/src/test/testdata/csharp/dotnet/DotNetECDsaTestFile.cs b/src/test/testdata/csharp/dotnet/DotNetECDsaTestFile.cs new file mode 100755 index 0000000..addadc0 --- /dev/null +++ b/src/test/testdata/csharp/dotnet/DotNetECDsaTestFile.cs @@ -0,0 +1,4 @@ +using System.Security.Cryptography; +public class DotNetECDsaTest { + public void TestECDsaCreate() { var ecdsa = ECDsa.Create(); } // Noncompliant +} diff --git a/src/test/testdata/csharp/dotnet/DotNetHMACTestFile.cs b/src/test/testdata/csharp/dotnet/DotNetHMACTestFile.cs new file mode 100755 index 0000000..b652359 --- /dev/null +++ b/src/test/testdata/csharp/dotnet/DotNetHMACTestFile.cs @@ -0,0 +1,8 @@ +using System.Security.Cryptography; +public class DotNetHMACTest { + public void TestHmacSha1() { var h = new HMACSHA1(); } // Noncompliant + public void TestHmacSha256() { var h = new HMACSHA256(); } // Noncompliant + public void TestHmacSha384() { var h = new HMACSHA384(); } // Noncompliant + public void TestHmacSha512() { var h = new HMACSHA512(); } // Noncompliant + public void TestHmacMd5() { var h = new HMACMD5(); } // Noncompliant +} diff --git a/src/test/testdata/csharp/dotnet/DotNetRC2TestFile.cs b/src/test/testdata/csharp/dotnet/DotNetRC2TestFile.cs new file mode 100755 index 0000000..ac73952 --- /dev/null +++ b/src/test/testdata/csharp/dotnet/DotNetRC2TestFile.cs @@ -0,0 +1,4 @@ +using System.Security.Cryptography; +public class DotNetRC2Test { + public void TestRc2Create() { var rc2 = RC2.Create(); } // Noncompliant +} diff --git a/src/test/testdata/csharp/dotnet/DotNetRSATestFile.cs b/src/test/testdata/csharp/dotnet/DotNetRSATestFile.cs new file mode 100755 index 0000000..1478482 --- /dev/null +++ b/src/test/testdata/csharp/dotnet/DotNetRSATestFile.cs @@ -0,0 +1,4 @@ +using System.Security.Cryptography; +public class DotNetRSATest { + public void TestRsaCreate() { var rsa = RSA.Create(); } // Noncompliant +} diff --git a/src/test/testdata/csharp/dotnet/DotNetRfc2898DeriveBytesTestFile.cs b/src/test/testdata/csharp/dotnet/DotNetRfc2898DeriveBytesTestFile.cs new file mode 100755 index 0000000..eefd474 --- /dev/null +++ b/src/test/testdata/csharp/dotnet/DotNetRfc2898DeriveBytesTestFile.cs @@ -0,0 +1,6 @@ +using System.Security.Cryptography; +public class DotNetRfc2898DeriveBytesTest { + public void TestPbkdf2() { + var kdf = new Rfc2898DeriveBytes("password", new byte[16], 10000, HashAlgorithmName.SHA256); // Noncompliant + } +} diff --git a/src/test/testdata/csharp/dotnet/DotNetSHATestFile.cs b/src/test/testdata/csharp/dotnet/DotNetSHATestFile.cs new file mode 100755 index 0000000..9ab3b53 --- /dev/null +++ b/src/test/testdata/csharp/dotnet/DotNetSHATestFile.cs @@ -0,0 +1,8 @@ +using System.Security.Cryptography; +public class DotNetSHATest { + public void TestSha1Create() { var h = SHA1.Create(); } // Noncompliant + public void TestSha256Create() { var h = SHA256.Create(); } // Noncompliant + public void TestSha384Create() { var h = SHA384.Create(); } // Noncompliant + public void TestSha512Create() { var h = SHA512.Create(); } // Noncompliant + public void TestMd5Create() { var h = MD5.Create(); } // Noncompliant +} diff --git a/src/test/testdata/csharp/dotnet/DotNetTripleDESTestFile.cs b/src/test/testdata/csharp/dotnet/DotNetTripleDESTestFile.cs new file mode 100755 index 0000000..9c85d16 --- /dev/null +++ b/src/test/testdata/csharp/dotnet/DotNetTripleDESTestFile.cs @@ -0,0 +1,4 @@ +using System.Security.Cryptography; +public class DotNetTripleDESTest { + public void TestTripleDesCreate() { var des = TripleDES.Create(); } // Noncompliant +} diff --git a/src/test/testdata/csharp/module/module.cs b/src/test/testdata/csharp/module/module.cs new file mode 100644 index 0000000..e69de29 diff --git a/src/test/testdata/csharp/module/module.csproj b/src/test/testdata/csharp/module/module.csproj new file mode 100644 index 0000000..e69de29 diff --git a/src/test/testdata/go/gocrypto/118c1b0b6b7b456b8b205c3fbd6c7913/18327813402862104194/sonar-go-to-slang-darwin-arm64 b/src/test/testdata/go/gocrypto/118c1b0b6b7b456b8b205c3fbd6c7913/18327813402862104194/sonar-go-to-slang-darwin-arm64 new file mode 100755 index 0000000..e3180ee Binary files /dev/null and b/src/test/testdata/go/gocrypto/118c1b0b6b7b456b8b205c3fbd6c7913/18327813402862104194/sonar-go-to-slang-darwin-arm64 differ diff --git a/src/test/testdata/go/gocrypto/3d045eab77ce43a68a8e7de0f4e1f055/14751112134127390757/sonar-go-to-slang-darwin-arm64 b/src/test/testdata/go/gocrypto/3d045eab77ce43a68a8e7de0f4e1f055/14751112134127390757/sonar-go-to-slang-darwin-arm64 new file mode 100755 index 0000000..e3180ee Binary files /dev/null and b/src/test/testdata/go/gocrypto/3d045eab77ce43a68a8e7de0f4e1f055/14751112134127390757/sonar-go-to-slang-darwin-arm64 differ diff --git a/src/test/testdata/go/gocrypto/502e370baa53434894cf982ddda128c8/18138029745714173922/sonar-go-to-slang-darwin-arm64 b/src/test/testdata/go/gocrypto/502e370baa53434894cf982ddda128c8/18138029745714173922/sonar-go-to-slang-darwin-arm64 new file mode 100755 index 0000000..e3180ee Binary files /dev/null and b/src/test/testdata/go/gocrypto/502e370baa53434894cf982ddda128c8/18138029745714173922/sonar-go-to-slang-darwin-arm64 differ diff --git a/src/test/testdata/go/gocrypto/5b222988e9754ef18678431de7343c7d/14909100671640466717/sonar-go-to-slang-darwin-arm64 b/src/test/testdata/go/gocrypto/5b222988e9754ef18678431de7343c7d/14909100671640466717/sonar-go-to-slang-darwin-arm64 new file mode 100755 index 0000000..e3180ee Binary files /dev/null and b/src/test/testdata/go/gocrypto/5b222988e9754ef18678431de7343c7d/14909100671640466717/sonar-go-to-slang-darwin-arm64 differ diff --git a/src/test/testdata/go/gocrypto/85b8c309f1fc458e8ab4b2111ae8062c/11401187076560982630/sonar-go-to-slang-darwin-arm64 b/src/test/testdata/go/gocrypto/85b8c309f1fc458e8ab4b2111ae8062c/11401187076560982630/sonar-go-to-slang-darwin-arm64 new file mode 100755 index 0000000..e3180ee Binary files /dev/null and b/src/test/testdata/go/gocrypto/85b8c309f1fc458e8ab4b2111ae8062c/11401187076560982630/sonar-go-to-slang-darwin-arm64 differ diff --git a/src/test/testdata/go/gocrypto/9b6654c27d384ae8b20b4b53ded88455/13814205431856933034/sonar-go-to-slang-darwin-arm64 b/src/test/testdata/go/gocrypto/9b6654c27d384ae8b20b4b53ded88455/13814205431856933034/sonar-go-to-slang-darwin-arm64 new file mode 100755 index 0000000..e3180ee Binary files /dev/null and b/src/test/testdata/go/gocrypto/9b6654c27d384ae8b20b4b53ded88455/13814205431856933034/sonar-go-to-slang-darwin-arm64 differ diff --git a/src/test/testdata/go/gocrypto/GoCryptoAESGCMEncryptTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoAESGCMEncryptTestFile.go new file mode 100644 index 0000000..34b8569 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoAESGCMEncryptTestFile.go @@ -0,0 +1,37 @@ +package main + +import ( + "crypto/aes" + "crypto/cipher" + crand "crypto/rand" + "encoding/base64" + "io" +) + +// Encrypt encrypts "data" with the specified "key" (must be valid 32 char AES key). +// +// This method uses AES-256-GCM block cypher mode. +func Encrypt(data []byte, key string) (string, error) { + block, err := aes.NewCipher([]byte(key)) // Noncompliant {{(AuthenticatedEncryption) AES-GCM}} + if err != nil { + return "", err + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return "", err + } + + nonce := make([]byte, gcm.NonceSize()) + + // populates the nonce with a cryptographically secure random sequence + if _, err := io.ReadFull(crand.Reader, nonce); err != nil { + return "", err + } + + cipherByte := gcm.Seal(nonce, nonce, data, nil) + + result := base64.StdEncoding.EncodeToString(cipherByte) + + return result, nil +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoAESGCMWithNonceSizeTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoAESGCMWithNonceSizeTestFile.go new file mode 100644 index 0000000..02ede48 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoAESGCMWithNonceSizeTestFile.go @@ -0,0 +1,42 @@ +package main + +import ( + "crypto/aes" + "crypto/cipher" +) + +// AES-GCM Decryption with custom nonce size +func AesGcmDecrypt(cipherText, cek, nonce, authTag, aad []byte) ([]byte, error) { + cipherTextWithAuthTag := append(cipherText, authTag...) + + block, err := aes.NewCipher(cek) // Noncompliant {{(AuthenticatedEncryption) AES-GCM}} + if err != nil { + return nil, err + } + aesgcm, err := cipher.NewGCMWithNonceSize(block, len(nonce)) + if err != nil { + return nil, err + } + plainText, err := aesgcm.Open(nil, nonce, cipherTextWithAuthTag, aad) + if err != nil { + return nil, err + } + return plainText, nil +} + +// AES-GCM Encryption with custom nonce size +func AesGcmEncrypt(plainText, cek, nonce, aad []byte) ([]byte, []byte, error) { + _len := len(plainText) + block, err := aes.NewCipher(cek) // Noncompliant {{(AuthenticatedEncryption) AES-GCM}} + if err != nil { + return nil, nil, err + } + + aesGcm, err := cipher.NewGCMWithNonceSize(block, len(nonce)) + if err != nil { + return nil, nil, err + } + + cipherText := aesGcm.Seal(nil, nonce, plainText, aad) + return cipherText[:_len], cipherText[_len:], nil +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoAESTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoAESTestFile.go new file mode 100644 index 0000000..582ec2d --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoAESTestFile.go @@ -0,0 +1,41 @@ +package main + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "io" +) + +func main() { + // Generate a random 32-byte key (AES-256) + key := make([]byte, 32) + if _, err := io.ReadFull(rand.Reader, key); err != nil { + panic(err) + } + + // Create a new AES cipher block - this should be detected + block, err := aes.NewCipher(key) // Noncompliant {{(AuthenticatedEncryption) AES256-GCM}} + if err != nil { + panic(err) + } + + // Create a GCM mode cipher + gcm, err := cipher.NewGCM(block) + if err != nil { + panic(err) + } + + // Example plaintext + plaintext := []byte("Hello, World!") + + // Generate a random nonce + nonce := make([]byte, gcm.NonceSize()) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + panic(err) + } + + // Encrypt + ciphertext := gcm.Seal(nonce, nonce, plaintext, nil) + _ = ciphertext +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoDESTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoDESTestFile.go new file mode 100644 index 0000000..bca1166 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoDESTestFile.go @@ -0,0 +1,14 @@ +package main + +import ( + "crypto/des" +) + +func main() { + key := make([]byte, 8) + block, err := des.NewCipher(key) // Noncompliant {{(BlockCipher) DES64}} + if err != nil { + panic(err) + } + _ = block +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoDSATestFile.go b/src/test/testdata/go/gocrypto/GoCryptoDSATestFile.go new file mode 100644 index 0000000..ad5a442 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoDSATestFile.go @@ -0,0 +1,34 @@ +package main + +import ( + "crypto/dsa" + "crypto/rand" +) + +func main() { + // Generate DSA parameters with L2048N256 size + params := new(dsa.Parameters) + err := dsa.GenerateParameters(params, rand.Reader, dsa.L2048N256) + if err != nil { + panic(err) + } + + // Generate a DSA key pair + privateKey := new(dsa.PrivateKey) + privateKey.Parameters = *params + err = dsa.GenerateKey(privateKey, rand.Reader) // Noncompliant {{(Signature) DSA}} + if err != nil { + panic(err) + } + + // Sign a hash + hash := []byte("test message hash") + r, s, err := dsa.Sign(rand.Reader, privateKey, hash) // Noncompliant {{(Signature) DSA}} + if err != nil { + panic(err) + } + + // Verify the signature + valid := dsa.Verify(&privateKey.PublicKey, hash, r, s) // Noncompliant {{(Signature) DSA}} + _ = valid +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoECDHNewPrivateKeyTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoECDHNewPrivateKeyTestFile.go new file mode 100644 index 0000000..8f34493 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoECDHNewPrivateKeyTestFile.go @@ -0,0 +1,19 @@ +package main + +import ( + "crypto/ecdh" +) + +func main() { + // Test NewPrivateKey with P256 curve + curve := ecdh.P256() // Noncompliant {{(KeyAgreement) ECDH}} + + // Create a private key from raw bytes (32 bytes for P256) + privateKeyBytes := make([]byte, 32) + privateKey, err := curve.NewPrivateKey(privateKeyBytes) + if err != nil { + panic(err) + } + + _ = privateKey +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoECDHNewPublicKeyTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoECDHNewPublicKeyTestFile.go new file mode 100644 index 0000000..7c8e812 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoECDHNewPublicKeyTestFile.go @@ -0,0 +1,19 @@ +package main + +import ( + "crypto/ecdh" +) + +func main() { + // Test NewPublicKey with X25519 curve + curve := ecdh.X25519() // Noncompliant {{(KeyAgreement) ECDH}} + + // Create a public key from raw bytes (32 bytes for X25519) + publicKeyBytes := make([]byte, 32) + publicKey, err := curve.NewPublicKey(publicKeyBytes) + if err != nil { + panic(err) + } + + _ = publicKey +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoECDHTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoECDHTestFile.go new file mode 100644 index 0000000..1bbd475 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoECDHTestFile.go @@ -0,0 +1,19 @@ +package main + +import ( + "crypto/ecdh" + "crypto/rand" +) + +func main() { + // Get the P256 curve + curve := ecdh.P256() // Noncompliant {{(KeyAgreement) ECDH}} + + // Generate a key pair + privateKey, err := curve.GenerateKey(rand.Reader) + if err != nil { + panic(err) + } + + _ = privateKey +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoECDSASignASN1TestFile.go b/src/test/testdata/go/gocrypto/GoCryptoECDSASignASN1TestFile.go new file mode 100644 index 0000000..c44e6f6 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoECDSASignASN1TestFile.go @@ -0,0 +1,19 @@ +package main + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" +) + +func main() { + // Sign the hash using SignASN1 + privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) // Noncompliant {{(Signature) ECDSA}} + + var hash []byte + sig, err := ecdsa.SignASN1(rand.Reader, privateKey, hash) // Noncompliant {{(Signature) ECDSA}} + if err != nil { + panic(err) + } + _ = sig +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoECDSATestFile.go b/src/test/testdata/go/gocrypto/GoCryptoECDSATestFile.go new file mode 100644 index 0000000..003dfa1 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoECDSATestFile.go @@ -0,0 +1,16 @@ +package main + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" +) + +func main() { + // Generate an ECDSA key pair using P-256 curve + privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) // Noncompliant {{(Signature) ECDSA}} + if err != nil { + panic(err) + } + _ = privateKey +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoECDSAVerifyASN1TestFile.go b/src/test/testdata/go/gocrypto/GoCryptoECDSAVerifyASN1TestFile.go new file mode 100644 index 0000000..583d7b2 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoECDSAVerifyASN1TestFile.go @@ -0,0 +1,22 @@ +package main + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" +) + +func main() { + // Verify the signature using VerifyASN1 + privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) // Noncompliant {{(Signature) ECDSA}} + if err != nil { + panic(err) + } + + var publicKey = &privateKey.PublicKey + + var hash []byte + var sig []byte + valid := ecdsa.VerifyASN1(publicKey, hash, sig) // Noncompliant {{(Signature) ECDSA}} + _ = valid +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoEd25519SignTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoEd25519SignTestFile.go new file mode 100644 index 0000000..6d54234 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoEd25519SignTestFile.go @@ -0,0 +1,19 @@ +package main + +import ( + "crypto/ed25519" + "crypto/rand" +) + +func main() { + // Generate an Ed25519 key pair + _, priv, err := ed25519.GenerateKey(rand.Reader) // Noncompliant {{(Signature) Ed25519}} + if err != nil { + panic(err) + } + + // Sign a message + message := []byte("test message") + sig := ed25519.Sign(priv, message) // Noncompliant {{(Signature) Ed25519}} + _ = sig +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoEd25519TestFile.go b/src/test/testdata/go/gocrypto/GoCryptoEd25519TestFile.go new file mode 100644 index 0000000..9a76caa --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoEd25519TestFile.go @@ -0,0 +1,18 @@ +package main + +import ( + "crypto/ed25519" + "crypto/rand" +) + +func main() { + // GenerateKey - generates a public/private key pair + _, _, err := ed25519.GenerateKey(rand.Reader) // Noncompliant {{(Signature) Ed25519}} + if err != nil { + panic(err) + } + + // NewKeyFromSeed - creates a private key from seed + seed := make([]byte, ed25519.SeedSize) + _ = ed25519.NewKeyFromSeed(seed) // Noncompliant {{(Signature) Ed25519}} +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoEd25519VerifyTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoEd25519VerifyTestFile.go new file mode 100644 index 0000000..f7e554f --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoEd25519VerifyTestFile.go @@ -0,0 +1,20 @@ +package main + +import ( + "crypto/ed25519" + "crypto/rand" +) + +func main() { + // Generate an Ed25519 key pair + pub, _, err := ed25519.GenerateKey(rand.Reader) // Noncompliant {{(Signature) Ed25519}} + if err != nil { + panic(err) + } + + // Verify a signature + var message []byte + var sig []byte + valid := ed25519.Verify(pub, message, sig) // Noncompliant {{(Signature) Ed25519}} + _ = valid +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoEllipticTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoEllipticTestFile.go new file mode 100644 index 0000000..72177be --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoEllipticTestFile.go @@ -0,0 +1,24 @@ +package main + +import ( + "crypto/elliptic" + "fmt" +) + +func main() { + // Test P-224 curve + p224 := elliptic.P224() + fmt.Println("P-224:", p224.Params().Name) + + // Test P-256 curve + p256 := elliptic.P256() + fmt.Println("P-256:", p256.Params().Name) + + // Test P-384 curve + p384 := elliptic.P384() + fmt.Println("P-384:", p384.Params().Name) + + // Test P-521 curve + p521 := elliptic.P521() + fmt.Println("P-521:", p521.Params().Name) +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoHKDFExpandTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoHKDFExpandTestFile.go new file mode 100644 index 0000000..83c0710 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoHKDFExpandTestFile.go @@ -0,0 +1,19 @@ +package main + +import ( + "crypto/sha256" + "golang.org/x/crypto/hkdf" +) + +func main() { + secret := []byte("secret") + salt := []byte("salt") + info := []byte("info") + + // HKDF Extract step + prk := hkdf.Extract(sha256.New, secret, salt) + + // HKDF Expand step + reader := hkdf.Expand(sha256.New, prk, info, 32) // Noncompliant {{(KeyDerivationFunction) HKDF-SHA256}} + _ = reader +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoHKDFTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoHKDFTestFile.go new file mode 100644 index 0000000..019751d --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoHKDFTestFile.go @@ -0,0 +1,16 @@ +package main + +import ( + "crypto/sha256" + "golang.org/x/crypto/hkdf" +) + +func main() { + secret := []byte("secret") + salt := []byte("salt") + info := []byte("info") + + // HKDF Key derivation + reader := hkdf.New(sha256.New, secret, salt, info) // Noncompliant {{(KeyDerivationFunction) HKDF-SHA256}} + _ = reader +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoHMACTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoHMACTestFile.go new file mode 100644 index 0000000..3f8d4a8 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoHMACTestFile.go @@ -0,0 +1,14 @@ +package main + +import ( + "crypto/hmac" + "crypto/sha256" + "fmt" +) + +func main() { + key := []byte("secret-key") + h := hmac.New(sha256.New, key) // Noncompliant {{(Mac) HMAC-SHA256}} + h.Write([]byte("hello")) + fmt.Printf("%x\n", h.Sum(nil)) +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoMD5TestFile.go b/src/test/testdata/go/gocrypto/GoCryptoMD5TestFile.go new file mode 100644 index 0000000..56b8b13 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoMD5TestFile.go @@ -0,0 +1,17 @@ +package main + +import ( + "crypto/md5" + "fmt" +) + +func main() { + h := md5.New() // Noncompliant {{(MessageDigest) MD5}} + h.Write([]byte("hello")) + sum := h.Sum(nil) + fmt.Printf("%x\n", sum) + + // Also test md5.Sum directly + checksum := md5.Sum([]byte("data")) // Noncompliant {{(MessageDigest) MD5}} + fmt.Printf("%x\n", checksum) +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoMLKEM1024TestFile.go b/src/test/testdata/go/gocrypto/GoCryptoMLKEM1024TestFile.go new file mode 100644 index 0000000..38b4031 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoMLKEM1024TestFile.go @@ -0,0 +1,15 @@ +package main + +import ( + "crypto/mlkem" +) + +func main() { + // Generate an ML-KEM-1024 decapsulation key + dk, err := mlkem.GenerateKey1024() // Noncompliant {{(KeyEncapsulationMechanism) ML-KEM-1024}} + if err != nil { + panic(err) + } + + _ = dk +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoMLKEMNewDecapsulationKeyTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoMLKEMNewDecapsulationKeyTestFile.go new file mode 100644 index 0000000..2b2f972 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoMLKEMNewDecapsulationKeyTestFile.go @@ -0,0 +1,16 @@ +package main + +import ( + "crypto/mlkem" +) + +func main() { + // Create an ML-KEM-768 decapsulation key from a seed (SeedSize = 64) + seed := make([]byte, 64) + dk, err := mlkem.NewDecapsulationKey768(seed) // Noncompliant {{(KeyEncapsulationMechanism) ML-KEM-768}} + if err != nil { + panic(err) + } + + _ = dk +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoMLKEMTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoMLKEMTestFile.go new file mode 100644 index 0000000..ea84cfe --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoMLKEMTestFile.go @@ -0,0 +1,15 @@ +package main + +import ( + "crypto/mlkem" +) + +func main() { + // Generate an ML-KEM-768 decapsulation key + dk, err := mlkem.GenerateKey768() // Noncompliant {{(KeyEncapsulationMechanism) ML-KEM-768}} + if err != nil { + panic(err) + } + + _ = dk +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoPBKDF2StdlibTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoPBKDF2StdlibTestFile.go new file mode 100644 index 0000000..9d63628 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoPBKDF2StdlibTestFile.go @@ -0,0 +1,18 @@ +package main + +import ( + "crypto/pbkdf2" + "crypto/sha256" +) + +func main() { + salt := make([]byte, 16) + + // PBKDF2 Key derivation using stdlib API (Go 1.24+) + key, err := pbkdf2.Key(sha256.New, "password", salt, 600000, 32) // Noncompliant {{(PasswordBasedKeyDerivationFunction) PBKDF2-SHA256}} + if err != nil { + panic(err) + } + + _ = key +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoPBKDF2TestFile.go b/src/test/testdata/go/gocrypto/GoCryptoPBKDF2TestFile.go new file mode 100644 index 0000000..bfc157a --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoPBKDF2TestFile.go @@ -0,0 +1,17 @@ +package main + +import ( + "crypto/sha256" + "golang.org/x/crypto/pbkdf2" +) + +func main() { + password := []byte("password") + salt := []byte("salt") + iterations := 10000 + keyLen := 32 + + // PBKDF2 Key derivation + key := pbkdf2.Key(password, salt, iterations, keyLen, sha256.New) // Noncompliant {{(PasswordBasedKeyDerivationFunction) PBKDF2-SHA256}} + _ = key +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoRC4TestFile.go b/src/test/testdata/go/gocrypto/GoCryptoRC4TestFile.go new file mode 100644 index 0000000..a495512 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoRC4TestFile.go @@ -0,0 +1,20 @@ +package main + +import ( + "crypto/rc4" +) + +func main() { + key := make([]byte, 16) + + // Create a new RC4 cipher with a 128-bit key + cipher, err := rc4.NewCipher(key) // Noncompliant {{(StreamCipher) RC4}} + if err != nil { + panic(err) + } + + // Encrypt data using XOR key stream + src := []byte("plaintext") + dst := make([]byte, len(src)) + cipher.XORKeyStream(dst, src) +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoRSAEncryptOAEPTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoRSAEncryptOAEPTestFile.go new file mode 100644 index 0000000..94b29d9 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoRSAEncryptOAEPTestFile.go @@ -0,0 +1,24 @@ +package main + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/sha256" +) + +func main() { + // Generate a 2048-bit RSA key + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) // Noncompliant {{(PublicKeyEncryption) RSA-2048}} + if err != nil { + panic(err) + } + + var pub = &privateKey.PublicKey + + // Encrypt with RSA-OAEP using SHA-256 + ciphertext, err2 := rsa.EncryptOAEP(sha256.New(), rand.Reader, pub, []byte("hello"), nil) // Noncompliant {{(PublicKeyEncryption) RSA-OAEP}} + if err2 != nil { + panic(err2) + } + _ = ciphertext +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoRSAEncryptPKCS1v15TestFile.go b/src/test/testdata/go/gocrypto/GoCryptoRSAEncryptPKCS1v15TestFile.go new file mode 100644 index 0000000..14e059b --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoRSAEncryptPKCS1v15TestFile.go @@ -0,0 +1,23 @@ +package main + +import ( + "crypto/rand" + "crypto/rsa" +) + +func main() { + // Generate a 2048-bit RSA key + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) // Noncompliant {{(PublicKeyEncryption) RSA-2048}} + if err != nil { + panic(err) + } + + var pub = &privateKey.PublicKey + + // Encrypt with RSA PKCS#1 v1.5 + ciphertext, err2 := rsa.EncryptPKCS1v15(rand.Reader, pub, []byte("hello")) // Noncompliant {{(PublicKeyEncryption) RSA-2048}} + if err2 != nil { + panic(err2) + } + _ = ciphertext +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoRSASignPKCS1v15TestFile.go b/src/test/testdata/go/gocrypto/GoCryptoRSASignPKCS1v15TestFile.go new file mode 100644 index 0000000..6ec1189 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoRSASignPKCS1v15TestFile.go @@ -0,0 +1,26 @@ +package main + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" +) + +func main() { + // Generate a 2048-bit RSA key + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) // Noncompliant {{(PublicKeyEncryption) RSA-2048}} + if err != nil { + panic(err) + } + + var priv = privateKey + + hashed := []byte("hash of message that is 32 bytes") + + // Sign with RSA PKCS#1 v1.5 using SHA-256 + sig, err2 := rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA256, hashed) // Noncompliant {{(Signature) RSA}} + if err2 != nil { + panic(err2) + } + _ = sig +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoRSASignPSSTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoRSASignPSSTestFile.go new file mode 100644 index 0000000..8c97fa9 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoRSASignPSSTestFile.go @@ -0,0 +1,26 @@ +package main + +import ( + "crypto" + "crypto/rand" + "crypto/rsa" +) + +func main() { + // Generate a 2048-bit RSA key + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) // Noncompliant {{(PublicKeyEncryption) RSA-2048}} + if err != nil { + panic(err) + } + + var priv = privateKey + + hashed := []byte("hash of message that is 32 bytes") + + // Sign with RSA-PSS using SHA-256 + sig, err2 := rsa.SignPSS(rand.Reader, priv, crypto.SHA256, hashed, nil) // Noncompliant {{(Signature) RSA}} + if err2 != nil { + panic(err2) + } + _ = sig +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoRSATestFile.go b/src/test/testdata/go/gocrypto/GoCryptoRSATestFile.go new file mode 100644 index 0000000..15c1d63 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoRSATestFile.go @@ -0,0 +1,15 @@ +package main + +import ( + "crypto/rand" + "crypto/rsa" +) + +func main() { + // Generate a 2048-bit RSA key + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) // Noncompliant {{(PublicKeyEncryption) RSA-2048}} + if err != nil { + panic(err) + } + _ = privateKey +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoRandTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoRandTestFile.go new file mode 100644 index 0000000..0556bd7 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoRandTestFile.go @@ -0,0 +1,15 @@ +package main + +import ( + "crypto/rand" + "fmt" +) + +func main() { + key := make([]byte, 32) + _, err := rand.Read(key) // Noncompliant {{(PseudorandomNumberGenerator) NATIVEPRNG}} + if err != nil { + panic(err) + } + fmt.Printf("%x\n", key) +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoSHA1TestFile.go b/src/test/testdata/go/gocrypto/GoCryptoSHA1TestFile.go new file mode 100644 index 0000000..39a3bc8 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoSHA1TestFile.go @@ -0,0 +1,17 @@ +package main + +import ( + "crypto/sha1" + "fmt" +) + +func main() { + h := sha1.New() // Noncompliant {{(MessageDigest) SHA1}} + h.Write([]byte("hello")) + sum := h.Sum(nil) + fmt.Printf("%x\n", sum) + + // Also test sha1.Sum directly + checksum := sha1.Sum([]byte("data")) // Noncompliant {{(MessageDigest) SHA1}} + fmt.Printf("%x\n", checksum) +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoSHA256TestFile.go b/src/test/testdata/go/gocrypto/GoCryptoSHA256TestFile.go new file mode 100644 index 0000000..1a4afa3 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoSHA256TestFile.go @@ -0,0 +1,28 @@ +package main + +import ( + "crypto/sha256" + "fmt" +) + +func main() { + // Test sha256.New() - SHA-256 + h := sha256.New() // Noncompliant {{(MessageDigest) SHA256}} + h.Write([]byte("hello")) + sum := h.Sum(nil) + fmt.Printf("%x\n", sum) + + // Test sha256.New224() - SHA-224 + h224 := sha256.New224() // Noncompliant {{(MessageDigest) SHA224}} + h224.Write([]byte("hello")) + sum224 := h224.Sum(nil) + fmt.Printf("%x\n", sum224) + + // Test sha256.Sum256() - SHA-256 + sum256 := sha256.Sum256([]byte("data")) // Noncompliant {{(MessageDigest) SHA256}} + _ = sum256 + + // Test sha256.Sum224() - SHA-224 + sum224Direct := sha256.Sum224([]byte("data")) // Noncompliant {{(MessageDigest) SHA224}} + _ = sum224Direct +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoSHA3TestFile.go b/src/test/testdata/go/gocrypto/GoCryptoSHA3TestFile.go new file mode 100644 index 0000000..c564de6 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoSHA3TestFile.go @@ -0,0 +1,20 @@ +package main + +import ( + "golang.org/x/crypto/sha3" +) + +func main() { + // SHA3-256 hash + h256 := sha3.New256() // Noncompliant {{(MessageDigest) SHA3-256}} + h256.Write([]byte("test")) + _ = h256.Sum(nil) + + // SHA3-512 hash + h512 := sha3.New512() // Noncompliant {{(MessageDigest) SHA3-512}} + _ = h512 + + // Sum256 - direct hash computation + hash := sha3.Sum256([]byte("test")) // Noncompliant {{(MessageDigest) SHA3-256}} + _ = hash +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoSHA512TestFile.go b/src/test/testdata/go/gocrypto/GoCryptoSHA512TestFile.go new file mode 100644 index 0000000..9382ed8 --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoSHA512TestFile.go @@ -0,0 +1,28 @@ +package main + +import ( + "crypto/sha512" + "fmt" +) + +func main() { + // Test sha512.New() - SHA-512 + h := sha512.New() // Noncompliant {{(MessageDigest) SHA512}} + h.Write([]byte("hello")) + sum := h.Sum(nil) + fmt.Printf("%x\n", sum) + + // Test sha512.New384() - SHA-384 + h384 := sha512.New384() // Noncompliant {{(MessageDigest) SHA384}} + h384.Write([]byte("hello")) + sum384 := h384.Sum(nil) + fmt.Printf("%x\n", sum384) + + // Test sha512.Sum512() - SHA-512 + sum512 := sha512.Sum512([]byte("data")) // Noncompliant {{(MessageDigest) SHA512}} + _ = sum512 + + // Test sha512.Sum384() - SHA-384 + sum384Direct := sha512.Sum384([]byte("data")) // Noncompliant {{(MessageDigest) SHA384}} + _ = sum384Direct +} diff --git a/src/test/testdata/go/gocrypto/GoCryptoTLSTestFile.go b/src/test/testdata/go/gocrypto/GoCryptoTLSTestFile.go new file mode 100644 index 0000000..2e3f5da --- /dev/null +++ b/src/test/testdata/go/gocrypto/GoCryptoTLSTestFile.go @@ -0,0 +1,22 @@ +package main + +import ( + "crypto/tls" +) + +func main() { + // Dial a TLS connection + conf := tls.Config{ // Noncompliant {{(TLS) TLSv1.2}} + MinVersion: tls.VersionTLS12, + CipherSuites: []uint16{ + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }, + } + + conn, err := tls.Dial("tcp", "example.com:443", &conf) + if err != nil { + panic(err) + } + defer conn.Close() +} diff --git a/src/test/testdata/go/gocrypto/a0e0397ec9cc45c48b0f059804ae3969/9073269741158945390/sonar-go-to-slang-darwin-arm64 b/src/test/testdata/go/gocrypto/a0e0397ec9cc45c48b0f059804ae3969/9073269741158945390/sonar-go-to-slang-darwin-arm64 new file mode 100755 index 0000000..e3180ee Binary files /dev/null and b/src/test/testdata/go/gocrypto/a0e0397ec9cc45c48b0f059804ae3969/9073269741158945390/sonar-go-to-slang-darwin-arm64 differ diff --git a/src/test/testdata/go/gocrypto/b5193bbd4c684df89b31c9c497bab3e1/11711218209443524556/sonar-go-to-slang-darwin-arm64 b/src/test/testdata/go/gocrypto/b5193bbd4c684df89b31c9c497bab3e1/11711218209443524556/sonar-go-to-slang-darwin-arm64 new file mode 100755 index 0000000..e3180ee Binary files /dev/null and b/src/test/testdata/go/gocrypto/b5193bbd4c684df89b31c9c497bab3e1/11711218209443524556/sonar-go-to-slang-darwin-arm64 differ diff --git a/src/test/testdata/go/gocrypto/f2162b0596bf4497903e3a9e577ec837/2876185731772615516/sonar-go-to-slang-darwin-arm64 b/src/test/testdata/go/gocrypto/f2162b0596bf4497903e3a9e577ec837/2876185731772615516/sonar-go-to-slang-darwin-arm64 new file mode 100755 index 0000000..e3180ee Binary files /dev/null and b/src/test/testdata/go/gocrypto/f2162b0596bf4497903e3a9e577ec837/2876185731772615516/sonar-go-to-slang-darwin-arm64 differ