233 lines
10 KiB
Diff
Executable File
233 lines
10 KiB
Diff
Executable File
From d58382eb0c18949cd04b76c12c556e6f11036573 Mon Sep 17 00:00:00 2001
|
|
From: miaozhuojun <mouzhuojun@huawei.com>
|
|
Date: Sat, 11 Sep 2021 11:35:19 +0800
|
|
Subject: [PATCH 14/23] 8268453: sun/security/pkcs12/EmptyPassword.java fails
|
|
with Sequence tag error
|
|
|
|
Summary: < JDK> : 8268453: sun/security/pkcs12/EmptyPassword.java fails with Sequence tag error
|
|
LLT: ./jdk8u/jdk/test/sun/security/pkcs12/EmptyPassword.java
|
|
Patch Type: backport
|
|
Bug url: https://bugs.openjdk.java.net/browse/JDK-8268453
|
|
---
|
|
.../sun/security/pkcs12/PKCS12KeyStore.java | 125 +++++++++---------
|
|
1 file changed, 64 insertions(+), 61 deletions(-)
|
|
|
|
diff --git a/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java b/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
|
|
index cdd01d6ab..ea3d61f30 100644
|
|
--- a/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
|
|
+++ b/jdk/src/share/classes/sun/security/pkcs12/PKCS12KeyStore.java
|
|
@@ -286,6 +286,9 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
|
} catch (Exception e) {
|
|
if (password.length == 0) {
|
|
// Retry using an empty password with a NUL terminator.
|
|
+ if (debug != null) {
|
|
+ debug.println("Retry with a NUL password");
|
|
+ }
|
|
return f.tryOnce(new char[1]);
|
|
}
|
|
throw e;
|
|
@@ -366,7 +369,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
|
|
|
try {
|
|
PBEParameterSpec pbeSpec;
|
|
- int ic = 0;
|
|
+ int ic;
|
|
|
|
if (algParams != null) {
|
|
try {
|
|
@@ -380,68 +383,72 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
|
if (ic > MAX_ITERATION_COUNT) {
|
|
throw new IOException("PBE iteration count too large");
|
|
}
|
|
+ } else {
|
|
+ ic = 0;
|
|
}
|
|
|
|
- byte[] keyInfo = RetryWithZero.run(pass -> {
|
|
+ key = RetryWithZero.run(pass -> {
|
|
// Use JCE
|
|
SecretKey skey = getPBEKey(pass);
|
|
Cipher cipher = Cipher.getInstance(
|
|
mapPBEParamsToAlgorithm(algOid, algParams));
|
|
cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
|
|
- return cipher.doFinal(encryptedKey);
|
|
- }, password);
|
|
-
|
|
- /*
|
|
- * Parse the key algorithm and then use a JCA key factory
|
|
- * to re-create the key.
|
|
- */
|
|
- DerValue val = new DerValue(keyInfo);
|
|
- DerInputStream in = val.toDerInputStream();
|
|
- int i = in.getInteger();
|
|
- DerValue[] value = in.getSequence(2);
|
|
- if (value.length < 1 || value.length > 2) {
|
|
- throw new IOException("Invalid length for AlgorithmIdentifier");
|
|
- }
|
|
- AlgorithmId algId = new AlgorithmId(value[0].getOID());
|
|
- String keyAlgo = algId.getName();
|
|
-
|
|
- // decode private key
|
|
- if (entry instanceof PrivateKeyEntry) {
|
|
- KeyFactory kfac = KeyFactory.getInstance(keyAlgo);
|
|
- PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(keyInfo);
|
|
- key = kfac.generatePrivate(kspec);
|
|
-
|
|
- if (debug != null) {
|
|
- debug.println("Retrieved a protected private key at alias" +
|
|
- " '" + alias + "' (" +
|
|
- new AlgorithmId(algOid).getName() +
|
|
- " iterations: " + ic + ")");
|
|
+ byte[] keyInfo = cipher.doFinal(encryptedKey);
|
|
+ /*
|
|
+ * Parse the key algorithm and then use a JCA key factory
|
|
+ * to re-create the key.
|
|
+ */
|
|
+ DerValue val = new DerValue(keyInfo);
|
|
+ DerInputStream in = val.toDerInputStream();
|
|
+ int i = in.getInteger();
|
|
+ DerValue[] value = in.getSequence(2);
|
|
+ if (value.length < 1 || value.length > 2) {
|
|
+ throw new IOException("Invalid length for AlgorithmIdentifier");
|
|
}
|
|
+ AlgorithmId algId = new AlgorithmId(value[0].getOID());
|
|
+ String keyAlgo = algId.getName();
|
|
|
|
- // decode secret key
|
|
- } else {
|
|
- byte[] keyBytes = in.getOctetString();
|
|
- SecretKeySpec secretKeySpec =
|
|
- new SecretKeySpec(keyBytes, keyAlgo);
|
|
-
|
|
- // Special handling required for PBE: needs a PBEKeySpec
|
|
- if (keyAlgo.startsWith("PBE")) {
|
|
- SecretKeyFactory sKeyFactory =
|
|
- SecretKeyFactory.getInstance(keyAlgo);
|
|
- KeySpec pbeKeySpec =
|
|
- sKeyFactory.getKeySpec(secretKeySpec, PBEKeySpec.class);
|
|
- key = sKeyFactory.generateSecret(pbeKeySpec);
|
|
+ // decode private key
|
|
+ if (entry instanceof PrivateKeyEntry) {
|
|
+ KeyFactory kfac = KeyFactory.getInstance(keyAlgo);
|
|
+ PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(keyInfo);
|
|
+ Key tmp = kfac.generatePrivate(kspec);
|
|
+
|
|
+ if (debug != null) {
|
|
+ debug.println("Retrieved a protected private key at alias" +
|
|
+ " '" + alias + "' (" +
|
|
+ new AlgorithmId(algOid).getName() +
|
|
+ " iterations: " + ic + ")");
|
|
+ }
|
|
+ return tmp;
|
|
+ // decode secret key
|
|
} else {
|
|
- key = secretKeySpec;
|
|
- }
|
|
+ byte[] keyBytes = in.getOctetString();
|
|
+ SecretKeySpec secretKeySpec =
|
|
+ new SecretKeySpec(keyBytes, keyAlgo);
|
|
+
|
|
+ // Special handling required for PBE: needs a PBEKeySpec
|
|
+ Key tmp;
|
|
+ if (keyAlgo.startsWith("PBE")) {
|
|
+ SecretKeyFactory sKeyFactory =
|
|
+ SecretKeyFactory.getInstance(keyAlgo);
|
|
+ KeySpec pbeKeySpec =
|
|
+ sKeyFactory.getKeySpec(secretKeySpec, PBEKeySpec.class);
|
|
+ tmp = sKeyFactory.generateSecret(pbeKeySpec);
|
|
+ } else {
|
|
+ tmp = secretKeySpec;
|
|
+ }
|
|
|
|
- if (debug != null) {
|
|
- debug.println("Retrieved a protected secret key at alias " +
|
|
- "'" + alias + "' (" +
|
|
- new AlgorithmId(algOid).getName() +
|
|
- " iterations: " + ic + ")");
|
|
+ if (debug != null) {
|
|
+ debug.println("Retrieved a protected secret key at alias " +
|
|
+ "'" + alias + "' (" +
|
|
+ new AlgorithmId(algOid).getName() +
|
|
+ " iterations: " + ic + ")");
|
|
+ }
|
|
+ return tmp;
|
|
}
|
|
- }
|
|
+ }, password);
|
|
+
|
|
} catch (Exception e) {
|
|
UnrecoverableKeyException uke =
|
|
new UnrecoverableKeyException("Get Key failed: " +
|
|
@@ -1984,7 +1991,6 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
|
* Spin over the ContentInfos.
|
|
*/
|
|
for (int i = 0; i < count; i++) {
|
|
- byte[] safeContentsData;
|
|
ContentInfo safeContents;
|
|
DerInputStream sci;
|
|
byte[] eAlgId = null;
|
|
@@ -1992,14 +1998,13 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
|
sci = new DerInputStream(safeContentsArray[i].toByteArray());
|
|
safeContents = new ContentInfo(sci);
|
|
contentType = safeContents.getContentType();
|
|
- safeContentsData = null;
|
|
if (contentType.equals((Object)ContentInfo.DATA_OID)) {
|
|
|
|
if (debug != null) {
|
|
debug.println("Loading PKCS#7 data");
|
|
}
|
|
|
|
- safeContentsData = safeContents.getData();
|
|
+ loadSafeContents(new DerInputStream(safeContents.getData()));
|
|
} else if (contentType.equals((Object)ContentInfo.ENCRYPTED_DATA_OID)) {
|
|
if (password == null) {
|
|
|
|
@@ -2029,7 +2034,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
|
if (seq[2].isConstructed())
|
|
newTag |= 0x20;
|
|
seq[2].resetTag(newTag);
|
|
- safeContentsData = seq[2].getOctetString();
|
|
+ byte[] rawData = seq[2].getOctetString();
|
|
|
|
// parse Algorithm parameters
|
|
DerInputStream in = seq[1].toDerInputStream();
|
|
@@ -2060,14 +2065,14 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
|
" iterations: " + ic + ")");
|
|
}
|
|
|
|
- byte[] rawData = safeContentsData;
|
|
try {
|
|
- safeContentsData = RetryWithZero.run(pass -> {
|
|
+ RetryWithZero.run(pass -> {
|
|
// Use JCE
|
|
SecretKey skey = getPBEKey(pass);
|
|
Cipher cipher = Cipher.getInstance(algOid.toString());
|
|
cipher.init(Cipher.DECRYPT_MODE, skey, algParams);
|
|
- return cipher.doFinal(rawData);
|
|
+ loadSafeContents(new DerInputStream(cipher.doFinal(rawData)));
|
|
+ return null;
|
|
}, password);
|
|
} catch (Exception e) {
|
|
throw new IOException("keystore password was incorrect",
|
|
@@ -2078,8 +2083,6 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
|
throw new IOException("public key protected PKCS12" +
|
|
" not supported");
|
|
}
|
|
- DerInputStream sc = new DerInputStream(safeContentsData);
|
|
- loadSafeContents(sc, password);
|
|
}
|
|
|
|
// The MacData is optional.
|
|
@@ -2204,7 +2207,7 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
|
|
else return null;
|
|
}
|
|
|
|
- private void loadSafeContents(DerInputStream stream, char[] password)
|
|
+ private void loadSafeContents(DerInputStream stream)
|
|
throws IOException, NoSuchAlgorithmException, CertificateException
|
|
{
|
|
DerValue[] safeBags = stream.getSequence(2);
|
|
--
|
|
2.22.0
|
|
|