Skip to content

Commit 1781b18

Browse files
author
Mark Powers
committed
8343232: PKCS#12 KeyStore support for RFC 9879: Use of Password-Based Message Authentication Code 1 (PBMAC1)
Reviewed-by: weijun, mullan
1 parent 8236800 commit 1781b18

File tree

11 files changed

+901
-279
lines changed

11 files changed

+901
-279
lines changed

src/java.base/share/classes/com/sun/crypto/provider/PBES2Parameters.java

Lines changed: 21 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
3232
import java.security.spec.InvalidParameterSpecException;
3333
import javax.crypto.spec.IvParameterSpec;
3434
import javax.crypto.spec.PBEParameterSpec;
35+
import sun.security.util.PBKDF2Parameters;
3536
import sun.security.util.*;
3637

3738
/**
@@ -93,7 +94,7 @@
9394
abstract class PBES2Parameters extends AlgorithmParametersSpi {
9495

9596
private static final ObjectIdentifier pkcs5PBKDF2_OID =
96-
ObjectIdentifier.of(KnownOIDs.PBKDF2WithHmacSHA1);
97+
ObjectIdentifier.of(KnownOIDs.PBKDF2);
9798
private static final ObjectIdentifier pkcs5PBES2_OID =
9899
ObjectIdentifier.of(KnownOIDs.PBES2);
99100
private static final ObjectIdentifier aes128CBC_OID =
@@ -224,77 +225,32 @@ protected void engineInit(byte[] encoded)
224225
// next DerValue as the real PBES2-params.
225226
if (kdf.getTag() == DerValue.tag_ObjectId) {
226227
pBES2_params = pBES2_params.data.getDerValue();
228+
if (pBES2_params.tag != DerValue.tag_Sequence) {
229+
throw new IOException("PBE parameter parsing error: "
230+
+ "not an ASN.1 SEQUENCE tag");
231+
}
227232
kdf = pBES2_params.data.getDerValue();
228233
}
229234

230-
String kdfAlgo = parseKDF(kdf);
231-
232-
if (pBES2_params.tag != DerValue.tag_Sequence) {
233-
throw new IOException("PBE parameter parsing error: "
234-
+ "not an ASN.1 SEQUENCE tag");
235-
}
236-
String cipherAlgo = parseES(pBES2_params.data.getDerValue());
237-
238-
this.pbes2AlgorithmName = "PBEWith" + kdfAlgo + "And" + cipherAlgo;
239-
}
240-
241-
private String parseKDF(DerValue keyDerivationFunc) throws IOException {
242-
243-
if (!pkcs5PBKDF2_OID.equals(keyDerivationFunc.data.getOID())) {
235+
if (!pkcs5PBKDF2_OID.equals(kdf.data.getOID())) {
244236
throw new IOException("PBE parameter parsing error: "
245237
+ "expecting the object identifier for PBKDF2");
246238
}
247-
if (keyDerivationFunc.tag != DerValue.tag_Sequence) {
239+
if (kdf.tag != DerValue.tag_Sequence) {
248240
throw new IOException("PBE parameter parsing error: "
249241
+ "not an ASN.1 SEQUENCE tag");
250242
}
251-
DerValue pBKDF2_params = keyDerivationFunc.data.getDerValue();
252-
if (pBKDF2_params.tag != DerValue.tag_Sequence) {
253-
throw new IOException("PBE parameter parsing error: "
254-
+ "not an ASN.1 SEQUENCE tag");
255-
}
256-
DerValue specified = pBKDF2_params.data.getDerValue();
257-
// the 'specified' ASN.1 CHOICE for 'salt' is supported
258-
if (specified.tag == DerValue.tag_OctetString) {
259-
salt = specified.getOctetString();
260-
} else {
261-
// the 'otherSource' ASN.1 CHOICE for 'salt' is not supported
262-
throw new IOException("PBE parameter parsing error: "
263-
+ "not an ASN.1 OCTET STRING tag");
264-
}
265-
iCount = pBKDF2_params.data.getInteger();
243+
DerValue pBKDF2_params = kdf.data.getDerValue();
266244

267-
// keyLength INTEGER (1..MAX) OPTIONAL,
268-
var ksDer = pBKDF2_params.data.getOptional(DerValue.tag_Integer);
269-
if (ksDer.isPresent()) {
270-
keysize = ksDer.get().getInteger() * 8; // keysize (in bits)
271-
}
245+
var kdfParams = new PBKDF2Parameters(pBKDF2_params);
246+
String kdfAlgo = kdfParams.getPrfAlgo();
247+
salt = kdfParams.getSalt();
248+
iCount = kdfParams.getIterationCount();
249+
keysize = kdfParams.getKeyLength();
272250

273-
// prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1
274-
String kdfAlgo;
275-
var prfDer = pBKDF2_params.data.getOptional(DerValue.tag_Sequence);
276-
if (prfDer.isPresent()) {
277-
DerValue prf = prfDer.get();
278-
kdfAlgo_OID = prf.data.getOID();
279-
KnownOIDs o = KnownOIDs.findMatch(kdfAlgo_OID.toString());
280-
if (o == null || (!o.stdName().equals("HmacSHA1") &&
281-
!o.stdName().equals("HmacSHA224") &&
282-
!o.stdName().equals("HmacSHA256") &&
283-
!o.stdName().equals("HmacSHA384") &&
284-
!o.stdName().equals("HmacSHA512") &&
285-
!o.stdName().equals("HmacSHA512/224") &&
286-
!o.stdName().equals("HmacSHA512/256"))) {
287-
throw new IOException("PBE parameter parsing error: "
288-
+ "expecting the object identifier for a HmacSHA key "
289-
+ "derivation function");
290-
}
291-
kdfAlgo = o.stdName();
292-
prf.data.getOptional(DerValue.tag_Null);
293-
prf.data.atEnd();
294-
} else {
295-
kdfAlgo = "HmacSHA1";
296-
}
297-
return kdfAlgo;
251+
String cipherAlgo = parseES(pBES2_params.data.getDerValue());
252+
253+
this.pbes2AlgorithmName = "PBEWith" + kdfAlgo + "And" + cipherAlgo;
298254
}
299255

300256
private String parseES(DerValue encryptionScheme) throws IOException {
@@ -345,26 +301,9 @@ protected byte[] engineGetEncoded() throws IOException {
345301

346302
DerOutputStream pBES2_params = new DerOutputStream();
347303

348-
DerOutputStream keyDerivationFunc = new DerOutputStream();
349-
keyDerivationFunc.putOID(pkcs5PBKDF2_OID);
350-
351-
DerOutputStream pBKDF2_params = new DerOutputStream();
352-
pBKDF2_params.putOctetString(salt); // choice: 'specified OCTET STRING'
353-
pBKDF2_params.putInteger(iCount);
354-
355-
if (keysize > 0) {
356-
pBKDF2_params.putInteger(keysize / 8); // derived key length (in octets)
357-
}
358-
359-
DerOutputStream prf = new DerOutputStream();
360-
// algorithm is id-hmacWith<MD>
361-
prf.putOID(kdfAlgo_OID);
362-
// parameters is 'NULL'
363-
prf.putNull();
364-
pBKDF2_params.write(DerValue.tag_Sequence, prf);
365-
366-
keyDerivationFunc.write(DerValue.tag_Sequence, pBKDF2_params);
367-
pBES2_params.write(DerValue.tag_Sequence, keyDerivationFunc);
304+
// keysize encoded as octets
305+
pBES2_params.writeBytes(PBKDF2Parameters.encode(salt, iCount,
306+
keysize/8, kdfAlgo_OID));
368307

369308
DerOutputStream encryptionScheme = new DerOutputStream();
370309
// algorithm is id-aes128-CBC or id-aes256-CBC

src/java.base/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
* @author Valerie Peng
5656
*
5757
*/
58-
final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
58+
public final class PBKDF2KeyImpl implements javax.crypto.interfaces.PBEKey {
5959

6060
@java.io.Serial
6161
private static final long serialVersionUID = -2234868909660948157L;

0 commit comments

Comments
 (0)