From d58382eb0c18949cd04b76c12c556e6f11036573 Mon Sep 17 00:00:00 2001 From: miaozhuojun 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