提交 5f8ecbc4 编写于 作者: X xuelei

7106773: 512 bits RSA key cannot work with SHA384 and SHA512

Reviewed-by: weijun
上级 6a03b12d
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -870,7 +870,7 @@ final class P11Cipher extends CipherSpi { ...@@ -870,7 +870,7 @@ final class P11Cipher extends CipherSpi {
@Override @Override
protected int engineGetKeySize(Key key) throws InvalidKeyException { protected int engineGetKeySize(Key key) throws InvalidKeyException {
int n = P11SecretKeyFactory.convertKey int n = P11SecretKeyFactory.convertKey
(token, key, keyAlgorithm).keyLength(); (token, key, keyAlgorithm).length();
return n; return n;
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -46,6 +46,7 @@ import sun.security.pkcs11.wrapper.*; ...@@ -46,6 +46,7 @@ import sun.security.pkcs11.wrapper.*;
import static sun.security.pkcs11.wrapper.PKCS11Constants.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
import sun.security.util.DerValue; import sun.security.util.DerValue;
import sun.security.util.Length;
/** /**
* Key implementation classes. * Key implementation classes.
...@@ -61,7 +62,7 @@ import sun.security.util.DerValue; ...@@ -61,7 +62,7 @@ import sun.security.util.DerValue;
* @author Andreas Sterbenz * @author Andreas Sterbenz
* @since 1.5 * @since 1.5
*/ */
abstract class P11Key implements Key { abstract class P11Key implements Key, Length {
private final static String PUBLIC = "public"; private final static String PUBLIC = "public";
private final static String PRIVATE = "private"; private final static String PRIVATE = "private";
...@@ -212,7 +213,11 @@ abstract class P11Key implements Key { ...@@ -212,7 +213,11 @@ abstract class P11Key implements Key {
return s1; return s1;
} }
int keyLength() { /**
* Return bit length of the key.
*/
@Override
public int length() {
return keyLength; return keyLength;
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -216,7 +216,7 @@ final class P11RSACipher extends CipherSpi { ...@@ -216,7 +216,7 @@ final class P11RSACipher extends CipherSpi {
} else { } else {
throw new InvalidKeyException("Unknown key type: " + p11Key); throw new InvalidKeyException("Unknown key type: " + p11Key);
} }
int n = (p11Key.keyLength() + 7) >> 3; int n = (p11Key.length() + 7) >> 3;
outputSize = n; outputSize = n;
buffer = new byte[n]; buffer = new byte[n];
maxInputSize = ((padType == PAD_PKCS1 && encrypt) ? maxInputSize = ((padType == PAD_PKCS1 && encrypt) ?
...@@ -495,7 +495,7 @@ final class P11RSACipher extends CipherSpi { ...@@ -495,7 +495,7 @@ final class P11RSACipher extends CipherSpi {
// see JCE spec // see JCE spec
protected int engineGetKeySize(Key key) throws InvalidKeyException { 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; return n;
} }
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -272,7 +272,7 @@ final class P11Signature extends SignatureSpi { ...@@ -272,7 +272,7 @@ final class P11Signature extends SignatureSpi {
if (keyAlgorithm.equals("DSA")) { if (keyAlgorithm.equals("DSA")) {
signature = new byte[40]; signature = new byte[40];
} else { } else {
signature = new byte[(p11Key.keyLength() + 7) >> 3]; signature = new byte[(p11Key.length() + 7) >> 3];
} }
if (type == T_UPDATE) { if (type == T_UPDATE) {
token.p11.C_VerifyFinal(session.id(), signature); token.p11.C_VerifyFinal(session.id(), signature);
...@@ -357,7 +357,7 @@ final class P11Signature extends SignatureSpi { ...@@ -357,7 +357,7 @@ final class P11Signature extends SignatureSpi {
if (keyAlgorithm.equals("RSA") && publicKey != p11Key) { if (keyAlgorithm.equals("RSA") && publicKey != p11Key) {
int keyLen; int keyLen;
if (publicKey instanceof P11Key) { if (publicKey instanceof P11Key) {
keyLen = ((P11Key) publicKey).keyLength(); keyLen = ((P11Key) publicKey).length();
} else { } else {
keyLen = ((RSAKey) publicKey).getModulus().bitLength(); keyLen = ((RSAKey) publicKey).getModulus().bitLength();
} }
...@@ -618,7 +618,7 @@ final class P11Signature extends SignatureSpi { ...@@ -618,7 +618,7 @@ final class P11Signature extends SignatureSpi {
private byte[] pkcs1Pad(byte[] data) { private byte[] pkcs1Pad(byte[] data) {
try { try {
int len = (p11Key.keyLength() + 7) >> 3; int len = (p11Key.length() + 7) >> 3;
RSAPadding padding = RSAPadding.getInstance RSAPadding padding = RSAPadding.getInstance
(RSAPadding.PAD_BLOCKTYPE_1, len); (RSAPadding.PAD_BLOCKTYPE_1, len);
byte[] padded = padding.pad(data); byte[] padded = padding.pad(data);
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -957,7 +957,8 @@ final class ClientHandshaker extends Handshaker { ...@@ -957,7 +957,8 @@ final class ClientHandshaker extends Handshaker {
if (protocolVersion.v >= ProtocolVersion.TLS12.v) { if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
preferableSignatureAlgorithm = preferableSignatureAlgorithm =
SignatureAndHashAlgorithm.getPreferableAlgorithm( SignatureAndHashAlgorithm.getPreferableAlgorithm(
peerSupportedSignAlgs, signingKey.getAlgorithm()); peerSupportedSignAlgs, signingKey.getAlgorithm(),
signingKey);
if (preferableSignatureAlgorithm == null) { if (preferableSignatureAlgorithm == null) {
throw new SSLHandshakeException( throw new SSLHandshakeException(
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -1024,37 +1024,39 @@ final class ServerHandshaker extends Handshaker { ...@@ -1024,37 +1024,39 @@ final class ServerHandshaker extends Handshaker {
} }
break; break;
case K_DHE_RSA: case K_DHE_RSA:
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
// get preferable peer signature algorithm for server key exchange // get preferable peer signature algorithm for server key exchange
if (protocolVersion.v >= ProtocolVersion.TLS12.v) { if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
preferableSignatureAlgorithm = preferableSignatureAlgorithm =
SignatureAndHashAlgorithm.getPreferableAlgorithm( SignatureAndHashAlgorithm.getPreferableAlgorithm(
supportedSignAlgs, "RSA"); supportedSignAlgs, "RSA", privateKey);
if (preferableSignatureAlgorithm == null) { if (preferableSignatureAlgorithm == null) {
return false; return false;
} }
} }
setupEphemeralDHKeys(suite.exportable);
break;
case K_ECDHE_RSA:
// need RSA certs for authentication // need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) { if (setupPrivateKeyAndChain("RSA") == false) {
return false; return false;
} }
setupEphemeralDHKeys(suite.exportable);
break;
case K_ECDHE_RSA:
// get preferable peer signature algorithm for server key exchange // get preferable peer signature algorithm for server key exchange
if (protocolVersion.v >= ProtocolVersion.TLS12.v) { if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
preferableSignatureAlgorithm = preferableSignatureAlgorithm =
SignatureAndHashAlgorithm.getPreferableAlgorithm( SignatureAndHashAlgorithm.getPreferableAlgorithm(
supportedSignAlgs, "RSA"); supportedSignAlgs, "RSA", privateKey);
if (preferableSignatureAlgorithm == null) { if (preferableSignatureAlgorithm == null) {
return false; return false;
} }
} }
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
if (setupEphemeralECDHKeys() == false) { if (setupEphemeralECDHKeys() == false) {
return false; return false;
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -27,6 +27,7 @@ package sun.security.ssl; ...@@ -27,6 +27,7 @@ package sun.security.ssl;
import java.security.AlgorithmConstraints; import java.security.AlgorithmConstraints;
import java.security.CryptoPrimitive; import java.security.CryptoPrimitive;
import java.security.PrivateKey;
import java.util.Set; import java.util.Set;
import java.util.HashSet; import java.util.HashSet;
...@@ -37,6 +38,8 @@ import java.util.Collection; ...@@ -37,6 +38,8 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.ArrayList; import java.util.ArrayList;
import sun.security.util.KeyLength;
/** /**
* Signature and hash algorithm. * Signature and hash algorithm.
* *
...@@ -231,6 +234,14 @@ final class SignatureAndHashAlgorithm { ...@@ -231,6 +234,14 @@ final class SignatureAndHashAlgorithm {
static SignatureAndHashAlgorithm getPreferableAlgorithm( static SignatureAndHashAlgorithm getPreferableAlgorithm(
Collection<SignatureAndHashAlgorithm> algorithms, String expected) { Collection<SignatureAndHashAlgorithm> algorithms, String expected) {
return SignatureAndHashAlgorithm.getPreferableAlgorithm(
algorithms, expected, null);
}
static SignatureAndHashAlgorithm getPreferableAlgorithm(
Collection<SignatureAndHashAlgorithm> algorithms,
String expected, PrivateKey signingKey) {
if (expected == null && !algorithms.isEmpty()) { if (expected == null && !algorithms.isEmpty()) {
for (SignatureAndHashAlgorithm sigAlg : algorithms) { for (SignatureAndHashAlgorithm sigAlg : algorithms) {
if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM) { if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM) {
...@@ -241,13 +252,54 @@ final class SignatureAndHashAlgorithm { ...@@ -241,13 +252,54 @@ final class SignatureAndHashAlgorithm {
return null; // no supported algorithm 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) { for (SignatureAndHashAlgorithm algorithm : algorithms) {
int signValue = algorithm.id & 0xFF; int signValue = algorithm.id & 0xFF;
if ((expected.equalsIgnoreCase("dsa") && if (expected.equalsIgnoreCase("rsa") &&
signValue == SignatureAlgorithm.RSA.value) {
if (algorithm.hash.length <= maxDigestLength) {
return algorithm;
}
} else if (
(expected.equalsIgnoreCase("dsa") &&
signValue == SignatureAlgorithm.DSA.value) || signValue == SignatureAlgorithm.DSA.value) ||
(expected.equalsIgnoreCase("rsa") &&
signValue == SignatureAlgorithm.RSA.value) ||
(expected.equalsIgnoreCase("ecdsa") && (expected.equalsIgnoreCase("ecdsa") &&
signValue == SignatureAlgorithm.ECDSA.value) || signValue == SignatureAlgorithm.ECDSA.value) ||
(expected.equalsIgnoreCase("ec") && (expected.equalsIgnoreCase("ec") &&
...@@ -260,25 +312,28 @@ final class SignatureAndHashAlgorithm { ...@@ -260,25 +312,28 @@ final class SignatureAndHashAlgorithm {
} }
static enum HashAlgorithm { static enum HashAlgorithm {
UNDEFINED("undefined", "", -1), UNDEFINED("undefined", "", -1, -1),
NONE( "none", "NONE", 0), NONE( "none", "NONE", 0, -1),
MD5( "md5", "MD5", 1), MD5( "md5", "MD5", 1, 16),
SHA1( "sha1", "SHA-1", 2), SHA1( "sha1", "SHA-1", 2, 20),
SHA224( "sha224", "SHA-224", 3), SHA224( "sha224", "SHA-224", 3, 28),
SHA256( "sha256", "SHA-256", 4), SHA256( "sha256", "SHA-256", 4, 32),
SHA384( "sha384", "SHA-384", 5), SHA384( "sha384", "SHA-384", 5, 48),
SHA512( "sha512", "SHA-512", 6); SHA512( "sha512", "SHA-512", 6, 64);
final String name; // not the standard signature algorithm name final String name; // not the standard signature algorithm name
// except the UNDEFINED, other names are defined // except the UNDEFINED, other names are defined
// by TLS 1.2 protocol // by TLS 1.2 protocol
final String standardName; // the standard MessageDigest algorithm name final String standardName; // the standard MessageDigest algorithm name
final int value; 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.name = name;
this.standardName = standardName; this.standardName = standardName;
this.value = value; this.value = value;
this.length = length;
} }
static HashAlgorithm valueOf(int value) { static HashAlgorithm valueOf(int value) {
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -33,11 +33,6 @@ import java.security.Key; ...@@ -33,11 +33,6 @@ import java.security.Key;
import java.security.Security; import java.security.Security;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.security.AccessController; 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.Locale;
import java.util.Set; import java.util.Set;
...@@ -443,40 +438,15 @@ public class DisabledAlgorithmConstraints implements AlgorithmConstraints { ...@@ -443,40 +438,15 @@ public class DisabledAlgorithmConstraints implements AlgorithmConstraints {
// Does this key constraint disable the specified key? // Does this key constraint disable the specified key?
public boolean disables(Key key) { public boolean disables(Key key) {
int size = -1; int size = KeyLength.getKeySize(key);
// 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.
if (size == 0) { if (size == 0) {
return true; // we don't allow any key of size 0. return true; // we don't allow any key of size 0.
} } else if (size > 0) {
if (size >= 0) {
return ((size < minSize) || (size > maxSize) || return ((size < minSize) || (size > maxSize) ||
(prohibitedSize == size)); (prohibitedSize == size));
} } // Otherwise, the key size is not accessible. Conservatively,
// please don't disable such keys.
return false; return false;
} }
......
/*
* 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;
}
}
/*
* 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();
}
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
package sun.security.mscapi; package sun.security.mscapi;
import sun.security.util.Length;
/** /**
* The handle for an RSA or DSA key using the Microsoft Crypto API. * The handle for an RSA or DSA key using the Microsoft Crypto API.
* *
...@@ -35,7 +37,7 @@ package sun.security.mscapi; ...@@ -35,7 +37,7 @@ package sun.security.mscapi;
* @since 1.6 * @since 1.6
* @author Stanley Man-Kit Ho * @author Stanley Man-Kit Ho
*/ */
abstract class Key implements java.security.Key abstract class Key implements java.security.Key, Length
{ {
// Native handle // Native handle
...@@ -81,7 +83,8 @@ abstract class Key implements java.security.Key ...@@ -81,7 +83,8 @@ abstract class Key implements java.security.Key
/** /**
* Return bit length of the key. * Return bit length of the key.
*/ */
public int bitLength() @Override
public int length()
{ {
return keyLength; return keyLength;
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -235,12 +235,12 @@ public final class RSACipher extends CipherSpi { ...@@ -235,12 +235,12 @@ public final class RSACipher extends CipherSpi {
mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY; mode = encrypt ? MODE_ENCRYPT : MODE_VERIFY;
publicKey = (sun.security.mscapi.Key)key; publicKey = (sun.security.mscapi.Key)key;
privateKey = null; privateKey = null;
outputSize = publicKey.bitLength() / 8; outputSize = publicKey.length() / 8;
} else if (key instanceof PrivateKey) { } else if (key instanceof PrivateKey) {
mode = encrypt ? MODE_SIGN : MODE_DECRYPT; mode = encrypt ? MODE_SIGN : MODE_DECRYPT;
privateKey = (sun.security.mscapi.Key)key; privateKey = (sun.security.mscapi.Key)key;
publicKey = null; publicKey = null;
outputSize = privateKey.bitLength() / 8; outputSize = privateKey.length() / 8;
} else { } else {
throw new InvalidKeyException("Unknown key type: " + key); throw new InvalidKeyException("Unknown key type: " + key);
} }
...@@ -395,7 +395,7 @@ public final class RSACipher extends CipherSpi { ...@@ -395,7 +395,7 @@ public final class RSACipher extends CipherSpi {
protected int engineGetKeySize(Key key) throws InvalidKeyException { protected int engineGetKeySize(Key key) throws InvalidKeyException {
if (key instanceof sun.security.mscapi.Key) { 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) { } else if (key instanceof RSAKey) {
return ((RSAKey) key).getModulus().bitLength(); return ((RSAKey) key).getModulus().bitLength();
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -290,7 +290,7 @@ abstract class RSASignature extends java.security.SignatureSpi ...@@ -290,7 +290,7 @@ abstract class RSASignature extends java.security.SignatureSpi
// Check against the local and global values to make sure // Check against the local and global values to make sure
// the sizes are ok. Round up to nearest byte. // 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, null, RSAKeyPairGenerator.KEY_SIZE_MIN,
RSAKeyPairGenerator.KEY_SIZE_MAX); RSAKeyPairGenerator.KEY_SIZE_MAX);
......
#!/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
#!/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
#!/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
/*
* 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;
}
}
}
}
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -155,6 +155,14 @@ public class ClientAuth extends PKCS11Test { ...@@ -155,6 +155,14 @@ public class ClientAuth extends PKCS11Test {
SSLSocket sslSocket = (SSLSocket) SSLSocket sslSocket = (SSLSocket)
sslsf.createSocket("localhost", serverPort); sslsf.createSocket("localhost", serverPort);
if (clientProtocol != null) {
sslSocket.setEnabledProtocols(new String[] {clientProtocol});
}
if (clientCiperSuite != null) {
sslSocket.setEnabledCipherSuites(new String[] {clientCiperSuite});
}
InputStream sslIS = sslSocket.getInputStream(); InputStream sslIS = sslSocket.getInputStream();
OutputStream sslOS = sslSocket.getOutputStream(); OutputStream sslOS = sslSocket.getOutputStream();
...@@ -176,7 +184,22 @@ public class ClientAuth extends PKCS11Test { ...@@ -176,7 +184,22 @@ public class ClientAuth extends PKCS11Test {
volatile Exception serverException = null; volatile Exception serverException = null;
volatile Exception clientException = 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 { public static void main(String[] args) throws Exception {
// Get the customized arguments.
parseArguments(args);
main(new ClientAuth()); main(new ClientAuth());
} }
......
# #
# 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. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -22,8 +22,9 @@ ...@@ -22,8 +22,9 @@
# #
# @test # @test
# @bug 4938185 # @bug 4938185 7106773
# @summary KeyStore support for NSS cert/key databases # @summary KeyStore support for NSS cert/key databases
# 512 bits RSA key cannot work with SHA384 and SHA512
# #
# @run shell ClientAuth.sh # @run shell ClientAuth.sh
...@@ -126,6 +127,7 @@ ${TESTJAVA}${FS}bin${FS}javac \ ...@@ -126,6 +127,7 @@ ${TESTJAVA}${FS}bin${FS}javac \
${TESTSRC}${FS}ClientAuth.java ${TESTSRC}${FS}ClientAuth.java
# run test # run test
echo "Run ClientAuth ..."
${TESTJAVA}${FS}bin${FS}java \ ${TESTJAVA}${FS}bin${FS}java \
-classpath ${TESTCLASSES}${PS}${TESTSRC}${FS}loader.jar \ -classpath ${TESTCLASSES}${PS}${TESTSRC}${FS}loader.jar \
-DDIR=${TESTSRC}${FS}ClientAuthData${FS} \ -DDIR=${TESTSRC}${FS}ClientAuthData${FS} \
...@@ -140,5 +142,26 @@ ${TESTJAVA}${FS}bin${FS}java \ ...@@ -140,5 +142,26 @@ ${TESTJAVA}${FS}bin${FS}java \
# save error status # save error status
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 # return
exit $status exit $status
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -91,7 +91,7 @@ public class SSLContextVersion { ...@@ -91,7 +91,7 @@ public class SSLContextVersion {
ciphers = parameters.getCipherSuites(); ciphers = parameters.getCipherSuites();
if (protocols.length == 0 || ciphers.length == 0) { 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; isMatch = false;
...@@ -104,7 +104,7 @@ public class SSLContextVersion { ...@@ -104,7 +104,7 @@ public class SSLContextVersion {
} }
if (!isMatch) { if (!isMatch) {
throw new Exception("No matched default protocol"); throw new Exception("No matched supported protocol");
} }
System.out.println("\t... Success"); System.out.println("\t... Success");
} }
......
/*
* 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;
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册