Skip to content

Commit d87f83d

Browse files
committed
Added marker interface for BCKeys to allow composite to fall back to other providers.
1 parent 963c9d4 commit d87f83d

File tree

9 files changed

+91
-23
lines changed

9 files changed

+91
-23
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package org.bouncycastle.jcajce.interfaces;
2+
3+
/**
4+
* Marker interface for key implementations that are implemented inside Bouncy Castle.
5+
*/
6+
public interface BCKey
7+
{
8+
}

prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/compositesignatures/SignatureSpi.java

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.security.spec.MGF1ParameterSpec;
1717
import java.security.spec.PSSParameterSpec;
1818
import java.util.HashMap;
19+
import java.util.List;
1920
import java.util.Map;
2021

2122
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
@@ -29,6 +30,7 @@
2930
import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers;
3031
import org.bouncycastle.jcajce.CompositePrivateKey;
3132
import org.bouncycastle.jcajce.CompositePublicKey;
33+
import org.bouncycastle.jcajce.interfaces.BCKey;
3234
import org.bouncycastle.jcajce.spec.ContextParameterSpec;
3335
import org.bouncycastle.jcajce.util.BCJcaJceHelper;
3436
import org.bouncycastle.jcajce.util.JcaJceHelper;
@@ -94,6 +96,7 @@ public class SignatureSpi
9496

9597
//List of Signatures. Each entry corresponds to a component signature from the composite definition.
9698
private final ASN1ObjectIdentifier algorithm;
99+
private final String[] algs;
97100
private final Signature[] componentSignatures;
98101
private final byte[] domain;
99102
private final Digest preHashDigest;
@@ -110,20 +113,8 @@ public class SignatureSpi
110113
this.preHashDigest = preHashDigest;
111114
this.domain = domainSeparators.get(algorithm);
112115

113-
String[] algs = CompositeIndex.getPairing(algorithm);
114-
116+
this.algs = CompositeIndex.getPairing(algorithm);
115117
this.componentSignatures = new Signature[algs.length];
116-
try
117-
{
118-
for (int i = 0; i != componentSignatures.length; i++)
119-
{
120-
componentSignatures[i] = Signature.getInstance(algs[i], "BC");
121-
}
122-
}
123-
catch (GeneralSecurityException e)
124-
{
125-
throw Exceptions.illegalStateException(e.getMessage(), e);
126-
}
127118
}
128119

129120
protected void engineInitVerify(PublicKey publicKey)
@@ -137,11 +128,13 @@ protected void engineInitVerify(PublicKey publicKey)
137128
this.compositeKey = publicKey;
138129

139130
CompositePublicKey compositePublicKey = (CompositePublicKey)this.compositeKey;
131+
140132
if (!compositePublicKey.getAlgorithmIdentifier().getAlgorithm().equals(this.algorithm))
141133
{
142134
throw new InvalidKeyException("Provided composite public key cannot be used with the composite signature algorithm.");
143135
}
144-
136+
createComponentSignatures(compositePublicKey.getPublicKeys());
137+
145138
sigInitVerify();
146139
}
147140

@@ -171,10 +164,33 @@ protected void engineInitSign(PrivateKey privateKey)
171164
{
172165
throw new InvalidKeyException("Provided composite private key cannot be used with the composite signature algorithm.");
173166
}
167+
createComponentSignatures(compositePrivateKey.getPrivateKeys());
174168

175169
sigInitSign();
176170
}
177171

172+
private void createComponentSignatures(List keys)
173+
{
174+
try
175+
{
176+
for (int i = 0; i != componentSignatures.length; i++)
177+
{
178+
if (keys.get(i) instanceof BCKey)
179+
{
180+
componentSignatures[i] = Signature.getInstance(algs[i], "BC");
181+
}
182+
else
183+
{
184+
componentSignatures[i] = Signature.getInstance(algs[i]);
185+
}
186+
}
187+
}
188+
catch (GeneralSecurityException e)
189+
{
190+
throw Exceptions.illegalStateException(e.getMessage(), e);
191+
}
192+
}
193+
178194
private void sigInitSign()
179195
throws InvalidKeyException
180196
{

prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPrivateKey.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.bouncycastle.crypto.params.ECDomainParameters;
2626
import org.bouncycastle.crypto.params.ECNamedDomainParameters;
2727
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
28+
import org.bouncycastle.jcajce.interfaces.BCKey;
2829
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
2930
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
3031
import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
@@ -37,7 +38,7 @@
3738
import org.bouncycastle.util.Arrays;
3839

3940
public class BCECPrivateKey
40-
implements ECPrivateKey, org.bouncycastle.jce.interfaces.ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder
41+
implements ECPrivateKey, org.bouncycastle.jce.interfaces.ECPrivateKey, PKCS12BagAttributeCarrier, ECPointEncoder, BCKey
4142
{
4243
static final long serialVersionUID = 994553197664784084L;
4344

prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/ec/BCECPublicKey.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
2222
import org.bouncycastle.crypto.params.ECDomainParameters;
2323
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
24+
import org.bouncycastle.jcajce.interfaces.BCKey;
2425
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
2526
import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
2627
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
@@ -32,7 +33,7 @@
3233
import org.bouncycastle.util.Properties;
3334

3435
public class BCECPublicKey
35-
implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder
36+
implements ECPublicKey, org.bouncycastle.jce.interfaces.ECPublicKey, ECPointEncoder, BCKey
3637
{
3738
static final long serialVersionUID = 2422789860422731812L;
3839

prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCEdDSAPrivateKey.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,14 @@
1515
import org.bouncycastle.crypto.params.Ed448PublicKeyParameters;
1616
import org.bouncycastle.crypto.util.PrivateKeyInfoFactory;
1717
import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers;
18+
import org.bouncycastle.jcajce.interfaces.BCKey;
1819
import org.bouncycastle.jcajce.interfaces.EdDSAPrivateKey;
1920
import org.bouncycastle.jcajce.interfaces.EdDSAPublicKey;
2021
import org.bouncycastle.util.Arrays;
2122
import org.bouncycastle.util.Properties;
2223

2324
public class BCEdDSAPrivateKey
24-
implements EdDSAPrivateKey
25+
implements EdDSAPrivateKey, BCKey
2526
{
2627
static final long serialVersionUID = 1L;
2728

prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/edec/BCEdDSAPublicKey.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@
1111
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters;
1212
import org.bouncycastle.crypto.params.Ed448PublicKeyParameters;
1313
import org.bouncycastle.internal.asn1.edec.EdECObjectIdentifiers;
14+
import org.bouncycastle.jcajce.interfaces.BCKey;
1415
import org.bouncycastle.jcajce.interfaces.EdDSAPublicKey;
1516
import org.bouncycastle.util.Arrays;
1617
import org.bouncycastle.util.Properties;
1718

1819
public class BCEdDSAPublicKey
19-
implements EdDSAPublicKey
20+
implements EdDSAPublicKey, BCKey
2021
{
2122
static final long serialVersionUID = 1L;
2223

prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPrivateKey.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@
1313
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
1414
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
1515
import org.bouncycastle.crypto.params.RSAKeyParameters;
16+
import org.bouncycastle.jcajce.interfaces.BCKey;
1617
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
1718
import org.bouncycastle.jcajce.provider.asymmetric.util.PKCS12BagAttributeCarrierImpl;
1819
import org.bouncycastle.jce.interfaces.PKCS12BagAttributeCarrier;
1920
import org.bouncycastle.util.Strings;
2021

2122
public class BCRSAPrivateKey
22-
implements RSAPrivateKey, PKCS12BagAttributeCarrier
23+
implements RSAPrivateKey, PKCS12BagAttributeCarrier, BCKey
2324
{
2425
static final long serialVersionUID = 5110188922551353628L;
2526

prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/rsa/BCRSAPublicKey.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@
1212
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
1313
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
1414
import org.bouncycastle.crypto.params.RSAKeyParameters;
15+
import org.bouncycastle.jcajce.interfaces.BCKey;
1516
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
1617
import org.bouncycastle.util.Strings;
1718

1819
public class BCRSAPublicKey
19-
implements RSAPublicKey
20+
implements RSAPublicKey, BCKey
2021
{
2122
static final AlgorithmIdentifier DEFAULT_ALGORITHM_IDENTIFIER = new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE);
2223

prov/src/test/java/org/bouncycastle/jcajce/provider/test/CompositeSignaturesTest.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,9 @@
2626

2727
import junit.framework.TestCase;
2828
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
29-
import org.bouncycastle.asn1.ASN1Primitive;
3029
import org.bouncycastle.asn1.DEROctetString;
3130
import org.bouncycastle.asn1.bc.BCObjectIdentifiers;
3231
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
33-
import org.bouncycastle.asn1.util.ASN1Dump;
3432
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
3533
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
3634
import org.bouncycastle.internal.asn1.misc.MiscObjectIdentifiers;
@@ -306,7 +304,47 @@ public void testSelfComposition()
306304
TestCase.assertTrue(signature.verify(signatureValue));
307305

308306
KeyFactory compFact = KeyFactory.getInstance(BCObjectIdentifiers.id_MLDSA44_ECDSA_P256_SHA256.getId(), "BC");
309-
System.err.println(ASN1Dump.dumpAsString(ASN1Primitive.fromByteArray(compPrivateKey.getEncoded())));
307+
PrivateKey compPriv = compFact.generatePrivate(new PKCS8EncodedKeySpec(compPrivateKey.getEncoded()));
308+
PublicKey compPub = compFact.generatePublic(new X509EncodedKeySpec(compPublicKey.getEncoded()));
309+
310+
signature.initSign(compPriv);
311+
signature.update(Strings.toUTF8ByteArray(messageToBeSigned));
312+
signatureValue = signature.sign();
313+
314+
signature.initVerify(compPub);
315+
signature.update(Strings.toUTF8ByteArray(messageToBeSigned));
316+
TestCase.assertTrue(signature.verify(signatureValue));
317+
318+
}
319+
320+
public void testMixedComposition()
321+
throws Exception
322+
{
323+
KeyPairGenerator mldsaKpGen = KeyPairGenerator.getInstance("ML-DSA", "BC");
324+
325+
mldsaKpGen.initialize(MLDSAParameterSpec.ml_dsa_44);
326+
327+
KeyPair mldsaKp = mldsaKpGen.generateKeyPair();
328+
329+
KeyPairGenerator ecKpGen = KeyPairGenerator.getInstance("EC", "SunEC");
330+
331+
ecKpGen.initialize(new ECGenParameterSpec("secp256r1"));
332+
333+
KeyPair ecKp = ecKpGen.generateKeyPair();
334+
335+
CompositePublicKey compPublicKey = new CompositePublicKey(BCObjectIdentifiers.id_MLDSA44_ECDSA_P256_SHA256, mldsaKp.getPublic(), ecKp.getPublic());
336+
CompositePrivateKey compPrivateKey = new CompositePrivateKey(BCObjectIdentifiers.id_MLDSA44_ECDSA_P256_SHA256, mldsaKp.getPrivate(), ecKp.getPrivate());
337+
338+
Signature signature = Signature.getInstance(BCObjectIdentifiers.id_MLDSA44_ECDSA_P256_SHA256.getId(), "BC");
339+
signature.initSign(compPrivateKey);
340+
signature.update(Strings.toUTF8ByteArray(messageToBeSigned));
341+
byte[] signatureValue = signature.sign();
342+
343+
signature.initVerify(compPublicKey);
344+
signature.update(Strings.toUTF8ByteArray(messageToBeSigned));
345+
TestCase.assertTrue(signature.verify(signatureValue));
346+
347+
KeyFactory compFact = KeyFactory.getInstance(BCObjectIdentifiers.id_MLDSA44_ECDSA_P256_SHA256.getId(), "BC");
310348
PrivateKey compPriv = compFact.generatePrivate(new PKCS8EncodedKeySpec(compPrivateKey.getEncoded()));
311349
PublicKey compPub = compFact.generatePublic(new X509EncodedKeySpec(compPublicKey.getEncoded()));
312350

0 commit comments

Comments
 (0)