--- a/jdk/src/share/classes/com/sun/crypto/provider/RSACipher.java Wed Apr 09 17:19:19 2014 +0800
+++ b/jdk/src/share/classes/com/sun/crypto/provider/RSACipher.java Wed Apr 09 12:49:51 2014 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, 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
@@ -39,6 +39,8 @@
import sun.security.rsa.*;
import sun.security.jca.Providers;
+import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
+import sun.security.util.KeyUtil;
/**
* RSA cipher implementation. Supports RSA en/decryption and signing/verifying
@@ -91,8 +93,8 @@
// padding object
private RSAPadding padding;
- // cipher parameter for OAEP padding
- private OAEPParameterSpec spec = null;
+ // cipher parameter for OAEP padding and TLS RSA premaster secret
+ private AlgorithmParameterSpec spec = null;
// buffer for the data
private byte[] buffer;
@@ -110,6 +112,9 @@
// hash algorithm for OAEP
private String oaepHashAlgorithm = "SHA-1";
+ // the source of randomness
+ private SecureRandom random;
+
public RSACipher() {
paddingType = PAD_PKCS1;
}
@@ -175,7 +180,7 @@
// see JCE spec
protected AlgorithmParameters engineGetParameters() {
- if (spec != null) {
+ if (spec != null && spec instanceof OAEPParameterSpec) {
try {
AlgorithmParameters params =
AlgorithmParameters.getInstance("OAEP",
@@ -276,8 +281,13 @@
buffer = new byte[n];
} else if (paddingType == PAD_PKCS1) {
if (params != null) {
- throw new InvalidAlgorithmParameterException
- ("Parameters not supported");
+ if (!(params instanceof TlsRsaPremasterSecretParameterSpec)) {
+ throw new InvalidAlgorithmParameterException(
+ "Parameters not supported");
+ }
+
+ spec = params;
+ this.random = random; // for TLS RSA premaster secret
}
int blockType = (mode <= MODE_DECRYPT) ? RSAPadding.PAD_BLOCKTYPE_2
: RSAPadding.PAD_BLOCKTYPE_1;
@@ -293,19 +303,18 @@
throw new InvalidKeyException
("OAEP cannot be used to sign or verify signatures");
}
- OAEPParameterSpec myParams;
if (params != null) {
if (!(params instanceof OAEPParameterSpec)) {
throw new InvalidAlgorithmParameterException
("Wrong Parameters for OAEP Padding");
}
- myParams = (OAEPParameterSpec) params;
+ spec = params;
} else {
- myParams = new OAEPParameterSpec(oaepHashAlgorithm, "MGF1",
+ spec = new OAEPParameterSpec(oaepHashAlgorithm, "MGF1",
MGF1ParameterSpec.SHA1, PSource.PSpecified.DEFAULT);
}
padding = RSAPadding.getInstance(RSAPadding.PAD_OAEP_MGF1, n,
- random, myParams);
+ random, (OAEPParameterSpec)spec);
if (encrypt) {
int k = padding.getMaxDataSize();
buffer = new byte[k];
@@ -420,17 +429,40 @@
if (wrappedKey.length > buffer.length) {
throw new InvalidKeyException("Key is too long for unwrapping");
}
+
+ boolean isTlsRsaPremasterSecret =
+ algorithm.equals("TlsRsaPremasterSecret");
+ Exception failover = null;
+ byte[] encoded = null;
+
update(wrappedKey, 0, wrappedKey.length);
try {
- byte[] encoded = doFinal();
- return ConstructKeys.constructKey(encoded, algorithm, type);
+ encoded = doFinal();
} catch (BadPaddingException e) {
- // should not occur
- throw new InvalidKeyException("Unwrapping failed", 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);
}
+
+ if (isTlsRsaPremasterSecret) {
+ if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) {
+ throw new IllegalStateException(
+ "No TlsRsaPremasterSecretParameterSpec specified");
+ }
+
+ // polish the TLS premaster secret
+ encoded = KeyUtil.checkTlsPreMasterSecretKey(
+ ((TlsRsaPremasterSecretParameterSpec)spec).getClientVersion(),
+ ((TlsRsaPremasterSecretParameterSpec)spec).getServerVersion(),
+ random, encoded, (failover != null));
+ }
+
+ return ConstructKeys.constructKey(encoded, algorithm, type);
}
// see JCE spec
@@ -438,5 +470,4 @@
RSAKey rsaKey = RSAKeyFactory.toRSAKey(key);
return rsaKey.getModulus().bitLength();
}
-
}