8134605: Partial rework of the fix for 8081297
Reviewed-by: xuelei, coffeys, valeriep
This commit is contained in:
parent
31abfb24a9
commit
57e9de3136
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,12 +41,6 @@ public final class JCAUtil {
|
||||
// no instantiation
|
||||
}
|
||||
|
||||
// lock to use for synchronization
|
||||
private static final Object LOCK = JCAUtil.class;
|
||||
|
||||
// cached SecureRandom instance
|
||||
private static volatile SecureRandom secureRandom;
|
||||
|
||||
// size of the temporary arrays we use. Should fit into the CPU's 1st
|
||||
// level cache and could be adjusted based on the platform
|
||||
private static final int ARRAY_SIZE = 4096;
|
||||
@ -60,26 +54,19 @@ public final class JCAUtil {
|
||||
return Math.min(ARRAY_SIZE, totalSize);
|
||||
}
|
||||
|
||||
// cached SecureRandom instance
|
||||
private static class CachedSecureRandomHolder {
|
||||
public static SecureRandom instance = new SecureRandom();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a SecureRandom instance. This method should me used by JDK
|
||||
* Get a SecureRandom instance. This method should be used by JDK
|
||||
* internal code in favor of calling "new SecureRandom()". That needs to
|
||||
* iterate through the provider table to find the default SecureRandom
|
||||
* implementation, which is fairly inefficient.
|
||||
*/
|
||||
public static SecureRandom getSecureRandom() {
|
||||
// we use double checked locking to minimize synchronization
|
||||
// works because we use a volatile reference
|
||||
SecureRandom r = secureRandom;
|
||||
if (r == null) {
|
||||
synchronized (LOCK) {
|
||||
r = secureRandom;
|
||||
if (r == null) {
|
||||
r = new SecureRandom();
|
||||
secureRandom = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
return CachedSecureRandomHolder.instance;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -113,18 +113,23 @@ final class RSAClientKeyExchange extends HandshakeMessage {
|
||||
}
|
||||
}
|
||||
|
||||
boolean needFailover = false;
|
||||
byte[] encoded = null;
|
||||
try {
|
||||
Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1);
|
||||
needFailover = !KeyUtil.isOracleJCEProvider(
|
||||
cipher.getProvider().getName());
|
||||
boolean needFailover = !KeyUtil.isOracleJCEProvider(
|
||||
cipher.getProvider().getName());
|
||||
if (needFailover) {
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
encoded = cipher.doFinal(encrypted);
|
||||
boolean failed = false;
|
||||
try {
|
||||
encoded = cipher.doFinal(encrypted);
|
||||
} catch (BadPaddingException bpe) {
|
||||
// Note: encoded == null
|
||||
failed = true;
|
||||
}
|
||||
encoded = KeyUtil.checkTlsPreMasterSecretKey(
|
||||
maxVersion.v, currentVersion.v,
|
||||
generator, encoded, false);
|
||||
generator, encoded, failed);
|
||||
preMaster = generatePreMasterSecret(
|
||||
maxVersion.v, currentVersion.v,
|
||||
encoded, generator);
|
||||
@ -136,18 +141,6 @@ final class RSAClientKeyExchange extends HandshakeMessage {
|
||||
preMaster = (SecretKey)cipher.unwrap(encrypted,
|
||||
"TlsRsaPremasterSecret", Cipher.SECRET_KEY);
|
||||
}
|
||||
} catch (BadPaddingException bpe) {
|
||||
if (needFailover) {
|
||||
encoded = KeyUtil.checkTlsPreMasterSecretKey(
|
||||
maxVersion.v, currentVersion.v,
|
||||
generator, null, false);
|
||||
preMaster = generatePreMasterSecret(
|
||||
maxVersion.v, currentVersion.v,
|
||||
encoded, generator);
|
||||
} else {
|
||||
// Otherwise, unlikely to happen
|
||||
throw new RuntimeException("Unexpected exception", bpe);
|
||||
}
|
||||
} catch (InvalidKeyException ibk) {
|
||||
// the message is too big to process with RSA
|
||||
throw new SSLProtocolException(
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -41,6 +41,8 @@ import javax.crypto.spec.DHParameterSpec;
|
||||
import javax.crypto.spec.DHPublicKeySpec;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import sun.security.jca.JCAUtil;
|
||||
|
||||
/**
|
||||
* A utility class to get key length, valiate keys, etc.
|
||||
*/
|
||||
@ -201,7 +203,7 @@ public final class KeyUtil {
|
||||
byte[] encoded, boolean isFailOver) {
|
||||
|
||||
if (random == null) {
|
||||
random = new SecureRandom();
|
||||
random = JCAUtil.getSecureRandom();
|
||||
}
|
||||
byte[] replacer = new byte[48];
|
||||
random.nextBytes(replacer);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -35,6 +35,7 @@ import javax.crypto.*;
|
||||
import javax.crypto.spec.*;
|
||||
|
||||
import sun.nio.ch.DirectBuffer;
|
||||
import sun.security.jca.JCAUtil;
|
||||
import sun.security.pkcs11.wrapper.*;
|
||||
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
|
||||
|
||||
@ -379,7 +380,7 @@ final class P11Cipher extends CipherSpi {
|
||||
}
|
||||
// generate random IV
|
||||
if (random == null) {
|
||||
random = new SecureRandom();
|
||||
random = JCAUtil.getSecureRandom();
|
||||
}
|
||||
iv = new byte[blockSize];
|
||||
random.nextBytes(iv);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -470,49 +470,49 @@ final class P11RSACipher extends CipherSpi {
|
||||
algorithm.equals("TlsRsaPremasterSecret");
|
||||
Exception failover = null;
|
||||
|
||||
SecureRandom secureRandom = random;
|
||||
if (secureRandom == null && isTlsRsaPremasterSecret) {
|
||||
secureRandom = new SecureRandom();
|
||||
}
|
||||
|
||||
// Should C_Unwrap be preferred for non-TLS RSA premaster secret?
|
||||
if (token.supportsRawSecretKeyImport()) {
|
||||
// XXX implement unwrap using C_Unwrap() for all keys
|
||||
implInit(Cipher.DECRYPT_MODE, p11Key);
|
||||
if (wrappedKey.length > maxInputSize) {
|
||||
throw new InvalidKeyException("Key is too long for unwrapping");
|
||||
}
|
||||
|
||||
byte[] encoded = null;
|
||||
implUpdate(wrappedKey, 0, wrappedKey.length);
|
||||
try {
|
||||
encoded = doFinal();
|
||||
} catch (BadPaddingException e) {
|
||||
if (isTlsRsaPremasterSecret) {
|
||||
failover = e;
|
||||
} else {
|
||||
if (wrappedKey.length > maxInputSize) {
|
||||
throw new InvalidKeyException("Key is too long for unwrapping");
|
||||
}
|
||||
|
||||
byte[] encoded = null;
|
||||
implUpdate(wrappedKey, 0, wrappedKey.length);
|
||||
try {
|
||||
encoded = doFinal();
|
||||
} catch (BadPaddingException e) {
|
||||
if (isTlsRsaPremasterSecret) {
|
||||
failover = e;
|
||||
} else {
|
||||
throw new InvalidKeyException("Unwrapping failed", e);
|
||||
}
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
// should not occur, handled with length check above
|
||||
throw new InvalidKeyException("Unwrapping failed", e);
|
||||
}
|
||||
} catch (IllegalBlockSizeException e) {
|
||||
// should not occur, handled with length check above
|
||||
throw new InvalidKeyException("Unwrapping failed", e);
|
||||
}
|
||||
|
||||
if (isTlsRsaPremasterSecret) {
|
||||
if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
|
||||
throw new IllegalStateException(
|
||||
"No TlsRsaPremasterSecretParameterSpec specified");
|
||||
if (isTlsRsaPremasterSecret) {
|
||||
if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
|
||||
throw new IllegalStateException(
|
||||
"No TlsRsaPremasterSecretParameterSpec specified");
|
||||
}
|
||||
|
||||
// polish the TLS premaster secret
|
||||
TlsRsaPremasterSecretParameterSpec psps =
|
||||
(TlsRsaPremasterSecretParameterSpec)spec;
|
||||
encoded = KeyUtil.checkTlsPreMasterSecretKey(
|
||||
psps.getClientVersion(), psps.getServerVersion(),
|
||||
random, encoded, (failover != null));
|
||||
}
|
||||
|
||||
// polish the TLS premaster secret
|
||||
TlsRsaPremasterSecretParameterSpec psps =
|
||||
(TlsRsaPremasterSecretParameterSpec)spec;
|
||||
encoded = KeyUtil.checkTlsPreMasterSecretKey(
|
||||
psps.getClientVersion(), psps.getServerVersion(),
|
||||
secureRandom, encoded, (failover != null));
|
||||
return ConstructKeys.constructKey(encoded, algorithm, type);
|
||||
} finally {
|
||||
// Restore original mode
|
||||
implInit(Cipher.UNWRAP_MODE, p11Key);
|
||||
}
|
||||
|
||||
return ConstructKeys.constructKey(encoded, algorithm, type);
|
||||
} else {
|
||||
Session s = null;
|
||||
SecretKey secretKey = null;
|
||||
@ -540,20 +540,13 @@ final class P11RSACipher extends CipherSpi {
|
||||
}
|
||||
|
||||
if (isTlsRsaPremasterSecret) {
|
||||
byte[] replacer = new byte[48];
|
||||
if (failover == null) {
|
||||
// Does smart compiler dispose this operation?
|
||||
secureRandom.nextBytes(replacer);
|
||||
}
|
||||
|
||||
TlsRsaPremasterSecretParameterSpec psps =
|
||||
(TlsRsaPremasterSecretParameterSpec)spec;
|
||||
|
||||
// Please use the tricky failover and replacer byte array
|
||||
// as the parameters so that smart compiler won't dispose
|
||||
// the unused variable .
|
||||
// Please use the tricky failover as the parameter so that
|
||||
// smart compiler won't dispose the unused variable.
|
||||
secretKey = polishPreMasterSecretKey(token, s,
|
||||
failover, replacer, secretKey,
|
||||
failover, secretKey,
|
||||
psps.getClientVersion(), psps.getServerVersion());
|
||||
}
|
||||
|
||||
@ -572,29 +565,27 @@ final class P11RSACipher extends CipherSpi {
|
||||
|
||||
private static SecretKey polishPreMasterSecretKey(
|
||||
Token token, Session session,
|
||||
Exception failover, byte[] replacer, SecretKey secretKey,
|
||||
Exception failover, SecretKey unwrappedKey,
|
||||
int clientVersion, int serverVersion) {
|
||||
|
||||
if (failover != null) {
|
||||
CK_VERSION version = new CK_VERSION(
|
||||
(clientVersion >>> 8) & 0xFF, clientVersion & 0xFF);
|
||||
try {
|
||||
CK_ATTRIBUTE[] attributes = token.getAttributes(
|
||||
O_GENERATE, CKO_SECRET_KEY,
|
||||
CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
|
||||
long keyID = token.p11.C_GenerateKey(session.id(),
|
||||
// new CK_MECHANISM(CKM_TLS_PRE_MASTER_KEY_GEN, version),
|
||||
new CK_MECHANISM(CKM_SSL3_PRE_MASTER_KEY_GEN, version),
|
||||
attributes);
|
||||
return P11Key.secretKey(session,
|
||||
keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
|
||||
} catch (PKCS11Exception e) {
|
||||
throw new ProviderException(
|
||||
"Could not generate premaster secret", e);
|
||||
}
|
||||
SecretKey newKey;
|
||||
CK_VERSION version = new CK_VERSION(
|
||||
(clientVersion >>> 8) & 0xFF, clientVersion & 0xFF);
|
||||
try {
|
||||
CK_ATTRIBUTE[] attributes = token.getAttributes(
|
||||
O_GENERATE, CKO_SECRET_KEY,
|
||||
CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]);
|
||||
long keyID = token.p11.C_GenerateKey(session.id(),
|
||||
new CK_MECHANISM(CKM_SSL3_PRE_MASTER_KEY_GEN, version),
|
||||
attributes);
|
||||
newKey = P11Key.secretKey(session,
|
||||
keyID, "TlsRsaPremasterSecret", 48 << 3, attributes);
|
||||
} catch (PKCS11Exception e) {
|
||||
throw new ProviderException(
|
||||
"Could not generate premaster secret", e);
|
||||
}
|
||||
|
||||
return secretKey;
|
||||
return (failover == null) ? unwrappedKey : newKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ import javax.crypto.*;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
import sun.security.jca.JCAUtil;
|
||||
|
||||
/**
|
||||
* Cipher wrapper class utilizing ucrypto APIs. This class currently supports
|
||||
* - AES/ECB/NOPADDING
|
||||
@ -288,7 +290,10 @@ class NativeCipher extends CipherSpi {
|
||||
if (encrypt) {
|
||||
// generate IV if none supplied for encryption
|
||||
ivBytes = new byte[blockSize];
|
||||
new SecureRandom().nextBytes(ivBytes);
|
||||
if (random == null) {
|
||||
random = JCAUtil.getSecureRandom();
|
||||
}
|
||||
random.nextBytes(ivBytes);
|
||||
} else {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Parameters required for decryption");
|
||||
|
@ -36,6 +36,8 @@ import javax.crypto.*;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
|
||||
import sun.security.jca.JCAUtil;
|
||||
|
||||
/**
|
||||
* Cipher wrapper class utilizing ucrypto APIs. This class currently supports
|
||||
* - AES/GCM/NoPADDING
|
||||
@ -200,7 +202,10 @@ class NativeGCMCipher extends NativeCipher {
|
||||
|
||||
// generate IV if none supplied for encryption
|
||||
ivBytes = new byte[blockSize];
|
||||
new SecureRandom().nextBytes(ivBytes);
|
||||
if (random == null) {
|
||||
random = JCAUtil.getSecureRandom();
|
||||
}
|
||||
random.nextBytes(ivBytes);
|
||||
} else {
|
||||
throw new InvalidAlgorithmParameterException("Parameters required for decryption");
|
||||
}
|
||||
|
@ -63,6 +63,7 @@ import javax.crypto.ShortBufferException;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
|
||||
import sun.security.jca.JCAUtil;
|
||||
import sun.security.util.KeyUtil;
|
||||
|
||||
/**
|
||||
@ -201,6 +202,9 @@ public class NativeRSACipher extends CipherSpi {
|
||||
"No Parameters can be specified");
|
||||
}
|
||||
spec = params;
|
||||
if (random == null) {
|
||||
random = JCAUtil.getSecureRandom();
|
||||
}
|
||||
this.random = random; // for TLS RSA premaster secret
|
||||
}
|
||||
boolean doEncrypt = (opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.WRAP_MODE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user