# HG changeset patch # User xuelei # Date 1326368377 28800 # Node ID d7698e6c5f51175d60b523073acc0ed64c437778 # Parent 1c485b79de814b470cc7f34f0fb4e4faff8f94c3 7106773: 512 bits RSA key cannot work with SHA384 and SHA512 Reviewed-by: weijun diff -r 1c485b79de81 -r d7698e6c5f51 jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java --- a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Wed Jan 11 08:14:47 2012 -0800 +++ b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Thu Jan 12 03:39:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, 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 @@ -870,7 +870,7 @@ @Override protected int engineGetKeySize(Key key) throws InvalidKeyException { int n = P11SecretKeyFactory.convertKey - (token, key, keyAlgorithm).keyLength(); + (token, key, keyAlgorithm).length(); return n; } diff -r 1c485b79de81 -r d7698e6c5f51 jdk/src/share/classes/sun/security/pkcs11/P11Key.java --- a/jdk/src/share/classes/sun/security/pkcs11/P11Key.java Wed Jan 11 08:14:47 2012 -0800 +++ b/jdk/src/share/classes/sun/security/pkcs11/P11Key.java Thu Jan 12 03:39:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, 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 -r 1c485b79de81 -r d7698e6c5f51 jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java --- a/jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java Wed Jan 11 08:14:47 2012 -0800 +++ b/jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java Thu Jan 12 03:39:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, 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 @@ -216,7 +216,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 = ((padType == PAD_PKCS1 && encrypt) ? @@ -495,7 +495,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 -r 1c485b79de81 -r d7698e6c5f51 jdk/src/share/classes/sun/security/pkcs11/P11Signature.java --- a/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java Wed Jan 11 08:14:47 2012 -0800 +++ b/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java Thu Jan 12 03:39:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, 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 @@ -272,7 +272,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); @@ -357,7 +357,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(); } @@ -618,7 +618,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 -r 1c485b79de81 -r d7698e6c5f51 jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java --- a/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java Wed Jan 11 08:14:47 2012 -0800 +++ b/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java Thu Jan 12 03:39:37 2012 -0800 @@ -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 @@ -957,7 +957,8 @@ if (protocolVersion.v >= ProtocolVersion.TLS12.v) { preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm( - peerSupportedSignAlgs, signingKey.getAlgorithm()); + peerSupportedSignAlgs, signingKey.getAlgorithm(), + signingKey); if (preferableSignatureAlgorithm == null) { throw new SSLHandshakeException( diff -r 1c485b79de81 -r d7698e6c5f51 jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java --- a/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java Wed Jan 11 08:14:47 2012 -0800 +++ b/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java Thu Jan 12 03:39:37 2012 -0800 @@ -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 @@ -1024,37 +1024,39 @@ } break; case K_DHE_RSA: + // need RSA certs for authentication + if (setupPrivateKeyAndChain("RSA") == false) { + return false; + } + // get preferable peer signature algorithm for server key exchange if (protocolVersion.v >= ProtocolVersion.TLS12.v) { preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm( - supportedSignAlgs, "RSA"); + supportedSignAlgs, "RSA", privateKey); if (preferableSignatureAlgorithm == null) { return false; } } + setupEphemeralDHKeys(suite.exportable); + break; + case K_ECDHE_RSA: // need RSA certs for authentication if (setupPrivateKeyAndChain("RSA") == false) { return false; } - setupEphemeralDHKeys(suite.exportable); - break; - case K_ECDHE_RSA: + // get preferable peer signature algorithm for server key exchange if (protocolVersion.v >= ProtocolVersion.TLS12.v) { preferableSignatureAlgorithm = SignatureAndHashAlgorithm.getPreferableAlgorithm( - supportedSignAlgs, "RSA"); + supportedSignAlgs, "RSA", privateKey); if (preferableSignatureAlgorithm == null) { return false; } } - // need RSA certs for authentication - if (setupPrivateKeyAndChain("RSA") == false) { - return false; - } if (setupEphemeralECDHKeys() == false) { return false; } diff -r 1c485b79de81 -r d7698e6c5f51 jdk/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java --- a/jdk/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Wed Jan 11 08:14:47 2012 -0800 +++ b/jdk/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Thu Jan 12 03:39:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -27,6 +27,7 @@ import java.security.AlgorithmConstraints; import java.security.CryptoPrimitive; +import java.security.PrivateKey; import java.util.Set; import java.util.HashSet; @@ -37,6 +38,8 @@ import java.util.Collections; import java.util.ArrayList; +import sun.security.util.KeyLength; + /** * Signature and hash algorithm. * @@ -231,6 +234,14 @@ static SignatureAndHashAlgorithm getPreferableAlgorithm( Collection algorithms, String expected) { + return SignatureAndHashAlgorithm.getPreferableAlgorithm( + algorithms, expected, null); + } + + static SignatureAndHashAlgorithm getPreferableAlgorithm( + Collection algorithms, + String expected, PrivateKey signingKey) { + if (expected == null && !algorithms.isEmpty()) { for (SignatureAndHashAlgorithm sigAlg : algorithms) { if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM) { @@ -241,17 +252,58 @@ return null; // no supported algorithm } + if (expected == null ) { + return null; // no expected algorithm, no supported algorithm + } + + /* + * Need to check RSA key length to match the length of hash value + */ + int maxDigestLength = Integer.MAX_VALUE; + if (signingKey != null && + "rsa".equalsIgnoreCase(signingKey.getAlgorithm()) && + expected.equalsIgnoreCase("rsa")) { + /* + * RSA keys of 512 bits have been shown to be practically + * breakable, it does not make much sense to use the strong + * hash algorithm for keys whose key size less than 512 bits. + * So it is not necessary to caculate the required max digest + * length exactly. + * + * If key size is greater than or equals to 768, there is no max + * digest length limitation in currect implementation. + * + * If key size is greater than or equals to 512, but less than + * 768, the digest length should be less than or equal to 32 bytes. + * + * If key size is less than 512, the digest length should be + * less than or equal to 20 bytes. + */ + int keySize = KeyLength.getKeySize(signingKey); + if (keySize >= 768) { + maxDigestLength = HashAlgorithm.SHA512.length; + } else if ((keySize >= 512) && (keySize < 768)) { + maxDigestLength = HashAlgorithm.SHA256.length; + } else if ((keySize > 0) && (keySize < 512)) { + maxDigestLength = HashAlgorithm.SHA1.length; + } // Otherwise, cannot determine the key size, prefer the most + // perferable hash algorithm. + } for (SignatureAndHashAlgorithm algorithm : algorithms) { int signValue = algorithm.id & 0xFF; - if ((expected.equalsIgnoreCase("dsa") && - signValue == SignatureAlgorithm.DSA.value) || - (expected.equalsIgnoreCase("rsa") && - signValue == SignatureAlgorithm.RSA.value) || - (expected.equalsIgnoreCase("ecdsa") && - signValue == SignatureAlgorithm.ECDSA.value) || - (expected.equalsIgnoreCase("ec") && - signValue == SignatureAlgorithm.ECDSA.value)) { + if (expected.equalsIgnoreCase("rsa") && + signValue == SignatureAlgorithm.RSA.value) { + if (algorithm.hash.length <= maxDigestLength) { + return algorithm; + } + } else if ( + (expected.equalsIgnoreCase("dsa") && + signValue == SignatureAlgorithm.DSA.value) || + (expected.equalsIgnoreCase("ecdsa") && + signValue == SignatureAlgorithm.ECDSA.value) || + (expected.equalsIgnoreCase("ec") && + signValue == SignatureAlgorithm.ECDSA.value)) { return algorithm; } } @@ -260,25 +312,28 @@ } static enum HashAlgorithm { - UNDEFINED("undefined", "", -1), - NONE( "none", "NONE", 0), - MD5( "md5", "MD5", 1), - SHA1( "sha1", "SHA-1", 2), - SHA224( "sha224", "SHA-224", 3), - SHA256( "sha256", "SHA-256", 4), - SHA384( "sha384", "SHA-384", 5), - SHA512( "sha512", "SHA-512", 6); + UNDEFINED("undefined", "", -1, -1), + NONE( "none", "NONE", 0, -1), + MD5( "md5", "MD5", 1, 16), + SHA1( "sha1", "SHA-1", 2, 20), + SHA224( "sha224", "SHA-224", 3, 28), + SHA256( "sha256", "SHA-256", 4, 32), + SHA384( "sha384", "SHA-384", 5, 48), + SHA512( "sha512", "SHA-512", 6, 64); final String name; // not the standard signature algorithm name // except the UNDEFINED, other names are defined // by TLS 1.2 protocol final String standardName; // the standard MessageDigest algorithm name final int value; + final int length; // digest length in bytes, -1 means not applicable - private HashAlgorithm(String name, String standardName, int value) { + private HashAlgorithm(String name, String standardName, + int value, int length) { this.name = name; this.standardName = standardName; this.value = value; + this.length = length; } static HashAlgorithm valueOf(int value) { diff -r 1c485b79de81 -r d7698e6c5f51 jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java --- a/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Wed Jan 11 08:14:47 2012 -0800 +++ b/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Thu Jan 12 03:39:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -33,11 +33,6 @@ import java.security.Security; 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; import java.util.Locale; import java.util.Set; @@ -443,40 +438,15 @@ // Does this key constraint disable the specified key? public boolean disables(Key key) { - int size = -1; - - // it is a SecretKey - if (key instanceof SecretKey) { - SecretKey sk = (SecretKey)key; - if (sk.getFormat().equals("RAW") && sk.getEncoded() != null) { - size = sk.getEncoded().length * 8; - - } - } - - // it is an asymmetric key - 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(); - } // else, it is not a key we know. + int size = KeyLength.getKeySize(key); if (size == 0) { return true; // we don't allow any key of size 0. - } - - if (size >= 0) { + } else if (size > 0) { return ((size < minSize) || (size > maxSize) || (prohibitedSize == size)); - } + } // Otherwise, the key size is not accessible. Conservatively, + // please don't disable such keys. return false; } diff -r 1c485b79de81 -r d7698e6c5f51 jdk/src/share/classes/sun/security/util/KeyLength.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/sun/security/util/KeyLength.java Thu Jan 12 03:39:37 2012 -0800 @@ -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 -r 1c485b79de81 -r d7698e6c5f51 jdk/src/share/classes/sun/security/util/Length.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/sun/security/util/Length.java Thu Jan 12 03:39:37 2012 -0800 @@ -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 + *

+ * 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(); +} diff -r 1c485b79de81 -r d7698e6c5f51 jdk/src/windows/classes/sun/security/mscapi/Key.java --- a/jdk/src/windows/classes/sun/security/mscapi/Key.java Wed Jan 11 08:14:47 2012 -0800 +++ b/jdk/src/windows/classes/sun/security/mscapi/Key.java Thu Jan 12 03:39:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -25,6 +25,8 @@ package sun.security.mscapi; +import sun.security.util.Length; + /** * The handle for an RSA or DSA key using the Microsoft Crypto API. * @@ -35,7 +37,7 @@ * @since 1.6 * @author Stanley Man-Kit Ho */ -abstract class Key implements java.security.Key +abstract class Key implements java.security.Key, Length { // Native handle @@ -81,7 +83,8 @@ /** * Return bit length of the key. */ - public int bitLength() + @Override + public int length() { return keyLength; } diff -r 1c485b79de81 -r d7698e6c5f51 jdk/src/windows/classes/sun/security/mscapi/RSACipher.java --- a/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java Wed Jan 11 08:14:47 2012 -0800 +++ b/jdk/src/windows/classes/sun/security/mscapi/RSACipher.java Thu Jan 12 03:39:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -235,12 +235,12 @@ mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY; publicKey = (sun.security.mscapi.Key)key; privateKey = null; - outputSize = publicKey.bitLength() / 8; + outputSize = publicKey.length() / 8; } else if (key instanceof PrivateKey) { mode = encrypt ? MODE_SIGN : MODE_DECRYPT; privateKey = (sun.security.mscapi.Key)key; publicKey = null; - outputSize = privateKey.bitLength() / 8; + outputSize = privateKey.length() / 8; } else { throw new InvalidKeyException("Unknown key type: " + key); } @@ -395,7 +395,7 @@ protected int engineGetKeySize(Key key) throws InvalidKeyException { if (key instanceof sun.security.mscapi.Key) { - return ((sun.security.mscapi.Key) key).bitLength(); + return ((sun.security.mscapi.Key) key).length(); } else if (key instanceof RSAKey) { return ((RSAKey) key).getModulus().bitLength(); diff -r 1c485b79de81 -r d7698e6c5f51 jdk/src/windows/classes/sun/security/mscapi/RSASignature.java --- a/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java Wed Jan 11 08:14:47 2012 -0800 +++ b/jdk/src/windows/classes/sun/security/mscapi/RSASignature.java Thu Jan 12 03:39:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -290,7 +290,7 @@ // Check against the local and global values to make sure // the sizes are ok. Round up to nearest byte. - RSAKeyFactory.checkKeyLengths(((privateKey.bitLength() + 7) & ~7), + RSAKeyFactory.checkKeyLengths(((privateKey.length() + 7) & ~7), null, RSAKeyPairGenerator.KEY_SIZE_MIN, RSAKeyPairGenerator.KEY_SIZE_MAX); diff -r 1c485b79de81 -r d7698e6c5f51 jdk/test/sun/security/mscapi/ShortRSAKey1024.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/mscapi/ShortRSAKey1024.sh Thu Jan 12 03:39:37 2012 -0800 @@ -0,0 +1,85 @@ +#!/bin/sh + +# +# 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. +# +# 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. +# + + +# @test +# @bug 7106773 +# @summary 512 bits RSA key cannot work with SHA384 and SHA512 +# @run shell ShortRSAKey1024.sh + +# set a few environment variables so that the shell-script can run stand-alone +# in the source directory +if [ "${TESTSRC}" = "" ] ; then + TESTSRC="." +fi + +if [ "${TESTCLASSES}" = "" ] ; then + TESTCLASSES="." +fi + +if [ "${TESTJAVA}" = "" ] ; then + echo "TESTJAVA not set. Test cannot execute." + echo "FAILED!!!" + exit 1 +fi + +OS=`uname -s` +case "$OS" in + Windows* | CYGWIN* ) + + echo "Creating a temporary RSA keypair in the Windows-My store..." + ${TESTJAVA}/bin/keytool \ + -genkeypair \ + -storetype Windows-My \ + -keyalg RSA \ + -alias 7106773.1024 \ + -keysize 1024 \ + -dname "cn=localhost,c=US" \ + -noprompt + + echo + echo "Running the test..." + ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\ShortRSAKeyWithinTLS.java + ${TESTJAVA}/bin/java ShortRSAKeyWithinTLS 7106773.1024 1024 \ + TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA + + rc=$? + + echo + echo "Removing the temporary RSA keypair from the Windows-My store..." + ${TESTJAVA}/bin/keytool \ + -delete \ + -storetype Windows-My \ + -alias 7106773.1024 + + echo done. + exit $rc + ;; + + * ) + echo "This test is not intended for '$OS' - passing test" + exit 0 + ;; +esac diff -r 1c485b79de81 -r d7698e6c5f51 jdk/test/sun/security/mscapi/ShortRSAKey512.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/mscapi/ShortRSAKey512.sh Thu Jan 12 03:39:37 2012 -0800 @@ -0,0 +1,86 @@ +#!/bin/sh + +# +# 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. +# +# 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. +# + + +# @test +# @bug 7106773 +# @summary 512 bits RSA key cannot work with SHA384 and SHA512 +# @run shell ShortRSAKey512.sh + +# set a few environment variables so that the shell-script can run stand-alone +# in the source directory +if [ "${TESTSRC}" = "" ] ; then + TESTSRC="." +fi + +if [ "${TESTCLASSES}" = "" ] ; then + TESTCLASSES="." +fi + +if [ "${TESTJAVA}" = "" ] ; then + echo "TESTJAVA not set. Test cannot execute." + echo "FAILED!!!" + exit 1 +fi + +OS=`uname -s` +case "$OS" in + Windows* | CYGWIN* ) + + echo "Creating a temporary RSA keypair in the Windows-My store..." + ${TESTJAVA}/bin/keytool \ + -genkeypair \ + -storetype Windows-My \ + -keyalg RSA \ + -alias 7106773.512 \ + -keysize 512 \ + -dname "cn=localhost,c=US" \ + -noprompt + + echo + echo "Running the test..." + ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\ShortRSAKeyWithinTLS.java + ${TESTJAVA}/bin/java ShortRSAKeyWithinTLS 7106773.512 512 \ + TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA + + + rc=$? + + echo + echo "Removing the temporary RSA keypair from the Windows-My store..." + ${TESTJAVA}/bin/keytool \ + -delete \ + -storetype Windows-My \ + -alias 7106773.512 + + echo done. + exit $rc + ;; + + * ) + echo "This test is not intended for '$OS' - passing test" + exit 0 + ;; +esac diff -r 1c485b79de81 -r d7698e6c5f51 jdk/test/sun/security/mscapi/ShortRSAKey768.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/mscapi/ShortRSAKey768.sh Thu Jan 12 03:39:37 2012 -0800 @@ -0,0 +1,85 @@ +#!/bin/sh + +# +# 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. +# +# 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. +# + + +# @test +# @bug 7106773 +# @summary 512 bits RSA key cannot work with SHA384 and SHA512 +# @run shell ShortRSAKey768.sh + +# set a few environment variables so that the shell-script can run stand-alone +# in the source directory +if [ "${TESTSRC}" = "" ] ; then + TESTSRC="." +fi + +if [ "${TESTCLASSES}" = "" ] ; then + TESTCLASSES="." +fi + +if [ "${TESTJAVA}" = "" ] ; then + echo "TESTJAVA not set. Test cannot execute." + echo "FAILED!!!" + exit 1 +fi + +OS=`uname -s` +case "$OS" in + Windows* | CYGWIN* ) + + echo "Creating a temporary RSA keypair in the Windows-My store..." + ${TESTJAVA}/bin/keytool \ + -genkeypair \ + -storetype Windows-My \ + -keyalg RSA \ + -alias 7106773.768 \ + -keysize 768 \ + -dname "cn=localhost,c=US" \ + -noprompt + + echo + echo "Running the test..." + ${TESTJAVA}/bin/javac -d . ${TESTSRC}\\ShortRSAKeyWithinTLS.java + ${TESTJAVA}/bin/java ShortRSAKeyWithinTLS 7106773.768 768 \ + TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA + + rc=$? + + echo + echo "Removing the temporary RSA keypair from the Windows-My store..." + ${TESTJAVA}/bin/keytool \ + -delete \ + -storetype Windows-My \ + -alias 7106773.768 + + echo done. + exit $rc + ;; + + * ) + echo "This test is not intended for '$OS' - passing test" + exit 0 + ;; +esac diff -r 1c485b79de81 -r d7698e6c5f51 jdk/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/mscapi/ShortRSAKeyWithinTLS.java Thu Jan 12 03:39:37 2012 -0800 @@ -0,0 +1,355 @@ +/* + * 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. + * + * 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. + */ + +import java.io.*; +import java.net.*; +import java.util.*; +import java.security.*; +import javax.net.*; +import javax.net.ssl.*; +import java.lang.reflect.*; + +import sun.security.util.KeyLength; + +public class ShortRSAKeyWithinTLS { + + /* + * ============================================================= + * Set the various variables needed for the tests, then + * specify what tests to run on each side. + */ + + /* + * Should we run the client or server in a separate thread? + * Both sides can throw exceptions, but do you have a preference + * as to which side should be the main thread. + */ + static boolean separateServerThread = false; + + /* + * Is the server ready to serve? + */ + volatile static boolean serverReady = false; + + /* + * Turn on SSL debugging? + */ + static boolean debug = false; + + /* + * If the client or server is doing some kind of object creation + * that the other side depends on, and that thread prematurely + * exits, you may experience a hang. The test harness will + * terminate all hung threads after its timeout has expired, + * currently 3 minutes by default, but you might try to be + * smart about it.... + */ + + /* + * Define the server side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doServerSide() throws Exception { + + // load the key store + KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI"); + ks.load(null, null); + System.out.println("Loaded keystore: Windows-MY"); + + // check key size + checkKeySize(ks); + + // initialize the SSLContext + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, null); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ks); + + SSLContext ctx = SSLContext.getInstance("TLS"); + ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + ServerSocketFactory ssf = ctx.getServerSocketFactory(); + SSLServerSocket sslServerSocket = (SSLServerSocket) + ssf.createServerSocket(serverPort); + sslServerSocket.setNeedClientAuth(true); + serverPort = sslServerSocket.getLocalPort(); + System.out.println("serverPort = " + serverPort); + + /* + * Signal Client, we're ready for his connect. + */ + serverReady = true; + + SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslIS.read(); + sslOS.write(85); + sslOS.flush(); + + sslSocket.close(); + } + + /* + * Define the client side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doClientSide() throws Exception { + + /* + * Wait for server to get started. + */ + while (!serverReady) { + Thread.sleep(50); + } + + // load the key store + KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI"); + ks.load(null, null); + System.out.println("Loaded keystore: Windows-MY"); + + // initialize the SSLContext + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + kmf.init(ks, null); + + TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); + tmf.init(ks); + + SSLContext ctx = SSLContext.getInstance("TLS"); + ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + + SSLSocketFactory sslsf = ctx.getSocketFactory(); + SSLSocket sslSocket = (SSLSocket) + sslsf.createSocket("localhost", serverPort); + + if (clientProtocol != null) { + sslSocket.setEnabledProtocols(new String[] {clientProtocol}); + } + + if (clientCiperSuite != null) { + sslSocket.setEnabledCipherSuites(new String[] {clientCiperSuite}); + } + + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslOS.write(280); + sslOS.flush(); + sslIS.read(); + + sslSocket.close(); + } + + private void checkKeySize(KeyStore ks) throws Exception { + PrivateKey privateKey = null; + PublicKey publicKey = null; + + if (ks.containsAlias(keyAlias)) { + System.out.println("Loaded entry: " + keyAlias); + privateKey = (PrivateKey)ks.getKey(keyAlias, null); + publicKey = (PublicKey)ks.getCertificate(keyAlias).getPublicKey(); + + int privateKeySize = KeyLength.getKeySize(privateKey); + if (privateKeySize != keySize) { + throw new Exception("Expected key size is " + keySize + + ", but the private key size is " + privateKeySize); + } + + int publicKeySize = KeyLength.getKeySize(publicKey); + if (publicKeySize != keySize) { + throw new Exception("Expected key size is " + keySize + + ", but the public key size is " + publicKeySize); + } + } + } + + /* + * ============================================================= + * The remainder is just support stuff + */ + + // use any free port by default + volatile int serverPort = 0; + + volatile Exception serverException = null; + volatile Exception clientException = null; + + private static String keyAlias; + private static int keySize; + private static String clientProtocol = null; + private static String clientCiperSuite = null; + + private static void parseArguments(String[] args) { + keyAlias = args[0]; + keySize = Integer.parseInt(args[1]); + + if (args.length > 2) { + clientProtocol = args[2]; + } + + if (args.length > 3) { + clientCiperSuite = args[3]; + } + } + + public static void main(String[] args) throws Exception { + if (debug) { + System.setProperty("javax.net.debug", "all"); + } + + // Get the customized arguments. + parseArguments(args); + + new ShortRSAKeyWithinTLS(); + } + + Thread clientThread = null; + Thread serverThread = null; + + /* + * Primary constructor, used to drive remainder of the test. + * + * Fork off the other side, then do your work. + */ + ShortRSAKeyWithinTLS() throws Exception { + try { + if (separateServerThread) { + startServer(true); + startClient(false); + } else { + startClient(true); + startServer(false); + } + } catch (Exception e) { + // swallow for now. Show later + } + + /* + * Wait for other side to close down. + */ + if (separateServerThread) { + serverThread.join(); + } else { + clientThread.join(); + } + + /* + * When we get here, the test is pretty much over. + * Which side threw the error? + */ + Exception local; + Exception remote; + String whichRemote; + + if (separateServerThread) { + remote = serverException; + local = clientException; + whichRemote = "server"; + } else { + remote = clientException; + local = serverException; + whichRemote = "client"; + } + + /* + * If both failed, return the curthread's exception, but also + * print the remote side Exception + */ + if ((local != null) && (remote != null)) { + System.out.println(whichRemote + " also threw:"); + remote.printStackTrace(); + System.out.println(); + throw local; + } + + if (remote != null) { + throw remote; + } + + if (local != null) { + throw local; + } + } + + void startServer(boolean newThread) throws Exception { + if (newThread) { + serverThread = new Thread() { + public void run() { + try { + doServerSide(); + } catch (Exception e) { + /* + * Our server thread just died. + * + * Release the client, if not active already... + */ + System.err.println("Server died..."); + serverReady = true; + serverException = e; + } + } + }; + serverThread.start(); + } else { + try { + doServerSide(); + } catch (Exception e) { + serverException = e; + } finally { + serverReady = true; + } + } + } + + void startClient(boolean newThread) throws Exception { + if (newThread) { + clientThread = new Thread() { + public void run() { + try { + doClientSide(); + } catch (Exception e) { + /* + * Our client thread just died. + */ + System.err.println("Client died..."); + clientException = e; + } + } + }; + clientThread.start(); + } else { + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } + } + } +} + diff -r 1c485b79de81 -r d7698e6c5f51 jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.java --- a/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.java Wed Jan 11 08:14:47 2012 -0800 +++ b/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.java Thu Jan 12 03:39:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2007, 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 @@ -155,6 +155,14 @@ SSLSocket sslSocket = (SSLSocket) sslsf.createSocket("localhost", serverPort); + if (clientProtocol != null) { + sslSocket.setEnabledProtocols(new String[] {clientProtocol}); + } + + if (clientCiperSuite != null) { + sslSocket.setEnabledCipherSuites(new String[] {clientCiperSuite}); + } + InputStream sslIS = sslSocket.getInputStream(); OutputStream sslOS = sslSocket.getOutputStream(); @@ -176,7 +184,22 @@ volatile Exception serverException = null; volatile Exception clientException = null; + private static String clientProtocol = null; + private static String clientCiperSuite = null; + + private static void parseArguments(String[] args) { + if (args.length > 0) { + clientProtocol = args[0]; + } + + if (args.length > 1) { + clientCiperSuite = args[1]; + } + } + public static void main(String[] args) throws Exception { + // Get the customized arguments. + parseArguments(args); main(new ClientAuth()); } diff -r 1c485b79de81 -r d7698e6c5f51 jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.sh --- a/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.sh Wed Jan 11 08:14:47 2012 -0800 +++ b/jdk/test/sun/security/pkcs11/KeyStore/ClientAuth.sh Thu Jan 12 03:39:37 2012 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2003, 2006, 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 @@ -22,8 +22,9 @@ # # @test -# @bug 4938185 +# @bug 4938185 7106773 # @summary KeyStore support for NSS cert/key databases +# 512 bits RSA key cannot work with SHA384 and SHA512 # # @run shell ClientAuth.sh @@ -126,6 +127,7 @@ ${TESTSRC}${FS}ClientAuth.java # run test +echo "Run ClientAuth ..." ${TESTJAVA}${FS}bin${FS}java \ -classpath ${TESTCLASSES}${PS}${TESTSRC}${FS}loader.jar \ -DDIR=${TESTSRC}${FS}ClientAuthData${FS} \ @@ -140,5 +142,26 @@ # save error status status=$? +# return if failed +if [ "${status}" != "0" ] ; then + exit $status +fi + +# run test with specified TLS protocol and cipher suite +echo "Run ClientAuth TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA" +${TESTJAVA}${FS}bin${FS}java \ + -classpath ${TESTCLASSES}${PS}${TESTSRC}${FS}loader.jar \ + -DDIR=${TESTSRC}${FS}ClientAuthData${FS} \ + -DCUSTOM_DB_DIR=${TESTCLASSES} \ + -DCUSTOM_P11_CONFIG=${TESTSRC}${FS}ClientAuthData${FS}p11-nss.txt \ + -DNO_DEFAULT=true \ + -DNO_DEIMOS=true \ + -Dtest.src=${TESTSRC} \ + -Dtest.classes=${TESTCLASSES} \ + ClientAuth TLSv1.2 TLS_DHE_RSA_WITH_AES_128_CBC_SHA + +# save error status +status=$? + # return exit $status diff -r 1c485b79de81 -r d7698e6c5f51 jdk/test/sun/security/ssl/javax/net/ssl/SSLContextVersion.java --- a/jdk/test/sun/security/ssl/javax/net/ssl/SSLContextVersion.java Wed Jan 11 08:14:47 2012 -0800 +++ b/jdk/test/sun/security/ssl/javax/net/ssl/SSLContextVersion.java Thu Jan 12 03:39:37 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -91,7 +91,7 @@ ciphers = parameters.getCipherSuites(); if (protocols.length == 0 || ciphers.length == 0) { - throw new Exception("No default protocols or cipher suites"); + throw new Exception("No supported protocols or cipher suites"); } isMatch = false; @@ -104,7 +104,7 @@ } if (!isMatch) { - throw new Exception("No matched default protocol"); + throw new Exception("No matched supported protocol"); } System.out.println("\t... Success"); } diff -r 1c485b79de81 -r d7698e6c5f51 jdk/test/sun/security/ssl/javax/net/ssl/TLSv12/ShortRSAKey512.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv12/ShortRSAKey512.java Thu Jan 12 03:39:37 2012 -0800 @@ -0,0 +1,414 @@ +/* + * 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. + */ + +/* + * @test + * @bug 7106773 + * @summary 512 bits RSA key cannot work with SHA384 and SHA512 + * + * SunJSSE does not support dynamic system properties, no way to re-use + * system properties in samevm/agentvm mode. + * @run main/othervm ShortRSAKey512 PKIX + * @run main/othervm ShortRSAKey512 SunX509 + */ + +import java.net.*; +import java.util.*; +import java.io.*; +import javax.net.ssl.*; +import java.security.KeyStore; +import java.security.KeyFactory; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.spec.*; +import java.security.interfaces.*; +import sun.misc.BASE64Decoder; + + +public class ShortRSAKey512 { + + /* + * ============================================================= + * Set the various variables needed for the tests, then + * specify what tests to run on each side. + */ + + /* + * Should we run the client or server in a separate thread? + * Both sides can throw exceptions, but do you have a preference + * as to which side should be the main thread. + */ + static boolean separateServerThread = false; + + /* + * Where do we find the keystores? + */ + // Certificates and key used in the test. + static String trustedCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + + "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + + "MTEwODE5MDE1MjE5WhcNMzIwNzI5MDE1MjE5WjA7MQswCQYDVQQGEwJVUzENMAsG\n" + + "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" + + "KoZIhvcNAQEBBQADgY0AMIGJAoGBAM8orG08DtF98TMSscjGsidd1ZoN4jiDpi8U\n" + + "ICz+9dMm1qM1d7O2T+KH3/mxyox7Rc2ZVSCaUD0a3CkhPMnlAx8V4u0H+E9sqso6\n" + + "iDW3JpOyzMExvZiRgRG/3nvp55RMIUV4vEHOZ1QbhuqG4ebN0Vz2DkRft7+flthf\n" + + "vDld6f5JAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLl81dnfp0wDrv0OJ1sxlWzH83Xh\n" + + "MGMGA1UdIwRcMFqAFLl81dnfp0wDrv0OJ1sxlWzH83XhoT+kPTA7MQswCQYDVQQG\n" + + "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" + + "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEE\n" + + "BQADgYEALlgaH1gWtoBZ84EW8Hu6YtGLQ/L9zIFmHonUPZwn3Pr//icR9Sqhc3/l\n" + + "pVTxOINuFHLRz4BBtEylzRIOPzK3tg8XwuLb1zd0db90x3KBCiAL6E6cklGEPwLe\n" + + "XYMHDn9eDsaq861Tzn6ZwzMgw04zotPMoZN0mVd/3Qca8UJFucE=\n" + + "-----END CERTIFICATE-----"; + + static String targetCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICNDCCAZ2gAwIBAgIBDDANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + + "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + + "MTExMTA3MTM1NTUyWhcNMzEwNzI1MTM1NTUyWjBPMQswCQYDVQQGEwJVUzENMAsG\n" + + "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" + + "BAMTCWxvY2FsaG9zdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3Pb49OSPfOD2G\n" + + "HSXFCFx1GJEZfqG9ZUf7xuIi/ra5dLjPGAaoY5QF2QOa8VnOriQCXDfyXHxsuRnE\n" + + "OomxL7EVAgMBAAGjeDB2MAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUXNCJK3/dtCIc\n" + + "xb+zlA/JINlvs/MwHwYDVR0jBBgwFoAUuXzV2d+nTAOu/Q4nWzGVbMfzdeEwJwYD\n" + + "VR0lBCAwHgYIKwYBBQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDAzANBgkqhkiG9w0B\n" + + "AQQFAAOBgQB2qIDUxA2caMPpGtUACZAPRUtrGssCINIfItETXJZCx/cRuZ5sP4D9\n" + + "N1acoNDn0hCULe3lhXAeTC9NZ97680yJzregQMV5wATjo1FGsKY30Ma+sc/nfzQW\n" + + "+h/7RhYtoG0OTsiaDCvyhI6swkNJzSzrAccPY4+ZgU8HiDLzZTmM3Q==\n" + + "-----END CERTIFICATE-----"; + + // Private key in the format of PKCS#8, key size is 512 bits. + static String targetPrivateKey = + "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAtz2+PTkj3zg9hh0l\n" + + "xQhcdRiRGX6hvWVH+8biIv62uXS4zxgGqGOUBdkDmvFZzq4kAlw38lx8bLkZxDqJ\n" + + "sS+xFQIDAQABAkByx/5Oo2hQ/w2q4L8z+NTRlJ3vdl8iIDtC/4XPnfYfnGptnpG6\n" + + "ZThQRvbMZiai0xHQPQMszvAHjZVme1eDl3EBAiEA3aKJHynPVCEJhpfCLWuMwX5J\n" + + "1LntwJO7NTOyU5m8rPECIQDTpzn5X44r2rzWBDna/Sx7HW9IWCxNgUD2Eyi2nA7W\n" + + "ZQIgJerEorw4aCAuzQPxiGu57PB6GRamAihEAtoRTBQlH0ECIQDN08FgTtnesgCU\n" + + "DFYLLcw1CiHvc7fZw4neBDHCrC8NtQIgA8TOUkGnpCZlQ0KaI8KfKWI+vxFcgFnH\n" + + "3fnqsTgaUs4="; + + static char passphrase[] = "passphrase".toCharArray(); + + /* + * Is the server ready to serve? + */ + volatile static boolean serverReady = false; + + /* + * Turn on SSL debugging? + */ + static boolean debug = false; + + /* + * Define the server side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doServerSide() throws Exception { + SSLContext context = generateSSLContext(null, targetCertStr, + targetPrivateKey); + SSLServerSocketFactory sslssf = context.getServerSocketFactory(); + SSLServerSocket sslServerSocket = + (SSLServerSocket)sslssf.createServerSocket(serverPort); + serverPort = sslServerSocket.getLocalPort(); + + /* + * Signal Client, we're ready for his connect. + */ + serverReady = true; + + SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept(); + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslIS.read(); + sslOS.write('A'); + sslOS.flush(); + + sslSocket.close(); + } + + /* + * Define the client side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doClientSide() throws Exception { + + /* + * Wait for server to get started. + */ + while (!serverReady) { + Thread.sleep(50); + } + + SSLContext context = generateSSLContext(trustedCertStr, null, null); + SSLSocketFactory sslsf = context.getSocketFactory(); + + SSLSocket sslSocket = + (SSLSocket)sslsf.createSocket("localhost", serverPort); + + // enable TLSv1.2 only + sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"}); + + // enable a block cipher + sslSocket.setEnabledCipherSuites( + new String[] {"TLS_DHE_RSA_WITH_AES_128_CBC_SHA"}); + + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslOS.write('B'); + sslOS.flush(); + sslIS.read(); + + sslSocket.close(); + } + + /* + * ============================================================= + * The remainder is just support stuff + */ + private static String tmAlgorithm; // trust manager + + private static void parseArguments(String[] args) { + tmAlgorithm = args[0]; + } + + private static SSLContext generateSSLContext(String trustedCertStr, + String keyCertStr, String keySpecStr) throws Exception { + + // generate certificate from cert string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + // create a key store + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(null, null); + + // import the trused cert + Certificate trusedCert = null; + ByteArrayInputStream is = null; + if (trustedCertStr != null) { + is = new ByteArrayInputStream(trustedCertStr.getBytes()); + trusedCert = cf.generateCertificate(is); + is.close(); + + ks.setCertificateEntry("RSA Export Signer", trusedCert); + } + + if (keyCertStr != null) { + // generate the private key. + PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( + new BASE64Decoder().decodeBuffer(keySpecStr)); + KeyFactory kf = KeyFactory.getInstance("RSA"); + RSAPrivateKey priKey = + (RSAPrivateKey)kf.generatePrivate(priKeySpec); + + // generate certificate chain + is = new ByteArrayInputStream(keyCertStr.getBytes()); + Certificate keyCert = cf.generateCertificate(is); + is.close(); + + Certificate[] chain = null; + if (trusedCert != null) { + chain = new Certificate[2]; + chain[0] = keyCert; + chain[1] = trusedCert; + } else { + chain = new Certificate[1]; + chain[0] = keyCert; + } + + // import the key entry. + ks.setKeyEntry("Whatever", priKey, passphrase, chain); + } + + // create SSL context + TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm); + tmf.init(ks); + + SSLContext ctx = SSLContext.getInstance("TLS"); + if (keyCertStr != null && !keyCertStr.isEmpty()) { + KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509"); + kmf.init(ks, passphrase); + + ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); + ks = null; + } else { + ctx.init(null, tmf.getTrustManagers(), null); + } + + return ctx; + } + + + // use any free port by default + volatile int serverPort = 0; + + volatile Exception serverException = null; + volatile Exception clientException = null; + + public static void main(String[] args) throws Exception { + if (debug) + System.setProperty("javax.net.debug", "all"); + + /* + * Get the customized arguments. + */ + parseArguments(args); + + /* + * Start the tests. + */ + new ShortRSAKey512(); + } + + Thread clientThread = null; + Thread serverThread = null; + + /* + * Primary constructor, used to drive remainder of the test. + * + * Fork off the other side, then do your work. + */ + ShortRSAKey512() throws Exception { + try { + if (separateServerThread) { + startServer(true); + startClient(false); + } else { + startClient(true); + startServer(false); + } + } catch (Exception e) { + // swallow for now. Show later + } + + /* + * Wait for other side to close down. + */ + if (separateServerThread) { + serverThread.join(); + } else { + clientThread.join(); + } + + /* + * When we get here, the test is pretty much over. + * Which side threw the error? + */ + Exception local; + Exception remote; + String whichRemote; + + if (separateServerThread) { + remote = serverException; + local = clientException; + whichRemote = "server"; + } else { + remote = clientException; + local = serverException; + whichRemote = "client"; + } + + /* + * If both failed, return the curthread's exception, but also + * print the remote side Exception + */ + if ((local != null) && (remote != null)) { + System.out.println(whichRemote + " also threw:"); + remote.printStackTrace(); + System.out.println(); + throw local; + } + + if (remote != null) { + throw remote; + } + + if (local != null) { + throw local; + } + } + + void startServer(boolean newThread) throws Exception { + if (newThread) { + serverThread = new Thread() { + public void run() { + try { + doServerSide(); + } catch (Exception e) { + /* + * Our server thread just died. + * + * Release the client, if not active already... + */ + System.err.println("Server died..."); + serverReady = true; + serverException = e; + } + } + }; + serverThread.start(); + } else { + try { + doServerSide(); + } catch (Exception e) { + serverException = e; + } finally { + serverReady = true; + } + } + } + + void startClient(boolean newThread) throws Exception { + if (newThread) { + clientThread = new Thread() { + public void run() { + try { + doClientSide(); + } catch (Exception e) { + /* + * Our client thread just died. + */ + System.err.println("Client died..."); + clientException = e; + } + } + }; + clientThread.start(); + } else { + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } + } + } +}