提交 ef7b6b22 编写于 作者: I igerasim

8134605: Partial rework of the fix for 8081297

Reviewed-by: xuelei, coffeys, valeriep
上级 2a29d1f0
/*
* 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 final static 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;
}
}
......@@ -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);
......
......@@ -468,49 +468,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;
......@@ -538,20 +538,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());
}
......@@ -570,29 +563,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;
}
}
......
......@@ -111,18 +111,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);
......@@ -134,18 +139,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(
......
/*
* 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.
*/
......@@ -200,7 +202,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);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册