Skip to content

Commit 24509b5

Browse files
author
royb
committed
Merge remote-tracking branch 'origin/main'
2 parents 8de3703 + b8e4716 commit 24509b5

File tree

9 files changed

+80
-56
lines changed

9 files changed

+80
-56
lines changed

core/src/main/java/org/bouncycastle/crypto/params/ECNamedDomainParameters.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,26 @@
33
import java.math.BigInteger;
44

55
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
6+
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
67
import org.bouncycastle.asn1.x9.X9ECParameters;
8+
import org.bouncycastle.crypto.ec.CustomNamedCurves;
79
import org.bouncycastle.math.ec.ECConstants;
810
import org.bouncycastle.math.ec.ECCurve;
911
import org.bouncycastle.math.ec.ECPoint;
1012

1113
public class ECNamedDomainParameters
1214
extends ECDomainParameters
1315
{
16+
public static ECNamedDomainParameters lookup(ASN1ObjectIdentifier name)
17+
{
18+
X9ECParameters x9 = CustomNamedCurves.getByOID(name);
19+
if (x9 == null)
20+
{
21+
x9 = ECNamedCurveTable.getByOID(name);
22+
}
23+
return new ECNamedDomainParameters(name, x9);
24+
}
25+
1426
private ASN1ObjectIdentifier name;
1527

1628
public ECNamedDomainParameters(ASN1ObjectIdentifier name, ECCurve curve, ECPoint G, BigInteger n)

core/src/main/java/org/bouncycastle/crypto/util/OpenSSHPrivateKeyUtil.java

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@
1313
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
1414
import org.bouncycastle.asn1.pkcs.RSAPrivateKey;
1515
import org.bouncycastle.asn1.sec.ECPrivateKey;
16-
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
16+
import org.bouncycastle.asn1.x9.X962Parameters;
1717
import org.bouncycastle.asn1.x9.X9ECParameters;
1818
import org.bouncycastle.crypto.CryptoServicesRegistrar;
1919
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
2020
import org.bouncycastle.crypto.params.DSAParameters;
2121
import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
22+
import org.bouncycastle.crypto.params.ECDomainParameters;
2223
import org.bouncycastle.crypto.params.ECNamedDomainParameters;
2324
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
2425
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
@@ -199,13 +200,24 @@ else if (sequence.size() == 4)
199200
&& sequence.getObjectAt(2) instanceof ASN1TaggedObject)
200201
{
201202
ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(sequence);
202-
ASN1ObjectIdentifier curveOID = ASN1ObjectIdentifier.getInstance(ecPrivateKey.getParametersObject());
203-
X9ECParameters x9Params = ECNamedCurveTable.getByOID(curveOID);
204-
result = new ECPrivateKeyParameters(
205-
ecPrivateKey.getKey(),
206-
new ECNamedDomainParameters(
207-
curveOID,
208-
x9Params));
203+
204+
X962Parameters parameters = X962Parameters.getInstance(
205+
ecPrivateKey.getParametersObject().toASN1Primitive());
206+
ECDomainParameters domainParams;
207+
if (parameters.isNamedCurve())
208+
{
209+
ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(parameters.getParameters());
210+
domainParams = ECNamedDomainParameters.lookup(oid);
211+
}
212+
else
213+
{
214+
X9ECParameters x9 = X9ECParameters.getInstance(parameters.getParameters());
215+
domainParams = new ECDomainParameters(x9);
216+
}
217+
218+
BigInteger d = ecPrivateKey.getKey();
219+
220+
result = new ECPrivateKeyParameters(d, domainParams);
209221
}
210222
}
211223
}

core/src/main/java/org/bouncycastle/crypto/util/PrivateKeyFactory.java

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.bouncycastle.asn1.x9.X962Parameters;
2727
import org.bouncycastle.asn1.x9.X9ECParameters;
2828
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
29-
import org.bouncycastle.crypto.ec.CustomNamedCurves;
3029
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
3130
import org.bouncycastle.crypto.params.DHParameters;
3231
import org.bouncycastle.crypto.params.DHPrivateKeyParameters;
@@ -155,33 +154,24 @@ else if (algOID.equals(X9ObjectIdentifiers.id_dsa))
155154
}
156155
else if (algOID.equals(X9ObjectIdentifiers.id_ecPublicKey))
157156
{
158-
X962Parameters params = X962Parameters.getInstance(algId.getParameters());
157+
ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(keyInfo.parsePrivateKey());
159158

160-
X9ECParameters x9;
161-
ECDomainParameters dParams;
162-
163-
if (params.isNamedCurve())
159+
X962Parameters parameters = X962Parameters.getInstance(algId.getParameters().toASN1Primitive());
160+
ECDomainParameters domainParams;
161+
if (parameters.isNamedCurve())
164162
{
165-
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
166-
167-
x9 = CustomNamedCurves.getByOID(oid);
168-
if (x9 == null)
169-
{
170-
x9 = ECNamedCurveTable.getByOID(oid);
171-
}
172-
dParams = new ECNamedDomainParameters(oid, x9);
163+
ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(parameters.getParameters());
164+
domainParams = ECNamedDomainParameters.lookup(oid);
173165
}
174166
else
175167
{
176-
x9 = X9ECParameters.getInstance(params.getParameters());
177-
dParams = new ECDomainParameters(
178-
x9.getCurve(), x9.getG(), x9.getN(), x9.getH(), x9.getSeed());
168+
X9ECParameters x9 = X9ECParameters.getInstance(parameters.getParameters());
169+
domainParams = new ECDomainParameters(x9);
179170
}
180171

181-
ECPrivateKey ec = ECPrivateKey.getInstance(keyInfo.parsePrivateKey());
182-
BigInteger d = ec.getKey();
172+
BigInteger d = ecPrivateKey.getKey();
183173

184-
return new ECPrivateKeyParameters(d, dParams);
174+
return new ECPrivateKeyParameters(d, domainParams);
185175
}
186176
else if (algOID.equals(EdECObjectIdentifiers.id_X25519))
187177
{

core/src/main/java/org/bouncycastle/crypto/util/PublicKeyFactory.java

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,12 @@
3232
import org.bouncycastle.asn1.x509.X509ObjectIdentifiers;
3333
import org.bouncycastle.asn1.x9.DHPublicKey;
3434
import org.bouncycastle.asn1.x9.DomainParameters;
35-
import org.bouncycastle.asn1.x9.ECNamedCurveTable;
3635
import org.bouncycastle.asn1.x9.ValidationParams;
3736
import org.bouncycastle.asn1.x9.X962Parameters;
3837
import org.bouncycastle.asn1.x9.X9ECParameters;
3938
import org.bouncycastle.asn1.x9.X9ECPoint;
4039
import org.bouncycastle.asn1.x9.X9IntegerConverter;
4140
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
42-
import org.bouncycastle.crypto.ec.CustomNamedCurves;
4341
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
4442
import org.bouncycastle.crypto.params.DHParameters;
4543
import org.bouncycastle.crypto.params.DHPublicKeyParameters;
@@ -291,13 +289,7 @@ AsymmetricKeyParameter getPublicKeyParameters(SubjectPublicKeyInfo keyInfo, Obje
291289
if (params.isNamedCurve())
292290
{
293291
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)params.getParameters();
294-
295-
X9ECParameters x9 = CustomNamedCurves.getByOID(oid);
296-
if (x9 == null)
297-
{
298-
x9 = ECNamedCurveTable.getByOID(oid);
299-
}
300-
dParams = new ECNamedDomainParameters(oid, x9);
292+
dParams = ECNamedDomainParameters.lookup(oid);
301293
}
302294
else if (params.isImplicitlyCA())
303295
{

core/src/main/java/org/bouncycastle/pqc/asn1/KyberPrivateKey.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313
/**
1414
*
1515
* Crystal Kyber Private Key Format.
16-
* See https://www.ietf.org/archive/id/draft-uni-qsckeys-kyber-00.html for details.
16+
* See https://www.ietf.org/archive/id/draft-uni-qsckeys-kyber-01.html for details.
1717
* <pre>
1818
* KyberPrivateKey ::= SEQUENCE {
19-
* version INTEGER {v0(0)} -- version (round 3)
20-
* s OCTET STRING, -- EMPTY
21-
* hpk OCTET STRING -- EMPTY
22-
* nonce OCTET STRING, -- d
23-
* publicKey [0] IMPLICIT KyberPublicKey OPTIONAL,
24-
* -- see next section
19+
* version INTEGER {v0(0)} -- version (round 3)
20+
* s OCTET STRING, -- sample s
21+
* publicKey [0] IMPLICIT KyberPublicKey OPTIONAL,
22+
* -- see next section
23+
* hpk OCTET STRING -- H(pk)
24+
* nonce OCTET STRING, -- z
2525
* }
2626
* </pre>
2727
*/

core/src/main/java/org/bouncycastle/pqc/asn1/KyberPublicKey.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
/**
1313
*
1414
* Crystal Kyber Public Key Format.
15-
* See https://www.ietf.org/archive/id/draft-uni-qsckeys-kyber-00.html for details.
15+
* See https://www.ietf.org/archive/id/draft-uni-qsckeys-kyber-01.html for details.
1616
* <pre>
1717
* KyberPublicKey ::= SEQUENCE {
1818
* t OCTET STRING,

docs/releasenotes.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ <h2>2.0 Release History</h2>
2323
Date:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2024, TBD.
2424
<h3>2.1.2 Defects Fixed</h3>
2525
<ul>
26+
<li>Leading zeroes were sometimes dropped from Ed25519 signatures leading to verification errors in the PGP API. This has been fixed.</li>
2627
</ul>
2728
<h3>2.1.3 Additional Features and Functionality</h3>
2829
<ul>

pg/src/main/java/org/bouncycastle/openpgp/PGPSignature.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -455,19 +455,18 @@ else if (getKeyAlgorithm() == PublicKeyAlgorithmTags.EDDSA_LEGACY)
455455
{
456456
byte[] a = BigIntegers.asUnsignedByteArray(sigValues[0].getValue());
457457
byte[] b = BigIntegers.asUnsignedByteArray(sigValues[1].getValue());
458-
if (a.length + b.length == Ed25519.SIGNATURE_SIZE)
459-
{
460-
signature = new byte[Ed25519.SIGNATURE_SIZE];
461-
System.arraycopy(a, 0, signature, Ed25519.PUBLIC_KEY_SIZE - a.length, a.length);
462-
System.arraycopy(b, 0, signature, Ed25519.SIGNATURE_SIZE - b.length, b.length);
463-
}
464-
else
458+
if (a.length + b.length > Ed25519.SIGNATURE_SIZE)
465459
{
466460
signature = new byte[Ed448.SIGNATURE_SIZE];
467461
System.arraycopy(a, 0, signature, Ed448.PUBLIC_KEY_SIZE - a.length, a.length);
468462
System.arraycopy(b, 0, signature, Ed448.SIGNATURE_SIZE - b.length, b.length);
469463
}
470-
464+
else
465+
{
466+
signature = new byte[Ed25519.SIGNATURE_SIZE];
467+
System.arraycopy(a, 0, signature, Ed25519.PUBLIC_KEY_SIZE - a.length, a.length);
468+
System.arraycopy(b, 0, signature, Ed25519.SIGNATURE_SIZE - b.length, b.length);
469+
}
471470
}
472471
else
473472
{

pkix/src/main/java/org/bouncycastle/cms/jcajce/JceKeyAgreeRecipientInfoGenerator.java

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public class JceKeyAgreeRecipientInfoGenerator
5757
private PrivateKey senderPrivateKey;
5858

5959
private EnvelopedDataHelper helper = new EnvelopedDataHelper(new DefaultJcaJceExtHelper());
60+
private EnvelopedDataHelper wrappingHelper = null;
61+
6062
private SecureRandom random;
6163
private KeyPair ephemeralKP;
6264
private byte[] userKeyingMaterial;
@@ -90,6 +92,20 @@ public JceKeyAgreeRecipientInfoGenerator setProvider(String providerName)
9092
return this;
9193
}
9294

95+
public JceKeyAgreeRecipientInfoGenerator setKeyWrappingProvider(Provider provider)
96+
{
97+
this.wrappingHelper = new EnvelopedDataHelper(new ProviderJcaJceExtHelper(provider));
98+
99+
return this;
100+
}
101+
102+
public JceKeyAgreeRecipientInfoGenerator setKeyWrappingProvider(String providerName)
103+
{
104+
this.wrappingHelper = new EnvelopedDataHelper(new NamedJcaJceExtHelper(providerName));
105+
106+
return this;
107+
}
108+
93109
public JceKeyAgreeRecipientInfoGenerator setSecureRandom(SecureRandom random)
94110
{
95111
this.random = random;
@@ -203,16 +219,18 @@ else if (CMSUtils.isGOST(keyAgreementOID))
203219

204220
SecretKey keyEncryptionKey = keyAgreement.generateSecret(keyEncAlg.getId());
205221

222+
EnvelopedDataHelper keyWrapHelper = (wrappingHelper != null) ? wrappingHelper : helper;
223+
206224
// Wrap the content encryption key with the agreement key
207-
Cipher keyEncryptionCipher = helper.createCipher(keyEncAlg);
225+
Cipher keyEncryptionCipher = keyWrapHelper.createCipher(keyEncAlg);
208226
ASN1OctetString encryptedKey;
209227

210228
if (keyEncAlg.equals(CryptoProObjectIdentifiers.id_Gost28147_89_None_KeyWrap)
211229
|| keyEncAlg.equals(CryptoProObjectIdentifiers.id_Gost28147_89_CryptoPro_KeyWrap))
212230
{
213231
keyEncryptionCipher.init(Cipher.WRAP_MODE, keyEncryptionKey, new GOST28147WrapParameterSpec(CryptoProObjectIdentifiers.id_Gost28147_89_CryptoPro_A_ParamSet, userKeyingMaterial));
214232

215-
byte[] encKeyBytes = keyEncryptionCipher.wrap(helper.getJceKey(contentEncryptionKey));
233+
byte[] encKeyBytes = keyEncryptionCipher.wrap(keyWrapHelper.getJceKey(contentEncryptionKey));
216234

217235
Gost2814789EncryptedKey encKey = new Gost2814789EncryptedKey(
218236
Arrays.copyOfRange(encKeyBytes, 0, encKeyBytes.length - 4),
@@ -224,7 +242,7 @@ else if (CMSUtils.isGOST(keyAgreementOID))
224242
{
225243
keyEncryptionCipher.init(Cipher.WRAP_MODE, keyEncryptionKey, random);
226244

227-
byte[] encryptedKeyBytes = keyEncryptionCipher.wrap(helper.getJceKey(contentEncryptionKey));
245+
byte[] encryptedKeyBytes = keyEncryptionCipher.wrap(keyWrapHelper.getJceKey(contentEncryptionKey));
228246

229247
encryptedKey = new DEROctetString(encryptedKeyBytes);
230248
}

0 commit comments

Comments
 (0)