src/java.base/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java
changeset 51504 c9a3e3cac9c7
parent 47216 71c04702a3d5
--- a/src/java.base/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java	Thu Aug 23 10:52:27 2018 +0200
+++ b/src/java.base/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java	Thu Aug 23 11:37:14 2018 +0100
@@ -104,6 +104,7 @@
             Arrays.fill(D, (byte)type);
             concat(salt, I, 0, s);
             concat(passwd, I, s, p);
+            Arrays.fill(passwd, (byte) 0x00);
 
             byte[] Ai;
             byte[] B = new byte[v];
@@ -268,87 +269,92 @@
             salt = pbeKey.getSalt(); // maybe null if unspecified
             iCount = pbeKey.getIterationCount(); // maybe 0 if unspecified
         } else if (key instanceof SecretKey) {
-            byte[] passwdBytes = key.getEncoded();
-            if ((passwdBytes == null) ||
-                !(key.getAlgorithm().regionMatches(true, 0, "PBE", 0, 3))) {
+            byte[] passwdBytes;
+            if (!(key.getAlgorithm().regionMatches(true, 0, "PBE", 0, 3)) ||
+                    (passwdBytes = key.getEncoded()) == null) {
                 throw new InvalidKeyException("Missing password");
             }
             passwdChars = new char[passwdBytes.length];
             for (int i=0; i<passwdChars.length; i++) {
                 passwdChars[i] = (char) (passwdBytes[i] & 0x7f);
             }
+            Arrays.fill(passwdBytes, (byte)0x00);
         } else {
             throw new InvalidKeyException("SecretKey of PBE type required");
         }
 
-        if (((opmode == Cipher.DECRYPT_MODE) ||
-             (opmode == Cipher.UNWRAP_MODE)) &&
-            ((params == null) && ((salt == null) || (iCount == 0)))) {
-            throw new InvalidAlgorithmParameterException
-                ("Parameters missing");
-        }
+        try {
+            if (((opmode == Cipher.DECRYPT_MODE) ||
+                    (opmode == Cipher.UNWRAP_MODE)) &&
+                    ((params == null) && ((salt == null) || (iCount == 0)))) {
+                throw new InvalidAlgorithmParameterException
+                        ("Parameters missing");
+            }
 
-        if (params == null) {
-            // generate default for salt and iteration count if necessary
-            if (salt == null) {
-                salt = new byte[DEFAULT_SALT_LENGTH];
-                if (random != null) {
-                    random.nextBytes(salt);
+            if (params == null) {
+                // generate default for salt and iteration count if necessary
+                if (salt == null) {
+                    salt = new byte[DEFAULT_SALT_LENGTH];
+                    if (random != null) {
+                        random.nextBytes(salt);
+                    } else {
+                        SunJCE.getRandom().nextBytes(salt);
+                    }
+                }
+                if (iCount == 0) iCount = DEFAULT_COUNT;
+            } else if (!(params instanceof PBEParameterSpec)) {
+                throw new InvalidAlgorithmParameterException
+                        ("PBEParameterSpec type required");
+            } else {
+                PBEParameterSpec pbeParams = (PBEParameterSpec) params;
+                // make sure the parameter values are consistent
+                if (salt != null) {
+                    if (!Arrays.equals(salt, pbeParams.getSalt())) {
+                        throw new InvalidAlgorithmParameterException
+                                ("Inconsistent value of salt between key and params");
+                    }
                 } else {
-                    SunJCE.getRandom().nextBytes(salt);
+                    salt = pbeParams.getSalt();
+                }
+                if (iCount != 0) {
+                    if (iCount != pbeParams.getIterationCount()) {
+                        throw new InvalidAlgorithmParameterException
+                                ("Different iteration count between key and params");
+                    }
+                } else {
+                    iCount = pbeParams.getIterationCount();
                 }
             }
-            if (iCount == 0) iCount = DEFAULT_COUNT;
-        } else if (!(params instanceof PBEParameterSpec)) {
-            throw new InvalidAlgorithmParameterException
-                ("PBEParameterSpec type required");
-        } else {
-            PBEParameterSpec pbeParams = (PBEParameterSpec) params;
-            // make sure the parameter values are consistent
-            if (salt != null) {
-                if (!Arrays.equals(salt, pbeParams.getSalt())) {
-                    throw new InvalidAlgorithmParameterException
-                        ("Inconsistent value of salt between key and params");
-                }
-            } else {
-                salt = pbeParams.getSalt();
+            // salt is recommended to be ideally as long as the output
+            // of the hash function. However, it may be too strict to
+            // force this; so instead, we'll just require the minimum
+            // salt length to be 8-byte which is what PKCS#5 recommends
+            // and openssl does.
+            if (salt.length < 8) {
+                throw new InvalidAlgorithmParameterException
+                        ("Salt must be at least 8 bytes long");
             }
-            if (iCount != 0) {
-                if (iCount != pbeParams.getIterationCount()) {
-                    throw new InvalidAlgorithmParameterException
-                        ("Different iteration count between key and params");
-                }
-            } else {
-                iCount = pbeParams.getIterationCount();
+            if (iCount <= 0) {
+                throw new InvalidAlgorithmParameterException
+                        ("IterationCount must be a positive number");
             }
-        }
-        // salt is recommended to be ideally as long as the output
-        // of the hash function. However, it may be too strict to
-        // force this; so instead, we'll just require the minimum
-        // salt length to be 8-byte which is what PKCS#5 recommends
-        // and openssl does.
-        if (salt.length < 8) {
-            throw new InvalidAlgorithmParameterException
-                ("Salt must be at least 8 bytes long");
-        }
-        if (iCount <= 0) {
-            throw new InvalidAlgorithmParameterException
-                ("IterationCount must be a positive number");
-        }
-        byte[] derivedKey = derive(passwdChars, salt, iCount,
-                                   keySize, CIPHER_KEY);
-        SecretKey cipherKey = new SecretKeySpec(derivedKey, algo);
+            byte[] derivedKey = derive(passwdChars, salt, iCount,
+                    keySize, CIPHER_KEY);
+            SecretKey cipherKey = new SecretKeySpec(derivedKey, algo);
+
+            if (cipherImpl != null && cipherImpl instanceof ARCFOURCipher) {
+                ((ARCFOURCipher)cipherImpl).engineInit(opmode, cipherKey, random);
 
-        if (cipherImpl != null && cipherImpl instanceof ARCFOURCipher) {
-            ((ARCFOURCipher)cipherImpl).engineInit(opmode, cipherKey, random);
+            } else {
+                byte[] derivedIv = derive(passwdChars, salt, iCount, 8,
+                        CIPHER_IV);
+                IvParameterSpec ivSpec = new IvParameterSpec(derivedIv, 0, 8);
 
-        } else {
-            byte[] derivedIv = derive(passwdChars, salt, iCount, 8,
-                                  CIPHER_IV);
-            IvParameterSpec ivSpec = new IvParameterSpec(derivedIv, 0, 8);
-
-            // initialize the underlying cipher
-            cipher.init(opmode, cipherKey, ivSpec, random);
+                // initialize the underlying cipher
+                cipher.init(opmode, cipherKey, ivSpec, random);
+            }
+        } finally {
+           Arrays.fill(passwdChars, '\0');
         }
     }