# HG changeset patch # User xuelei # Date 1343529770 25200 # Node ID faa4afc89a09b8be0aac750658f66736fc50ab45 # Parent 10681074e61b736864648137637a8764a716fcff 7186286: TLS implementation to better adhere to RFC Summary: also reviewed by Alexander Fomin , Andrew Gross, Sean Coffey Reviewed-by: valeriep, wetmore diff -r 10681074e61b -r faa4afc89a09 jdk/src/share/classes/sun/security/ssl/HandshakeInStream.java --- a/jdk/src/share/classes/sun/security/ssl/HandshakeInStream.java Fri Jun 22 18:19:48 2012 +0400 +++ b/jdk/src/share/classes/sun/security/ssl/HandshakeInStream.java Sat Jul 28 19:42:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2009, 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 @@ public 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 -r 10681074e61b -r faa4afc89a09 jdk/src/share/classes/sun/security/ssl/Handshaker.java --- a/jdk/src/share/classes/sun/security/ssl/Handshaker.java Fri Jun 22 18:19:48 2012 +0400 +++ b/jdk/src/share/classes/sun/security/ssl/Handshaker.java Sat Jul 28 19:42:50 2012 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, 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 @@ -1063,7 +1063,6 @@ 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"); } if (requestedVersion != null) { @@ -1130,7 +1129,6 @@ System.out.println("RSA PreMasterSecret version error: expected" + protocolVersion + " or " + requestedVersion + ", decrypted: " + premasterVersion); - System.out.println("Generating new random premaster secret"); } preMasterSecret = RSAClientKeyExchange.generateDummySecret(requestedVersion); diff -r 10681074e61b -r faa4afc89a09 jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java --- a/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Fri Jun 22 18:19:48 2012 +0400 +++ b/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Sat Jul 28 19:42:50 2012 -0700 @@ -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 @@ -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 @@ -192,26 +193,38 @@ "unable to get the plaintext of the premaster secret"); } - // We are not always able to get the encoded key of the - // premaster secret. Pass the cheking to master 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(clientHelloVersion); + } + + // 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) { + } else if (clientHelloVersion.v <= ProtocolVersion.TLS10.v && + currentVersion.major == encoded[0] && + currentVersion.minor == encoded[1]) { /* - * we never checked the client_version in server side - * for TLS v1.0 and SSL v3.0. For compatibility, we - * maintain this behavior. + * 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. */ - if (currentVersion.major == encoded[0] && - currentVersion.minor == encoded[1]) { - this.protocolVersion = currentVersion; - return secretKey; - } + this.protocolVersion = currentVersion; + return secretKey; } if (debug != null && Debug.isOn("handshake")) { @@ -220,22 +233,23 @@ ", while PreMasterSecret.client_version is " + ProtocolVersion.valueOf(encoded[0], encoded[1])); } + + return generateDummySecret(clientHelloVersion); } else { if (debug != null && Debug.isOn("handshake")) { System.out.println( "incorrect length of premaster secret: " + encoded.length); } + + return generateDummySecret(clientHelloVersion); } } - if (debug != null && Debug.isOn("handshake")) { - if (failoverException != null) { - System.out.println("Error decrypting premaster secret:"); - failoverException.printStackTrace(System.out); - } - - System.out.println("Generating random secret"); + if (debug != null && Debug.isOn("handshake") && + failoverException != null) { + System.out.println("Error decrypting premaster secret:"); + failoverException.printStackTrace(System.out); } return generateDummySecret(clientHelloVersion); @@ -243,6 +257,10 @@ // 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 { String s = ((version.v >= ProtocolVersion.TLS12.v) ? "SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret");