diff options
Diffstat (limited to 'java/openjdk6/files/icedtea/security/7186286.patch')
-rw-r--r-- | java/openjdk6/files/icedtea/security/7186286.patch | 552 |
1 files changed, 552 insertions, 0 deletions
diff --git a/java/openjdk6/files/icedtea/security/7186286.patch b/java/openjdk6/files/icedtea/security/7186286.patch new file mode 100644 index 000000000000..cc5adc1a3cf9 --- /dev/null +++ b/java/openjdk6/files/icedtea/security/7186286.patch @@ -0,0 +1,552 @@ +# HG changeset patch +# User xuelei +# Date 1343546404 25200 +# Node ID a6294da5a21f609b67a0d4d216028dda9f56e689 +# Parent 88243aa6e67b6b84ff529ccdfd3b476410f60057 +7186286: TLS implementation to better adhere to RFC +Summary: also reviewed by Alexander Fomin <Alexander.Fomin@Oracle.COM>, Andrew Gross<Andrew.Gross@Oracle.COM>, Sean Coffey<Sean.Coffey@Oracle.COM> +Reviewed-by: valeriep, wetmore + +diff --git a/src/share/classes/sun/security/pkcs11/P11Cipher.java b/src/share/classes/sun/security/pkcs11/P11Cipher.java +--- jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java ++++ jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2003, 2012, 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 +@@ -650,7 +650,7 @@ + // see JCE spec + protected int engineGetKeySize(Key key) throws InvalidKeyException { + int n = P11SecretKeyFactory.convertKey +- (token, key, keyAlgorithm).keyLength(); ++ (token, key, keyAlgorithm).length(); + return n; + } + } +diff --git a/src/share/classes/sun/security/pkcs11/P11Key.java b/src/share/classes/sun/security/pkcs11/P11Key.java +--- jdk/src/share/classes/sun/security/pkcs11/P11Key.java ++++ jdk/src/share/classes/sun/security/pkcs11/P11Key.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2003, 2012, 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 +@@ -46,6 +46,7 @@ + import static sun.security.pkcs11.wrapper.PKCS11Constants.*; + + import sun.security.util.DerValue; ++import sun.security.util.Length; + + /** + * Key implementation classes. +@@ -61,7 +62,7 @@ + * @author Andreas Sterbenz + * @since 1.5 + */ +-abstract class P11Key implements Key { ++abstract class P11Key implements Key, Length { + + private final static String PUBLIC = "public"; + private final static String PRIVATE = "private"; +@@ -212,7 +213,11 @@ + return s1; + } + +- int keyLength() { ++ /** ++ * Return bit length of the key. ++ */ ++ @Override ++ public int length() { + return keyLength; + } + +diff --git a/src/share/classes/sun/security/pkcs11/P11RSACipher.java b/src/share/classes/sun/security/pkcs11/P11RSACipher.java +--- jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java ++++ jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2003, 2012, 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 +@@ -201,7 +201,7 @@ + } else { + throw new InvalidKeyException("Unknown key type: " + p11Key); + } +- int n = (p11Key.keyLength() + 7) >> 3; ++ int n = (p11Key.length() + 7) >> 3; + outputSize = n; + buffer = new byte[n]; + maxInputSize = encrypt ? (n - PKCS1_MIN_PADDING_LENGTH) : n; +@@ -458,7 +458,7 @@ + + // see JCE spec + protected int engineGetKeySize(Key key) throws InvalidKeyException { +- int n = P11KeyFactory.convertKey(token, key, algorithm).keyLength(); ++ int n = P11KeyFactory.convertKey(token, key, algorithm).length(); + return n; + } + } +diff --git a/src/share/classes/sun/security/pkcs11/P11Signature.java b/src/share/classes/sun/security/pkcs11/P11Signature.java +--- jdk/src/share/classes/sun/security/pkcs11/P11Signature.java ++++ jdk/src/share/classes/sun/security/pkcs11/P11Signature.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 2003, 2012, 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 +@@ -274,7 +274,7 @@ + if (keyAlgorithm.equals("DSA")) { + signature = new byte[40]; + } else { +- signature = new byte[(p11Key.keyLength() + 7) >> 3]; ++ signature = new byte[(p11Key.length() + 7) >> 3]; + } + if (type == T_UPDATE) { + token.p11.C_VerifyFinal(session.id(), signature); +@@ -359,7 +359,7 @@ + if (keyAlgorithm.equals("RSA") && publicKey != p11Key) { + int keyLen; + if (publicKey instanceof P11Key) { +- keyLen = ((P11Key) publicKey).keyLength(); ++ keyLen = ((P11Key) publicKey).length(); + } else { + keyLen = ((RSAKey) publicKey).getModulus().bitLength(); + } +@@ -620,7 +620,7 @@ + + private byte[] pkcs1Pad(byte[] data) { + try { +- int len = (p11Key.keyLength() + 7) >> 3; ++ int len = (p11Key.length() + 7) >> 3; + RSAPadding padding = RSAPadding.getInstance + (RSAPadding.PAD_BLOCKTYPE_1, len); + byte[] padded = padding.pad(data); +diff --git a/src/share/classes/sun/security/ssl/HandshakeInStream.java b/src/share/classes/sun/security/ssl/HandshakeInStream.java +--- jdk/src/share/classes/sun/security/ssl/HandshakeInStream.java ++++ jdk/src/share/classes/sun/security/ssl/HandshakeInStream.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 2012, 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 +@@ -190,6 +190,7 @@ + + byte[] getBytes8() throws IOException { + int len = getInt8(); ++ verifyLength(len); + byte b[] = new byte[len]; + + read(b, 0, len); +@@ -198,6 +199,7 @@ + + byte[] getBytes16() throws IOException { + int len = getInt16(); ++ verifyLength(len); + byte b[] = new byte[len]; + + read(b, 0, len); +@@ -206,10 +208,19 @@ + + byte[] getBytes24() throws IOException { + int len = getInt24(); ++ verifyLength(len); + byte b[] = new byte[len]; + + read(b, 0, len); + return b; + } + ++ // Is a length greater than available bytes in the record? ++ private void verifyLength(int len) throws SSLException { ++ if (len > available()) { ++ throw new SSLException( ++ "Not enough data to fill declared vector size"); ++ } ++ } ++ + } +diff --git a/src/share/classes/sun/security/ssl/Handshaker.java b/src/share/classes/sun/security/ssl/Handshaker.java +--- jdk/src/share/classes/sun/security/ssl/Handshaker.java ++++ jdk/src/share/classes/sun/security/ssl/Handshaker.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 2012, 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 +@@ -776,9 +776,9 @@ + if (debug != null && Debug.isOn("handshake")) { + System.out.println("RSA master secret generation error:"); + e.printStackTrace(System.out); +- System.out.println("Generating new random premaster secret"); + } +- preMasterSecret = RSAClientKeyExchange.generateDummySecret(protocolVersion); ++ preMasterSecret = ++ RSAClientKeyExchange.generateDummySecret(protocolVersion); + // recursive call with new premaster secret + return calculateMasterSecret(preMasterSecret, null); + } +@@ -821,9 +821,9 @@ + System.out.println("RSA PreMasterSecret version error: expected" + + protocolVersion + " or " + requestedVersion + ", decrypted: " + + premasterVersion); +- System.out.println("Generating new random premaster secret"); + } +- preMasterSecret = RSAClientKeyExchange.generateDummySecret(protocolVersion); ++ preMasterSecret = ++ RSAClientKeyExchange.generateDummySecret(protocolVersion); + // recursive call with new premaster secret + return calculateMasterSecret(preMasterSecret, null); + } +diff --git a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java +--- jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java ++++ jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 2012, 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 +@@ -36,6 +36,7 @@ + import javax.net.ssl.*; + + import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; ++import sun.security.util.KeyLength; + + /** + * This is the client key exchange message (CLIENT --> SERVER) used with +@@ -85,7 +86,8 @@ + * it, using its RSA private key. Result is the same size as the + * server's public key, and uses PKCS #1 block format 02. + */ +- RSAClientKeyExchange(ProtocolVersion protocolVersion, ProtocolVersion maxVersion, ++ RSAClientKeyExchange(ProtocolVersion protocolVersion, ++ ProtocolVersion maxVersion, + SecureRandom generator, PublicKey publicKey) throws IOException { + if (publicKey.getAlgorithm().equals("RSA") == false) { + throw new SSLKeyException("Public key not of type RSA"); +@@ -120,7 +122,8 @@ + * Server gets the PKCS #1 (block format 02) data, decrypts + * it with its private key. + */ +- RSAClientKeyExchange(ProtocolVersion currentVersion, HandshakeInStream input, ++ RSAClientKeyExchange(ProtocolVersion currentVersion, ++ ProtocolVersion maxVersion, HandshakeInStream input, + int messageSize, PrivateKey privateKey) throws IOException { + + if (privateKey.getAlgorithm().equals("RSA") == false) { +@@ -143,28 +146,119 @@ + cipher.init(Cipher.UNWRAP_MODE, privateKey); + preMaster = (SecretKey)cipher.unwrap(encrypted, + "TlsRsaPremasterSecret", Cipher.SECRET_KEY); ++ ++ // polish the premaster secret ++ preMaster = polishPreMasterSecretKey( ++ currentVersion, maxVersion, preMaster, null); + } catch (Exception e) { +- /* +- * Bogus decrypted ClientKeyExchange? If so, conjure a +- * a random preMaster secret that will fail later during +- * Finished message processing. This is a countermeasure against +- * the "interactive RSA PKCS#1 encryption envelop attack" reported +- * in June 1998. Preserving the executation path will +- * mitigate timing attacks and force consistent error handling +- * that will prevent an attacking client from differentiating +- * different kinds of decrypted ClientKeyExchange bogosities. +- */ +- if (debug != null && Debug.isOn("handshake")) { +- System.out.println("Error decrypting premaster secret:"); +- e.printStackTrace(System.out); +- System.out.println("Generating random secret"); ++ // polish the premaster secret ++ preMaster = polishPreMasterSecretKey( ++ currentVersion, maxVersion, preMaster, e); ++ } ++ } ++ ++ /** ++ * To avoid vulnerabilities described by section 7.4.7.1, RFC 5246, ++ * treating incorrectly formatted message blocks and/or mismatched ++ * version numbers in a manner indistinguishable from correctly ++ * formatted RSA blocks. ++ * ++ * RFC 5246 describes the approach as : ++ * ++ * 1. Generate a string R of 46 random bytes ++ * ++ * 2. Decrypt the message to recover the plaintext M ++ * ++ * 3. If the PKCS#1 padding is not correct, or the length of message ++ * M is not exactly 48 bytes: ++ * pre_master_secret = ClientHello.client_version || R ++ * else If ClientHello.client_version <= TLS 1.0, and version ++ * number check is explicitly disabled: ++ * pre_master_secret = M ++ * else: ++ * pre_master_secret = ClientHello.client_version || M[2..47] ++ * ++ * Note that although TLS 1.2 is not supported in this release, we still ++ * want to make use of the above approach to provide better protection. ++ */ ++ private SecretKey polishPreMasterSecretKey( ++ ProtocolVersion currentVersion, ProtocolVersion clientHelloVersion, ++ SecretKey secretKey, Exception failoverException) { ++ ++ if (failoverException == null && secretKey != null) { ++ // check the length ++ byte[] encoded = secretKey.getEncoded(); ++ if (encoded == null) { // unable to get the encoded key ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println( ++ "unable to get the plaintext of the premaster secret"); ++ } ++ ++ int keySize = KeyLength.getKeySize(secretKey); ++ if (keySize > 0 && keySize != 384) { // 384 = 48 * 8 ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println( ++ "incorrect length of premaster secret: " + ++ (keySize/8)); ++ } ++ ++ return generateDummySecret(currentVersion); ++ } ++ ++ // The key size is exactly 48 bytes or not accessible. ++ // ++ // Conservatively, pass the checking to master secret ++ // calculation. ++ return secretKey; ++ } else if (encoded.length == 48) { ++ // check the version ++ if (clientHelloVersion.major == encoded[0] && ++ clientHelloVersion.minor == encoded[1]) { ++ ++ return secretKey; ++ } else if (clientHelloVersion.v <= ProtocolVersion.TLS10.v && ++ currentVersion.major == encoded[0] && ++ currentVersion.minor == encoded[1]) { ++ /* ++ * For compatibility, we maintain the behavior that the ++ * version in pre_master_secret can be the negotiated ++ * version for TLS v1.0 and SSL v3.0. ++ */ ++ return secretKey; ++ } ++ ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println("Mismatching Protocol Versions, " + ++ "ClientHello.client_version is " + clientHelloVersion + ++ ", while PreMasterSecret.client_version is " + ++ ProtocolVersion.valueOf(encoded[0], encoded[1])); ++ } ++ return generateDummySecret(currentVersion); ++ } else { ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println( ++ "incorrect length of premaster secret: " + ++ encoded.length); ++ } ++ return generateDummySecret(currentVersion); + } +- preMaster = generateDummySecret(currentVersion); + } ++ ++ if (debug != null && Debug.isOn("handshake") && ++ failoverException != null) { ++ System.out.println("Error decrypting premaster secret:"); ++ failoverException.printStackTrace(System.out); ++ } ++ ++ return generateDummySecret(currentVersion); + } + + // generate a premaster secret with the specified version number + static SecretKey generateDummySecret(ProtocolVersion version) { ++ if (debug != null && Debug.isOn("handshake")) { ++ System.out.println("Generating a random fake premaster secret"); ++ } ++ + try { + KeyGenerator kg = + JsseJce.getKeyGenerator("SunTlsRsaPremasterSecret"); +diff --git a/src/share/classes/sun/security/ssl/ServerHandshaker.java b/src/share/classes/sun/security/ssl/ServerHandshaker.java +--- jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java ++++ jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 2012, 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 +@@ -190,8 +190,9 @@ + * temporary one used for non-export or signing-only + * certificates/keys. + */ +- RSAClientKeyExchange pms = new RSAClientKeyExchange +- (protocolVersion, input, message_len, privateKey); ++ RSAClientKeyExchange pms = new RSAClientKeyExchange( ++ protocolVersion, clientRequestedVersion, ++ input, message_len, privateKey); + preMasterSecret = this.clientKeyExchange(pms); + break; + case K_KRB5: +diff --git a/src/share/classes/sun/security/util/KeyLength.java b/src/share/classes/sun/security/util/KeyLength.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/security/util/KeyLength.java +@@ -0,0 +1,91 @@ ++/* ++ * Copyright (c) 2012, 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 ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++package sun.security.util; ++ ++import java.security.Key; ++import java.security.PrivilegedAction; ++import java.security.AccessController; ++import java.security.interfaces.ECKey; ++import java.security.interfaces.RSAKey; ++import java.security.interfaces.DSAKey; ++import javax.crypto.SecretKey; ++import javax.crypto.interfaces.DHKey; ++ ++/** ++ * A utility class to get key length ++ */ ++public final class KeyLength { ++ ++ /** ++ * Returns the key size of the given key object in bits. ++ * ++ * @param key the key object, cannot be null ++ * @return the key size of the given key object in bits, or -1 if the ++ * key size is not accessible ++ */ ++ final public static int getKeySize(Key key) { ++ int size = -1; ++ ++ if (key instanceof Length) { ++ try { ++ Length ruler = (Length)key; ++ size = ruler.length(); ++ } catch (UnsupportedOperationException usoe) { ++ // ignore the exception ++ } ++ ++ if (size >= 0) { ++ return size; ++ } ++ } ++ ++ // try to parse the length from key specification ++ if (key instanceof SecretKey) { ++ SecretKey sk = (SecretKey)key; ++ String format = sk.getFormat(); ++ if ("RAW".equals(format) && sk.getEncoded() != null) { ++ size = (sk.getEncoded().length * 8); ++ } // Otherwise, it may be a unextractable key of PKCS#11, or ++ // a key we are not able to handle. ++ } else if (key instanceof RSAKey) { ++ RSAKey pubk = (RSAKey)key; ++ size = pubk.getModulus().bitLength(); ++ } else if (key instanceof ECKey) { ++ ECKey pubk = (ECKey)key; ++ size = pubk.getParams().getOrder().bitLength(); ++ } else if (key instanceof DSAKey) { ++ DSAKey pubk = (DSAKey)key; ++ size = pubk.getParams().getP().bitLength(); ++ } else if (key instanceof DHKey) { ++ DHKey pubk = (DHKey)key; ++ size = pubk.getParams().getP().bitLength(); ++ } // Otherwise, it may be a unextractable key of PKCS#11, or ++ // a key we are not able to handle. ++ ++ return size; ++ } ++} ++ +diff --git a/src/share/classes/sun/security/util/Length.java b/src/share/classes/sun/security/util/Length.java +new file mode 100644 +--- /dev/null ++++ jdk/src/share/classes/sun/security/util/Length.java +@@ -0,0 +1,43 @@ ++/* ++ * Copyright (c) 2012, 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 ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++package sun.security.util; ++ ++/** ++ * The Length interface defines the length of an object ++ */ ++public interface Length { ++ ++ /** ++ * Gets the length of this object ++ * <p> ++ * Note that if a class of java.security.Key implements this interfaces, ++ * the length should be measured in bits. ++ * ++ * @return the length of this object ++ * @throws UnsupportedOperationException if the operation is not supported ++ */ ++ public int length(); ++} |