From d83c49e7a5af69c271448b56ce1e79545b00f0a0 Mon Sep 17 00:00:00 2001 From: sanchaysingh Date: Thu, 21 May 2026 22:09:48 +0530 Subject: [PATCH] Add precise parameter detection for BC KEM and digest constructors Signed-off-by: sanchaysingh --- .../bc/cipherparameters/BcBIKEParameters.java | 84 +++++++++++++ .../bc/cipherparameters/BcCMCEParameters.java | 86 +++++++++++++ .../cipherparameters/BcCipherParameters.java | 8 ++ .../cipherparameters/BcFrodoParameters.java | 82 +++++++++++++ .../bc/cipherparameters/BcHQCParameters.java | 82 +++++++++++++ .../cipherparameters/BcKyberParameters.java | 95 +++++++++++++++ .../BcNTRULPRimeParameters.java | 77 ++++++++++++ .../bc/cipherparameters/BcNTRUParameters.java | 70 +++++++++++ .../BcSNTRUPrimeParameters.java | 77 ++++++++++++ .../rules/detection/bc/digest/BcDigests.java | 51 +++++++- .../BcEncapsulatedSecretExtractor.java | 43 +++++-- .../BcBIKEKEMExtractorTest.java | 9 +- .../bc/signer/BcDSADigestSignerTest.java | 115 +++++++++--------- 13 files changed, 806 insertions(+), 73 deletions(-) create mode 100644 java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcBIKEParameters.java create mode 100644 java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcCMCEParameters.java create mode 100644 java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcFrodoParameters.java create mode 100644 java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcHQCParameters.java create mode 100644 java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcKyberParameters.java create mode 100644 java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcNTRULPRimeParameters.java create mode 100644 java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcNTRUParameters.java create mode 100644 java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcSNTRUPrimeParameters.java diff --git a/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcBIKEParameters.java b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcBIKEParameters.java new file mode 100644 index 000000000..63bdb7dff --- /dev/null +++ b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcBIKEParameters.java @@ -0,0 +1,84 @@ +/* + * Sonar Cryptography Plugin + * 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 + * + * 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.rules.detection.bc.cipherparameters; + +import static com.ibm.plugin.rules.detection.TypeShortcuts.BYTE_ARRAY_TYPE; + +import com.ibm.engine.model.AlgorithmParameter; +import com.ibm.engine.model.context.KeyContext; +import com.ibm.engine.model.factory.AlgorithmParameterFactory; +import com.ibm.engine.rule.IDetectionRule; +import com.ibm.engine.rule.builder.DetectionRuleBuilder; +import java.util.List; +import javax.annotation.Nonnull; +import org.sonar.plugins.java.api.tree.Tree; + +public final class BcBIKEParameters { + + private BcBIKEParameters() { + // nothing + } + + private static final IDetectionRule KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectExactTypes("org.bouncycastle.pqc.crypto.bike.BIKEKeyParameters") + .forConstructor() + .withMethodParameter("boolean") + .withMethodParameter("org.bouncycastle.pqc.crypto.bike.BIKEParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + private static final IDetectionRule PRIVATE_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes("org.bouncycastle.pqc.crypto.bike.BIKEPrivateKeyParameters") + .forConstructor() + .withMethodParameter("org.bouncycastle.pqc.crypto.bike.BIKEParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + private static final IDetectionRule PUBLIC_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes("org.bouncycastle.pqc.crypto.bike.BIKEPublicKeyParameters") + .forConstructor() + .withMethodParameter("org.bouncycastle.pqc.crypto.bike.BIKEParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + @Nonnull + public static List> rules() { + return List.of(KEY_CONSTRUCTOR, PRIVATE_KEY_CONSTRUCTOR, PUBLIC_KEY_CONSTRUCTOR); + } +} diff --git a/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcCMCEParameters.java b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcCMCEParameters.java new file mode 100644 index 000000000..44a7751f9 --- /dev/null +++ b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcCMCEParameters.java @@ -0,0 +1,86 @@ +/* + * Sonar Cryptography Plugin + * 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 + * + * 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.rules.detection.bc.cipherparameters; + +import static com.ibm.plugin.rules.detection.TypeShortcuts.BYTE_ARRAY_TYPE; + +import com.ibm.engine.model.AlgorithmParameter; +import com.ibm.engine.model.context.KeyContext; +import com.ibm.engine.model.factory.AlgorithmParameterFactory; +import com.ibm.engine.rule.IDetectionRule; +import com.ibm.engine.rule.builder.DetectionRuleBuilder; +import java.util.List; +import javax.annotation.Nonnull; +import org.sonar.plugins.java.api.tree.Tree; + +public final class BcCMCEParameters { + + private BcCMCEParameters() { + // nothing + } + + private static final IDetectionRule KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectExactTypes("org.bouncycastle.pqc.crypto.cmce.CMCEKeyParameters") + .forConstructor() + .withMethodParameter("boolean") + .withMethodParameter("org.bouncycastle.pqc.crypto.cmce.CMCEParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + private static final IDetectionRule PRIVATE_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes("org.bouncycastle.pqc.crypto.cmce.CMCEPrivateKeyParameters") + .forConstructor() + .withMethodParameter("org.bouncycastle.pqc.crypto.cmce.CMCEParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + private static final IDetectionRule PUBLIC_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes("org.bouncycastle.pqc.crypto.cmce.CMCEPublicKeyParameters") + .forConstructor() + .withMethodParameter("org.bouncycastle.pqc.crypto.cmce.CMCEParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + @Nonnull + public static List> rules() { + return List.of(KEY_CONSTRUCTOR, PRIVATE_KEY_CONSTRUCTOR, PUBLIC_KEY_CONSTRUCTOR); + } +} diff --git a/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcCipherParameters.java b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcCipherParameters.java index 81d942096..4cdf6f4b7 100644 --- a/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcCipherParameters.java +++ b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcCipherParameters.java @@ -35,15 +35,23 @@ private BcCipherParameters() { public static List> bases() { return Stream.of( BcAEADParameters.rules().stream(), + BcBIKEParameters.rules().stream(), BcCCMParameters.rules().stream(), + BcCMCEParameters.rules().stream(), BcCramerShoupParameters.rules().stream(), + BcFrodoParameters.rules().stream(), BcGMSSParameters.rules().stream(), + BcHQCParameters.rules().stream(), BcIESParameters.rules().stream(), BcKeyParameter.rules().stream(), + BcKyberParameters.rules().stream(), BcNTRUEncryptionParameters.rules().stream(), + BcNTRUParameters.rules().stream(), + BcNTRULPRimeParameters.rules().stream(), BcNTRUSigningPrivateKeyParameters.rules().stream(), BcNTRUSigningPublicKeyParameters.rules().stream(), BcSABERParameters.rules().stream(), + BcSNTRUPrimeParameters.rules().stream(), BcMLKEMKeyParameters.rules().stream(), BcMLKEMPrivateKeyParameters.rules().stream(), BcMLKEMPublicKeyParameters.rules().stream(), diff --git a/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcFrodoParameters.java b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcFrodoParameters.java new file mode 100644 index 000000000..c500afd09 --- /dev/null +++ b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcFrodoParameters.java @@ -0,0 +1,82 @@ +/* + * Sonar Cryptography Plugin + * 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 + * + * 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.rules.detection.bc.cipherparameters; + +import static com.ibm.plugin.rules.detection.TypeShortcuts.BYTE_ARRAY_TYPE; + +import com.ibm.engine.model.AlgorithmParameter; +import com.ibm.engine.model.context.KeyContext; +import com.ibm.engine.model.factory.AlgorithmParameterFactory; +import com.ibm.engine.rule.IDetectionRule; +import com.ibm.engine.rule.builder.DetectionRuleBuilder; +import java.util.List; +import javax.annotation.Nonnull; +import org.sonar.plugins.java.api.tree.Tree; + +public final class BcFrodoParameters { + + private BcFrodoParameters() { + // nothing + } + + private static final IDetectionRule KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectExactTypes("org.bouncycastle.pqc.crypto.frodo.FrodoKeyParameters") + .forConstructor() + .withMethodParameter("boolean") + .withMethodParameter("org.bouncycastle.pqc.crypto.frodo.FrodoParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + private static final IDetectionRule PRIVATE_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes("org.bouncycastle.pqc.crypto.frodo.FrodoPrivateKeyParameters") + .forConstructor() + .withMethodParameter("org.bouncycastle.pqc.crypto.frodo.FrodoParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + private static final IDetectionRule PUBLIC_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes("org.bouncycastle.pqc.crypto.frodo.FrodoPublicKeyParameters") + .forConstructor() + .withMethodParameter("org.bouncycastle.pqc.crypto.frodo.FrodoParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + @Nonnull + public static List> rules() { + return List.of(KEY_CONSTRUCTOR, PRIVATE_KEY_CONSTRUCTOR, PUBLIC_KEY_CONSTRUCTOR); + } +} diff --git a/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcHQCParameters.java b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcHQCParameters.java new file mode 100644 index 000000000..2f782d981 --- /dev/null +++ b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcHQCParameters.java @@ -0,0 +1,82 @@ +/* + * Sonar Cryptography Plugin + * 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 + * + * 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.rules.detection.bc.cipherparameters; + +import static com.ibm.plugin.rules.detection.TypeShortcuts.BYTE_ARRAY_TYPE; + +import com.ibm.engine.model.AlgorithmParameter; +import com.ibm.engine.model.context.KeyContext; +import com.ibm.engine.model.factory.AlgorithmParameterFactory; +import com.ibm.engine.rule.IDetectionRule; +import com.ibm.engine.rule.builder.DetectionRuleBuilder; +import java.util.List; +import javax.annotation.Nonnull; +import org.sonar.plugins.java.api.tree.Tree; + +public final class BcHQCParameters { + + private BcHQCParameters() { + // nothing + } + + private static final IDetectionRule KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectExactTypes("org.bouncycastle.pqc.crypto.hqc.HQCKeyParameters") + .forConstructor() + .withMethodParameter("boolean") + .withMethodParameter("org.bouncycastle.pqc.crypto.hqc.HQCParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + private static final IDetectionRule PRIVATE_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes("org.bouncycastle.pqc.crypto.hqc.HQCPrivateKeyParameters") + .forConstructor() + .withMethodParameter("org.bouncycastle.pqc.crypto.hqc.HQCParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + private static final IDetectionRule PUBLIC_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes("org.bouncycastle.pqc.crypto.hqc.HQCPublicKeyParameters") + .forConstructor() + .withMethodParameter("org.bouncycastle.pqc.crypto.hqc.HQCParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + @Nonnull + public static List> rules() { + return List.of(KEY_CONSTRUCTOR, PRIVATE_KEY_CONSTRUCTOR, PUBLIC_KEY_CONSTRUCTOR); + } +} diff --git a/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcKyberParameters.java b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcKyberParameters.java new file mode 100644 index 000000000..e94242781 --- /dev/null +++ b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcKyberParameters.java @@ -0,0 +1,95 @@ +/* + * Sonar Cryptography Plugin + * 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 + * + * 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.rules.detection.bc.cipherparameters; + +import static com.ibm.plugin.rules.detection.TypeShortcuts.BYTE_ARRAY_TYPE; + +import com.ibm.engine.model.AlgorithmParameter; +import com.ibm.engine.model.context.KeyContext; +import com.ibm.engine.model.factory.AlgorithmParameterFactory; +import com.ibm.engine.rule.IDetectionRule; +import com.ibm.engine.rule.builder.DetectionRuleBuilder; +import java.util.List; +import javax.annotation.Nonnull; +import org.sonar.plugins.java.api.tree.Tree; + +@SuppressWarnings("java:S1192") +public final class BcKyberParameters { + + private BcKyberParameters() { + // nothing + } + + // deprecated since bc 1.79 + private static final IDetectionRule KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectExactTypes( + "org.bouncycastle.pqc.crypto.crystals.kyber.KyberKeyParameters") + .forConstructor() + .withMethodParameter("boolean") + .withMethodParameter( + "org.bouncycastle.pqc.crypto.crystals.kyber.KyberParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + private static final IDetectionRule PRIVATE_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes( + "org.bouncycastle.pqc.crypto.crystals.kyber.KyberPrivateKeyParameters") + .forConstructor() + .withMethodParameter( + "org.bouncycastle.pqc.crypto.crystals.kyber.KyberParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + private static final IDetectionRule PUBLIC_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes( + "org.bouncycastle.pqc.crypto.crystals.kyber.KyberPublicKeyParameters") + .forConstructor() + .withMethodParameter( + "org.bouncycastle.pqc.crypto.crystals.kyber.KyberParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + @Nonnull + public static List> rules() { + return List.of(KEY_CONSTRUCTOR, PRIVATE_KEY_CONSTRUCTOR, PUBLIC_KEY_CONSTRUCTOR); + } +} diff --git a/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcNTRULPRimeParameters.java b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcNTRULPRimeParameters.java new file mode 100644 index 000000000..03c5bf7f6 --- /dev/null +++ b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcNTRULPRimeParameters.java @@ -0,0 +1,77 @@ +/* + * Sonar Cryptography Plugin + * 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 + * + * 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.rules.detection.bc.cipherparameters; + +import static com.ibm.plugin.rules.detection.TypeShortcuts.BYTE_ARRAY_TYPE; + +import com.ibm.engine.model.AlgorithmParameter; +import com.ibm.engine.model.context.KeyContext; +import com.ibm.engine.model.factory.AlgorithmParameterFactory; +import com.ibm.engine.rule.IDetectionRule; +import com.ibm.engine.rule.builder.DetectionRuleBuilder; +import java.util.List; +import javax.annotation.Nonnull; +import org.sonar.plugins.java.api.tree.Tree; + +@SuppressWarnings("java:S1192") +public final class BcNTRULPRimeParameters { + + private BcNTRULPRimeParameters() { + // nothing + } + + private static final IDetectionRule PRIVATE_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes( + "org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePrivateKeyParameters") + .forConstructor() + .withMethodParameter( + "org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + private static final IDetectionRule PUBLIC_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes( + "org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePublicKeyParameters") + .forConstructor() + .withMethodParameter( + "org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimeParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + @Nonnull + public static List> rules() { + return List.of(PRIVATE_KEY_CONSTRUCTOR, PUBLIC_KEY_CONSTRUCTOR); + } +} diff --git a/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcNTRUParameters.java b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcNTRUParameters.java new file mode 100644 index 000000000..0a019b8f6 --- /dev/null +++ b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcNTRUParameters.java @@ -0,0 +1,70 @@ +/* + * Sonar Cryptography Plugin + * 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 + * + * 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.rules.detection.bc.cipherparameters; + +import static com.ibm.plugin.rules.detection.TypeShortcuts.BYTE_ARRAY_TYPE; + +import com.ibm.engine.model.AlgorithmParameter; +import com.ibm.engine.model.context.KeyContext; +import com.ibm.engine.model.factory.AlgorithmParameterFactory; +import com.ibm.engine.rule.IDetectionRule; +import com.ibm.engine.rule.builder.DetectionRuleBuilder; +import java.util.List; +import javax.annotation.Nonnull; +import org.sonar.plugins.java.api.tree.Tree; + +@SuppressWarnings("java:S1192") +public final class BcNTRUParameters { + + private BcNTRUParameters() { + // nothing + } + + private static final IDetectionRule PRIVATE_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes("org.bouncycastle.pqc.crypto.ntru.NTRUPrivateKeyParameters") + .forConstructor() + .withMethodParameter("org.bouncycastle.pqc.crypto.ntru.NTRUParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + private static final IDetectionRule PUBLIC_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes("org.bouncycastle.pqc.crypto.ntru.NTRUPublicKeyParameters") + .forConstructor() + .withMethodParameter("org.bouncycastle.pqc.crypto.ntru.NTRUParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + @Nonnull + public static List> rules() { + return List.of(PRIVATE_KEY_CONSTRUCTOR, PUBLIC_KEY_CONSTRUCTOR); + } +} diff --git a/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcSNTRUPrimeParameters.java b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcSNTRUPrimeParameters.java new file mode 100644 index 000000000..0a95fa880 --- /dev/null +++ b/java/src/main/java/com/ibm/plugin/rules/detection/bc/cipherparameters/BcSNTRUPrimeParameters.java @@ -0,0 +1,77 @@ +/* + * Sonar Cryptography Plugin + * 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 + * + * 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.rules.detection.bc.cipherparameters; + +import static com.ibm.plugin.rules.detection.TypeShortcuts.BYTE_ARRAY_TYPE; + +import com.ibm.engine.model.AlgorithmParameter; +import com.ibm.engine.model.context.KeyContext; +import com.ibm.engine.model.factory.AlgorithmParameterFactory; +import com.ibm.engine.rule.IDetectionRule; +import com.ibm.engine.rule.builder.DetectionRuleBuilder; +import java.util.List; +import javax.annotation.Nonnull; +import org.sonar.plugins.java.api.tree.Tree; + +@SuppressWarnings("java:S1192") +public final class BcSNTRUPrimeParameters { + + private BcSNTRUPrimeParameters() { + // nothing + } + + private static final IDetectionRule PRIVATE_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes( + "org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimePrivateKeyParameters") + .forConstructor() + .withMethodParameter( + "org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + private static final IDetectionRule PUBLIC_KEY_CONSTRUCTOR = + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectTypes( + "org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimePublicKeyParameters") + .forConstructor() + .withMethodParameter( + "org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimeParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .withMethodParameter(BYTE_ARRAY_TYPE) + .buildForContext(new KeyContext()) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules(); + + @Nonnull + public static List> rules() { + return List.of(PRIVATE_KEY_CONSTRUCTOR, PUBLIC_KEY_CONSTRUCTOR); + } +} diff --git a/java/src/main/java/com/ibm/plugin/rules/detection/bc/digest/BcDigests.java b/java/src/main/java/com/ibm/plugin/rules/detection/bc/digest/BcDigests.java index c381c123a..ee96a445f 100644 --- a/java/src/main/java/com/ibm/plugin/rules/detection/bc/digest/BcDigests.java +++ b/java/src/main/java/com/ibm/plugin/rules/detection/bc/digest/BcDigests.java @@ -19,9 +19,11 @@ */ package com.ibm.plugin.rules.detection.bc.digest; +import com.ibm.engine.model.AlgorithmParameter; import com.ibm.engine.model.Size; import com.ibm.engine.model.context.DigestContext; import com.ibm.engine.model.context.IDetectionContext; +import com.ibm.engine.model.factory.AlgorithmParameterFactory; import com.ibm.engine.model.factory.DigestSizeFactory; import com.ibm.engine.model.factory.ValueActionFactory; import com.ibm.engine.rule.IDetectionRule; @@ -60,8 +62,7 @@ private BcDigests() { * a constructor, we use `forObjectExactTypes` in associated rules otherwise we would have several * detections (a class and its parent) instead of one. */ - infoMap.putKey("AsconDigest"); - infoMap.putKey("AsconXof"); + /* AsconDigest and AsconXof are handled in parameterizedConstructors() */ infoMap.putKey("Blake2bDigest"); infoMap.putKey("Blake2bpDigest"); infoMap.putKey("Blake2sDigest"); @@ -191,6 +192,48 @@ private static List> otherConstructors( return constructorsList; } + @Nonnull + private static List> parameterizedConstructors( + @Nullable IDetectionContext detectionValueContext) { + List> constructorsList = new LinkedList<>(); + IDetectionContext context = + detectionValueContext != null ? detectionValueContext : new DigestContext(); + + // AsconDigest(AsconDigest.AsconParameters) + constructorsList.add( + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectExactTypes("org.bouncycastle.crypto.digests.AsconDigest") + .forConstructor() + .shouldBeDetectedAs(new ValueActionFactory<>("AsconDigest")) + .withMethodParameter( + "org.bouncycastle.crypto.digests.AsconDigest$AsconParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .asChildOfParameterWithId(-1) + .buildForContext(context) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules()); + + // AsconXof(AsconXof.AsconParameters) + constructorsList.add( + new DetectionRuleBuilder() + .createDetectionRule() + .forObjectExactTypes("org.bouncycastle.crypto.digests.AsconXof") + .forConstructor() + .shouldBeDetectedAs(new ValueActionFactory<>("AsconXof")) + .withMethodParameter( + "org.bouncycastle.crypto.digests.AsconXof$AsconParameters") + .shouldBeDetectedAs( + new AlgorithmParameterFactory<>(AlgorithmParameter.Kind.ANY)) + .asChildOfParameterWithId(-1) + .buildForContext(context) + .inBundle(() -> "Bc") + .withoutDependingDetectionRules()); + + return constructorsList; + } + @Nonnull public static List> rules() { return rules(null); @@ -199,9 +242,11 @@ public static List> rules() { @Nonnull public static List> rules( @Nullable IDetectionContext detectionValueContext) { - return Stream.concat( + return Stream.of( regularConstructors(detectionValueContext).stream(), + parameterizedConstructors(detectionValueContext).stream(), otherConstructors(detectionValueContext).stream()) + .flatMap(i -> i) .toList(); } } diff --git a/java/src/main/java/com/ibm/plugin/rules/detection/bc/encapsulatedsecret/BcEncapsulatedSecretExtractor.java b/java/src/main/java/com/ibm/plugin/rules/detection/bc/encapsulatedsecret/BcEncapsulatedSecretExtractor.java index 5f6713eb3..9f87095c6 100644 --- a/java/src/main/java/com/ibm/plugin/rules/detection/bc/encapsulatedsecret/BcEncapsulatedSecretExtractor.java +++ b/java/src/main/java/com/ibm/plugin/rules/detection/bc/encapsulatedsecret/BcEncapsulatedSecretExtractor.java @@ -44,16 +44,36 @@ private BcEncapsulatedSecretExtractor() { private static final BouncyCastleInfoMap infoMap = new BouncyCastleInfoMap(); static { - infoMap.putKey("BIKEKEMExtractor").putType("org.bouncycastle.pqc.crypto.bike."); - infoMap.putKey("CMCEKEMExtractor").putType("org.bouncycastle.pqc.crypto.cmce."); - infoMap.putKey("FrodoKEMExtractor").putType("org.bouncycastle.pqc.crypto.frodo."); - infoMap.putKey("HQCKEMExtractor").putType("org.bouncycastle.pqc.crypto.hqc."); + infoMap.putKey("BIKEKEMExtractor") + .putType("org.bouncycastle.pqc.crypto.bike.") + .putParameterClass("org.bouncycastle.pqc.crypto.bike.BIKEPrivateKeyParameters"); + infoMap.putKey("CMCEKEMExtractor") + .putType("org.bouncycastle.pqc.crypto.cmce.") + .putParameterClass("org.bouncycastle.pqc.crypto.cmce.CMCEPrivateKeyParameters"); + infoMap.putKey("FrodoKEMExtractor") + .putType("org.bouncycastle.pqc.crypto.frodo.") + .putParameterClass("org.bouncycastle.pqc.crypto.frodo.FrodoKeyParameters"); + infoMap.putKey("HQCKEMExtractor") + .putType("org.bouncycastle.pqc.crypto.hqc.") + .putParameterClass("org.bouncycastle.pqc.crypto.hqc.HQCPrivateKeyParameters"); infoMap.putKey("KyberKEMExtractor") - .putType("org.bouncycastle.pqc.crypto.crystals.kyber."); // deprecated since bc 1.79 - infoMap.putKey("NTRUKEMExtractor").putType("org.bouncycastle.pqc.crypto.ntru."); - infoMap.putKey("NTRULPRimeKEMExtractor").putType("org.bouncycastle.pqc.crypto.ntruprime."); - infoMap.putKey("SABERKEMExtractor").putType("org.bouncycastle.pqc.crypto.saber."); - infoMap.putKey("SNTRUPrimeKEMExtractor").putType("org.bouncycastle.pqc.crypto.ntruprime."); + .putType("org.bouncycastle.pqc.crypto.crystals.kyber.") + .putParameterClass( + "org.bouncycastle.pqc.crypto.crystals.kyber.KyberPrivateKeyParameters"); // deprecated since bc 1.79 + infoMap.putKey("NTRUKEMExtractor") + .putType("org.bouncycastle.pqc.crypto.ntru.") + .putParameterClass("org.bouncycastle.pqc.crypto.ntru.NTRUPrivateKeyParameters"); + infoMap.putKey("NTRULPRimeKEMExtractor") + .putType("org.bouncycastle.pqc.crypto.ntruprime.") + .putParameterClass( + "org.bouncycastle.pqc.crypto.ntruprime.NTRULPRimePrivateKeyParameters"); + infoMap.putKey("SABERKEMExtractor") + .putType("org.bouncycastle.pqc.crypto.saber.") + .putParameterClass("org.bouncycastle.pqc.crypto.saber.SABERPrivateKeyParameters"); + infoMap.putKey("SNTRUPrimeKEMExtractor") + .putType("org.bouncycastle.pqc.crypto.ntruprime.") + .putParameterClass( + "org.bouncycastle.pqc.crypto.ntruprime.SNTRUPrimePrivateKeyParameters"); } private static @Nonnull List> simpleConstructors() { @@ -62,14 +82,15 @@ private BcEncapsulatedSecretExtractor() { for (Map.Entry entry : infoMap.entrySet()) { String extractor = entry.getKey(); String type = entry.getValue().getType(); + String parameterClass = entry.getValue().getParameterClass(); constructorsList.add( new DetectionRuleBuilder() .createDetectionRule() .forObjectTypes(type + extractor) .forConstructor() .shouldBeDetectedAs(new ValueActionFactory<>(extractor)) - // We want to capture all possible constructors (some have arguments) - .withAnyParameters() + .withMethodParameter(parameterClass) + .addDependingDetectionRules(BcCipherParameters.rules()) .buildForContext(new KeyContext(Map.of("kind", "KEM"))) .inBundle(() -> "Bc") .withoutDependingDetectionRules()); diff --git a/java/src/test/java/com/ibm/plugin/rules/detection/bc/encapsulatedsecret/BcBIKEKEMExtractorTest.java b/java/src/test/java/com/ibm/plugin/rules/detection/bc/encapsulatedsecret/BcBIKEKEMExtractorTest.java index 1545057cc..0d88568f4 100644 --- a/java/src/test/java/com/ibm/plugin/rules/detection/bc/encapsulatedsecret/BcBIKEKEMExtractorTest.java +++ b/java/src/test/java/com/ibm/plugin/rules/detection/bc/encapsulatedsecret/BcBIKEKEMExtractorTest.java @@ -27,6 +27,7 @@ import com.ibm.engine.model.context.KeyContext; import com.ibm.mapper.model.INode; import com.ibm.mapper.model.KeyEncapsulationMechanism; +import com.ibm.mapper.model.ParameterSetIdentifier; import com.ibm.mapper.model.functionality.Decapsulate; import com.ibm.plugin.TestBase; import com.ibm.plugin.rules.detection.bc.BouncyCastleJars; @@ -75,7 +76,7 @@ public void asserts( INode keyEncapsulationMechanismNode = nodes.get(0); assertThat(keyEncapsulationMechanismNode.getKind()) .isEqualTo(KeyEncapsulationMechanism.class); - assertThat(keyEncapsulationMechanismNode.getChildren()).hasSize(1); + assertThat(keyEncapsulationMechanismNode.getChildren()).hasSize(2); assertThat(keyEncapsulationMechanismNode.asString()).isEqualTo("BIKE"); // Decapsulate under KeyEncapsulationMechanism @@ -83,5 +84,11 @@ public void asserts( assertThat(decapsulateNode).isNotNull(); assertThat(decapsulateNode.getChildren()).isEmpty(); assertThat(decapsulateNode.asString()).isEqualTo("DECAPSULATE"); + + // ParameterSetIdentifier under KeyEncapsulationMechanism + INode parameterSetIdentifierNode = + keyEncapsulationMechanismNode.getChildren().get(ParameterSetIdentifier.class); + assertThat(parameterSetIdentifierNode).isNotNull(); + assertThat(parameterSetIdentifierNode.getChildren()).isEmpty(); } } diff --git a/java/src/test/java/com/ibm/plugin/rules/detection/bc/signer/BcDSADigestSignerTest.java b/java/src/test/java/com/ibm/plugin/rules/detection/bc/signer/BcDSADigestSignerTest.java index e2dcad6ba..da2ed1b41 100644 --- a/java/src/test/java/com/ibm/plugin/rules/detection/bc/signer/BcDSADigestSignerTest.java +++ b/java/src/test/java/com/ibm/plugin/rules/detection/bc/signer/BcDSADigestSignerTest.java @@ -23,7 +23,6 @@ import com.ibm.engine.detection.DetectionStore; import com.ibm.engine.model.IValue; -import com.ibm.engine.model.OperationMode; import com.ibm.engine.model.ValueAction; import com.ibm.engine.model.context.DigestContext; import com.ibm.engine.model.context.SignatureContext; @@ -134,64 +133,64 @@ public void asserts( assertThat(oidNode).isNotNull(); assertThat(oidNode.getChildren()).isEmpty(); assertThat(oidNode.asString()).isEqualTo("1.2.840.10040.4.1"); - } else if (findingId == 2) { - /* - * Detection Store - */ - assertThat(detectionStore).isNotNull(); - assertThat(detectionStore.getDetectionValues()).hasSize(1); - assertThat(detectionStore.getDetectionValueContext()) + } else if (findingId == 2) { + /* + * Detection Store + */ + assertThat(detectionStore).isNotNull(); + assertThat(detectionStore.getDetectionValues()).hasSize(1); + assertThat(detectionStore.getDetectionValueContext()) .isInstanceOf(SignatureContext.class); - IValue value0 = detectionStore.getDetectionValues().get(0); - assertThat(value0).isInstanceOf(ValueAction.class); - assertThat(value0.asString()).isEqualTo("DSADigestSigner"); - - /* - * Translation - */ - assertThat(nodes).hasSize(1); - - // Signature - INode signatureNode = nodes.get(0); - assertThat(signatureNode.getKind()).isEqualTo(Signature.class); - assertThat(signatureNode.getChildren()).hasSize(3); - assertThat(signatureNode.asString()).isEqualTo("SHA256withDSA"); - - // MessageDigest under Signature - INode messageDigestNode = signatureNode.getChildren().get(MessageDigest.class); - assertThat(messageDigestNode).isNotNull(); - assertThat(messageDigestNode.getChildren()).hasSize(4); - assertThat(messageDigestNode.asString()).isEqualTo("SHA256"); - - // DigestSize under MessageDigest under Signature - INode digestSizeNode = messageDigestNode.getChildren().get(DigestSize.class); - assertThat(digestSizeNode).isNotNull(); - assertThat(digestSizeNode.getChildren()).isEmpty(); - assertThat(digestSizeNode.asString()).isEqualTo("256"); - - // Oid under MessageDigest under Signature - INode oidNode = messageDigestNode.getChildren().get(Oid.class); - assertThat(oidNode).isNotNull(); - assertThat(oidNode.getChildren()).isEmpty(); - assertThat(oidNode.asString()).isEqualTo("2.16.840.1.101.3.4.2.1"); - - // BlockSize under MessageDigest under Signature - INode blockSizeNode = messageDigestNode.getChildren().get(BlockSize.class); - assertThat(blockSizeNode).isNotNull(); - assertThat(blockSizeNode.getChildren()).isEmpty(); - assertThat(blockSizeNode.asString()).isEqualTo("512"); - - // Digest under MessageDigest under Signature - INode digestNode = messageDigestNode.getChildren().get(Digest.class); - assertThat(digestNode).isNotNull(); - assertThat(digestNode.getChildren()).isEmpty(); - assertThat(digestNode.asString()).isEqualTo("DIGEST"); - - // Sign under Signature - INode signNode = signatureNode.getChildren().get(Sign.class); - assertThat(signNode).isNotNull(); - assertThat(signNode.getChildren()).isEmpty(); - assertThat(signNode.asString()).isEqualTo("SIGN"); + IValue value0 = detectionStore.getDetectionValues().get(0); + assertThat(value0).isInstanceOf(ValueAction.class); + assertThat(value0.asString()).isEqualTo("DSADigestSigner"); + + /* + * Translation + */ + assertThat(nodes).hasSize(1); + + // Signature + INode signatureNode = nodes.get(0); + assertThat(signatureNode.getKind()).isEqualTo(Signature.class); + assertThat(signatureNode.getChildren()).hasSize(3); + assertThat(signatureNode.asString()).isEqualTo("SHA256withDSA"); + + // MessageDigest under Signature + INode messageDigestNode = signatureNode.getChildren().get(MessageDigest.class); + assertThat(messageDigestNode).isNotNull(); + assertThat(messageDigestNode.getChildren()).hasSize(4); + assertThat(messageDigestNode.asString()).isEqualTo("SHA256"); + + // DigestSize under MessageDigest under Signature + INode digestSizeNode = messageDigestNode.getChildren().get(DigestSize.class); + assertThat(digestSizeNode).isNotNull(); + assertThat(digestSizeNode.getChildren()).isEmpty(); + assertThat(digestSizeNode.asString()).isEqualTo("256"); + + // Oid under MessageDigest under Signature + INode oidNode = messageDigestNode.getChildren().get(Oid.class); + assertThat(oidNode).isNotNull(); + assertThat(oidNode.getChildren()).isEmpty(); + assertThat(oidNode.asString()).isEqualTo("2.16.840.1.101.3.4.2.1"); + + // BlockSize under MessageDigest under Signature + INode blockSizeNode = messageDigestNode.getChildren().get(BlockSize.class); + assertThat(blockSizeNode).isNotNull(); + assertThat(blockSizeNode.getChildren()).isEmpty(); + assertThat(blockSizeNode.asString()).isEqualTo("512"); + + // Digest under MessageDigest under Signature + INode digestNode = messageDigestNode.getChildren().get(Digest.class); + assertThat(digestNode).isNotNull(); + assertThat(digestNode.getChildren()).isEmpty(); + assertThat(digestNode.asString()).isEqualTo("DIGEST"); + + // Sign under Signature + INode signNode = signatureNode.getChildren().get(Sign.class); + assertThat(signNode).isNotNull(); + assertThat(signNode.getChildren()).isEmpty(); + assertThat(signNode.asString()).isEqualTo("SIGN"); } } }