From 65a703870898a96ebd36002e7a65eaf47e454934 Mon Sep 17 00:00:00 2001 From: Andreas Kretschmer Date: Wed, 18 Sep 2024 10:47:12 +0200 Subject: [PATCH] Adapt to NIST 203..205 and BC beta from 13. Sept 2024 --- .../cryptoservices/AlgorithmHelper.java | 6 +- .../main/TestNistSignature.java | 55 +++++++++++++++++++ .../msggeneration/PkiMessageGenerator.java | 12 ++-- .../protection/SignatureBasedProtection.java | 3 +- .../test/framework/CmpCaMock.java | 25 ++++----- .../cmpracomponent/test/framework/TcAlgs.java | 39 ++++++------- .../framework/TrustChainAndPrivateKey.java | 22 ++++---- 7 files changed, 102 insertions(+), 60 deletions(-) create mode 100644 src/main/java/com/siemens/pki/cmpracomponent/main/TestNistSignature.java diff --git a/src/main/java/com/siemens/pki/cmpracomponent/cryptoservices/AlgorithmHelper.java b/src/main/java/com/siemens/pki/cmpracomponent/cryptoservices/AlgorithmHelper.java index 88d0f566..cbcafd15 100644 --- a/src/main/java/com/siemens/pki/cmpracomponent/cryptoservices/AlgorithmHelper.java +++ b/src/main/java/com/siemens/pki/cmpracomponent/cryptoservices/AlgorithmHelper.java @@ -389,8 +389,10 @@ public static Mac getMac(final String macId) throws NoSuchAlgorithmException { * @return signature * @throws NoSuchAlgorithmException if signatureId is unknown */ - public static Signature getSignature(final String signatureId) throws NoSuchAlgorithmException { - return tryWithAllProviders(p -> Signature.getInstance(signatureId, p)); + public static Signature getSignature(String signatureId) throws NoSuchAlgorithmException { + // XXX hack around https://github.com/bcgit/bc-java/issues/1841 + String internalSigId = signatureId.startsWith("SLH-DSA") ? "SLH-DSA" : signatureId; + return tryWithAllProviders(p -> Signature.getInstance(internalSigId, p)); } /** diff --git a/src/main/java/com/siemens/pki/cmpracomponent/main/TestNistSignature.java b/src/main/java/com/siemens/pki/cmpracomponent/main/TestNistSignature.java new file mode 100644 index 00000000..38617518 --- /dev/null +++ b/src/main/java/com/siemens/pki/cmpracomponent/main/TestNistSignature.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024 Siemens AG + * + * Licensed 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. + * + * SPDX-License-Identifier: Apache-2.0 + */ +package com.siemens.pki.cmpracomponent.main; + +import java.security.Key; +import java.security.KeyPairGenerator; +import java.security.Signature; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +public class TestNistSignature { + + private static final BouncyCastleProvider bcprov = new BouncyCastleProvider(); + + private static Signature deriveSignatureFromKey(Key key) throws Exception { + return Signature.getInstance(key.getAlgorithm(), bcprov); + } + + public static void main(String[] args) { + try { + // works + KeyPairGenerator ml_dsa_kp = + KeyPairGenerator.getInstance(NISTObjectIdentifiers.id_ml_dsa_87.getId(), bcprov); + Signature ml_dsa_sig = + deriveSignatureFromKey(ml_dsa_kp.generateKeyPair().getPrivate()); + System.out.println("got sig for " + ml_dsa_sig.getAlgorithm()); + + // fails + KeyPairGenerator slh_dsa_kp = + KeyPairGenerator.getInstance(NISTObjectIdentifiers.id_slh_dsa_sha2_128s.getId(), bcprov); + Signature slh_dsa_sig = + deriveSignatureFromKey(slh_dsa_kp.generateKeyPair().getPrivate()); + System.out.println("got sig for " + slh_dsa_sig.getAlgorithm()); + + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/siemens/pki/cmpracomponent/msggeneration/PkiMessageGenerator.java b/src/main/java/com/siemens/pki/cmpracomponent/msggeneration/PkiMessageGenerator.java index 07a93713..1adcc97a 100644 --- a/src/main/java/com/siemens/pki/cmpracomponent/msggeneration/PkiMessageGenerator.java +++ b/src/main/java/com/siemens/pki/cmpracomponent/msggeneration/PkiMessageGenerator.java @@ -47,7 +47,6 @@ import org.bouncycastle.asn1.ASN1OctetString; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DERBitString; -import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DEROctetString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.cmp.CMPCertificate; @@ -93,7 +92,6 @@ import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.ExtensionsGenerator; import org.bouncycastle.asn1.x509.GeneralName; -import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.cms.CMSAlgorithm; import org.bouncycastle.cms.CMSEnvelopedData; import org.bouncycastle.cms.CMSEnvelopedDataGenerator; @@ -432,15 +430,15 @@ public static PKIBody generateEncryptedIpCpKupBody(final int bodyType, X509Certi throws CertificateEncodingException, CMSException { // encrypt certificate // KDF2 -// AlgorithmIdentifier kdfAlgorithm = new AlgorithmIdentifier( -// X9ObjectIdentifiers.id_kdf_kdf2, -// new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE)); + // AlgorithmIdentifier kdfAlgorithm = new AlgorithmIdentifier( + // X9ObjectIdentifiers.id_kdf_kdf2, + // new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE)); // KDF3 // AlgorithmIdentifier kdfAlgorithm = new AlgorithmIdentifier( // X9ObjectIdentifiers.id_kdf_kdf3, // new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE)); - // SHAKE256 - AlgorithmIdentifier kdfAlgorithm = new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256); + // SHAKE256 + AlgorithmIdentifier kdfAlgorithm = new AlgorithmIdentifier(NISTObjectIdentifiers.id_shake256); CMSEnvelopedDataGenerator envGen = new CMSEnvelopedDataGenerator(); // Issuer + serialnumber diff --git a/src/main/java/com/siemens/pki/cmpracomponent/protection/SignatureBasedProtection.java b/src/main/java/com/siemens/pki/cmpracomponent/protection/SignatureBasedProtection.java index e8a7aa87..78d7b0ff 100644 --- a/src/main/java/com/siemens/pki/cmpracomponent/protection/SignatureBasedProtection.java +++ b/src/main/java/com/siemens/pki/cmpracomponent/protection/SignatureBasedProtection.java @@ -79,7 +79,8 @@ public AlgorithmIdentifier getProtectionAlg() { } @Override - public DERBitString getProtectionFor(final ProtectedPart protectedPart) throws GeneralSecurityException, IOException{ + public DERBitString getProtectionFor(final ProtectedPart protectedPart) + throws GeneralSecurityException, IOException { final Signature sig = AlgorithmHelper.getSignature(getSignatureAlgorithmName()); sig.initSign(getPrivateKey()); sig.update(protectedPart.getEncoded(ASN1Encoding.DER)); diff --git a/src/test/java/com/siemens/pki/cmpracomponent/test/framework/CmpCaMock.java b/src/test/java/com/siemens/pki/cmpracomponent/test/framework/CmpCaMock.java index 608cc58b..e8d6184d 100644 --- a/src/test/java/com/siemens/pki/cmpracomponent/test/framework/CmpCaMock.java +++ b/src/test/java/com/siemens/pki/cmpracomponent/test/framework/CmpCaMock.java @@ -17,8 +17,18 @@ */ package com.siemens.pki.cmpracomponent.test.framework; +import static com.siemens.pki.cmpracomponent.cryptoservices.ProviderWrapper.tryWithAllProviders; +import static com.siemens.pki.cmpracomponent.util.NullUtil.ifNotNull; import static org.junit.Assert.assertTrue; +import com.siemens.pki.cmpracomponent.configuration.SignatureCredentialContext; +import com.siemens.pki.cmpracomponent.cryptoservices.AlgorithmHelper; +import com.siemens.pki.cmpracomponent.cryptoservices.CertUtility; +import com.siemens.pki.cmpracomponent.main.CmpRaComponent; +import com.siemens.pki.cmpracomponent.msggeneration.PkiMessageGenerator; +import com.siemens.pki.cmpracomponent.protection.ProtectionProvider; +import com.siemens.pki.cmpracomponent.protection.SignatureBasedProtection; +import com.siemens.pki.cmpracomponent.util.MessageDumper; import java.math.BigInteger; import java.security.PrivateKey; import java.security.PublicKey; @@ -28,9 +38,7 @@ import java.util.Date; import java.util.LinkedList; import java.util.List; - import javax.security.auth.x500.X500Principal; - import org.bouncycastle.asn1.cmp.CMPCertificate; import org.bouncycastle.asn1.cmp.PKIBody; import org.bouncycastle.asn1.cmp.PKIFailureInfo; @@ -59,19 +67,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.siemens.pki.cmpracomponent.configuration.SignatureCredentialContext; -import com.siemens.pki.cmpracomponent.cryptoservices.AlgorithmHelper; -import com.siemens.pki.cmpracomponent.cryptoservices.CertUtility; -import com.siemens.pki.cmpracomponent.main.CmpRaComponent; -import com.siemens.pki.cmpracomponent.msggeneration.PkiMessageGenerator; -import com.siemens.pki.cmpracomponent.protection.ProtectionProvider; -import com.siemens.pki.cmpracomponent.protection.SignatureBasedProtection; -import com.siemens.pki.cmpracomponent.util.MessageDumper; - -import static com.siemens.pki.cmpracomponent.util.NullUtil.ifNotNull; - -import static com.siemens.pki.cmpracomponent.cryptoservices.ProviderWrapper.tryWithAllProviders; - /** * a mocked Certificate Authority */ diff --git a/src/test/java/com/siemens/pki/cmpracomponent/test/framework/TcAlgs.java b/src/test/java/com/siemens/pki/cmpracomponent/test/framework/TcAlgs.java index 05ca95a6..ab0c6cec 100644 --- a/src/test/java/com/siemens/pki/cmpracomponent/test/framework/TcAlgs.java +++ b/src/test/java/com/siemens/pki/cmpracomponent/test/framework/TcAlgs.java @@ -24,7 +24,7 @@ import java.util.List; import org.bouncycastle.asn1.bc.BCObjectIdentifiers; import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; -import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; /** * provide lists of algoritrhms to test @@ -35,30 +35,17 @@ private TcAlgs() {} public static List getPqSignatureAlgorithms() throws GeneralSecurityException, NoSuchAlgorithmException { return Arrays.asList(new Object[][] { + {"id_ml_dsa_44", KeyPairGeneratorFactory.getGenericKeyPairGenerator(NISTObjectIdentifiers.id_ml_dsa_44)}, + {"id_ml_dsa_65", KeyPairGeneratorFactory.getGenericKeyPairGenerator(NISTObjectIdentifiers.id_ml_dsa_65)}, + {"id_ml_dsa_87", KeyPairGeneratorFactory.getGenericKeyPairGenerator(NISTObjectIdentifiers.id_ml_dsa_87)}, { - "id_Falcon512_ECDSA_P256_SHA256", - KeyPairGeneratorFactory.getGenericKeyPairGenerator( - org.bouncycastle.asn1.misc.MiscObjectIdentifiers.id_Falcon512_ECDSA_P256_SHA256) - }, - {"LMS", KeyPairGeneratorFactory.getGenericKeyPairGenerator("LMS")}, - { - "id-alg-hss-lms-hashsig", - KeyPairGeneratorFactory.getGenericKeyPairGenerator(PKCSObjectIdentifiers.id_alg_hss_lms_hashsig) - }, - // - { - "SPHINCS+-SHA2-128s", - KeyPairGeneratorFactory.getGenericKeyPairGenerator(BCObjectIdentifiers.sphincsPlus_sha2_128f) + "sphincsPlus_sha2_128s", + KeyPairGeneratorFactory.getGenericKeyPairGenerator(BCObjectIdentifiers.sphincsPlus_sha2_128s) }, { - "SPHINCS+-SHAKE-256s", - KeyPairGeneratorFactory.getGenericKeyPairGenerator(BCObjectIdentifiers.sphincsPlus_shake_256s) + "id_slh_dsa_sha2_128s", + KeyPairGeneratorFactory.getGenericKeyPairGenerator(NISTObjectIdentifiers.id_slh_dsa_sha2_128s) }, - {"dilithium2", KeyPairGeneratorFactory.getGenericKeyPairGenerator(BCObjectIdentifiers.dilithium2)}, - {"dilithium3", KeyPairGeneratorFactory.getGenericKeyPairGenerator(BCObjectIdentifiers.dilithium3)}, - {"dilithium5", KeyPairGeneratorFactory.getGenericKeyPairGenerator(BCObjectIdentifiers.dilithium5)}, - {"falcon_512", KeyPairGeneratorFactory.getGenericKeyPairGenerator(BCObjectIdentifiers.falcon_512)}, - {"falcon_1024", KeyPairGeneratorFactory.getGenericKeyPairGenerator(BCObjectIdentifiers.falcon_1024)} // }); } @@ -141,8 +128,14 @@ public static List getCompositeAlgorithms() throws GeneralSecurityExce public static List getKemAlgorithms() throws GeneralSecurityException, NoSuchAlgorithmException { return Arrays.asList(new Object[][] { - {"KYBER512", KeyPairGeneratorFactory.getGenericKeyPairGenerator(BCObjectIdentifiers.kyber512)}, - {"KYBER1024", KeyPairGeneratorFactory.getGenericKeyPairGenerator(BCObjectIdentifiers.kyber1024)}, + { + "id_alg_ml_kem_512", + KeyPairGeneratorFactory.getGenericKeyPairGenerator(NISTObjectIdentifiers.id_alg_ml_kem_512) + }, + { + "id_alg_ml_kem_1024", + KeyPairGeneratorFactory.getGenericKeyPairGenerator(NISTObjectIdentifiers.id_alg_ml_kem_1024) + }, }); } diff --git a/src/test/java/com/siemens/pki/cmpracomponent/test/framework/TrustChainAndPrivateKey.java b/src/test/java/com/siemens/pki/cmpracomponent/test/framework/TrustChainAndPrivateKey.java index 0cfd2584..e9146829 100644 --- a/src/test/java/com/siemens/pki/cmpracomponent/test/framework/TrustChainAndPrivateKey.java +++ b/src/test/java/com/siemens/pki/cmpracomponent/test/framework/TrustChainAndPrivateKey.java @@ -17,6 +17,14 @@ */ package com.siemens.pki.cmpracomponent.test.framework; +import static com.siemens.pki.cmpracomponent.cryptoservices.ProviderWrapper.tryWithAllProviders; + +import com.siemens.pki.cmpracomponent.configuration.SignatureCredentialContext; +import com.siemens.pki.cmpracomponent.configuration.VerificationContext; +import com.siemens.pki.cmpracomponent.cryptoservices.AlgorithmHelper; +import com.siemens.pki.cmpracomponent.cryptoservices.KeyPairGeneratorFactory; +import com.siemens.pki.cmpracomponent.protection.ProtectionProvider; +import com.siemens.pki.cmpracomponent.util.NullUtil; import java.io.IOException; import java.math.BigInteger; import java.security.GeneralSecurityException; @@ -39,9 +47,7 @@ import java.util.LinkedList; import java.util.List; import java.util.Set; - import javax.security.auth.x500.X500Principal; - import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.DERBitString; @@ -62,15 +68,6 @@ import org.bouncycastle.operator.OperatorCreationException; import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; -import com.siemens.pki.cmpracomponent.configuration.SignatureCredentialContext; -import com.siemens.pki.cmpracomponent.configuration.VerificationContext; -import com.siemens.pki.cmpracomponent.cryptoservices.AlgorithmHelper; -import com.siemens.pki.cmpracomponent.cryptoservices.KeyPairGeneratorFactory; -import com.siemens.pki.cmpracomponent.protection.ProtectionProvider; -import com.siemens.pki.cmpracomponent.util.NullUtil; - -import static com.siemens.pki.cmpracomponent.cryptoservices.ProviderWrapper.tryWithAllProviders; - public class TrustChainAndPrivateKey implements SignatureCredentialContext, VerificationContext { // chain starting with end certificate ending with root certificate @@ -304,7 +301,8 @@ public AlgorithmIdentifier getProtectionAlg() { } @Override - public DERBitString getProtectionFor(final ProtectedPart protectedPart) throws GeneralSecurityException, IOException { + public DERBitString getProtectionFor(final ProtectedPart protectedPart) + throws GeneralSecurityException, IOException { final Signature sig = AlgorithmHelper.getSignature(AlgorithmHelper.getSigningAlgNameFromKey(privateKey)); sig.initSign(privateKey);