Skip to content

Commit 97412b2

Browse files
committed
Merge branch 'main' of gitlab.cryptoworkshop.com:root/bc-java
2 parents 22fc1ea + af6cd72 commit 97412b2

File tree

9 files changed

+187
-64
lines changed

9 files changed

+187
-64
lines changed

core/src/main/java/org/bouncycastle/asn1/ASN1InputStream.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,10 @@ static ASN1Primitive createPrimitiveDERObject(
540540
case INTEGER:
541541
return ASN1Integer.createPrimitive(defIn.toByteArray());
542542
case NULL:
543-
return ASN1Null.createPrimitive(defIn.toByteArray());
543+
{
544+
ASN1Null.checkContentsLength(defIn.getRemaining());
545+
return ASN1Null.createPrimitive();
546+
}
544547
case NUMERIC_STRING:
545548
return ASN1NumericString.createPrimitive(defIn.toByteArray());
546549
case OBJECT_DESCRIPTOR:

core/src/main/java/org/bouncycastle/asn1/ASN1Null.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ public abstract class ASN1Null
1212
{
1313
ASN1Primitive fromImplicitPrimitive(DEROctetString octetString)
1414
{
15-
return createPrimitive(octetString.getOctets());
15+
checkContentsLength(octetString.getOctetsLength());
16+
return createPrimitive();
1617
}
1718
};
1819

@@ -88,12 +89,16 @@ public String toString()
8889
return "NULL";
8990
}
9091

91-
static ASN1Null createPrimitive(byte[] contents)
92+
static void checkContentsLength(int contentsLength)
9293
{
93-
if (0 != contents.length)
94+
if (0 != contentsLength)
9495
{
9596
throw new IllegalStateException("malformed NULL encoding encountered");
9697
}
98+
}
99+
100+
static ASN1Null createPrimitive()
101+
{
97102
return DERNull.INSTANCE;
98103
}
99104
}

core/src/main/java/org/bouncycastle/asn1/pkcs/RSAESOAEPparams.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,17 @@ public AlgorithmIdentifier getPSourceAlgorithm()
100100
{
101101
return pSourceAlgorithm;
102102
}
103-
103+
104+
public RSAESOAEPparams withDefaultPSource()
105+
{
106+
if (DEFAULT_P_SOURCE_ALGORITHM == pSourceAlgorithm)
107+
{
108+
return this;
109+
}
110+
111+
return new RSAESOAEPparams(hashAlgorithm, maskGenAlgorithm, DEFAULT_P_SOURCE_ALGORITHM);
112+
}
113+
104114
/**
105115
* <pre>
106116
* RSAES-OAEP-params ::= SEQUENCE {
@@ -145,7 +155,7 @@ public ASN1Primitive toASN1Primitive()
145155
{
146156
v.add(new DERTaggedObject(true, 2, pSourceAlgorithm));
147157
}
148-
158+
149159
return new DERSequence(v);
150160
}
151161
}

core/src/main/java/org/bouncycastle/asn1/x509/X509ObjectIdentifiers.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public interface X509ObjectIdentifiers
3131
* id-SHA1 OBJECT IDENTIFIER ::=
3232
* {iso(1) identified-organization(3) oiw(14) secsig(3) algorithms(2) 26 }
3333
* <p>
34-
* OID: 1.3.14.3.2.27
34+
* OID: 1.3.14.3.2.26
3535
*/
3636
static final ASN1ObjectIdentifier id_SHA1 = new ASN1ObjectIdentifier("1.3.14.3.2.26").intern();
3737

core/src/main/java/org/bouncycastle/pqc/crypto/hqc/HQCEngine.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,12 @@ public int decaps(byte[] ss, byte[] ct, byte[] sk)
179179
pkeEncrypt(cKemPrimeU64, cKemPrimeV64, sk, mPrime, kThetaPrime, 32);
180180
hashGJ(kBar, 256, hashEkKem, sk, pkSize + SEED_BYTES, K_BYTE, ct, 0, ct.length, (byte)3);
181181

182-
if (!Arrays.constantTimeAreEqual(u64, cKemPrimeU64))
182+
if (!Arrays.constantTimeAreEqual(N_BYTE_64, u64, 0, cKemPrimeU64, 0))
183183
{
184184
result = 1;
185185
}
186186

187-
if (!Arrays.constantTimeAreEqual(v64, cKemPrimeV64))
187+
if (!Arrays.constantTimeAreEqual(N_BYTE_64, v64, 0, cKemPrimeV64, 0))
188188
{
189189
result = 1;
190190
}

core/src/main/java/org/bouncycastle/util/Arrays.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,37 @@ public static boolean constantTimeAreEqual(int len, byte[] a, int aOff, byte[] b
149149
return 0 == d;
150150
}
151151

152+
public static boolean constantTimeAreEqual(int len, long[] a, int aOff, long[] b, int bOff)
153+
{
154+
if (null == a)
155+
{
156+
throw new NullPointerException("'a' cannot be null");
157+
}
158+
if (null == b)
159+
{
160+
throw new NullPointerException("'b' cannot be null");
161+
}
162+
if (len < 0)
163+
{
164+
throw new IllegalArgumentException("'len' cannot be negative");
165+
}
166+
if (aOff > (a.length - len))
167+
{
168+
throw new IndexOutOfBoundsException("'aOff' value invalid for specified length");
169+
}
170+
if (bOff > (b.length - len))
171+
{
172+
throw new IndexOutOfBoundsException("'bOff' value invalid for specified length");
173+
}
174+
175+
long d = 0;
176+
for (int i = 0; i < len; ++i)
177+
{
178+
d |= (a[aOff + i] ^ b[bOff + i]);
179+
}
180+
return 0L == d;
181+
}
182+
152183
/**
153184
* A constant time equals comparison - does not terminate early if
154185
* comparison fails. For best results always pass the expected value

pkix/src/main/java/org/bouncycastle/operator/jcajce/OperatorHelper.java

Lines changed: 84 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,11 @@
2323
import javax.crypto.Cipher;
2424
import javax.crypto.KeyAgreement;
2525

26-
import org.bouncycastle.asn1.ASN1Encodable;
26+
import org.bouncycastle.asn1.ASN1Encoding;
2727
import org.bouncycastle.asn1.ASN1Integer;
2828
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
2929
import org.bouncycastle.asn1.ASN1Sequence;
3030
import org.bouncycastle.asn1.DERNull;
31-
import org.bouncycastle.asn1.DERSequence;
3231
import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers;
3332
import org.bouncycastle.asn1.kisa.KISAObjectIdentifiers;
3433
import org.bouncycastle.asn1.nist.NISTObjectIdentifiers;
@@ -47,6 +46,7 @@
4746
import org.bouncycastle.jcajce.util.MessageDigestUtils;
4847
import org.bouncycastle.operator.DefaultSignatureNameFinder;
4948
import org.bouncycastle.operator.OperatorCreationException;
49+
import org.bouncycastle.util.Arrays;
5050
import org.bouncycastle.util.Integers;
5151

5252
class OperatorHelper
@@ -56,13 +56,11 @@ class OperatorHelper
5656
private static final Map symmetricWrapperAlgNames = new HashMap();
5757
private static final Map symmetricKeyAlgNames = new HashMap();
5858
private static final Map symmetricWrapperKeySizes = new HashMap();
59+
// ASN1ObjectIdentifier -> OAEPParamsValue
60+
private static final Map oaepParamsMap = new HashMap();
5961

6062
private static DefaultSignatureNameFinder sigFinder = new DefaultSignatureNameFinder();
6163

62-
private static final RSAESOAEPparams oaepParams_sha256 = calculateDefForDigest(NISTObjectIdentifiers.id_sha256);
63-
private static final RSAESOAEPparams oaepParams_sha384 = calculateDefForDigest(NISTObjectIdentifiers.id_sha384);
64-
private static final RSAESOAEPparams oaepParams_sha512 = calculateDefForDigest(NISTObjectIdentifiers.id_sha512);
65-
6664
static
6765
{
6866
oids.put(OIWObjectIdentifiers.idSHA1, "SHA1");
@@ -107,17 +105,12 @@ class OperatorHelper
107105
symmetricKeyAlgNames.put(NISTObjectIdentifiers.id_aes256_CBC, "AES");
108106
symmetricKeyAlgNames.put(PKCSObjectIdentifiers.des_EDE3_CBC, "DESede");
109107
symmetricKeyAlgNames.put(PKCSObjectIdentifiers.RC2_CBC, "RC2");
110-
}
111108

112-
private static RSAESOAEPparams calculateDefForDigest(ASN1ObjectIdentifier digest)
113-
{
114-
AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(
115-
digest,
116-
DERNull.INSTANCE);
117-
AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(
118-
PKCSObjectIdentifiers.id_mgf1,
119-
new AlgorithmIdentifier(digest, DERNull.INSTANCE));
120-
return new RSAESOAEPparams(hashAlgorithm, maskGenAlgorithm, RSAESOAEPparams.DEFAULT_P_SOURCE_ALGORITHM);
109+
OAEPParamsValue.add(oaepParamsMap, "RSA/ECB/OAEPWithSHA-1AndMGF1Padding", OIWObjectIdentifiers.idSHA1);
110+
OAEPParamsValue.add(oaepParamsMap, "RSA/ECB/OAEPWithSHA-224AndMGF1Padding", NISTObjectIdentifiers.id_sha224);
111+
OAEPParamsValue.add(oaepParamsMap, "RSA/ECB/OAEPWithSHA-256AndMGF1Padding", NISTObjectIdentifiers.id_sha256);
112+
OAEPParamsValue.add(oaepParamsMap, "RSA/ECB/OAEPWithSHA-384AndMGF1Padding", NISTObjectIdentifiers.id_sha384);
113+
OAEPParamsValue.add(oaepParamsMap, "RSA/ECB/OAEPWithSHA-512AndMGF1Padding", NISTObjectIdentifiers.id_sha512);
121114
}
122115

123116
private JcaJceHelper helper;
@@ -207,52 +200,51 @@ KeyAgreement createKeyAgreement(ASN1ObjectIdentifier algorithm)
207200
Cipher createAsymmetricWrapper(AlgorithmIdentifier algorithmID, Map extraAlgNames)
208201
throws OperatorCreationException
209202
{
210-
ASN1ObjectIdentifier algorithm = algorithmID.getAlgorithm();
203+
if (algorithmID == null)
204+
{
205+
throw new NullPointerException("'algorithmID' cannot be null");
206+
}
207+
208+
ASN1ObjectIdentifier algOID = algorithmID.getAlgorithm();
211209
try
212210
{
213211
String cipherName = null;
214212

215-
if (!extraAlgNames.isEmpty())
213+
if (extraAlgNames != null && !extraAlgNames.isEmpty())
216214
{
217-
cipherName = (String)extraAlgNames.get(algorithm);
215+
cipherName = (String)extraAlgNames.get(algOID);
218216
}
219217

220218
if (cipherName == null)
221219
{
222-
cipherName = (String)asymmetricWrapperAlgNames.get(algorithm);
220+
cipherName = (String)asymmetricWrapperAlgNames.get(algOID);
221+
}
222+
223+
if (cipherName != null)
224+
{
223225
if (cipherName.indexOf("OAEPPadding") > 0)
224226
{
225-
ASN1Encodable params = algorithmID.getParameters().toASN1Primitive();
226-
if ((params instanceof ASN1Sequence))
227+
try
227228
{
228-
ASN1Sequence paramSeq = ASN1Sequence.getInstance(params);
229-
if (paramSeq.size() == 0)
229+
RSAESOAEPparams oaepParams = RSAESOAEPparams.getInstance(algorithmID.getParameters());
230+
if (oaepParams != null)
230231
{
231-
cipherName = "RSA/ECB/OAEPWithSHA-1AndMGF1Padding";
232-
}
233-
else if (paramSeq.size() >= 2)
234-
{
235-
// we only check the first 2 as pSource may be different
236-
paramSeq = new DERSequence(new ASN1Encodable[]{ paramSeq.getObjectAt(0), paramSeq.getObjectAt(1) });
237-
if (oaepParams_sha256.equals(paramSeq))
238-
{
239-
cipherName = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";
240-
}
241-
else if (oaepParams_sha512.equals(paramSeq))
242-
{
243-
cipherName = "RSA/ECB/OAEPWithSHA-512AndMGF1Padding";
244-
}
245-
else if (oaepParams_sha384.equals(paramSeq))
232+
ASN1ObjectIdentifier digestOID = oaepParams.getHashAlgorithm().getAlgorithm();
233+
OAEPParamsValue oaepParamsValue = (OAEPParamsValue)oaepParamsMap.get(digestOID);
234+
235+
// Note that the original pSourceAlgorithm is ignored for this comparison
236+
if (oaepParamsValue != null && oaepParamsValue.matches(oaepParams.withDefaultPSource()))
246237
{
247-
cipherName = "RSA/ECB/OAEPWithSHA-384AndMGF1Padding";
238+
cipherName = oaepParamsValue.getCipherName();
248239
}
249240
}
250241
}
242+
catch (Exception e)
243+
{
244+
// Ignore
245+
}
251246
}
252-
}
253247

254-
if (cipherName != null)
255-
{
256248
try
257249
{
258250
// this is reversed as the Sun policy files now allow unlimited strength RSA
@@ -288,7 +280,7 @@ else if (cipherName.indexOf("ECB/OAEPWith") > 0)
288280
}
289281
}
290282

291-
return helper.createCipher(algorithm.getId());
283+
return helper.createCipher(algOID.getId());
292284
}
293285
catch (GeneralSecurityException e)
294286
{
@@ -626,4 +618,52 @@ private boolean notDefaultPSSParams(ASN1Sequence seq)
626618

627619
return pssParams.getSaltLength().intValue() != digest.getDigestLength();
628620
}
621+
622+
private static class OAEPParamsValue
623+
{
624+
static void add(Map oaepParamsMap, String cipherName, ASN1ObjectIdentifier digestOID)
625+
{
626+
try
627+
{
628+
RSAESOAEPparams oaepParams = createOAEPParams(digestOID);
629+
byte[] derEncoding = getDEREncoding(oaepParams);
630+
oaepParamsMap.put(digestOID, new OAEPParamsValue(cipherName, derEncoding));
631+
}
632+
catch (Exception e)
633+
{
634+
throw new RuntimeException(e);
635+
}
636+
}
637+
638+
private String cipherName;
639+
private byte[] derEncoding;
640+
641+
private OAEPParamsValue(String cipherName, byte[] derEncoding)
642+
{
643+
this.cipherName = cipherName;
644+
this.derEncoding = derEncoding;
645+
}
646+
647+
String getCipherName()
648+
{
649+
return cipherName;
650+
}
651+
652+
boolean matches(RSAESOAEPparams oaepParams) throws IOException
653+
{
654+
return Arrays.areEqual(derEncoding, getDEREncoding(oaepParams));
655+
}
656+
657+
private static RSAESOAEPparams createOAEPParams(ASN1ObjectIdentifier digestOID)
658+
{
659+
AlgorithmIdentifier hashAlgorithm = new AlgorithmIdentifier(digestOID, DERNull.INSTANCE);
660+
AlgorithmIdentifier maskGenAlgorithm = new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgorithm);
661+
return new RSAESOAEPparams(hashAlgorithm, maskGenAlgorithm, RSAESOAEPparams.DEFAULT_P_SOURCE_ALGORITHM);
662+
}
663+
664+
private static byte[] getDEREncoding(RSAESOAEPparams oaepParams) throws IOException
665+
{
666+
return oaepParams.getEncoded(ASN1Encoding.DER);
667+
}
668+
}
629669
}

pkix/src/test/java/org/bouncycastle/cms/test/CMSTestUtil.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public class CMSTestUtil
5353
{
5454
public static SecureRandom rand;
5555
public static KeyPairGenerator kpg;
56+
public static KeyPairGenerator kpg_2048;
5657

5758
public static KeyPairGenerator gostKpg;
5859
public static KeyPairGenerator dsaKpg;
@@ -156,8 +157,8 @@ public class CMSTestUtil
156157
kpg = KeyPairGenerator.getInstance("RSA", "BC");
157158
kpg.initialize(1024, rand);
158159

159-
kpg = KeyPairGenerator.getInstance("RSA", "BC");
160-
kpg.initialize(1024, rand);
160+
kpg_2048 = KeyPairGenerator.getInstance("RSA", "BC");
161+
kpg_2048.initialize(2048, rand);
161162

162163
gostKpg = KeyPairGenerator.getInstance("GOST3410", "BC");
163164
GOST3410ParameterSpec gost3410P = new GOST3410ParameterSpec(CryptoProObjectIdentifiers.gostR3410_94_CryptoPro_A.getId());
@@ -278,6 +279,11 @@ public static KeyPair makeKeyPair()
278279
return kpg.generateKeyPair();
279280
}
280281

282+
public static KeyPair makeKeyPair_2048()
283+
{
284+
return kpg_2048.generateKeyPair();
285+
}
286+
281287
public static KeyPair makeGostKeyPair()
282288
{
283289
return gostKpg.generateKeyPair();

0 commit comments

Comments
 (0)