src/java.base/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java
changeset 51504 c9a3e3cac9c7
parent 47216 71c04702a3d5
equal deleted inserted replaced
51503:0265a70ea2a5 51504:c9a3e3cac9c7
   102             byte[] I = new byte[s + p];
   102             byte[] I = new byte[s + p];
   103 
   103 
   104             Arrays.fill(D, (byte)type);
   104             Arrays.fill(D, (byte)type);
   105             concat(salt, I, 0, s);
   105             concat(salt, I, 0, s);
   106             concat(passwd, I, s, p);
   106             concat(passwd, I, s, p);
       
   107             Arrays.fill(passwd, (byte) 0x00);
   107 
   108 
   108             byte[] Ai;
   109             byte[] Ai;
   109             byte[] B = new byte[v];
   110             byte[] B = new byte[v];
   110             byte[] tmp = new byte[v];
   111             byte[] tmp = new byte[v];
   111 
   112 
   266                 (javax.crypto.interfaces.PBEKey) key;
   267                 (javax.crypto.interfaces.PBEKey) key;
   267             passwdChars = pbeKey.getPassword();
   268             passwdChars = pbeKey.getPassword();
   268             salt = pbeKey.getSalt(); // maybe null if unspecified
   269             salt = pbeKey.getSalt(); // maybe null if unspecified
   269             iCount = pbeKey.getIterationCount(); // maybe 0 if unspecified
   270             iCount = pbeKey.getIterationCount(); // maybe 0 if unspecified
   270         } else if (key instanceof SecretKey) {
   271         } else if (key instanceof SecretKey) {
   271             byte[] passwdBytes = key.getEncoded();
   272             byte[] passwdBytes;
   272             if ((passwdBytes == null) ||
   273             if (!(key.getAlgorithm().regionMatches(true, 0, "PBE", 0, 3)) ||
   273                 !(key.getAlgorithm().regionMatches(true, 0, "PBE", 0, 3))) {
   274                     (passwdBytes = key.getEncoded()) == null) {
   274                 throw new InvalidKeyException("Missing password");
   275                 throw new InvalidKeyException("Missing password");
   275             }
   276             }
   276             passwdChars = new char[passwdBytes.length];
   277             passwdChars = new char[passwdBytes.length];
   277             for (int i=0; i<passwdChars.length; i++) {
   278             for (int i=0; i<passwdChars.length; i++) {
   278                 passwdChars[i] = (char) (passwdBytes[i] & 0x7f);
   279                 passwdChars[i] = (char) (passwdBytes[i] & 0x7f);
   279             }
   280             }
       
   281             Arrays.fill(passwdBytes, (byte)0x00);
   280         } else {
   282         } else {
   281             throw new InvalidKeyException("SecretKey of PBE type required");
   283             throw new InvalidKeyException("SecretKey of PBE type required");
   282         }
   284         }
   283 
   285 
   284         if (((opmode == Cipher.DECRYPT_MODE) ||
   286         try {
   285              (opmode == Cipher.UNWRAP_MODE)) &&
   287             if (((opmode == Cipher.DECRYPT_MODE) ||
   286             ((params == null) && ((salt == null) || (iCount == 0)))) {
   288                     (opmode == Cipher.UNWRAP_MODE)) &&
   287             throw new InvalidAlgorithmParameterException
   289                     ((params == null) && ((salt == null) || (iCount == 0)))) {
   288                 ("Parameters missing");
   290                 throw new InvalidAlgorithmParameterException
   289         }
   291                         ("Parameters missing");
   290 
   292             }
   291         if (params == null) {
   293 
   292             // generate default for salt and iteration count if necessary
   294             if (params == null) {
   293             if (salt == null) {
   295                 // generate default for salt and iteration count if necessary
   294                 salt = new byte[DEFAULT_SALT_LENGTH];
   296                 if (salt == null) {
   295                 if (random != null) {
   297                     salt = new byte[DEFAULT_SALT_LENGTH];
   296                     random.nextBytes(salt);
   298                     if (random != null) {
       
   299                         random.nextBytes(salt);
       
   300                     } else {
       
   301                         SunJCE.getRandom().nextBytes(salt);
       
   302                     }
       
   303                 }
       
   304                 if (iCount == 0) iCount = DEFAULT_COUNT;
       
   305             } else if (!(params instanceof PBEParameterSpec)) {
       
   306                 throw new InvalidAlgorithmParameterException
       
   307                         ("PBEParameterSpec type required");
       
   308             } else {
       
   309                 PBEParameterSpec pbeParams = (PBEParameterSpec) params;
       
   310                 // make sure the parameter values are consistent
       
   311                 if (salt != null) {
       
   312                     if (!Arrays.equals(salt, pbeParams.getSalt())) {
       
   313                         throw new InvalidAlgorithmParameterException
       
   314                                 ("Inconsistent value of salt between key and params");
       
   315                     }
   297                 } else {
   316                 } else {
   298                     SunJCE.getRandom().nextBytes(salt);
   317                     salt = pbeParams.getSalt();
   299                 }
   318                 }
   300             }
   319                 if (iCount != 0) {
   301             if (iCount == 0) iCount = DEFAULT_COUNT;
   320                     if (iCount != pbeParams.getIterationCount()) {
   302         } else if (!(params instanceof PBEParameterSpec)) {
   321                         throw new InvalidAlgorithmParameterException
   303             throw new InvalidAlgorithmParameterException
   322                                 ("Different iteration count between key and params");
   304                 ("PBEParameterSpec type required");
   323                     }
   305         } else {
   324                 } else {
   306             PBEParameterSpec pbeParams = (PBEParameterSpec) params;
   325                     iCount = pbeParams.getIterationCount();
   307             // make sure the parameter values are consistent
       
   308             if (salt != null) {
       
   309                 if (!Arrays.equals(salt, pbeParams.getSalt())) {
       
   310                     throw new InvalidAlgorithmParameterException
       
   311                         ("Inconsistent value of salt between key and params");
       
   312                 }
   326                 }
       
   327             }
       
   328             // salt is recommended to be ideally as long as the output
       
   329             // of the hash function. However, it may be too strict to
       
   330             // force this; so instead, we'll just require the minimum
       
   331             // salt length to be 8-byte which is what PKCS#5 recommends
       
   332             // and openssl does.
       
   333             if (salt.length < 8) {
       
   334                 throw new InvalidAlgorithmParameterException
       
   335                         ("Salt must be at least 8 bytes long");
       
   336             }
       
   337             if (iCount <= 0) {
       
   338                 throw new InvalidAlgorithmParameterException
       
   339                         ("IterationCount must be a positive number");
       
   340             }
       
   341             byte[] derivedKey = derive(passwdChars, salt, iCount,
       
   342                     keySize, CIPHER_KEY);
       
   343             SecretKey cipherKey = new SecretKeySpec(derivedKey, algo);
       
   344 
       
   345             if (cipherImpl != null && cipherImpl instanceof ARCFOURCipher) {
       
   346                 ((ARCFOURCipher)cipherImpl).engineInit(opmode, cipherKey, random);
       
   347 
   313             } else {
   348             } else {
   314                 salt = pbeParams.getSalt();
   349                 byte[] derivedIv = derive(passwdChars, salt, iCount, 8,
   315             }
   350                         CIPHER_IV);
   316             if (iCount != 0) {
   351                 IvParameterSpec ivSpec = new IvParameterSpec(derivedIv, 0, 8);
   317                 if (iCount != pbeParams.getIterationCount()) {
   352 
   318                     throw new InvalidAlgorithmParameterException
   353                 // initialize the underlying cipher
   319                         ("Different iteration count between key and params");
   354                 cipher.init(opmode, cipherKey, ivSpec, random);
   320                 }
   355             }
   321             } else {
   356         } finally {
   322                 iCount = pbeParams.getIterationCount();
   357            Arrays.fill(passwdChars, '\0');
   323             }
       
   324         }
       
   325         // salt is recommended to be ideally as long as the output
       
   326         // of the hash function. However, it may be too strict to
       
   327         // force this; so instead, we'll just require the minimum
       
   328         // salt length to be 8-byte which is what PKCS#5 recommends
       
   329         // and openssl does.
       
   330         if (salt.length < 8) {
       
   331             throw new InvalidAlgorithmParameterException
       
   332                 ("Salt must be at least 8 bytes long");
       
   333         }
       
   334         if (iCount <= 0) {
       
   335             throw new InvalidAlgorithmParameterException
       
   336                 ("IterationCount must be a positive number");
       
   337         }
       
   338         byte[] derivedKey = derive(passwdChars, salt, iCount,
       
   339                                    keySize, CIPHER_KEY);
       
   340         SecretKey cipherKey = new SecretKeySpec(derivedKey, algo);
       
   341 
       
   342         if (cipherImpl != null && cipherImpl instanceof ARCFOURCipher) {
       
   343             ((ARCFOURCipher)cipherImpl).engineInit(opmode, cipherKey, random);
       
   344 
       
   345         } else {
       
   346             byte[] derivedIv = derive(passwdChars, salt, iCount, 8,
       
   347                                   CIPHER_IV);
       
   348             IvParameterSpec ivSpec = new IvParameterSpec(derivedIv, 0, 8);
       
   349 
       
   350             // initialize the underlying cipher
       
   351             cipher.init(opmode, cipherKey, ivSpec, random);
       
   352         }
   358         }
   353     }
   359     }
   354 
   360 
   355     void implInit(int opmode, Key key, AlgorithmParameters params,
   361     void implInit(int opmode, Key key, AlgorithmParameters params,
   356                   SecureRandom random)
   362                   SecureRandom random)