diff --git a/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java index edc436365d..641e7505f9 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java @@ -47,6 +47,7 @@ import org.bouncycastle.internal.asn1.oiw.ElGamalParameter; import org.bouncycastle.internal.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; +import org.bouncycastle.tls.injection.Asn1BridgeForInjectedSigAlgs; import org.bouncycastle.util.Arrays; /** @@ -62,7 +63,7 @@ public class PrivateKeyFactory * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData) - throws IOException + throws IOException { if (privateKeyInfoData == null) { @@ -84,7 +85,7 @@ public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData) * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(InputStream inStr) - throws IOException + throws IOException { return createKey(PrivateKeyInfo.getInstance(new ASN1InputStream(inStr).readObject())); } @@ -97,7 +98,7 @@ public static AsymmetricKeyParameter createKey(InputStream inStr) * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo) - throws IOException + throws IOException { if (keyInfo == null) { @@ -107,23 +108,29 @@ public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo) AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm(); ASN1ObjectIdentifier algOID = algId.getAlgorithm(); + // #tls-injection + if (Asn1BridgeForInjectedSigAlgs.theInstance().isSupportedAlgorithm(algOID)) + { + return Asn1BridgeForInjectedSigAlgs.theInstance().createPrivateKeyParameter(keyInfo); + } + if (algOID.equals(PKCSObjectIdentifiers.rsaEncryption) - || algOID.equals(PKCSObjectIdentifiers.id_RSASSA_PSS) - || algOID.equals(X509ObjectIdentifiers.id_ea_rsa)) + || algOID.equals(PKCSObjectIdentifiers.id_RSASSA_PSS) + || algOID.equals(X509ObjectIdentifiers.id_ea_rsa)) { RSAPrivateKey keyStructure = RSAPrivateKey.getInstance(keyInfo.parsePrivateKey()); return new RSAPrivateCrtKeyParameters(keyStructure.getModulus(), - keyStructure.getPublicExponent(), keyStructure.getPrivateExponent(), - keyStructure.getPrime1(), keyStructure.getPrime2(), keyStructure.getExponent1(), - keyStructure.getExponent2(), keyStructure.getCoefficient()); + keyStructure.getPublicExponent(), keyStructure.getPrivateExponent(), + keyStructure.getPrime1(), keyStructure.getPrime2(), keyStructure.getExponent1(), + keyStructure.getExponent2(), keyStructure.getCoefficient()); } // TODO? // else if (algOID.equals(X9ObjectIdentifiers.dhpublicnumber)) else if (algOID.equals(PKCSObjectIdentifiers.dhKeyAgreement)) { DHParameter params = DHParameter.getInstance(algId.getParameters()); - ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey(); + ASN1Integer derX = (ASN1Integer) keyInfo.parsePrivateKey(); BigInteger lVal = params.getL(); int l = lVal == null ? 0 : lVal.intValue(); @@ -134,14 +141,14 @@ else if (algOID.equals(PKCSObjectIdentifiers.dhKeyAgreement)) else if (algOID.equals(OIWObjectIdentifiers.elGamalAlgorithm)) { ElGamalParameter params = ElGamalParameter.getInstance(algId.getParameters()); - ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey(); + ASN1Integer derX = (ASN1Integer) keyInfo.parsePrivateKey(); return new ElGamalPrivateKeyParameters(derX.getValue(), new ElGamalParameters( - params.getP(), params.getG())); + params.getP(), params.getG())); } else if (algOID.equals(X9ObjectIdentifiers.id_dsa)) { - ASN1Integer derX = (ASN1Integer)keyInfo.parsePrivateKey(); + ASN1Integer derX = (ASN1Integer) keyInfo.parsePrivateKey(); ASN1Encodable algParameters = algId.getParameters(); DSAParameters parameters = null; @@ -162,7 +169,7 @@ else if (algOID.equals(X9ObjectIdentifiers.id_ecPublicKey)) if (params.isNamedCurve()) { - ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters(); + ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) params.getParameters(); x9 = CustomNamedCurves.getByOID(oid); if (x9 == null) @@ -175,7 +182,7 @@ else if (algOID.equals(X9ObjectIdentifiers.id_ecPublicKey)) { x9 = X9ECParameters.getInstance(params.getParameters()); dParams = new ECDomainParameters( - x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); + x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed()); } ECPrivateKey ec = ECPrivateKey.getInstance(keyInfo.parsePrivateKey()); @@ -212,9 +219,9 @@ else if (algOID.equals(EdECObjectIdentifiers.id_Ed448)) return new Ed448PrivateKeyParameters(getRawKey(keyInfo)); } else if ( - algOID.equals(CryptoProObjectIdentifiers.gostR3410_2001) || - algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512) || - algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256)) + algOID.equals(CryptoProObjectIdentifiers.gostR3410_2001) || + algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512) || + algOID.equals(RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256)) { ASN1Encodable algParameters = algId.getParameters(); GOST3410PublicKeyAlgParameters gostParams = GOST3410PublicKeyAlgParameters.getInstance(algParameters); @@ -226,11 +233,11 @@ else if ( X9ECParameters ecP = ECGOST3410NamedCurves.getByOIDX9(gostParams.getPublicKeyParamSet()); ecSpec = new ECGOST3410Parameters( - new ECNamedDomainParameters( - gostParams.getPublicKeyParamSet(), ecP), - gostParams.getPublicKeyParamSet(), - gostParams.getDigestParamSet(), - gostParams.getEncryptionParamSet()); + new ECNamedDomainParameters( + gostParams.getPublicKeyParamSet(), ecP), + gostParams.getPublicKeyParamSet(), + gostParams.getDigestParamSet(), + gostParams.getEncryptionParamSet()); int privateKeyLength = keyInfo.getPrivateKeyLength(); @@ -262,8 +269,8 @@ else if ( X9ECParameters ecP = ECNamedCurveTable.getByOID(oid); ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(oid, ecP), - gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(), - gostParams.getEncryptionParamSet()); + gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(), + gostParams.getEncryptionParamSet()); } else if (params.isImplicitlyCA()) { @@ -273,8 +280,8 @@ else if (params.isImplicitlyCA()) { X9ECParameters ecP = X9ECParameters.getInstance(params.getParameters()); ecSpec = new ECGOST3410Parameters(new ECNamedDomainParameters(algOID, ecP), - gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(), - gostParams.getEncryptionParamSet()); + gostParams.getPublicKeyParamSet(), gostParams.getDigestParamSet(), + gostParams.getEncryptionParamSet()); } ASN1Encodable privKey = keyInfo.parsePrivateKey(); @@ -294,12 +301,12 @@ else if (params.isImplicitlyCA()) } return new ECPrivateKeyParameters( - d, - new ECGOST3410Parameters( - ecSpec, - gostParams.getPublicKeyParamSet(), - gostParams.getDigestParamSet(), - gostParams.getEncryptionParamSet())); + d, + new ECGOST3410Parameters( + ecSpec, + gostParams.getPublicKeyParamSet(), + gostParams.getDigestParamSet(), + gostParams.getEncryptionParamSet())); } else diff --git a/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyInfoFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyInfoFactory.java index 1b00473f5e..21fe06f9bd 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyInfoFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyInfoFactory.java @@ -41,6 +41,7 @@ import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.math.ec.ECPoint; import org.bouncycastle.math.ec.FixedPointCombMultiplier; +import org.bouncycastle.tls.injection.Asn1BridgeForInjectedSigAlgs; /** * Factory to create ASN.1 private key info objects from lightweight private keys. @@ -71,7 +72,7 @@ private PrivateKeyInfoFactory() * @throws java.io.IOException on an error encoding the key */ public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter privateKey) - throws IOException + throws IOException { return createPrivateKeyInfo(privateKey, null); } @@ -84,29 +85,37 @@ public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter private * @return the appropriate PrivateKeyInfo * @throws java.io.IOException on an error encoding the key */ - public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter privateKey, ASN1Set attributes) - throws IOException + public static PrivateKeyInfo createPrivateKeyInfo( + AsymmetricKeyParameter privateKey, + ASN1Set attributes) + throws IOException { + // #tls-injection + if (Asn1BridgeForInjectedSigAlgs.theInstance().isSupportedParameter(privateKey)) + { + return Asn1BridgeForInjectedSigAlgs.theInstance().createPrivateKeyInfo(privateKey, attributes); + } + if (privateKey instanceof RSAKeyParameters) { - RSAPrivateCrtKeyParameters priv = (RSAPrivateCrtKeyParameters)privateKey; + RSAPrivateCrtKeyParameters priv = (RSAPrivateCrtKeyParameters) privateKey; return new PrivateKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), - new RSAPrivateKey(priv.getModulus(), priv.getPublicExponent(), priv.getExponent(), priv.getP(), priv.getQ(), priv.getDP(), priv.getDQ(), priv.getQInv()), - attributes); + new RSAPrivateKey(priv.getModulus(), priv.getPublicExponent(), priv.getExponent(), priv.getP(), priv.getQ(), priv.getDP(), priv.getDQ(), priv.getQInv()), + attributes); } else if (privateKey instanceof DSAPrivateKeyParameters) { - DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters)privateKey; + DSAPrivateKeyParameters priv = (DSAPrivateKeyParameters) privateKey; DSAParameters params = priv.getParameters(); return new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_dsa, - new DSAParameter(params.getP(), params.getQ(), params.getG())), new ASN1Integer(priv.getX()), - attributes); + new DSAParameter(params.getP(), params.getQ(), params.getG())), new ASN1Integer(priv.getX()), + attributes); } else if (privateKey instanceof ECPrivateKeyParameters) { - ECPrivateKeyParameters priv = (ECPrivateKeyParameters)privateKey; + ECPrivateKeyParameters priv = (ECPrivateKeyParameters) privateKey; ECDomainParameters domainParams = priv.getParameters(); ASN1Encodable params; int orderBitLength; @@ -119,9 +128,9 @@ else if (privateKey instanceof ECPrivateKeyParameters) else if (domainParams instanceof ECGOST3410Parameters) { GOST3410PublicKeyAlgParameters gostParams = new GOST3410PublicKeyAlgParameters( - ((ECGOST3410Parameters)domainParams).getPublicKeyParamSet(), - ((ECGOST3410Parameters)domainParams).getDigestParamSet(), - ((ECGOST3410Parameters)domainParams).getEncryptionParamSet()); + ((ECGOST3410Parameters) domainParams).getPublicKeyParamSet(), + ((ECGOST3410Parameters) domainParams).getDigestParamSet(), + ((ECGOST3410Parameters) domainParams).getEncryptionParamSet()); int size; @@ -137,8 +146,8 @@ else if (domainParams instanceof ECGOST3410Parameters) boolean is512 = priv.getD().bitLength() > 256; identifier = (is512) ? - RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512 : - RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256; + RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512 : + RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256; size = (is512) ? 64 : 32; } byte[] encKey = new byte[size]; @@ -149,17 +158,17 @@ else if (domainParams instanceof ECGOST3410Parameters) } else if (domainParams instanceof ECNamedDomainParameters) { - params = new X962Parameters(((ECNamedDomainParameters)domainParams).getName()); + params = new X962Parameters(((ECNamedDomainParameters) domainParams).getName()); orderBitLength = domainParams.getN().bitLength(); } else { X9ECParameters ecP = new X9ECParameters( - domainParams.getCurve(), - new X9ECPoint(domainParams.getG(), false), - domainParams.getN(), - domainParams.getH(), - domainParams.getSeed()); + domainParams.getCurve(), + new X9ECPoint(domainParams.getG(), false), + domainParams.getN(), + domainParams.getH(), + domainParams.getSeed()); params = new X962Parameters(ecP); orderBitLength = domainParams.getN().bitLength(); @@ -171,37 +180,37 @@ else if (domainParams instanceof ECNamedDomainParameters) DERBitString publicKey = new DERBitString(q.getEncoded(false)); return new PrivateKeyInfo( - new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), - new ECPrivateKey(orderBitLength, priv.getD(), publicKey, params), - attributes); + new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), + new ECPrivateKey(orderBitLength, priv.getD(), publicKey, params), + attributes); } else if (privateKey instanceof X448PrivateKeyParameters) { - X448PrivateKeyParameters key = (X448PrivateKeyParameters)privateKey; + X448PrivateKeyParameters key = (X448PrivateKeyParameters) privateKey; return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X448), - new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded()); + new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded()); } else if (privateKey instanceof X25519PrivateKeyParameters) { - X25519PrivateKeyParameters key = (X25519PrivateKeyParameters)privateKey; + X25519PrivateKeyParameters key = (X25519PrivateKeyParameters) privateKey; return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), - new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded()); + new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded()); } else if (privateKey instanceof Ed448PrivateKeyParameters) { - Ed448PrivateKeyParameters key = (Ed448PrivateKeyParameters)privateKey; + Ed448PrivateKeyParameters key = (Ed448PrivateKeyParameters) privateKey; return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448), - new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded()); + new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded()); } else if (privateKey instanceof Ed25519PrivateKeyParameters) { - Ed25519PrivateKeyParameters key = (Ed25519PrivateKeyParameters)privateKey; + Ed25519PrivateKeyParameters key = (Ed25519PrivateKeyParameters) privateKey; return new PrivateKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), - new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded()); + new DEROctetString(key.getEncoded()), attributes, key.generatePublicKey().getEncoded()); } else { @@ -210,7 +219,11 @@ else if (privateKey instanceof Ed25519PrivateKeyParameters) } - private static void extractBytes(byte[] encKey, int size, int offSet, BigInteger bI) + private static void extractBytes( + byte[] encKey, + int size, + int offSet, + BigInteger bI) { byte[] val = bI.toByteArray(); if (val.length < size) diff --git a/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java index a8c7055e48..a74155f205 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java @@ -63,6 +63,7 @@ import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; import org.bouncycastle.math.ec.ECCurve; import org.bouncycastle.math.ec.ECPoint; +import org.bouncycastle.tls.injection.Asn1BridgeForInjectedSigAlgs; import org.bouncycastle.util.Arrays; /** @@ -103,7 +104,7 @@ public class PublicKeyFactory * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(byte[] keyInfoData) - throws IOException + throws IOException { if (keyInfoData == null) { @@ -124,7 +125,7 @@ public static AsymmetricKeyParameter createKey(byte[] keyInfoData) * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(InputStream inStr) - throws IOException + throws IOException { return createKey(SubjectPublicKeyInfo.getInstance(new ASN1InputStream(inStr).readObject())); } @@ -137,7 +138,7 @@ public static AsymmetricKeyParameter createKey(InputStream inStr) * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo) - throws IOException + throws IOException { if (keyInfo == null) { @@ -154,8 +155,10 @@ public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo) * @return the appropriate key parameter * @throws IOException on an error decoding the key */ - public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + public static AsymmetricKeyParameter createKey( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { if (keyInfo == null) { @@ -163,8 +166,15 @@ public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo, Obj } AlgorithmIdentifier algID = keyInfo.getAlgorithm(); + ASN1ObjectIdentifier algOID = algID.getAlgorithm(); - SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)converters.get(algID.getAlgorithm()); + // #tls-injection + if (Asn1BridgeForInjectedSigAlgs.theInstance().isSupportedAlgorithm((algOID))) + { + return Asn1BridgeForInjectedSigAlgs.theInstance().createPublicKeyParameter(keyInfo, defaultParams); + } + + SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter) converters.get(algID.getAlgorithm()); if (null == converter) { throw new IOException("algorithm identifier in public key not recognised: " + algID.getAlgorithm()); @@ -175,15 +185,19 @@ public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo, Obj private static abstract class SubjectPublicKeyInfoConverter { - abstract AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException; + abstract AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException; } private static class RSAConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { RSAPublicKey pubKey = RSAPublicKey.getInstance(keyInfo.parsePublicKey()); @@ -192,10 +206,12 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class DHPublicNumberConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { DHPublicKey dhPublicKey = DHPublicKey.getInstance(keyInfo.parsePublicKey()); @@ -230,13 +246,15 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class DHAgreementConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { DHParameter params = DHParameter.getInstance(keyInfo.getAlgorithm().getParameters()); - ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey(); + ASN1Integer derY = (ASN1Integer) keyInfo.parsePublicKey(); BigInteger lVal = params.getL(); int l = lVal == null ? 0 : lVal.intValue(); @@ -247,26 +265,30 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class ElGamalConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { ElGamalParameter params = ElGamalParameter.getInstance(keyInfo.getAlgorithm().getParameters()); - ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey(); + ASN1Integer derY = (ASN1Integer) keyInfo.parsePublicKey(); return new ElGamalPublicKeyParameters(derY.getValue(), new ElGamalParameters( - params.getP(), params.getG())); + params.getP(), params.getG())); } } private static class DSAConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { - ASN1Integer derY = (ASN1Integer)keyInfo.parsePublicKey(); + ASN1Integer derY = (ASN1Integer) keyInfo.parsePublicKey(); ASN1Encodable de = keyInfo.getAlgorithm().getParameters(); DSAParameters parameters = null; @@ -281,16 +303,18 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class ECConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) { X962Parameters params = X962Parameters.getInstance(keyInfo.getAlgorithm().getParameters()); ECDomainParameters dParams; if (params.isNamedCurve()) { - ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters(); + ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) params.getParameters(); X9ECParameters x9 = CustomNamedCurves.getByOID(oid); if (x9 == null) @@ -301,7 +325,7 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } else if (params.isImplicitlyCA()) { - dParams = (ECDomainParameters)defaultParams; + dParams = (ECDomainParameters) defaultParams; } else { @@ -317,7 +341,7 @@ else if (params.isImplicitlyCA()) // extra octet string - the old extra embedded octet string // if (data[0] == 0x04 && data[1] == data.length - 2 - && (data[2] == 0x02 || data[2] == 0x03)) + && (data[2] == 0x02 || data[2] == 0x03)) { int qLength = new X9IntegerConverter().getByteLength(dParams.getCurve()); @@ -325,9 +349,8 @@ else if (params.isImplicitlyCA()) { try { - key = (ASN1OctetString)ASN1Primitive.fromByteArray(data); - } - catch (IOException ex) + key = (ASN1OctetString) ASN1Primitive.fromByteArray(data); + } catch (IOException ex) { throw new IllegalArgumentException("error recovering public key"); } @@ -341,9 +364,11 @@ else if (params.isImplicitlyCA()) } private static class GOST3410_2001Converter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) { AlgorithmIdentifier algID = keyInfo.getAlgorithm(); // ASN1ObjectIdentifier algOid = algID.getAlgorithm(); @@ -351,17 +376,16 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje ASN1ObjectIdentifier publicKeyParamSet = gostParams.getPublicKeyParamSet(); ECGOST3410Parameters ecDomainParameters = new ECGOST3410Parameters( - new ECNamedDomainParameters(publicKeyParamSet, ECGOST3410NamedCurves.getByOIDX9(publicKeyParamSet)), - publicKeyParamSet, - gostParams.getDigestParamSet(), - gostParams.getEncryptionParamSet()); + new ECNamedDomainParameters(publicKeyParamSet, ECGOST3410NamedCurves.getByOIDX9(publicKeyParamSet)), + publicKeyParamSet, + gostParams.getDigestParamSet(), + gostParams.getEncryptionParamSet()); ASN1OctetString key; try { - key = (ASN1OctetString)keyInfo.parsePublicKey(); - } - catch (IOException ex) + key = (ASN1OctetString) keyInfo.parsePublicKey(); + } catch (IOException ex) { throw new IllegalArgumentException("error recovering GOST3410_2001 public key"); } @@ -390,9 +414,11 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class GOST3410_2012Converter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) { AlgorithmIdentifier algID = keyInfo.getAlgorithm(); ASN1ObjectIdentifier algOid = algID.getAlgorithm(); @@ -400,17 +426,16 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje ASN1ObjectIdentifier publicKeyParamSet = gostParams.getPublicKeyParamSet(); ECGOST3410Parameters ecDomainParameters = new ECGOST3410Parameters( - new ECNamedDomainParameters(publicKeyParamSet, ECGOST3410NamedCurves.getByOIDX9(publicKeyParamSet)), - publicKeyParamSet, - gostParams.getDigestParamSet(), - gostParams.getEncryptionParamSet()); + new ECNamedDomainParameters(publicKeyParamSet, ECGOST3410NamedCurves.getByOIDX9(publicKeyParamSet)), + publicKeyParamSet, + gostParams.getDigestParamSet(), + gostParams.getEncryptionParamSet()); ASN1OctetString key; try { - key = (ASN1OctetString)keyInfo.parsePublicKey(); - } - catch (IOException ex) + key = (ASN1OctetString) keyInfo.parsePublicKey(); + } catch (IOException ex) { throw new IllegalArgumentException("error recovering GOST3410_2012 public key"); } @@ -443,10 +468,12 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class DSTUConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { AlgorithmIdentifier algID = keyInfo.getAlgorithm(); ASN1ObjectIdentifier algOid = algID.getAlgorithm(); @@ -455,9 +482,8 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje ASN1OctetString key; try { - key = (ASN1OctetString)keyInfo.parsePublicKey(); - } - catch (IOException ex) + key = (ASN1OctetString) keyInfo.parsePublicKey(); + } catch (IOException ex) { throw new IllegalArgumentException("error recovering DSTU public key"); } @@ -513,42 +539,52 @@ private void reverseBytes(byte[] bytes) } private static class X25519Converter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) { return new X25519PublicKeyParameters(getRawKey(keyInfo, defaultParams)); } } private static class X448Converter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) { return new X448PublicKeyParameters(getRawKey(keyInfo, defaultParams)); } } private static class Ed25519Converter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) { return new Ed25519PublicKeyParameters(getRawKey(keyInfo, defaultParams)); } } private static class Ed448Converter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) { return new Ed448PublicKeyParameters(getRawKey(keyInfo, defaultParams)); } } - private static byte[] getRawKey(SubjectPublicKeyInfo keyInfo, Object defaultParams) + private static byte[] getRawKey( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) { /* * TODO[RFC 8422] diff --git a/core/src/main/java/org/bouncycastle/crypto/util/SubjectPublicKeyInfoFactory.java b/core/src/main/java/org/bouncycastle/crypto/util/SubjectPublicKeyInfoFactory.java index 3ade492281..c970516b66 100644 --- a/core/src/main/java/org/bouncycastle/crypto/util/SubjectPublicKeyInfoFactory.java +++ b/core/src/main/java/org/bouncycastle/crypto/util/SubjectPublicKeyInfoFactory.java @@ -36,6 +36,8 @@ import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers; import org.bouncycastle.internal.asn1.rosstandart.RosstandartObjectIdentifiers; +import org.bouncycastle.tls.injection.Asn1BridgeForInjectedSigAlgs; + /** * Factory to create ASN.1 subject public key info objects from lightweight public keys. */ @@ -65,17 +67,23 @@ private SubjectPublicKeyInfoFactory() * @throws java.io.IOException on an error encoding the key */ public static SubjectPublicKeyInfo createSubjectPublicKeyInfo(AsymmetricKeyParameter publicKey) - throws IOException + throws IOException { + // #tls-injection: + if (Asn1BridgeForInjectedSigAlgs.theInstance().isSupportedParameter(publicKey)) + { + return Asn1BridgeForInjectedSigAlgs.theInstance().createSubjectPublicKeyInfo(publicKey); + } + if (publicKey instanceof RSAKeyParameters) { - RSAKeyParameters pub = (RSAKeyParameters)publicKey; + RSAKeyParameters pub = (RSAKeyParameters) publicKey; return new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE), new RSAPublicKey(pub.getModulus(), pub.getExponent())); } else if (publicKey instanceof DSAPublicKeyParameters) { - DSAPublicKeyParameters pub = (DSAPublicKeyParameters)publicKey; + DSAPublicKeyParameters pub = (DSAPublicKeyParameters) publicKey; DSAParameter params = null; DSAParameters dsaParams = pub.getParameters(); @@ -88,7 +96,7 @@ else if (publicKey instanceof DSAPublicKeyParameters) } else if (publicKey instanceof ECPublicKeyParameters) { - ECPublicKeyParameters pub = (ECPublicKeyParameters)publicKey; + ECPublicKeyParameters pub = (ECPublicKeyParameters) publicKey; ECDomainParameters domainParams = pub.getParameters(); ASN1Encodable params; @@ -98,7 +106,7 @@ else if (publicKey instanceof ECPublicKeyParameters) } else if (domainParams instanceof ECGOST3410Parameters) { - ECGOST3410Parameters gostParams = (ECGOST3410Parameters)domainParams; + ECGOST3410Parameters gostParams = (ECGOST3410Parameters) domainParams; BigInteger bX = pub.getQ().getAffineXCoord().toBigInteger(); BigInteger bY = pub.getQ().getAffineYCoord().toBigInteger(); @@ -140,25 +148,24 @@ else if (domainParams instanceof ECGOST3410Parameters) try { return new SubjectPublicKeyInfo(new AlgorithmIdentifier(algIdentifier, params), new DEROctetString(encKey)); - } - catch (IOException e) + } catch (IOException e) { return null; } } else if (domainParams instanceof ECNamedDomainParameters) { - params = new X962Parameters(((ECNamedDomainParameters)domainParams).getName()); + params = new X962Parameters(((ECNamedDomainParameters) domainParams).getName()); } else { X9ECParameters ecP = new X9ECParameters( - domainParams.getCurve(), - // TODO Support point compression - new X9ECPoint(domainParams.getG(), false), - domainParams.getN(), - domainParams.getH(), - domainParams.getSeed()); + domainParams.getCurve(), + // TODO Support point compression + new X9ECPoint(domainParams.getG(), false), + domainParams.getN(), + domainParams.getH(), + domainParams.getSeed()); params = new X962Parameters(ecP); } @@ -170,25 +177,25 @@ else if (domainParams instanceof ECNamedDomainParameters) } else if (publicKey instanceof X448PublicKeyParameters) { - X448PublicKeyParameters key = (X448PublicKeyParameters)publicKey; + X448PublicKeyParameters key = (X448PublicKeyParameters) publicKey; return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X448), key.getEncoded()); } else if (publicKey instanceof X25519PublicKeyParameters) { - X25519PublicKeyParameters key = (X25519PublicKeyParameters)publicKey; + X25519PublicKeyParameters key = (X25519PublicKeyParameters) publicKey; return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), key.getEncoded()); } else if (publicKey instanceof Ed448PublicKeyParameters) { - Ed448PublicKeyParameters key = (Ed448PublicKeyParameters)publicKey; + Ed448PublicKeyParameters key = (Ed448PublicKeyParameters) publicKey; return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448), key.getEncoded()); } else if (publicKey instanceof Ed25519PublicKeyParameters) { - Ed25519PublicKeyParameters key = (Ed25519PublicKeyParameters)publicKey; + Ed25519PublicKeyParameters key = (Ed25519PublicKeyParameters) publicKey; return new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), key.getEncoded()); } @@ -198,7 +205,11 @@ else if (publicKey instanceof Ed25519PublicKeyParameters) } } - private static void extractBytes(byte[] encKey, int size, int offSet, BigInteger bI) + private static void extractBytes( + byte[] encKey, + int size, + int offSet, + BigInteger bI) { byte[] val = bI.toByteArray(); if (val.length < size) diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java index 5442f6c2ce..7e9568a3ee 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyFactory.java @@ -17,17 +17,7 @@ import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.pqc.asn1.CMCEPrivateKey; -import org.bouncycastle.pqc.asn1.FalconPrivateKey; -import org.bouncycastle.pqc.asn1.McElieceCCA2PrivateKey; -import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; -import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; -import org.bouncycastle.pqc.asn1.SPHINCSPLUSPrivateKey; -import org.bouncycastle.pqc.asn1.SPHINCSPLUSPublicKey; -import org.bouncycastle.pqc.asn1.XMSSKeyParams; -import org.bouncycastle.pqc.asn1.XMSSMTKeyParams; -import org.bouncycastle.pqc.asn1.XMSSMTPrivateKey; -import org.bouncycastle.pqc.asn1.XMSSPrivateKey; +import org.bouncycastle.pqc.asn1.*; import org.bouncycastle.pqc.crypto.bike.BIKEParameters; import org.bouncycastle.pqc.crypto.bike.BIKEPrivateKeyParameters; import org.bouncycastle.pqc.crypto.cmce.CMCEParameters; @@ -70,6 +60,7 @@ import org.bouncycastle.pqc.crypto.xmss.XMSSUtil; import org.bouncycastle.pqc.legacy.crypto.mceliece.McElieceCCA2PrivateKeyParameters; import org.bouncycastle.pqc.legacy.crypto.qtesla.QTESLAPrivateKeyParameters; +import org.bouncycastle.tls.injection.Asn1BridgeForInjectedSigAlgs; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Pack; @@ -86,7 +77,7 @@ public class PrivateKeyFactory * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData) - throws IOException + throws IOException { if (privateKeyInfoData == null) { @@ -108,7 +99,7 @@ public static AsymmetricKeyParameter createKey(byte[] privateKeyInfoData) * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(InputStream inStr) - throws IOException + throws IOException { return createKey(PrivateKeyInfo.getInstance(new ASN1InputStream(inStr).readObject())); } @@ -121,7 +112,7 @@ public static AsymmetricKeyParameter createKey(InputStream inStr) * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo) - throws IOException + throws IOException { if (keyInfo == null) { @@ -131,6 +122,12 @@ public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo) AlgorithmIdentifier algId = keyInfo.getPrivateKeyAlgorithm(); ASN1ObjectIdentifier algOID = algId.getAlgorithm(); + // #tls-injection: + if (Asn1BridgeForInjectedSigAlgs.theInstance().isSupportedAlgorithm(algOID)) + { + return Asn1BridgeForInjectedSigAlgs.theInstance().createPrivateKeyParameter(keyInfo); + } + if (algOID.on(PQCObjectIdentifiers.qTESLA)) { ASN1OctetString qTESLAPriv = ASN1OctetString.getInstance(keyInfo.parsePrivateKey()); @@ -140,7 +137,7 @@ public static AsymmetricKeyParameter createKey(PrivateKeyInfo keyInfo) else if (algOID.equals(PQCObjectIdentifiers.sphincs256)) { return new SPHINCSPrivateKeyParameters(ASN1OctetString.getInstance(keyInfo.parsePrivateKey()).getOctets(), - Utils.sphincs256LookupTreeAlgName(SPHINCS256KeyParams.getInstance(algId.getParameters()))); + Utils.sphincs256LookupTreeAlgName(SPHINCS256KeyParams.getInstance(algId.getParameters()))); } else if (algOID.equals(PQCObjectIdentifiers.newHope)) { @@ -182,7 +179,7 @@ else if (algOID.on(BCObjectIdentifiers.sphincsPlus) || algOID.on(BCObjectIdentif SPHINCSPLUSPrivateKey spKey = SPHINCSPLUSPrivateKey.getInstance(obj); SPHINCSPLUSPublicKey publicKey = spKey.getPublicKey(); return new SPHINCSPlusPrivateKeyParameters(spParams, spKey.getSkseed(), spKey.getSkprf(), - publicKey.getPkseed(), publicKey.getPkroot()); + publicKey.getPkseed(), publicKey.getPkroot()); } else { @@ -238,10 +235,10 @@ else if (algOID.on(BCObjectIdentifiers.pqc_kem_ntrulprime)) NTRULPRimeParameters spParams = Utils.ntrulprimeParamsLookup(algOID); return new NTRULPRimePrivateKeyParameters(spParams, - ASN1OctetString.getInstance(keyEnc.getObjectAt(0)).getOctets(), - ASN1OctetString.getInstance(keyEnc.getObjectAt(1)).getOctets(), - ASN1OctetString.getInstance(keyEnc.getObjectAt(2)).getOctets(), - ASN1OctetString.getInstance(keyEnc.getObjectAt(3)).getOctets()); + ASN1OctetString.getInstance(keyEnc.getObjectAt(0)).getOctets(), + ASN1OctetString.getInstance(keyEnc.getObjectAt(1)).getOctets(), + ASN1OctetString.getInstance(keyEnc.getObjectAt(2)).getOctets(), + ASN1OctetString.getInstance(keyEnc.getObjectAt(3)).getOctets()); } else if (algOID.on(BCObjectIdentifiers.pqc_kem_sntruprime)) { @@ -250,14 +247,14 @@ else if (algOID.on(BCObjectIdentifiers.pqc_kem_sntruprime)) SNTRUPrimeParameters spParams = Utils.sntruprimeParamsLookup(algOID); return new SNTRUPrimePrivateKeyParameters(spParams, - ASN1OctetString.getInstance(keyEnc.getObjectAt(0)).getOctets(), - ASN1OctetString.getInstance(keyEnc.getObjectAt(1)).getOctets(), - ASN1OctetString.getInstance(keyEnc.getObjectAt(2)).getOctets(), - ASN1OctetString.getInstance(keyEnc.getObjectAt(3)).getOctets(), - ASN1OctetString.getInstance(keyEnc.getObjectAt(4)).getOctets()); + ASN1OctetString.getInstance(keyEnc.getObjectAt(0)).getOctets(), + ASN1OctetString.getInstance(keyEnc.getObjectAt(1)).getOctets(), + ASN1OctetString.getInstance(keyEnc.getObjectAt(2)).getOctets(), + ASN1OctetString.getInstance(keyEnc.getObjectAt(3)).getOctets(), + ASN1OctetString.getInstance(keyEnc.getObjectAt(4)).getOctets()); } else if (algOID.equals(BCObjectIdentifiers.dilithium2) - || algOID.equals(BCObjectIdentifiers.dilithium3) || algOID.equals(BCObjectIdentifiers.dilithium5)) + || algOID.equals(BCObjectIdentifiers.dilithium3) || algOID.equals(BCObjectIdentifiers.dilithium5)) { ASN1Encodable keyObj = keyInfo.parsePrivateKey(); DilithiumParameters spParams = Utils.dilithiumParamsLookup(algOID); @@ -277,24 +274,24 @@ else if (algOID.equals(BCObjectIdentifiers.dilithium2) DilithiumPublicKeyParameters pubParams = PublicKeyFactory.DilithiumConverter.getPublicKeyParams(spParams, keyInfo.getPublicKeyData()); return new DilithiumPrivateKeyParameters(spParams, - ASN1BitString.getInstance(keyEnc.getObjectAt(1)).getOctets(), - ASN1BitString.getInstance(keyEnc.getObjectAt(2)).getOctets(), - ASN1BitString.getInstance(keyEnc.getObjectAt(3)).getOctets(), - ASN1BitString.getInstance(keyEnc.getObjectAt(4)).getOctets(), - ASN1BitString.getInstance(keyEnc.getObjectAt(5)).getOctets(), - ASN1BitString.getInstance(keyEnc.getObjectAt(6)).getOctets(), - pubParams.getT1()); // encT1 + ASN1BitString.getInstance(keyEnc.getObjectAt(1)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(2)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(3)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(4)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(5)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(6)).getOctets(), + pubParams.getT1()); // encT1 } else { return new DilithiumPrivateKeyParameters(spParams, - ASN1BitString.getInstance(keyEnc.getObjectAt(1)).getOctets(), - ASN1BitString.getInstance(keyEnc.getObjectAt(2)).getOctets(), - ASN1BitString.getInstance(keyEnc.getObjectAt(3)).getOctets(), - ASN1BitString.getInstance(keyEnc.getObjectAt(4)).getOctets(), - ASN1BitString.getInstance(keyEnc.getObjectAt(5)).getOctets(), - ASN1BitString.getInstance(keyEnc.getObjectAt(6)).getOctets(), - null); + ASN1BitString.getInstance(keyEnc.getObjectAt(1)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(2)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(3)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(4)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(5)).getOctets(), + ASN1BitString.getInstance(keyEnc.getObjectAt(6)).getOctets(), + null); } } else if (keyObj instanceof DEROctetString) @@ -353,12 +350,12 @@ else if (algOID.equals(PQCObjectIdentifiers.xmss)) try { XMSSPrivateKeyParameters.Builder keyBuilder = new XMSSPrivateKeyParameters - .Builder(new XMSSParameters(keyParams.getHeight(), Utils.getDigest(treeDigest))) - .withIndex(xmssPrivateKey.getIndex()) - .withSecretKeySeed(xmssPrivateKey.getSecretKeySeed()) - .withSecretKeyPRF(xmssPrivateKey.getSecretKeyPRF()) - .withPublicSeed(xmssPrivateKey.getPublicSeed()) - .withRoot(xmssPrivateKey.getRoot()); + .Builder(new XMSSParameters(keyParams.getHeight(), Utils.getDigest(treeDigest))) + .withIndex(xmssPrivateKey.getIndex()) + .withSecretKeySeed(xmssPrivateKey.getSecretKeySeed()) + .withSecretKeyPRF(xmssPrivateKey.getSecretKeyPRF()) + .withPublicSeed(xmssPrivateKey.getPublicSeed()) + .withRoot(xmssPrivateKey.getRoot()); if (xmssPrivateKey.getVersion() != 0) { @@ -367,13 +364,12 @@ else if (algOID.equals(PQCObjectIdentifiers.xmss)) if (xmssPrivateKey.getBdsState() != null) { - BDS bds = (BDS)XMSSUtil.deserialize(xmssPrivateKey.getBdsState(), BDS.class); + BDS bds = (BDS) XMSSUtil.deserialize(xmssPrivateKey.getBdsState(), BDS.class); keyBuilder.withBDSState(bds.withWOTSDigest(treeDigest)); } return keyBuilder.build(); - } - catch (ClassNotFoundException e) + } catch (ClassNotFoundException e) { throw new IOException("ClassNotFoundException processing BDS state: " + e.getMessage()); } @@ -388,12 +384,12 @@ else if (algOID.equals(PQCObjectIdentifiers.xmss_mt)) XMSSMTPrivateKey xmssMtPrivateKey = XMSSMTPrivateKey.getInstance(keyInfo.parsePrivateKey()); XMSSMTPrivateKeyParameters.Builder keyBuilder = new XMSSMTPrivateKeyParameters - .Builder(new XMSSMTParameters(keyParams.getHeight(), keyParams.getLayers(), Utils.getDigest(treeDigest))) - .withIndex(xmssMtPrivateKey.getIndex()) - .withSecretKeySeed(xmssMtPrivateKey.getSecretKeySeed()) - .withSecretKeyPRF(xmssMtPrivateKey.getSecretKeyPRF()) - .withPublicSeed(xmssMtPrivateKey.getPublicSeed()) - .withRoot(xmssMtPrivateKey.getRoot()); + .Builder(new XMSSMTParameters(keyParams.getHeight(), keyParams.getLayers(), Utils.getDigest(treeDigest))) + .withIndex(xmssMtPrivateKey.getIndex()) + .withSecretKeySeed(xmssMtPrivateKey.getSecretKeySeed()) + .withSecretKeyPRF(xmssMtPrivateKey.getSecretKeyPRF()) + .withPublicSeed(xmssMtPrivateKey.getPublicSeed()) + .withRoot(xmssMtPrivateKey.getRoot()); if (xmssMtPrivateKey.getVersion() != 0) { @@ -402,13 +398,12 @@ else if (algOID.equals(PQCObjectIdentifiers.xmss_mt)) if (xmssMtPrivateKey.getBdsState() != null) { - BDSStateMap bdsState = (BDSStateMap)XMSSUtil.deserialize(xmssMtPrivateKey.getBdsState(), BDSStateMap.class); + BDSStateMap bdsState = (BDSStateMap) XMSSUtil.deserialize(xmssMtPrivateKey.getBdsState(), BDSStateMap.class); keyBuilder.withBDSState(bdsState.withWOTSDigest(treeDigest)); } return keyBuilder.build(); - } - catch (ClassNotFoundException e) + } catch (ClassNotFoundException e) { throw new IOException("ClassNotFoundException processing BDS state: " + e.getMessage()); } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java index 1c97591500..f637be5ece 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PrivateKeyInfoFactory.java @@ -10,17 +10,7 @@ import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; -import org.bouncycastle.pqc.asn1.CMCEPrivateKey; -import org.bouncycastle.pqc.asn1.CMCEPublicKey; -import org.bouncycastle.pqc.asn1.FalconPrivateKey; -import org.bouncycastle.pqc.asn1.FalconPublicKey; -import org.bouncycastle.pqc.asn1.McElieceCCA2PrivateKey; -import org.bouncycastle.pqc.asn1.PQCObjectIdentifiers; -import org.bouncycastle.pqc.asn1.SPHINCS256KeyParams; -import org.bouncycastle.pqc.asn1.XMSSKeyParams; -import org.bouncycastle.pqc.asn1.XMSSMTKeyParams; -import org.bouncycastle.pqc.asn1.XMSSMTPrivateKey; -import org.bouncycastle.pqc.asn1.XMSSPrivateKey; +import org.bouncycastle.pqc.asn1.*; import org.bouncycastle.pqc.crypto.bike.BIKEPrivateKeyParameters; import org.bouncycastle.pqc.crypto.cmce.CMCEPrivateKeyParameters; import org.bouncycastle.pqc.crypto.crystals.dilithium.DilithiumPrivateKeyParameters; @@ -48,6 +38,7 @@ import org.bouncycastle.pqc.crypto.xmss.XMSSUtil; import org.bouncycastle.pqc.legacy.crypto.mceliece.McElieceCCA2PrivateKeyParameters; import org.bouncycastle.pqc.legacy.crypto.qtesla.QTESLAPrivateKeyParameters; +import org.bouncycastle.tls.injection.Asn1BridgeForInjectedSigAlgs; import org.bouncycastle.util.Pack; /** @@ -79,11 +70,19 @@ public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter private * @return the appropriate PrivateKeyInfo * @throws java.io.IOException on an error encoding the key */ - public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter privateKey, ASN1Set attributes) throws IOException + public static PrivateKeyInfo createPrivateKeyInfo( + AsymmetricKeyParameter privateKey, + ASN1Set attributes) throws IOException { + // #tls-injection: + if (Asn1BridgeForInjectedSigAlgs.theInstance().isSupportedParameter(privateKey)) + { + return Asn1BridgeForInjectedSigAlgs.theInstance().createPrivateKeyInfo(privateKey, attributes); + } + if (privateKey instanceof QTESLAPrivateKeyParameters) { - QTESLAPrivateKeyParameters keyParams = (QTESLAPrivateKeyParameters)privateKey; + QTESLAPrivateKeyParameters keyParams = (QTESLAPrivateKeyParameters) privateKey; AlgorithmIdentifier algorithmIdentifier = Utils.qTeslaLookupAlgID(keyParams.getSecurityCategory()); @@ -91,15 +90,15 @@ public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter private } else if (privateKey instanceof SPHINCSPrivateKeyParameters) { - SPHINCSPrivateKeyParameters params = (SPHINCSPrivateKeyParameters)privateKey; + SPHINCSPrivateKeyParameters params = (SPHINCSPrivateKeyParameters) privateKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.sphincs256, - new SPHINCS256KeyParams(Utils.sphincs256LookupTreeAlgID(params.getTreeDigest()))); + new SPHINCS256KeyParams(Utils.sphincs256LookupTreeAlgID(params.getTreeDigest()))); return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getKeyData())); } else if (privateKey instanceof NHPrivateKeyParameters) { - NHPrivateKeyParameters params = (NHPrivateKeyParameters)privateKey; + NHPrivateKeyParameters params = (NHPrivateKeyParameters) privateKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.newHope); @@ -115,7 +114,7 @@ else if (privateKey instanceof NHPrivateKeyParameters) } else if (privateKey instanceof LMSPrivateKeyParameters) { - LMSPrivateKeyParameters params = (LMSPrivateKeyParameters)privateKey; + LMSPrivateKeyParameters params = (LMSPrivateKeyParameters) privateKey; byte[] encoding = Composer.compose().u32str(1).bytes(params).build(); byte[] pubEncoding = Composer.compose().u32str(1).bytes(params.getPublicKey()).build(); @@ -125,7 +124,7 @@ else if (privateKey instanceof LMSPrivateKeyParameters) } else if (privateKey instanceof HSSPrivateKeyParameters) { - HSSPrivateKeyParameters params = (HSSPrivateKeyParameters)privateKey; + HSSPrivateKeyParameters params = (HSSPrivateKeyParameters) privateKey; byte[] encoding = Composer.compose().u32str(params.getL()).bytes(params).build(); byte[] pubEncoding = Composer.compose().u32str(params.getL()).bytes(params.getPublicKey().getLMSPublicKey()).build(); @@ -135,7 +134,7 @@ else if (privateKey instanceof HSSPrivateKeyParameters) } else if (privateKey instanceof SPHINCSPlusPrivateKeyParameters) { - SPHINCSPlusPrivateKeyParameters params = (SPHINCSPlusPrivateKeyParameters)privateKey; + SPHINCSPlusPrivateKeyParameters params = (SPHINCSPlusPrivateKeyParameters) privateKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.sphincsPlusOidLookup(params.getParameters())); @@ -143,7 +142,7 @@ else if (privateKey instanceof SPHINCSPlusPrivateKeyParameters) } else if (privateKey instanceof PicnicPrivateKeyParameters) { - PicnicPrivateKeyParameters params = (PicnicPrivateKeyParameters)privateKey; + PicnicPrivateKeyParameters params = (PicnicPrivateKeyParameters) privateKey; byte[] encoding = params.getEncoded(); @@ -152,7 +151,7 @@ else if (privateKey instanceof PicnicPrivateKeyParameters) } else if (privateKey instanceof CMCEPrivateKeyParameters) { - CMCEPrivateKeyParameters params = (CMCEPrivateKeyParameters)privateKey; + CMCEPrivateKeyParameters params = (CMCEPrivateKeyParameters) privateKey; //todo either make CMCEPrivateKey split the parameters from the private key or // (current) Make CMCEPrivateKey take parts of the private key splitted in the params @@ -165,25 +164,25 @@ else if (privateKey instanceof CMCEPrivateKeyParameters) } else if (privateKey instanceof XMSSPrivateKeyParameters) { - XMSSPrivateKeyParameters keyParams = (XMSSPrivateKeyParameters)privateKey; + XMSSPrivateKeyParameters keyParams = (XMSSPrivateKeyParameters) privateKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.xmss, - new XMSSKeyParams(keyParams.getParameters().getHeight(), - Utils.xmssLookupTreeAlgID(keyParams.getTreeDigest()))); + new XMSSKeyParams(keyParams.getParameters().getHeight(), + Utils.xmssLookupTreeAlgID(keyParams.getTreeDigest()))); return new PrivateKeyInfo(algorithmIdentifier, xmssCreateKeyStructure(keyParams), attributes); } else if (privateKey instanceof XMSSMTPrivateKeyParameters) { - XMSSMTPrivateKeyParameters keyParams = (XMSSMTPrivateKeyParameters)privateKey; + XMSSMTPrivateKeyParameters keyParams = (XMSSMTPrivateKeyParameters) privateKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.xmss_mt, - new XMSSMTKeyParams(keyParams.getParameters().getHeight(), keyParams.getParameters().getLayers(), - Utils.xmssLookupTreeAlgID(keyParams.getTreeDigest()))); + new XMSSMTKeyParams(keyParams.getParameters().getHeight(), keyParams.getParameters().getLayers(), + Utils.xmssLookupTreeAlgID(keyParams.getTreeDigest()))); return new PrivateKeyInfo(algorithmIdentifier, xmssmtCreateKeyStructure(keyParams), attributes); } else if (privateKey instanceof McElieceCCA2PrivateKeyParameters) { - McElieceCCA2PrivateKeyParameters priv = (McElieceCCA2PrivateKeyParameters)privateKey; + McElieceCCA2PrivateKeyParameters priv = (McElieceCCA2PrivateKeyParameters) privateKey; McElieceCCA2PrivateKey mcEliecePriv = new McElieceCCA2PrivateKey(priv.getN(), priv.getK(), priv.getField(), priv.getGoppaPoly(), priv.getP(), Utils.getAlgorithmIdentifier(priv.getDigest())); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.mcElieceCca2); @@ -191,7 +190,7 @@ else if (privateKey instanceof McElieceCCA2PrivateKeyParameters) } else if (privateKey instanceof FrodoPrivateKeyParameters) { - FrodoPrivateKeyParameters params = (FrodoPrivateKeyParameters)privateKey; + FrodoPrivateKeyParameters params = (FrodoPrivateKeyParameters) privateKey; byte[] encoding = params.getEncoded(); @@ -201,7 +200,7 @@ else if (privateKey instanceof FrodoPrivateKeyParameters) } else if (privateKey instanceof SABERPrivateKeyParameters) { - SABERPrivateKeyParameters params = (SABERPrivateKeyParameters)privateKey; + SABERPrivateKeyParameters params = (SABERPrivateKeyParameters) privateKey; byte[] encoding = params.getEncoded(); @@ -211,7 +210,7 @@ else if (privateKey instanceof SABERPrivateKeyParameters) } else if (privateKey instanceof NTRUPrivateKeyParameters) { - NTRUPrivateKeyParameters params = (NTRUPrivateKeyParameters)privateKey; + NTRUPrivateKeyParameters params = (NTRUPrivateKeyParameters) privateKey; byte[] encoding = params.getEncoded(); @@ -221,7 +220,7 @@ else if (privateKey instanceof NTRUPrivateKeyParameters) } else if (privateKey instanceof FalconPrivateKeyParameters) { - FalconPrivateKeyParameters params = (FalconPrivateKeyParameters)privateKey; + FalconPrivateKeyParameters params = (FalconPrivateKeyParameters) privateKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.falconOidLookup(params.getParameters())); @@ -232,15 +231,15 @@ else if (privateKey instanceof FalconPrivateKeyParameters) } else if (privateKey instanceof KyberPrivateKeyParameters) { - KyberPrivateKeyParameters params = (KyberPrivateKeyParameters)privateKey; - + KyberPrivateKeyParameters params = (KyberPrivateKeyParameters) privateKey; + AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.kyberOidLookup(params.getParameters())); return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(params.getEncoded()), attributes); } else if (privateKey instanceof NTRULPRimePrivateKeyParameters) { - NTRULPRimePrivateKeyParameters params = (NTRULPRimePrivateKeyParameters)privateKey; + NTRULPRimePrivateKeyParameters params = (NTRULPRimePrivateKeyParameters) privateKey; ASN1EncodableVector v = new ASN1EncodableVector(); @@ -255,7 +254,7 @@ else if (privateKey instanceof NTRULPRimePrivateKeyParameters) } else if (privateKey instanceof SNTRUPrimePrivateKeyParameters) { - SNTRUPrimePrivateKeyParameters params = (SNTRUPrimePrivateKeyParameters)privateKey; + SNTRUPrimePrivateKeyParameters params = (SNTRUPrimePrivateKeyParameters) privateKey; ASN1EncodableVector v = new ASN1EncodableVector(); @@ -271,7 +270,7 @@ else if (privateKey instanceof SNTRUPrimePrivateKeyParameters) } else if (privateKey instanceof DilithiumPrivateKeyParameters) { - DilithiumPrivateKeyParameters params = (DilithiumPrivateKeyParameters)privateKey; + DilithiumPrivateKeyParameters params = (DilithiumPrivateKeyParameters) privateKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.dilithiumOidLookup(params.getParameters())); @@ -281,21 +280,21 @@ else if (privateKey instanceof DilithiumPrivateKeyParameters) } else if (privateKey instanceof BIKEPrivateKeyParameters) { - BIKEPrivateKeyParameters params = (BIKEPrivateKeyParameters)privateKey; + BIKEPrivateKeyParameters params = (BIKEPrivateKeyParameters) privateKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.bikeOidLookup(params.getParameters())); byte[] encoding = params.getEncoded(); return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); } else if (privateKey instanceof HQCPrivateKeyParameters) { - HQCPrivateKeyParameters params = (HQCPrivateKeyParameters)privateKey; + HQCPrivateKeyParameters params = (HQCPrivateKeyParameters) privateKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.hqcOidLookup(params.getParameters())); byte[] encoding = params.getEncoded(); return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); } else if (privateKey instanceof RainbowPrivateKeyParameters) { - RainbowPrivateKeyParameters params = (RainbowPrivateKeyParameters)privateKey; + RainbowPrivateKeyParameters params = (RainbowPrivateKeyParameters) privateKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.rainbowOidLookup(params.getParameters())); byte[] encoding = params.getEncoded(); return new PrivateKeyInfo(algorithmIdentifier, new DEROctetString(encoding), attributes); @@ -307,7 +306,7 @@ else if (privateKey instanceof RainbowPrivateKeyParameters) } private static XMSSPrivateKey xmssCreateKeyStructure(XMSSPrivateKeyParameters keyParams) - throws IOException + throws IOException { byte[] keyData = keyParams.getEncoded(); @@ -320,7 +319,7 @@ private static XMSSPrivateKey xmssCreateKeyStructure(XMSSPrivateKeyParameters ke int rootSize = n; int position = 0; - int index = (int)XMSSUtil.bytesToXBigEndian(keyData, position, indexSize); + int index = (int) XMSSUtil.bytesToXBigEndian(keyData, position, indexSize); if (!XMSSUtil.isIndexValid(totalHeight, index)) { throw new IllegalArgumentException("index out of bounds"); @@ -334,14 +333,13 @@ private static XMSSPrivateKey xmssCreateKeyStructure(XMSSPrivateKeyParameters ke position += publicSeedSize; byte[] root = XMSSUtil.extractBytesAtOffset(keyData, position, rootSize); position += rootSize; - /* import BDS state */ + /* import BDS state */ byte[] bdsStateBinary = XMSSUtil.extractBytesAtOffset(keyData, position, keyData.length - position); BDS bds = null; try { - bds = (BDS)XMSSUtil.deserialize(bdsStateBinary, BDS.class); - } - catch (ClassNotFoundException e) + bds = (BDS) XMSSUtil.deserialize(bdsStateBinary, BDS.class); + } catch (ClassNotFoundException e) { throw new IOException("cannot parse BDS: " + e.getMessage()); } @@ -357,7 +355,7 @@ private static XMSSPrivateKey xmssCreateKeyStructure(XMSSPrivateKeyParameters ke } private static XMSSMTPrivateKey xmssmtCreateKeyStructure(XMSSMTPrivateKeyParameters keyParams) - throws IOException + throws IOException { byte[] keyData = keyParams.getEncoded(); @@ -370,7 +368,7 @@ private static XMSSMTPrivateKey xmssmtCreateKeyStructure(XMSSMTPrivateKeyParamet int rootSize = n; int position = 0; - int index = (int)XMSSUtil.bytesToXBigEndian(keyData, position, indexSize); + int index = (int) XMSSUtil.bytesToXBigEndian(keyData, position, indexSize); if (!XMSSUtil.isIndexValid(totalHeight, index)) { throw new IllegalArgumentException("index out of bounds"); @@ -384,14 +382,13 @@ private static XMSSMTPrivateKey xmssmtCreateKeyStructure(XMSSMTPrivateKeyParamet position += publicSeedSize; byte[] root = XMSSUtil.extractBytesAtOffset(keyData, position, rootSize); position += rootSize; - /* import BDS state */ + /* import BDS state */ byte[] bdsStateBinary = XMSSUtil.extractBytesAtOffset(keyData, position, keyData.length - position); BDSStateMap bds = null; try { - bds = (BDSStateMap)XMSSUtil.deserialize(bdsStateBinary, BDSStateMap.class); - } - catch (ClassNotFoundException e) + bds = (BDSStateMap) XMSSUtil.deserialize(bdsStateBinary, BDSStateMap.class); + } catch (ClassNotFoundException e) { throw new IOException("cannot parse BDSStateMap: " + e.getMessage()); } diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java index b5b0decbae..5b3fc3eb30 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/PublicKeyFactory.java @@ -63,6 +63,7 @@ import org.bouncycastle.pqc.crypto.xmss.XMSSPublicKeyParameters; import org.bouncycastle.pqc.legacy.crypto.mceliece.McElieceCCA2PublicKeyParameters; import org.bouncycastle.pqc.legacy.crypto.qtesla.QTESLAPublicKeyParameters; +import org.bouncycastle.tls.injection.Asn1BridgeForInjectedSigAlgs; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Pack; @@ -138,7 +139,7 @@ public class PublicKeyFactory converters.put(BCObjectIdentifiers.sphincsPlus_shake_256s, new SPHINCSPlusConverter()); converters.put(BCObjectIdentifiers.sphincsPlus_shake_256f, new SPHINCSPlusConverter()); converters.put(new ASN1ObjectIdentifier("1.3.9999.6.4.10"), new SPHINCSPlusConverter()); - + converters.put(BCObjectIdentifiers.mceliece348864_r3, new CMCEConverter()); converters.put(BCObjectIdentifiers.mceliece348864f_r3, new CMCEConverter()); converters.put(BCObjectIdentifiers.mceliece460896_r3, new CMCEConverter()); @@ -239,7 +240,7 @@ public class PublicKeyFactory * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(byte[] keyInfoData) - throws IOException + throws IOException { if (keyInfoData == null) { @@ -260,7 +261,7 @@ public static AsymmetricKeyParameter createKey(byte[] keyInfoData) * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(InputStream inStr) - throws IOException + throws IOException { return createKey(SubjectPublicKeyInfo.getInstance(new ASN1InputStream(inStr).readObject())); } @@ -273,7 +274,7 @@ public static AsymmetricKeyParameter createKey(InputStream inStr) * @throws IOException on an error decoding the key */ public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo) - throws IOException + throws IOException { if (keyInfo == null) { @@ -290,8 +291,10 @@ public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo) * @return the appropriate key parameter * @throws IOException on an error decoding the key */ - public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + public static AsymmetricKeyParameter createKey( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { if (keyInfo == null) { @@ -299,7 +302,15 @@ public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo, Obj } AlgorithmIdentifier algId = keyInfo.getAlgorithm(); - SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter)converters.get(algId.getAlgorithm()); + ASN1ObjectIdentifier algOID = algId.getAlgorithm(); + + // #tls-injection: + if (Asn1BridgeForInjectedSigAlgs.theInstance().isSupportedAlgorithm(algOID)) + { + return Asn1BridgeForInjectedSigAlgs.theInstance().createPublicKeyParameter(keyInfo, defaultParams); + } + + SubjectPublicKeyInfoConverter converter = (SubjectPublicKeyInfoConverter) converters.get(algId.getAlgorithm()); if (converter != null) { @@ -313,46 +324,56 @@ public static AsymmetricKeyParameter createKey(SubjectPublicKeyInfo keyInfo, Obj private static abstract class SubjectPublicKeyInfoConverter { - abstract AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException; + abstract AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException; } private static class QTeslaConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { return new QTESLAPublicKeyParameters(Utils.qTeslaLookupSecurityCategory(keyInfo.getAlgorithm()), keyInfo.getPublicKeyData().getOctets()); } } private static class SPHINCSConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { return new SPHINCSPublicKeyParameters(keyInfo.getPublicKeyData().getBytes(), - Utils.sphincs256LookupTreeAlgName(SPHINCS256KeyParams.getInstance(keyInfo.getAlgorithm().getParameters()))); + Utils.sphincs256LookupTreeAlgName(SPHINCS256KeyParams.getInstance(keyInfo.getAlgorithm().getParameters()))); } } private static class NHConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { return new NHPublicKeyParameters(keyInfo.getPublicKeyData().getBytes()); } } private static class XMSSConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { XMSSKeyParams keyParams = XMSSKeyParams.getInstance(keyInfo.getAlgorithm().getParameters()); @@ -362,26 +383,28 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje XMSSPublicKey xmssPublicKey = XMSSPublicKey.getInstance(keyInfo.parsePublicKey()); return new XMSSPublicKeyParameters - .Builder(new XMSSParameters(keyParams.getHeight(), Utils.getDigest(treeDigest))) - .withPublicSeed(xmssPublicKey.getPublicSeed()) - .withRoot(xmssPublicKey.getRoot()).build(); + .Builder(new XMSSParameters(keyParams.getHeight(), Utils.getDigest(treeDigest))) + .withPublicSeed(xmssPublicKey.getPublicSeed()) + .withRoot(xmssPublicKey.getRoot()).build(); } else { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); return new XMSSPublicKeyParameters - .Builder(XMSSParameters.lookupByOID(Pack.bigEndianToInt(keyEnc, 0))) - .withPublicKey(keyEnc).build(); + .Builder(XMSSParameters.lookupByOID(Pack.bigEndianToInt(keyEnc, 0))) + .withPublicKey(keyEnc).build(); } } } private static class XMSSMTConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { XMSSMTKeyParams keyParams = XMSSMTKeyParams.getInstance(keyInfo.getAlgorithm().getParameters()); @@ -392,26 +415,28 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje XMSSPublicKey xmssMtPublicKey = XMSSPublicKey.getInstance(keyInfo.parsePublicKey()); return new XMSSMTPublicKeyParameters - .Builder(new XMSSMTParameters(keyParams.getHeight(), keyParams.getLayers(), Utils.getDigest(treeDigest))) - .withPublicSeed(xmssMtPublicKey.getPublicSeed()) - .withRoot(xmssMtPublicKey.getRoot()).build(); + .Builder(new XMSSMTParameters(keyParams.getHeight(), keyParams.getLayers(), Utils.getDigest(treeDigest))) + .withPublicSeed(xmssMtPublicKey.getPublicSeed()) + .withRoot(xmssMtPublicKey.getRoot()).build(); } else { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); return new XMSSMTPublicKeyParameters - .Builder(XMSSMTParameters.lookupByOID(Pack.bigEndianToInt(keyEnc, 0))) - .withPublicKey(keyEnc).build(); + .Builder(XMSSMTParameters.lookupByOID(Pack.bigEndianToInt(keyEnc, 0))) + .withPublicKey(keyEnc).build(); } } } private static class LMSConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); @@ -432,10 +457,12 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class SPHINCSPlusConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { try { @@ -444,8 +471,7 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje SPHINCSPlusParameters spParams = Utils.sphincsPlusParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); return new SPHINCSPlusPublicKeyParameters(spParams, Arrays.copyOfRange(keyEnc, 4, keyEnc.length)); - } - catch (Exception e) + } catch (Exception e) { byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); @@ -457,10 +483,12 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class CMCEConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { try { @@ -469,9 +497,8 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje CMCEParameters spParams = Utils.mcElieceParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); return new CMCEPublicKeyParameters(spParams, keyEnc); - } - catch (Exception e) - { + } catch (Exception e) + { byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); CMCEParameters spParams = Utils.mcElieceParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); @@ -484,7 +511,9 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje private static class SABERConverter extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) throws IOException { byte[] keyEnc = ASN1OctetString.getInstance( @@ -497,10 +526,12 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class McElieceCCA2Converter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { McElieceCCA2PublicKey mKey = McElieceCCA2PublicKey.getInstance(keyInfo.parsePublicKey()); @@ -511,7 +542,9 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje private static class FrodoConverter extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) throws IOException { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); @@ -525,7 +558,9 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje private static class PicnicConverter extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) throws IOException { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); @@ -537,10 +572,12 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class NtruConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); @@ -551,10 +588,12 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class FalconConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); // FalconPublicKey falconPublicKey = FalconPublicKey.getInstance(keyInfo.parsePublicKey()); @@ -567,10 +606,12 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class KyberConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { KyberParameters kyberParameters = Utils.kyberParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); @@ -580,8 +621,7 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje KyberPublicKey kyberKey = KyberPublicKey.getInstance(obj); return new KyberPublicKeyParameters(kyberParameters, kyberKey.getT(), kyberKey.getRho()); - } - catch (Exception e) + } catch (Exception e) { // we're a raw encoding return new KyberPublicKeyParameters(kyberParameters, keyInfo.getPublicKeyData().getOctets()); @@ -590,10 +630,12 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class NTRULPrimeConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); @@ -604,10 +646,12 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class SNTRUPrimeConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); @@ -616,19 +660,23 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje return new SNTRUPrimePublicKeyParameters(ntruLPRimeParams, keyEnc); } } - + static class DilithiumConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { DilithiumParameters dilithiumParams = Utils.dilithiumParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); return getPublicKeyParams(dilithiumParams, keyInfo.getPublicKeyData()); } - static DilithiumPublicKeyParameters getPublicKeyParams(DilithiumParameters dilithiumParams, ASN1BitString publicKeyData) + static DilithiumPublicKeyParameters getPublicKeyParams( + DilithiumParameters dilithiumParams, + ASN1BitString publicKeyData) { try { @@ -638,8 +686,8 @@ static DilithiumPublicKeyParameters getPublicKeyParams(DilithiumParameters dilit ASN1Sequence keySeq = ASN1Sequence.getInstance(obj); return new DilithiumPublicKeyParameters(dilithiumParams, - ASN1OctetString.getInstance(keySeq.getObjectAt(0)).getOctets(), - ASN1OctetString.getInstance(keySeq.getObjectAt(1)).getOctets()); + ASN1OctetString.getInstance(keySeq.getObjectAt(0)).getOctets(), + ASN1OctetString.getInstance(keySeq.getObjectAt(1)).getOctets()); } else { @@ -647,8 +695,7 @@ static DilithiumPublicKeyParameters getPublicKeyParams(DilithiumParameters dilit return new DilithiumPublicKeyParameters(dilithiumParams, encKey); } - } - catch (Exception e) + } catch (Exception e) { // we're a raw encoding return new DilithiumPublicKeyParameters(dilithiumParams, publicKeyData.getOctets()); @@ -659,7 +706,9 @@ static DilithiumPublicKeyParameters getPublicKeyParams(DilithiumParameters dilit private static class BIKEConverter extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) throws IOException { try @@ -669,8 +718,7 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje BIKEParameters bikeParams = Utils.bikeParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); return new BIKEPublicKeyParameters(bikeParams, keyEnc); - } - catch (Exception e) + } catch (Exception e) { byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); @@ -684,7 +732,9 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje private static class HQCConverter extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) throws IOException { try @@ -694,8 +744,7 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje HQCParameters hqcParams = Utils.hqcParamsLookup(keyInfo.getAlgorithm().getAlgorithm()); return new HQCPublicKeyParameters(hqcParams, keyEnc); - } - catch (Exception e) + } catch (Exception e) { // raw encoding byte[] keyEnc = keyInfo.getPublicKeyData().getOctets(); @@ -708,10 +757,12 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje } private static class RainbowConverter - extends SubjectPublicKeyInfoConverter + extends SubjectPublicKeyInfoConverter { - AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Object defaultParams) - throws IOException + AsymmetricKeyParameter getPublicKeyParameters( + SubjectPublicKeyInfo keyInfo, + Object defaultParams) + throws IOException { byte[] keyEnc = ASN1OctetString.getInstance(keyInfo.parsePublicKey()).getOctets(); diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java b/core/src/main/java/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java index a6062e2ce2..ba5c687775 100644 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java +++ b/core/src/main/java/org/bouncycastle/pqc/crypto/util/SubjectPublicKeyInfoFactory.java @@ -39,6 +39,7 @@ import org.bouncycastle.pqc.crypto.xmss.XMSSPublicKeyParameters; import org.bouncycastle.pqc.legacy.crypto.mceliece.McElieceCCA2PublicKeyParameters; import org.bouncycastle.pqc.legacy.crypto.qtesla.QTESLAPublicKeyParameters; +import org.bouncycastle.tls.injection.Asn1BridgeForInjectedSigAlgs; /** * Factory to create ASN.1 subject public key info objects from lightweight public keys. @@ -58,33 +59,39 @@ private SubjectPublicKeyInfoFactory() * @throws java.io.IOException on an error encoding the key */ public static SubjectPublicKeyInfo createSubjectPublicKeyInfo(AsymmetricKeyParameter publicKey) - throws IOException + throws IOException { + // #tls-injection: + if (Asn1BridgeForInjectedSigAlgs.theInstance().isSupportedParameter(publicKey)) + { + return Asn1BridgeForInjectedSigAlgs.theInstance().createSubjectPublicKeyInfo(publicKey); + } + if (publicKey instanceof QTESLAPublicKeyParameters) { - QTESLAPublicKeyParameters keyParams = (QTESLAPublicKeyParameters)publicKey; + QTESLAPublicKeyParameters keyParams = (QTESLAPublicKeyParameters) publicKey; AlgorithmIdentifier algorithmIdentifier = Utils.qTeslaLookupAlgID(keyParams.getSecurityCategory()); return new SubjectPublicKeyInfo(algorithmIdentifier, keyParams.getPublicData()); } else if (publicKey instanceof SPHINCSPublicKeyParameters) { - SPHINCSPublicKeyParameters params = (SPHINCSPublicKeyParameters)publicKey; + SPHINCSPublicKeyParameters params = (SPHINCSPublicKeyParameters) publicKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.sphincs256, - new SPHINCS256KeyParams(Utils.sphincs256LookupTreeAlgID(params.getTreeDigest()))); + new SPHINCS256KeyParams(Utils.sphincs256LookupTreeAlgID(params.getTreeDigest()))); return new SubjectPublicKeyInfo(algorithmIdentifier, params.getKeyData()); } else if (publicKey instanceof NHPublicKeyParameters) { - NHPublicKeyParameters params = (NHPublicKeyParameters)publicKey; + NHPublicKeyParameters params = (NHPublicKeyParameters) publicKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.newHope); return new SubjectPublicKeyInfo(algorithmIdentifier, params.getPubData()); } else if (publicKey instanceof LMSPublicKeyParameters) { - LMSPublicKeyParameters params = (LMSPublicKeyParameters)publicKey; + LMSPublicKeyParameters params = (LMSPublicKeyParameters) publicKey; byte[] encoding = Composer.compose().u32str(1).bytes(params).build(); @@ -93,7 +100,7 @@ else if (publicKey instanceof LMSPublicKeyParameters) } else if (publicKey instanceof HSSPublicKeyParameters) { - HSSPublicKeyParameters params = (HSSPublicKeyParameters)publicKey; + HSSPublicKeyParameters params = (HSSPublicKeyParameters) publicKey; byte[] encoding = Composer.compose().u32str(params.getL()).bytes(params.getLMSPublicKey()).build(); @@ -102,7 +109,7 @@ else if (publicKey instanceof HSSPublicKeyParameters) } else if (publicKey instanceof SPHINCSPlusPublicKeyParameters) { - SPHINCSPlusPublicKeyParameters params = (SPHINCSPlusPublicKeyParameters)publicKey; + SPHINCSPlusPublicKeyParameters params = (SPHINCSPlusPublicKeyParameters) publicKey; byte[] encoding = params.getEncoded(); @@ -111,7 +118,7 @@ else if (publicKey instanceof SPHINCSPlusPublicKeyParameters) } else if (publicKey instanceof CMCEPublicKeyParameters) { - CMCEPublicKeyParameters params = (CMCEPublicKeyParameters)publicKey; + CMCEPublicKeyParameters params = (CMCEPublicKeyParameters) publicKey; byte[] encoding = params.getEncoded(); @@ -121,7 +128,7 @@ else if (publicKey instanceof CMCEPublicKeyParameters) } else if (publicKey instanceof XMSSPublicKeyParameters) { - XMSSPublicKeyParameters keyParams = (XMSSPublicKeyParameters)publicKey; + XMSSPublicKeyParameters keyParams = (XMSSPublicKeyParameters) publicKey; byte[] publicSeed = keyParams.getPublicSeed(); byte[] root = keyParams.getRoot(); @@ -135,14 +142,14 @@ else if (publicKey instanceof XMSSPublicKeyParameters) else { AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.xmss, - new XMSSKeyParams(keyParams.getParameters().getHeight(), Utils.xmssLookupTreeAlgID(keyParams.getTreeDigest()))); + new XMSSKeyParams(keyParams.getParameters().getHeight(), Utils.xmssLookupTreeAlgID(keyParams.getTreeDigest()))); return new SubjectPublicKeyInfo(algorithmIdentifier, new XMSSPublicKey(publicSeed, root)); } } else if (publicKey instanceof XMSSMTPublicKeyParameters) { - XMSSMTPublicKeyParameters keyParams = (XMSSMTPublicKeyParameters)publicKey; + XMSSMTPublicKeyParameters keyParams = (XMSSMTPublicKeyParameters) publicKey; byte[] publicSeed = keyParams.getPublicSeed(); byte[] root = keyParams.getRoot(); @@ -156,13 +163,13 @@ else if (publicKey instanceof XMSSMTPublicKeyParameters) else { AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.xmss_mt, new XMSSMTKeyParams(keyParams.getParameters().getHeight(), keyParams.getParameters().getLayers(), - Utils.xmssLookupTreeAlgID(keyParams.getTreeDigest()))); + Utils.xmssLookupTreeAlgID(keyParams.getTreeDigest()))); return new SubjectPublicKeyInfo(algorithmIdentifier, new XMSSMTPublicKey(keyParams.getPublicSeed(), keyParams.getRoot())); } } else if (publicKey instanceof McElieceCCA2PublicKeyParameters) { - McElieceCCA2PublicKeyParameters pub = (McElieceCCA2PublicKeyParameters)publicKey; + McElieceCCA2PublicKeyParameters pub = (McElieceCCA2PublicKeyParameters) publicKey; McElieceCCA2PublicKey mcEliecePub = new McElieceCCA2PublicKey(pub.getN(), pub.getT(), pub.getG(), Utils.getAlgorithmIdentifier(pub.getDigest())); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PQCObjectIdentifiers.mcElieceCca2); @@ -170,7 +177,7 @@ else if (publicKey instanceof McElieceCCA2PublicKeyParameters) } else if (publicKey instanceof FrodoPublicKeyParameters) { - FrodoPublicKeyParameters params = (FrodoPublicKeyParameters)publicKey; + FrodoPublicKeyParameters params = (FrodoPublicKeyParameters) publicKey; byte[] encoding = params.getEncoded(); @@ -180,17 +187,17 @@ else if (publicKey instanceof FrodoPublicKeyParameters) } else if (publicKey instanceof SABERPublicKeyParameters) { - SABERPublicKeyParameters params = (SABERPublicKeyParameters)publicKey; + SABERPublicKeyParameters params = (SABERPublicKeyParameters) publicKey; byte[] encoding = params.getEncoded(); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.saberOidLookup(params.getParameters())); - + return new SubjectPublicKeyInfo(algorithmIdentifier, new DERSequence(new DEROctetString(encoding))); } else if (publicKey instanceof PicnicPublicKeyParameters) { - PicnicPublicKeyParameters params = (PicnicPublicKeyParameters)publicKey; + PicnicPublicKeyParameters params = (PicnicPublicKeyParameters) publicKey; byte[] encoding = params.getEncoded(); @@ -199,7 +206,7 @@ else if (publicKey instanceof PicnicPublicKeyParameters) } else if (publicKey instanceof NTRUPublicKeyParameters) { - NTRUPublicKeyParameters params = (NTRUPublicKeyParameters)publicKey; + NTRUPublicKeyParameters params = (NTRUPublicKeyParameters) publicKey; byte[] encoding = params.getEncoded(); @@ -208,20 +215,20 @@ else if (publicKey instanceof NTRUPublicKeyParameters) } else if (publicKey instanceof FalconPublicKeyParameters) { - FalconPublicKeyParameters params = (FalconPublicKeyParameters)publicKey; + FalconPublicKeyParameters params = (FalconPublicKeyParameters) publicKey; byte[] encoding = params.getH(); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.falconOidLookup(params.getParameters())); byte[] keyEnc = new byte[encoding.length + 1]; - keyEnc[0] = (byte)(0x00 + params.getParameters().getLogN()); + keyEnc[0] = (byte) (0x00 + params.getParameters().getLogN()); System.arraycopy(encoding, 0, keyEnc, 1, encoding.length); return new SubjectPublicKeyInfo(algorithmIdentifier, keyEnc); } else if (publicKey instanceof KyberPublicKeyParameters) { - KyberPublicKeyParameters params = (KyberPublicKeyParameters)publicKey; + KyberPublicKeyParameters params = (KyberPublicKeyParameters) publicKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.kyberOidLookup(params.getParameters())); @@ -229,7 +236,7 @@ else if (publicKey instanceof KyberPublicKeyParameters) } else if (publicKey instanceof NTRULPRimePublicKeyParameters) { - NTRULPRimePublicKeyParameters params = (NTRULPRimePublicKeyParameters)publicKey; + NTRULPRimePublicKeyParameters params = (NTRULPRimePublicKeyParameters) publicKey; byte[] encoding = params.getEncoded(); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.ntrulprimeOidLookup(params.getParameters())); @@ -238,7 +245,7 @@ else if (publicKey instanceof NTRULPRimePublicKeyParameters) } else if (publicKey instanceof SNTRUPrimePublicKeyParameters) { - SNTRUPrimePublicKeyParameters params = (SNTRUPrimePublicKeyParameters)publicKey; + SNTRUPrimePublicKeyParameters params = (SNTRUPrimePublicKeyParameters) publicKey; byte[] encoding = params.getEncoded(); AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.sntruprimeOidLookup(params.getParameters())); @@ -247,7 +254,7 @@ else if (publicKey instanceof SNTRUPrimePublicKeyParameters) } else if (publicKey instanceof DilithiumPublicKeyParameters) { - DilithiumPublicKeyParameters params = (DilithiumPublicKeyParameters)publicKey; + DilithiumPublicKeyParameters params = (DilithiumPublicKeyParameters) publicKey; AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(Utils.dilithiumOidLookup(params.getParameters())); @@ -265,7 +272,7 @@ else if (publicKey instanceof BIKEPublicKeyParameters) } else if (publicKey instanceof HQCPublicKeyParameters) { - HQCPublicKeyParameters params = (HQCPublicKeyParameters)publicKey; + HQCPublicKeyParameters params = (HQCPublicKeyParameters) publicKey; byte[] encoding = params.getEncoded(); @@ -275,7 +282,7 @@ else if (publicKey instanceof HQCPublicKeyParameters) } else if (publicKey instanceof RainbowPublicKeyParameters) { - RainbowPublicKeyParameters params = (RainbowPublicKeyParameters)publicKey; + RainbowPublicKeyParameters params = (RainbowPublicKeyParameters) publicKey; byte[] encoding = params.getEncoded(); diff --git a/core/src/main/java/org/bouncycastle/tls/injection/Asn1Bridge.java b/core/src/main/java/org/bouncycastle/tls/injection/Asn1Bridge.java new file mode 100644 index 0000000000..c113e7f88f --- /dev/null +++ b/core/src/main/java/org/bouncycastle/tls/injection/Asn1Bridge.java @@ -0,0 +1,84 @@ +package org.bouncycastle.tls.injection; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; + +import java.io.IOException; + +/** + * #tls-injection + * + * The Asn1Bridge interface defines the bridge between ASN.1 notation for public/private keys and their internal + * representation inside the BC AsymmetricKeyParameter class. + * + * This interface is implemented by the Asn1BridgeForInjectedSigAlgs class (in the BC core package), + * which represents signature algorithms injected into TLS Injection Mechanism (in the BC tls package; + * however there is no compile-time dependency on "tls" from the "core" package). + * + * The Asn1BridgeForInjectedSigAlgs is consulted inside the BC core package in order to add the ability to + * work with public and private keys corresponding to the injected (perhaps, non-standard) signature algorithms. + * + * + */ +public interface Asn1Bridge { + + /** + * Checks whether the signature algorithm with the given object identified (OID) has been injected. + * @param oid the ASN object identifier of the algorithm in question + * @return returns true, iff the algorithm with the given oid has been injected + */ + boolean isSupportedAlgorithm(ASN1ObjectIdentifier oid); + + /** + * Checks whether the given BC key (public or private) can be converted to ASN.1. + * + * @param bcKey an internal BC representation of a public or a private key + * that has to be converted to ASN.1 + * @return returns true, iff bcKey is of known type and can be converted to ASN.1 + * (i.e., a PrivateKeyInfo or SubjectPublicKeyInfo instance) + */ + boolean isSupportedParameter(AsymmetricKeyParameter bcKey); + + /** + * Converts the given private key from ASN.1 to the internal BC representation. + * + * @param asnPrivateKey private key in the ASN.1 notation + * @return internal BC representation of the private key + * @throws IOException + */ + AsymmetricKeyParameter createPrivateKeyParameter(PrivateKeyInfo asnPrivateKey) throws IOException; + + + /** + * Converts the given private key from the internal BC representation to the ASN.1 notation. + * + * @param bcPrivateKey internal BC representation of a private key + * @param attributes ASN.1 attributes to be embedded into the ASN.1 representation + * @return ASN.1 representation of the private key + * @throws IOException + */ + PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter bcPrivateKey, ASN1Set attributes) throws IOException; + + + /** + * Converts the given public key from ASN.1 to the internal BC representation. + * + * @param ansPublicKey public key in the ASN.1 notation + * @param defaultParams some default parameters (currently, null is passed) + * @return internal BC representation of the public key + * @throws IOException + */ + AsymmetricKeyParameter createPublicKeyParameter(SubjectPublicKeyInfo ansPublicKey, Object defaultParams) throws IOException; + + /** + * Converts the given public key from the internal BC representation to the ASN.1 notation. + * + * @param bcPublicKey internal BC representation of a public key + * @return ASN.1 representation of the public key + * @throws IOException + */ + SubjectPublicKeyInfo createSubjectPublicKeyInfo(AsymmetricKeyParameter bcPublicKey) throws IOException; +} diff --git a/core/src/main/java/org/bouncycastle/tls/injection/Asn1BridgeForInjectedSigAlgs.java b/core/src/main/java/org/bouncycastle/tls/injection/Asn1BridgeForInjectedSigAlgs.java new file mode 100644 index 0000000000..61bd431e7e --- /dev/null +++ b/core/src/main/java/org/bouncycastle/tls/injection/Asn1BridgeForInjectedSigAlgs.java @@ -0,0 +1,149 @@ +package org.bouncycastle.tls.injection; + +import org.bouncycastle.asn1.ASN1ObjectIdentifier; +import org.bouncycastle.asn1.ASN1Set; +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.crypto.params.AsymmetricKeyParameter; + +import java.io.IOException; +import java.lang.reflect.Method; + +/** + * Represents signature algorithms injected into TLS Injection Mechanism in the BC "tls" package. + * However, there is no compile-time dependency on "tls" from our ("core") package. + *
+ * Asn1BridgeForInjectedSigAlgs tries to contact the TLS Injection Mechanism's InjectionPoint class dynamically
+ * to obtain the corresponding Asn1Bridge implementation representing all the injected signature algorithms.
+ * If InjectionPoint is not available, the default Asn1Bridge implementation
+ * (which doesn't support any of the signature algorithms) is used.
+ * The default Asn1Bridge implementation can be replaced via the replaceWith() call.
+ */
+public class Asn1BridgeForInjectedSigAlgs
+ implements Asn1Bridge
+{
+
+ // Bill Pugh Singleton Implementation, see https://www.geeksforgeeks.org/java-singleton-design-pattern-practices-examples/
+ private static class BillPughSingleton
+ {
+ private static Asn1Bridge INSTANCE = new Asn1BridgeForInjectedSigAlgs();
+ // ^^^ not final, since we allow to replace the instance via replaceWith
+ }
+
+
+ private Asn1Bridge delegate = null;
+
+ // private = do not allow to call the constructor directly; force using theInstance()
+ private Asn1BridgeForInjectedSigAlgs()
+ {
+ // Here we try to reach the InjectionPoint class in the dependent "tls" package. If it is present,
+ // we use that class as an implementation for Asn1Bridge.
+ try
+ {
+ Class> c = Class.forName("org.bouncycastle.tls.injection.InjectionPoint");
+ Method m1 = c.getMethod("theInstance");
+ Object o = m1.invoke(c);
+
+ Method m2 = c.getMethod("asn1Bridge");
+ Object bridge = m2.invoke(o);
+ assert bridge instanceof Asn1Bridge;
+ this.delegate = (Asn1Bridge) bridge;
+ } catch (Exception e)
+ {
+ // keeping the default implementation
+ }
+ }
+
+ public synchronized static Asn1Bridge theInstance()
+ {
+ return Asn1BridgeForInjectedSigAlgs.BillPughSingleton.INSTANCE;
+ }
+
+ public synchronized static void replaceWith(Asn1Bridge newInstance)
+ {
+ Asn1BridgeForInjectedSigAlgs.BillPughSingleton.INSTANCE = newInstance;
+ }
+
+ @Override
+ public boolean isSupportedAlgorithm(ASN1ObjectIdentifier oid)
+ {
+ if (delegate != null)
+ {
+ return delegate.isSupportedAlgorithm(oid);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+
+ @Override
+ public boolean isSupportedParameter(AsymmetricKeyParameter bcKey)
+ {
+ if (delegate != null)
+ {
+ return delegate.isSupportedParameter(bcKey);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ @Override
+ public AsymmetricKeyParameter createPrivateKeyParameter(PrivateKeyInfo asnPrivateKey) throws IOException
+ {
+ if (delegate != null)
+ {
+ return delegate.createPrivateKeyParameter(asnPrivateKey);
+ }
+ else
+ {
+ throw new IOException("No injected signature algorithms to choose from.");
+ }
+ }
+
+ @Override
+ public PrivateKeyInfo createPrivateKeyInfo(
+ AsymmetricKeyParameter bcPrivateKey,
+ ASN1Set attributes) throws IOException
+ {
+ if (delegate != null)
+ {
+ return delegate.createPrivateKeyInfo(bcPrivateKey, attributes);
+ }
+ else
+ {
+ throw new IOException("No injected signature algorithms to choose from.");
+ }
+ }
+
+ @Override
+ public AsymmetricKeyParameter createPublicKeyParameter(
+ SubjectPublicKeyInfo ansPublicKey,
+ Object defaultParams) throws IOException
+ {
+ if (delegate != null)
+ {
+ return delegate.createPublicKeyParameter(ansPublicKey, defaultParams);
+ }
+ else
+ {
+ throw new IOException("No injected signature algorithms to choose from.");
+ }
+ }
+
+ @Override
+ public SubjectPublicKeyInfo createSubjectPublicKeyInfo(AsymmetricKeyParameter bcPublicKey) throws IOException
+ {
+ if (delegate != null)
+ {
+ return delegate.createSubjectPublicKeyInfo(bcPublicKey);
+ }
+ else
+ {
+ throw new IOException("No injected signature algorithms to choose from.");
+ }
+ }
+}
diff --git a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java
index 94cfe757e3..f5f1c23640 100644
--- a/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java
+++ b/prov/src/main/java/org/bouncycastle/pqc/jcajce/provider/BouncyCastlePQCProvider.java
@@ -17,6 +17,7 @@
import org.bouncycastle.jcajce.provider.config.ProviderConfiguration;
import org.bouncycastle.jcajce.provider.util.AlgorithmProvider;
import org.bouncycastle.jcajce.provider.util.AsymmetricKeyInfoConverter;
+import org.bouncycastle.tls.injection.InjectionPoint;
public class BouncyCastlePQCProvider
extends Provider
@@ -43,6 +44,19 @@ public class BouncyCastlePQCProvider
"Dilithium", "NTRUPrime", "BIKE", "HQC", "Rainbow"
};
+ /**
+ * #tls-injection
+ * ALGORITHM_MAPPING_CLASSES contains real classes corresponding to the names given in ALGORITHMS.
+ * We rely on ALGORITHM_MAPPING_CLASSES when we are unable to load classes by names via reflection
+ * (important, since we cannot rely fully on reflection in NativeImage from GraalVM).
+ * #pqc-tls
+ */
+ private static final Class>[] ALGORITHM_MAPPING_CLASSES = {
+ SPHINCS.Mappings.class, LMS.Mappings.class, NH.Mappings.class, XMSS.Mappings.class, SPHINCSPlus.Mappings.class,
+ CMCE.Mappings.class, Frodo.Mappings.class, SABER.Mappings.class, Picnic.Mappings.class, NTRU.Mappings.class, Falcon.Mappings.class, Kyber.Mappings.class,
+ Dilithium.Mappings.class, NTRUPrime.Mappings.class, BIKE.Mappings.class, HQC.Mappings.class, Rainbow.Mappings.class
+ };
+
/**
* Construct a new provider. This should only be required when
* using runtime registration of the provider using the
@@ -71,13 +85,20 @@ private void loadAlgorithms(String packageName, String[] names)
{
for (int i = 0; i != names.length; i++)
{
- Class clazz = loadClass(BouncyCastlePQCProvider.class, packageName + names[i] + "$Mappings");
+ Class clazz;
+ if (i
@@ -415,6 +425,12 @@ String getHMACAlgorithmName(int cryptoHashAlgorithm)
public AlgorithmParameters getNamedGroupAlgorithmParameters(int namedGroup) throws GeneralSecurityException
{
+ // #tls-injection
+ // for injected KEMs (~NamedGroups), return null
+ if (InjectionPoint.kems().contain(namedGroup))
+ return null; // KEM is supported, no specific parameters (e.g., there are no disabled algorithms)
+
+
if (NamedGroup.refersToAnXDHCurve(namedGroup))
{
switch (namedGroup)
@@ -476,7 +492,14 @@ public AlgorithmParameters getSignatureSchemeAlgorithmParameters(int signatureSc
AlgorithmParameterSpec pssSpec = RSAUtil.getPSSParameterSpec(cryptoHashAlgorithm, digestName, getHelper());
- Signature signer = getHelper().createSignature(sigName);
+ Signature signer;
+ try {
+ signer = getHelper().createSignature(sigName);
+ }
+ catch(Exception e) {
+ signer = Signature.getInstance("RSASSA-PSS", "SunRsaSign");
+ // #tls-injection fix: using the sig alg name of the SunRsaSign provider
+ }
// NOTE: We explicitly set them even though they should be the defaults, because providers vary
signer.setParameter(pssSpec);
@@ -648,6 +671,10 @@ public boolean hasMacAlgorithm(int macAlgorithm)
public boolean hasNamedGroup(int namedGroup)
{
+ // #tls-injection
+ if (InjectionPoint.kems().contain(namedGroup)) {
+ return true;
+ }
final Integer key = Integers.valueOf(namedGroup);
synchronized (supportedNamedGroups)
{
@@ -749,6 +776,9 @@ public boolean hasSignatureAlgorithm(short signatureAlgorithm)
public boolean hasSignatureAndHashAlgorithm(SignatureAndHashAlgorithm sigAndHashAlgorithm)
{
+ if (InjectionPoint.sigAlgs().contain(sigAndHashAlgorithm))
+ return true; // #tls-injection
+
short signature = sigAndHashAlgorithm.getSignature();
switch (sigAndHashAlgorithm.getHash())
@@ -765,6 +795,9 @@ public boolean hasSignatureAndHashAlgorithm(SignatureAndHashAlgorithm sigAndHash
public boolean hasSignatureScheme(int signatureScheme)
{
+ if (InjectionPoint.sigAlgs().contain(signatureScheme))
+ return true; // #tls-injection
+
switch (signatureScheme)
{
case SignatureScheme.sm2sig_sm3:
@@ -1028,6 +1061,14 @@ protected Tls13Verifier createTls13Verifier(String algorithmName, AlgorithmParam
{
try
{
+ // #tls-injection
+ // try injected verifier...
+ try {
+ return InjectionPoint.sigAlgs().tls13VerifierFor(publicKey);
+ } catch (Exception e) {
+ // e.g., not injected, continue as usual
+ }
+
JcaJceHelper helper = getHelper();
if (null != parameter)
{
@@ -1148,6 +1189,11 @@ protected Boolean isSupportedNamedGroup(int namedGroup)
{
try
{
+ if (InjectionPoint.kems().contain(namedGroup))
+ {
+ return true; // #tls-injection
+ }
+ else
if (NamedGroup.refersToAnXDHCurve(namedGroup))
{
/*
diff --git a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsRSAPSSSigner.java b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsRSAPSSSigner.java
index 815431fc02..97e09426cb 100644
--- a/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsRSAPSSSigner.java
+++ b/tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsRSAPSSSigner.java
@@ -85,6 +85,13 @@ public TlsStreamSigner getStreamSigner(SignatureAndHashAlgorithm algorithm) thro
AlgorithmParameterSpec pssSpec = RSAUtil.getPSSParameterSpec(cryptoHashAlgorithm, digestName,
crypto.getHelper());
- return crypto.createStreamSigner(sigName, pssSpec, privateKey, true);
+ try {
+ return crypto.createStreamSigner(sigName, pssSpec, privateKey, true);
+ }
+ catch(Exception e) {
+ // #tls-injection fix: using the sig alg name of the SunRsaSign provider
+ sigName = "RSASSA-PSS";
+ return crypto.createStreamSigner(sigName, pssSpec, privateKey, true);
+ }
}
}
diff --git a/tls/src/main/java/org/bouncycastle/tls/injection/InjectableAlgorithms.java b/tls/src/main/java/org/bouncycastle/tls/injection/InjectableAlgorithms.java
new file mode 100644
index 0000000000..154f574de4
--- /dev/null
+++ b/tls/src/main/java/org/bouncycastle/tls/injection/InjectableAlgorithms.java
@@ -0,0 +1,88 @@
+package org.bouncycastle.tls.injection;
+
+import org.bouncycastle.asn1.ASN1ObjectIdentifier;
+import org.bouncycastle.tls.injection.kems.KemFactory;
+import org.bouncycastle.tls.injection.sigalgs.SigAlgAPI;
+
+import java.util.Collection;
+
+public class InjectableAlgorithms
+{
+
+ ///// KEMs
+ private final InjectableKEMs kems;
+ private final InjectableSigAlgs sigAlgs;
+
+
+ public InjectableAlgorithms()
+ {
+ this(new InjectableKEMs(), new InjectableSigAlgs());
+ }
+
+ private InjectableAlgorithms(
+ InjectableKEMs kems,
+ InjectableSigAlgs sigAlgs)
+ {
+ this.kems = kems;
+ this.sigAlgs = sigAlgs;
+ }
+
+ private InjectableAlgorithms(InjectableAlgorithms origin)
+ { // clone constructor
+ this.kems = new InjectableKEMs(origin.kems);
+ this.sigAlgs = new InjectableSigAlgs(origin.sigAlgs);
+ }
+
+
+ public InjectableAlgorithms withKEM(
+ String standardName,
+ int kemCodePoint,
+ KemFactory kemFactory,
+ InjectableKEMs.Ordering ordering)
+ {
+ return new InjectableAlgorithms(
+ this.kems.withKEM(kemCodePoint, standardName, kemFactory, ordering),
+ new InjectableSigAlgs(this.sigAlgs)
+ );
+ }
+
+ public InjectableAlgorithms withoutKEM(int kemCodePoint)
+ {
+ return new InjectableAlgorithms(
+ this.kems.withoutKEM(kemCodePoint),
+ this.sigAlgs
+ );
+ }
+
+ public InjectableAlgorithms withoutDefaultKEMs()
+ {
+ return new InjectableAlgorithms(
+ this.kems.withoutDefaultKEMs(),
+ this.sigAlgs
+ );
+ }
+
+ public InjectableAlgorithms withSigAlg(
+ String name,
+ Collection
+ * The three KEM functions actually define a half-KEM: keyGen() and decapsulate() are called at one side (e.g., the client),
+ * while encapsulate() is called at the other side (e.g., the server).
+ *
+ * This interface defines the three functions that are present in any KEM.
+ * All keys/secrets/ciphertexts are byte[]-encoded.
+ * #tls-injection
+ *
+ * @author Sergejs Kozlovics
+ */
+public interface KEM
+{
+ /**
+ * Generates a new key pair (pk, sk).
+ *
+ * @return a public key pk and its corresponding private key (=secret key) sk
+ */
+ Pair
+ * #tls-injection
+ *
+ * @author Sergejs Kozlovics
+ */
+public class InjectedSigVerifiers
+{
+
+ public interface VerifySignatureFunction
+ {
+ boolean verifySignature(
+ byte[] data,
+ byte[] key,
+ DigitallySigned signature);
+ }
+
+ private final Map