Mercurial > hg > release > icedtea6-1.10
view patches/security/20121016/7186286.patch @ 2593:6df81d93af9c
Add 2012/10/16 security updates.
2012-10-11 Andrew John Hughes <gnu.andrew@redhat.com>
* Makefile.am:
(SECURITY_PATCHES): Add new patches.
* patches/ecj/override.patch:
Add new cases in P11Key and RMIConnectionImpl
introduced by security patches.
* patches/ssl.patch:
Removed old unneeded patch which breaks with
this update.
* patches/security/20111018/7092186.patch:
Backport of patch added to OpenJDK6 by Oracle
as part of the last security update but not
included in the bundle delivered ahead of time.
* patches/security/20121016/6631398.patch,
* patches/security/20121016/7093490.patch,
* patches/security/20121016/7143535.patch,
* patches/security/20121016/7158801.patch,
* patches/security/20121016/7167656.patch,
* patches/security/20121016/7169884.patch,
* patches/security/20121016/7169888.patch,
* patches/security/20121016/7172522.patch,
* patches/security/20121016/7176337.patch,
* patches/security/20121016/7186286.patch,
* patches/security/20121016/7189103.patch,
* patches/security/20121016/7189490.patch,
* patches/security/20121016/7189567.patch,
* patches/security/20121016/7192975.patch,
* patches/security/20121016/7195194.patch,
* patches/security/20121016/7195917.patch,
* patches/security/20121016/7195919.patch,
* patches/security/20121016/7198296.patch,
* patches/security/20121016/7198606.patch,
* patches/security/20121016/hs20/7158800.patch,
* patches/security/20121016/hs20/7158804.patch,
* patches/security/20121016/original/7158800.patch,
* patches/security/20121016/original/7158804.patch:
New patches.
author | Andrew John Hughes <ahughes@redhat.com> |
---|---|
date | Fri, 12 Oct 2012 02:18:24 +0100 |
parents | |
children |
line wrap: on
line source
# 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 --- openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java +++ openjdk/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 --- openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Key.java +++ openjdk/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 --- openjdk/jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java +++ openjdk/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 --- openjdk/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java +++ openjdk/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 --- openjdk/jdk/src/share/classes/sun/security/ssl/HandshakeInStream.java +++ openjdk/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 --- openjdk/jdk/src/share/classes/sun/security/ssl/Handshaker.java +++ openjdk/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 --- openjdk/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java +++ openjdk/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 --- openjdk/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java +++ openjdk/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 +++ openjdk/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 +++ openjdk/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(); +}