--- a/jdk/make/java/java/FILES_java.gmk Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/make/java/java/FILES_java.gmk Tue Nov 02 19:40:45 2010 -0700
@@ -413,6 +413,7 @@
java/io/FilePermission.java \
java/io/Serializable.java \
java/io/Externalizable.java \
+ java/io/SerialCallbackContext.java \
java/io/Bits.java \
java/io/ObjectInput.java \
java/io/ObjectInputStream.java \
--- a/jdk/make/java/jli/Makefile Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/make/java/jli/Makefile Tue Nov 02 19:40:45 2010 -0700
@@ -148,14 +148,9 @@
#
ifeq ($(PLATFORM), windows)
-STATIC_LIBRARY_DIR = $(OBJDIR)/static
-STATIC_LIBRARY_NAME = $(LIBPREFIX)$(LIBRARY).lib
-STATIC_LIBRARY = $(STATIC_LIBRARY_DIR)/$(STATIC_LIBRARY_NAME)
+STATIC_LIBRARY = $(OBJDIR)/static/$(LIBPREFIX)$(LIBRARY).lib
-$(STATIC_LIBRARY_DIR): $(OBJDIR)
- @$(MKDIR) $(STATIC_LIBRARY_DIR)
-
-$(STATIC_LIBRARY): $(STATIC_LIBRARY_DIR)
+$(STATIC_LIBRARY): $(FILES_o)
@$(prep-target)
$(LIBEXE) -nologo -out:$@ $(FILES_o)
--- a/jdk/make/java/nio/FILES_java.gmk Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/make/java/nio/FILES_java.gmk Tue Nov 02 19:40:45 2010 -0700
@@ -33,7 +33,6 @@
java/nio/channels/AsynchronousByteChannel.java \
java/nio/channels/AsynchronousChannel.java \
java/nio/channels/AsynchronousChannelGroup.java \
- java/nio/channels/AsynchronousDatagramChannel.java \
java/nio/channels/AsynchronousFileChannel.java \
java/nio/channels/AsynchronousServerSocketChannel.java \
java/nio/channels/AsynchronousSocketChannel.java \
@@ -207,7 +206,6 @@
sun/nio/ch/SelChImpl.java \
sun/nio/ch/ServerSocketAdaptor.java \
sun/nio/ch/ServerSocketChannelImpl.java \
- sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java \
sun/nio/ch/SinkChannelImpl.java \
sun/nio/ch/SocketAdaptor.java \
sun/nio/ch/SocketChannelImpl.java \
--- a/jdk/make/netbeans/jmx/build.properties Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/make/netbeans/jmx/build.properties Tue Nov 02 19:40:45 2010 -0700
@@ -48,8 +48,8 @@
jar.jmx.sealed = true
jar.jmx.spec.title = JSR 003, 160, 255 - JMX API
jar.jmx.spec.version = ${project.spec.version}
-jar.jmx.spec.vendor = Sun Microsystems, Inc.
-jar.jmx.impl.title = JSR 003, 160, 255 - OpenJDK 7 JMX API
+jar.jmx.spec.vendor = Oracle Corporation
+jar.jmx.impl.title = JSR 003, 160, 255 - OpenJDK 7 JMX API
jar.jmx.impl.vendor = Project OpenJDK
javadoc.options=-J-Xmx256m
--- a/jdk/src/share/bin/java.c Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/bin/java.c Tue Nov 02 19:40:45 2010 -0700
@@ -355,7 +355,6 @@
JavaVM *vm = 0;
JNIEnv *env = 0;
- jstring mainClassName;
jclass mainClass;
jmethodID mainID;
jobjectArray mainArgs;
--- a/jdk/src/share/bin/parse_manifest.c Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/bin/parse_manifest.c Tue Nov 02 19:40:45 2010 -0700
@@ -72,7 +72,7 @@
if (entry->how == STORED) {
*(char *)((size_t)in + entry->csize) = '\0';
if (size_out) {
- *size_out = entry->csize;
+ *size_out = (int)entry->csize;
}
return (in);
} else if (entry->how == DEFLATED) {
@@ -103,7 +103,7 @@
return (NULL);
}
if (size_out) {
- *size_out = entry->isize;
+ *size_out = (int)entry->isize;
}
return (out);
} else
@@ -317,7 +317,7 @@
* manifest. If so, build the entry record from the data found in
* the header located and return success.
*/
- if (CENNAM(p) == JLI_StrLen(file_name) &&
+ if ((size_t)CENNAM(p) == JLI_StrLen(file_name) &&
memcmp((p + CENHDR), file_name, JLI_StrLen(file_name)) == 0) {
if (lseek(fd, base_offset + CENOFF(p), SEEK_SET) < (off_t)0) {
free(buffer);
@@ -606,8 +606,5 @@
}
free(mp);
close(fd);
- if (rc == 0)
- return (0);
- else
- return (-2);
+ return (rc == 0) ? 0 : -2;
}
--- a/jdk/src/share/bin/wildcard.c Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/bin/wildcard.c Tue Nov 02 19:40:45 2010 -0700
@@ -290,12 +290,12 @@
char *path;
char *p;
for (i = 0, size = 1; i < fl->size; i++)
- size += JLI_StrLen(fl->files[i]) + 1;
+ size += (int)JLI_StrLen(fl->files[i]) + 1;
path = JLI_MemAlloc(size);
for (i = 0, p = path; i < fl->size; i++) {
- int len = JLI_StrLen(fl->files[i]);
+ int len = (int)JLI_StrLen(fl->files[i]);
if (i > 0) *p++ = sep;
memcpy(p, fl->files[i], len);
p += len;
@@ -309,7 +309,7 @@
FileList_split(const char *path, char sep)
{
const char *p, *q;
- int len = JLI_StrLen(path);
+ int len = (int)JLI_StrLen(path);
int count;
FileList fl;
for (count = 1, p = path; p < path + len; p++)
@@ -330,7 +330,7 @@
static int
isJarFileName(const char *filename)
{
- int len = JLI_StrLen(filename);
+ int len = (int)JLI_StrLen(filename);
return (len >= 4) &&
(filename[len - 4] == '.') &&
(equal(filename + len - 3, "jar") ||
@@ -342,8 +342,8 @@
static char *
wildcardConcat(const char *wildcard, const char *basename)
{
- int wildlen = JLI_StrLen(wildcard);
- int baselen = JLI_StrLen(basename);
+ int wildlen = (int)JLI_StrLen(wildcard);
+ int baselen = (int)JLI_StrLen(basename);
char *filename = (char *) JLI_MemAlloc(wildlen + baselen);
/* Replace the trailing '*' with basename */
memcpy(filename, wildcard, wildlen-1);
@@ -369,7 +369,7 @@
static int
isWildcard(const char *filename)
{
- int len = JLI_StrLen(filename);
+ int len = (int)JLI_StrLen(filename);
return (len > 0) &&
(filename[len - 1] == '*') &&
(len == 1 || IS_FILE_SEPARATOR(filename[len - 2])) &&
--- a/jdk/src/share/classes/com/sun/crypto/provider/AESCrypt.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/AESCrypt.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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
@@ -253,7 +253,8 @@
for (j = 0; j < 8; j++) {
if (AA[i][j] != 0) {
AA[i][j] = (byte)
- alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF]) % 255];
+ alog[(255 + log[AA[i][j] & 0xFF] - log[pivot & 0xFF])
+ % 255];
}
}
for (t = 0; t < 4; t++) {
--- a/jdk/src/share/classes/com/sun/crypto/provider/ARCFOURCipher.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/ARCFOURCipher.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -92,7 +92,8 @@
}
// core crypt code. OFB style, so works for both encryption and decryption
- private void crypt(byte[] in, int inOfs, int inLen, byte[] out, int outOfs) {
+ private void crypt(byte[] in, int inOfs, int inLen, byte[] out,
+ int outOfs) {
if (is < 0) {
// doFinal() was called, need to reset the cipher to initial state
init(lastKey);
--- a/jdk/src/share/classes/com/sun/crypto/provider/DESedeCipher.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/DESedeCipher.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -31,8 +31,8 @@
import javax.crypto.spec.*;
/**
- * This class implements the DESede algorithm (DES-EDE, tripleDES) in its various
- * modes (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>,
+ * This class implements the DESede algorithm (DES-EDE, tripleDES) in
+ * its various modes (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>,
* <code>CBC</code>, <code>PCBC</code>) and padding schemes
* (<code>PKCS5Padding</code>, <code>NoPadding</code>,
* <code>ISO10126Padding</code>).
--- a/jdk/src/share/classes/com/sun/crypto/provider/DHPrivateKey.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/DHPrivateKey.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -190,7 +190,8 @@
ike.initCause(e);
throw ike;
} catch (IOException e) {
- InvalidKeyException ike = new InvalidKeyException("Error parsing key encoding: " + e.getMessage());
+ InvalidKeyException ike = new InvalidKeyException(
+ "Error parsing key encoding: " + e.getMessage());
ike.initCause(e);
throw ike;
}
@@ -300,7 +301,8 @@
DerInputStream in = new DerInputStream(this.key);
this.x = in.getBigInteger();
} catch (IOException e) {
- InvalidKeyException ike = new InvalidKeyException("Error parsing key encoding: " + e.getMessage());
+ InvalidKeyException ike = new InvalidKeyException(
+ "Error parsing key encoding: " + e.getMessage());
ike.initCause(e);
throw ike;
}
--- a/jdk/src/share/classes/com/sun/crypto/provider/DHPublicKey.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/DHPublicKey.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -180,7 +180,8 @@
throw new InvalidKeyException("Private-value length too big");
} catch (IOException e) {
- throw new InvalidKeyException("Error parsing key encoding: " + e.toString());
+ throw new InvalidKeyException(
+ "Error parsing key encoding: " + e.toString());
}
}
@@ -281,7 +282,8 @@
DerInputStream in = new DerInputStream(this.key);
this.y = in.getBigInteger();
} catch (IOException e) {
- throw new InvalidKeyException("Error parsing key encoding: " + e.toString());
+ throw new InvalidKeyException(
+ "Error parsing key encoding: " + e.toString());
}
}
--- a/jdk/src/share/classes/com/sun/crypto/provider/JceKeyStore.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/JceKeyStore.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2010, 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
@@ -764,7 +764,8 @@
cf = (CertificateFactory)cfs.get(certType);
} else {
// create new certificate factory
- cf = CertificateFactory.getInstance(certType);
+ cf = CertificateFactory.getInstance(
+ certType);
// store the certificate factory so we can
// reuse it later
cfs.put(certType, cf);
@@ -863,8 +864,9 @@
dis.readFully(actual);
for (int i = 0; i < computed.length; i++) {
if (computed[i] != actual[i]) {
- throw new IOException("Keystore was tampered with, or "
- + "password was incorrect");
+ throw new IOException(
+ "Keystore was tampered with, or "
+ + "password was incorrect");
}
}
}
--- a/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/OAEPParameters.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -139,7 +139,8 @@
if (!val.getOID().equals((Object) OID_MGF1)) {
throw new IOException("Only MGF1 mgf is supported");
}
- AlgorithmId params = AlgorithmId.parse(new DerValue(val.getEncodedParams()));
+ AlgorithmId params = AlgorithmId.parse(
+ new DerValue(val.getEncodedParams()));
String mgfDigestName = convertToStandardName(params.getName());
if (mgfDigestName.equals("SHA-1")) {
mgfSpec = MGF1ParameterSpec.SHA1;
@@ -150,7 +151,8 @@
} else if (mgfDigestName.equals("SHA-512")) {
mgfSpec = MGF1ParameterSpec.SHA512;
} else {
- throw new IOException("Unrecognized message digest algorithm");
+ throw new IOException(
+ "Unrecognized message digest algorithm");
}
} else if (data.isContextSpecific((byte) 0x02)) {
// pSource algid
--- a/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/PBKDF2KeyImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -121,8 +121,8 @@
this.key = deriveKey(prf, passwdBytes, salt, iterCount, keyLength);
}
- private static byte[] deriveKey(final Mac prf, final byte[] password, byte[] salt,
- int iterCount, int keyLengthInBit) {
+ private static byte[] deriveKey(final Mac prf, final byte[] password,
+ byte[] salt, int iterCount, int keyLengthInBit) {
int keyLength = keyLengthInBit/8;
byte[] key = new byte[keyLength];
try {
@@ -155,8 +155,9 @@
if (this == obj) return true;
if (this.getClass() != obj.getClass()) return false;
SecretKey sk = (SecretKey)obj;
- return prf.getAlgorithm().equalsIgnoreCase(sk.getAlgorithm()) &&
- Arrays.equals(password, sk.getEncoded());
+ return prf.getAlgorithm().equalsIgnoreCase(
+ sk.getAlgorithm()) &&
+ Arrays.equals(password, sk.getEncoded());
}
};
prf.init(macKey);
--- a/jdk/src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/PKCS12PBECipherCore.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -206,7 +206,8 @@
(algo.equalsIgnoreCase("RC2")?"RC2_40":algo), "SunJCE");
} catch (GeneralSecurityException gse) {
// should never happen
- throw new RuntimeException("SunJCE provider is not configured properly");
+ throw new RuntimeException(
+ "SunJCE provider is not configured properly");
}
try {
params.init(pbeSpec);
@@ -316,7 +317,8 @@
try {
paramSpec = params.getParameterSpec(PBEParameterSpec.class);
} catch (InvalidParameterSpecException ipse) {
- throw new InvalidAlgorithmParameterException("requires PBE parameters");
+ throw new InvalidAlgorithmParameterException(
+ "requires PBE parameters");
}
}
implInit(opmode, key, paramSpec, random);
--- a/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/SunJCE.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -423,15 +423,31 @@
/*
* SSL/TLS mechanisms
+ *
+ * These are strictly internal implementations and may
+ * be changed at any time. These names were chosen
+ * because PKCS11/SunPKCS11 does not yet have TLS1.2
+ * mechanisms, and it will cause calls to come here.
*/
put("KeyGenerator.SunTlsPrf",
- "com.sun.crypto.provider.TlsPrfGenerator");
- put("KeyGenerator.SunTlsRsaPremasterSecret",
- "com.sun.crypto.provider.TlsRsaPremasterSecretGenerator");
+ "com.sun.crypto.provider.TlsPrfGenerator$V10");
+ put("KeyGenerator.SunTls12Prf",
+ "com.sun.crypto.provider.TlsPrfGenerator$V12");
+
put("KeyGenerator.SunTlsMasterSecret",
- "com.sun.crypto.provider.TlsMasterSecretGenerator");
+ "com.sun.crypto.provider.TlsMasterSecretGenerator");
+ put("Alg.Alias.KeyGenerator.SunTls12MasterSecret",
+ "SunTlsMasterSecret");
+
put("KeyGenerator.SunTlsKeyMaterial",
- "com.sun.crypto.provider.TlsKeyMaterialGenerator");
+ "com.sun.crypto.provider.TlsKeyMaterialGenerator");
+ put("Alg.Alias.KeyGenerator.SunTls12KeyMaterial",
+ "SunTlsKeyMaterial");
+
+ put("KeyGenerator.SunTlsRsaPremasterSecret",
+ "com.sun.crypto.provider.TlsRsaPremasterSecretGenerator");
+ put("Alg.Alias.KeyGenerator.SunTls12RsaPremasterSecret",
+ "SunTlsRsaPremasterSecret");
return null;
}
--- a/jdk/src/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/TlsKeyMaterialGenerator.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -65,12 +65,14 @@
}
this.spec = (TlsKeyMaterialParameterSpec)params;
if ("RAW".equals(spec.getMasterSecret().getFormat()) == false) {
- throw new InvalidAlgorithmParameterException("Key format must be RAW");
+ throw new InvalidAlgorithmParameterException(
+ "Key format must be RAW");
}
- protocolVersion = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
- if ((protocolVersion < 0x0300) || (protocolVersion > 0x0302)) {
- throw new InvalidAlgorithmParameterException
- ("Only SSL 3.0, TLS 1.0, and TLS 1.1 supported");
+ protocolVersion = (spec.getMajorVersion() << 8)
+ | spec.getMinorVersion();
+ if ((protocolVersion < 0x0300) || (protocolVersion > 0x0303)) {
+ throw new InvalidAlgorithmParameterException(
+ "Only SSL 3.0, TLS 1.0/1.1/1.2 supported");
}
}
@@ -80,8 +82,8 @@
protected SecretKey engineGenerateKey() {
if (spec == null) {
- throw new IllegalStateException
- ("TlsKeyMaterialGenerator must be initialized");
+ throw new IllegalStateException(
+ "TlsKeyMaterialGenerator must be initialized");
}
try {
return engineGenerateKey0();
@@ -99,8 +101,8 @@
SecretKey clientMacKey = null;
SecretKey serverMacKey = null;
SecretKey clientCipherKey = null;
+ SecretKey serverCipherKey = null;
IvParameterSpec clientIv = null;
- SecretKey serverCipherKey = null;
IvParameterSpec serverIv = null;
int macLength = spec.getMacKeyLength();
@@ -109,21 +111,33 @@
int keyLength = spec.getCipherKeyLength();
int ivLength = spec.getIvLength();
- int keyBlockLen = macLength + keyLength + (isExportable ? 0 : ivLength);
+ int keyBlockLen = macLength + keyLength
+ + (isExportable ? 0 : ivLength);
keyBlockLen <<= 1;
byte[] keyBlock = new byte[keyBlockLen];
- MessageDigest md5 = MessageDigest.getInstance("MD5");
- MessageDigest sha = MessageDigest.getInstance("SHA1");
+ // These may be used again later for exportable suite calculations.
+ MessageDigest md5 = null;
+ MessageDigest sha = null;
// generate key block
- if (protocolVersion >= 0x0301) {
- // TLS
+ if (protocolVersion >= 0x0303) {
+ // TLS 1.2
byte[] seed = concat(serverRandom, clientRandom);
- keyBlock = doPRF(masterSecret, LABEL_KEY_EXPANSION, seed,
+ keyBlock = doTLS12PRF(masterSecret, LABEL_KEY_EXPANSION, seed,
+ keyBlockLen, spec.getPRFHashAlg(),
+ spec.getPRFHashLength(), spec.getPRFBlockSize());
+ } else if (protocolVersion >= 0x0301) {
+ // TLS 1.0/1.1
+ md5 = MessageDigest.getInstance("MD5");
+ sha = MessageDigest.getInstance("SHA1");
+ byte[] seed = concat(serverRandom, clientRandom);
+ keyBlock = doTLS10PRF(masterSecret, LABEL_KEY_EXPANSION, seed,
keyBlockLen, md5, sha);
} else {
// SSL
+ md5 = MessageDigest.getInstance("MD5");
+ sha = MessageDigest.getInstance("SHA1");
keyBlock = new byte[keyBlockLen];
byte[] tmp = new byte[20];
@@ -169,6 +183,7 @@
String alg = spec.getCipherAlgorithm();
+ // cipher keys
byte[] clientKeyBytes = new byte[keyLength];
System.arraycopy(keyBlock, ofs, clientKeyBytes, 0, keyLength);
ofs += keyLength;
@@ -182,6 +197,7 @@
clientCipherKey = new SecretKeySpec(clientKeyBytes, alg);
serverCipherKey = new SecretKeySpec(serverKeyBytes, alg);
+ // IV keys if needed.
if (ivLength != 0) {
tmp = new byte[ivLength];
@@ -194,21 +210,28 @@
serverIv = new IvParameterSpec(tmp);
}
} else {
+ // if exportable suites, calculate the alternate
// cipher key expansion and IV generation
- if (protocolVersion >= 0x0301) {
+ if (protocolVersion >= 0x0302) {
+ // TLS 1.1+
+ throw new RuntimeException(
+ "Internal Error: TLS 1.1+ should not be negotiating" +
+ "exportable ciphersuites");
+ } else if (protocolVersion == 0x0301) {
+ // TLS 1.0
byte[] seed = concat(clientRandom, serverRandom);
- tmp = doPRF(clientKeyBytes, LABEL_CLIENT_WRITE_KEY, seed,
+ tmp = doTLS10PRF(clientKeyBytes, LABEL_CLIENT_WRITE_KEY, seed,
expandedKeyLength, md5, sha);
clientCipherKey = new SecretKeySpec(tmp, alg);
- tmp = doPRF(serverKeyBytes, LABEL_SERVER_WRITE_KEY, seed,
+ tmp = doTLS10PRF(serverKeyBytes, LABEL_SERVER_WRITE_KEY, seed,
expandedKeyLength, md5, sha);
serverCipherKey = new SecretKeySpec(tmp, alg);
if (ivLength != 0) {
tmp = new byte[ivLength];
- byte[] block = doPRF(null, LABEL_IV_BLOCK, seed,
+ byte[] block = doTLS10PRF(null, LABEL_IV_BLOCK, seed,
ivLength << 1, md5, sha);
System.arraycopy(block, 0, tmp, 0, ivLength);
clientIv = new IvParameterSpec(tmp);
@@ -216,6 +239,7 @@
serverIv = new IvParameterSpec(tmp);
}
} else {
+ // SSLv3
tmp = new byte[expandedKeyLength];
md5.update(clientKeyBytes);
--- a/jdk/src/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/TlsMasterSecretGenerator.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -64,12 +64,14 @@
}
this.spec = (TlsMasterSecretParameterSpec)params;
if ("RAW".equals(spec.getPremasterSecret().getFormat()) == false) {
- throw new InvalidAlgorithmParameterException("Key format must be RAW");
+ throw new InvalidAlgorithmParameterException(
+ "Key format must be RAW");
}
- protocolVersion = (spec.getMajorVersion() << 8) | spec.getMinorVersion();
- if ((protocolVersion < 0x0300) || (protocolVersion > 0x0302)) {
- throw new InvalidAlgorithmParameterException
- ("Only SSL 3.0, TLS 1.0, and TLS 1.1 supported");
+ protocolVersion = (spec.getMajorVersion() << 8)
+ | spec.getMinorVersion();
+ if ((protocolVersion < 0x0300) || (protocolVersion > 0x0303)) {
+ throw new InvalidAlgorithmParameterException(
+ "Only SSL 3.0, TLS 1.0/1.1/1.2 supported");
}
}
@@ -79,8 +81,8 @@
protected SecretKey engineGenerateKey() {
if (spec == null) {
- throw new IllegalStateException
- ("TlsMasterSecretGenerator must be initialized");
+ throw new IllegalStateException(
+ "TlsMasterSecretGenerator must be initialized");
}
SecretKey premasterKey = spec.getPremasterSecret();
byte[] premaster = premasterKey.getEncoded();
@@ -103,7 +105,11 @@
if (protocolVersion >= 0x0301) {
byte[] seed = concat(clientRandom, serverRandom);
- master = doPRF(premaster, LABEL_MASTER_SECRET, seed, 48);
+ master = ((protocolVersion >= 0x0303) ?
+ doTLS12PRF(premaster, LABEL_MASTER_SECRET, seed, 48,
+ spec.getPRFHashAlg(), spec.getPRFHashLength(),
+ spec.getPRFBlockSize()) :
+ doTLS10PRF(premaster, LABEL_MASTER_SECRET, seed, 48));
} else {
master = new byte[48];
MessageDigest md5 = MessageDigest.getInstance("MD5");
@@ -124,7 +130,8 @@
}
- return new TlsMasterSecretKey(master, premasterMajor, premasterMinor);
+ return new TlsMasterSecretKey(master, premasterMajor,
+ premasterMinor);
} catch (NoSuchAlgorithmException e) {
throw new ProviderException(e);
} catch (DigestException e) {
--- a/jdk/src/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/TlsPrfGenerator.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -37,11 +37,15 @@
/**
* KeyGenerator implementation for the TLS PRF function.
+ * <p>
+ * This class duplicates the HMAC functionality (RFC 2104) with
+ * performance optimizations (e.g. XOR'ing keys with padding doesn't
+ * need to be redone for each HMAC operation).
*
* @author Andreas Sterbenz
* @since 1.6
*/
-public final class TlsPrfGenerator extends KeyGeneratorSpi {
+abstract class TlsPrfGenerator extends KeyGeneratorSpi {
// magic constants and utility functions, also used by other files
// in this package
@@ -69,8 +73,10 @@
* TLS HMAC "inner" and "outer" padding. This isn't a function
* of the digest algorithm.
*/
- private static final byte[] HMAC_ipad = genPad((byte)0x36, 64);
- private static final byte[] HMAC_opad = genPad((byte)0x5c, 64);
+ private static final byte[] HMAC_ipad64 = genPad((byte)0x36, 64);
+ private static final byte[] HMAC_ipad128 = genPad((byte)0x36, 128);
+ private static final byte[] HMAC_opad64 = genPad((byte)0x5c, 64);
+ private static final byte[] HMAC_opad128 = genPad((byte)0x5c, 128);
// SSL3 magic mix constants ("A", "BB", "CCC", ...)
final static byte[][] SSL3_CONST = genConst();
@@ -123,8 +129,8 @@
this.spec = (TlsPrfParameterSpec)params;
SecretKey key = spec.getSecret();
if ((key != null) && ("RAW".equals(key.getFormat()) == false)) {
- throw new InvalidAlgorithmParameterException
- ("Key encoding format must be RAW");
+ throw new InvalidAlgorithmParameterException(
+ "Key encoding format must be RAW");
}
}
@@ -132,17 +138,21 @@
throw new InvalidParameterException(MSG);
}
- protected SecretKey engineGenerateKey() {
+ SecretKey engineGenerateKey0(boolean tls12) {
if (spec == null) {
- throw new IllegalStateException
- ("TlsPrfGenerator must be initialized");
+ throw new IllegalStateException(
+ "TlsPrfGenerator must be initialized");
}
SecretKey key = spec.getSecret();
byte[] secret = (key == null) ? null : key.getEncoded();
try {
byte[] labelBytes = spec.getLabel().getBytes("UTF8");
int n = spec.getOutputLength();
- byte[] prfBytes = doPRF(secret, labelBytes, spec.getSeed(), n);
+ byte[] prfBytes = (tls12 ?
+ doTLS12PRF(secret, labelBytes, spec.getSeed(), n,
+ spec.getPRFHashAlg(), spec.getPRFHashLength(),
+ spec.getPRFBlockSize()) :
+ doTLS10PRF(secret, labelBytes, spec.getSeed(), n));
return new SecretKeySpec(prfBytes, "TlsPrf");
} catch (GeneralSecurityException e) {
throw new ProviderException("Could not generate PRF", e);
@@ -151,16 +161,67 @@
}
}
- static final byte[] doPRF(byte[] secret, byte[] labelBytes, byte[] seed,
- int outputLength) throws NoSuchAlgorithmException, DigestException {
+ static byte[] doTLS12PRF(byte[] secret, byte[] labelBytes,
+ byte[] seed, int outputLength,
+ String prfHash, int prfHashLength, int prfBlockSize)
+ throws NoSuchAlgorithmException, DigestException {
+ if (prfHash == null) {
+ throw new NoSuchAlgorithmException("Unspecified PRF algorithm");
+ }
+ MessageDigest prfMD = MessageDigest.getInstance(prfHash);
+ return doTLS12PRF(secret, labelBytes, seed, outputLength,
+ prfMD, prfHashLength, prfBlockSize);
+ }
+
+ static byte[] doTLS12PRF(byte[] secret, byte[] labelBytes,
+ byte[] seed, int outputLength,
+ MessageDigest mdPRF, int mdPRFLen, int mdPRFBlockSize)
+ throws DigestException {
+
+ if (secret == null) {
+ secret = B0;
+ }
+
+ // If we have a long secret, digest it first.
+ if (secret.length > mdPRFBlockSize) {
+ secret = mdPRF.digest(secret);
+ }
+
+ byte[] output = new byte[outputLength];
+ byte [] ipad;
+ byte [] opad;
+
+ switch (mdPRFBlockSize) {
+ case 64:
+ ipad = HMAC_ipad64.clone();
+ opad = HMAC_opad64.clone();
+ break;
+ case 128:
+ ipad = HMAC_ipad128.clone();
+ opad = HMAC_opad128.clone();
+ break;
+ default:
+ throw new DigestException("Unexpected block size.");
+ }
+
+ // P_HASH(Secret, label + seed)
+ expand(mdPRF, mdPRFLen, secret, 0, secret.length, labelBytes,
+ seed, output, ipad, opad);
+
+ return output;
+ }
+
+ static byte[] doTLS10PRF(byte[] secret, byte[] labelBytes,
+ byte[] seed, int outputLength) throws NoSuchAlgorithmException,
+ DigestException {
MessageDigest md5 = MessageDigest.getInstance("MD5");
MessageDigest sha = MessageDigest.getInstance("SHA1");
- return doPRF(secret, labelBytes, seed, outputLength, md5, sha);
+ return doTLS10PRF(secret, labelBytes, seed, outputLength, md5, sha);
}
- static final byte[] doPRF(byte[] secret, byte[] labelBytes, byte[] seed,
- int outputLength, MessageDigest md5, MessageDigest sha)
- throws DigestException {
+ static byte[] doTLS10PRF(byte[] secret, byte[] labelBytes,
+ byte[] seed, int outputLength, MessageDigest md5,
+ MessageDigest sha) throws DigestException {
/*
* Split the secret into two halves S1 and S2 of same length.
* S1 is taken from the first half of the secret, S2 from the
@@ -183,10 +244,12 @@
byte[] output = new byte[outputLength];
// P_MD5(S1, label + seed)
- expand(md5, 16, secret, 0, seclen, labelBytes, seed, output);
+ expand(md5, 16, secret, 0, seclen, labelBytes, seed, output,
+ HMAC_ipad64.clone(), HMAC_opad64.clone());
// P_SHA-1(S2, label + seed)
- expand(sha, 20, secret, off, seclen, labelBytes, seed, output);
+ expand(sha, 20, secret, off, seclen, labelBytes, seed, output,
+ HMAC_ipad64.clone(), HMAC_opad64.clone());
return output;
}
@@ -201,16 +264,13 @@
* @param seed the seed
* @param output the output array
*/
- private static final void expand(MessageDigest digest, int hmacSize,
+ private static void expand(MessageDigest digest, int hmacSize,
byte[] secret, int secOff, int secLen, byte[] label, byte[] seed,
- byte[] output) throws DigestException {
+ byte[] output, byte[] pad1, byte[] pad2) throws DigestException {
/*
* modify the padding used, by XORing the key into our copy of that
* padding. That's to avoid doing that for each HMAC computation.
*/
- byte[] pad1 = HMAC_ipad.clone();
- byte[] pad2 = HMAC_opad.clone();
-
for (int i = 0; i < secLen; i++) {
pad1[i] ^= secret[i + secOff];
pad2[i] ^= secret[i + secOff];
@@ -275,7 +335,34 @@
}
remaining -= k;
}
-
}
+ /**
+ * A KeyGenerator implementation that supports TLS 1.2.
+ * <p>
+ * TLS 1.2 uses a different hash algorithm than 1.0/1.1 for the PRF
+ * calculations. As of 2010, there is no PKCS11-level support for TLS
+ * 1.2 PRF calculations, and no known OS's have an internal variant
+ * we could use. Therefore for TLS 1.2, we are updating JSSE to request
+ * a different provider algorithm: "SunTls12Prf". If we reused the
+ * name "SunTlsPrf", the PKCS11 provider would need be updated to
+ * fail correctly when presented with the wrong version number
+ * (via Provider.Service.supportsParameters()), and add the
+ * appropriate supportsParamters() checks into KeyGenerators (not
+ * currently there).
+ */
+ static public class V12 extends TlsPrfGenerator {
+ protected SecretKey engineGenerateKey() {
+ return engineGenerateKey0(true);
+ }
+ }
+
+ /**
+ * A KeyGenerator implementation that supports TLS 1.0/1.1.
+ */
+ static public class V10 extends TlsPrfGenerator {
+ protected SecretKey engineGenerateKey() {
+ return engineGenerateKey0(false);
+ }
+ }
}
--- a/jdk/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -69,8 +69,8 @@
protected SecretKey engineGenerateKey() {
if (spec == null) {
- throw new IllegalStateException
- ("TlsRsaPremasterSecretGenerator must be initialized");
+ throw new IllegalStateException(
+ "TlsRsaPremasterSecretGenerator must be initialized");
}
if (random == null) {
random = new SecureRandom();
--- a/jdk/src/share/classes/com/sun/jmx/defaults/ServiceName.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/defaults/ServiceName.java Tue Nov 02 19:40:45 2010 -0700
@@ -76,9 +76,9 @@
/**
* The vendor of the JMX specification implemented by this product.
* <BR>
- * The value is <CODE>Sun Microsystems</CODE>.
+ * The value is <CODE>Oracle Corporation</CODE>.
*/
- public static final String JMX_SPEC_VENDOR = "Sun Microsystems";
+ public static final String JMX_SPEC_VENDOR = "Oracle Corporation";
/**
* The name of this product implementing the JMX specification.
@@ -91,7 +91,7 @@
* The name of the vendor of this product implementing the
* JMX specification.
* <BR>
- * The value is <CODE>Sun Microsystems</CODE>.
+ * The value is <CODE>Oracle Corporation</CODE>.
*/
- public static final String JMX_IMPL_VENDOR = "Sun Microsystems";
+ public static final String JMX_IMPL_VENDOR = "Oracle Corporation";
}
--- a/jdk/src/share/classes/com/sun/jmx/snmp/ServiceName.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/snmp/ServiceName.java Tue Nov 02 19:40:45 2010 -0700
@@ -27,7 +27,7 @@
/**
* Used for storing default values used by SNMP Runtime services.
- * <p><b>This API is a Sun Microsystems internal API and is subject
+ * <p><b>This API is an Oracle Corporation internal API and is subject
* to change without notice.</b></p>
*/
public class ServiceName {
@@ -144,16 +144,16 @@
/**
* The vendor of the JMX specification implemented by this product.
* <BR>
- * The value is <CODE>Sun Microsystems</CODE>.
+ * The value is <CODE>Oracle Corporation</CODE>.
*/
- public static final String JMX_SPEC_VENDOR = "Sun Microsystems";
+ public static final String JMX_SPEC_VENDOR = "Oracle Corporation";
/**
* The name of the vendor of this product implementing the JMX specification.
* <BR>
- * The value is <CODE>Sun Microsystems</CODE>.
+ * The value is <CODE>Oracle Corporation</CODE>.
*/
- public static final String JMX_IMPL_VENDOR = "Sun Microsystems";
+ public static final String JMX_IMPL_VENDOR = "Oracle Corporation";
/**
* The build number of the current product version, of the form <CODE>rXX</CODE>.
--- a/jdk/src/share/classes/com/sun/management/package.html Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/com/sun/management/package.html Tue Nov 02 19:40:45 2010 -0700
@@ -30,7 +30,7 @@
</head>
<body bgcolor="white">
-This package contains Sun Microsystem's platform extension to
+This package contains Oracle Corporation's platform extension to
the implementation of the
<a href="{@docRoot}/../../../../api/java/lang/management/package-summary.html">
java.lang.management</a> API and also defines the management
--- a/jdk/src/share/classes/java/io/ObjectInputStream.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/java/io/ObjectInputStream.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, 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
@@ -265,7 +265,7 @@
* object currently being deserialized and descriptor for current class.
* Null when not during readObject upcall.
*/
- private CallbackContext curContext;
+ private SerialCallbackContext curContext;
/**
* Creates an ObjectInputStream that reads from the specified InputStream.
@@ -1798,7 +1798,7 @@
private void readExternalData(Externalizable obj, ObjectStreamClass desc)
throws IOException
{
- CallbackContext oldContext = curContext;
+ SerialCallbackContext oldContext = curContext;
curContext = null;
try {
boolean blocked = desc.hasBlockExternalData();
@@ -1857,10 +1857,10 @@
slotDesc.hasReadObjectMethod() &&
handles.lookupException(passHandle) == null)
{
- CallbackContext oldContext = curContext;
+ SerialCallbackContext oldContext = curContext;
try {
- curContext = new CallbackContext(obj, slotDesc);
+ curContext = new SerialCallbackContext(obj, slotDesc);
bin.setBlockDataMode(true);
slotDesc.invokeReadObject(obj, this);
@@ -3505,42 +3505,4 @@
}
}
- /**
- * Context that during upcalls to class-defined readObject methods; holds
- * object currently being deserialized and descriptor for current class.
- * This context keeps a boolean state to indicate that defaultReadObject
- * or readFields has already been invoked with this context or the class's
- * readObject method has returned; if true, the getObj method throws
- * NotActiveException.
- */
- private static class CallbackContext {
- private final Object obj;
- private final ObjectStreamClass desc;
- private final AtomicBoolean used = new AtomicBoolean();
-
- public CallbackContext(Object obj, ObjectStreamClass desc) {
- this.obj = obj;
- this.desc = desc;
- }
-
- public Object getObj() throws NotActiveException {
- checkAndSetUsed();
- return obj;
- }
-
- public ObjectStreamClass getDesc() {
- return desc;
- }
-
- private void checkAndSetUsed() throws NotActiveException {
- if (!used.compareAndSet(false, true)) {
- throw new NotActiveException(
- "not in readObject invocation or fields already read");
- }
- }
-
- public void setUsed() {
- used.set(true);
- }
- }
}
--- a/jdk/src/share/classes/java/io/ObjectOutputStream.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/java/io/ObjectOutputStream.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, 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
@@ -35,6 +35,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static java.io.ObjectStreamClass.processQueue;
+import java.io.SerialCallbackContext;
/**
* An ObjectOutputStream writes primitive data types and graphs of Java objects
@@ -191,10 +192,12 @@
private boolean enableReplace;
// values below valid only during upcalls to writeObject()/writeExternal()
- /** object currently being serialized */
- private Object curObj;
- /** descriptor for current class (null if in writeExternal()) */
- private ObjectStreamClass curDesc;
+ /**
+ * Context during upcalls to class-defined writeObject methods; holds
+ * object currently being serialized and descriptor for current class.
+ * Null when not during writeObject upcall.
+ */
+ private SerialCallbackContext curContext;
/** current PutField object */
private PutFieldImpl curPut;
@@ -426,9 +429,11 @@
* <code>OutputStream</code>
*/
public void defaultWriteObject() throws IOException {
- if (curObj == null || curDesc == null) {
+ if ( curContext == null ) {
throw new NotActiveException("not in call to writeObject");
}
+ Object curObj = curContext.getObj();
+ ObjectStreamClass curDesc = curContext.getDesc();
bout.setBlockDataMode(false);
defaultWriteFields(curObj, curDesc);
bout.setBlockDataMode(true);
@@ -446,9 +451,11 @@
*/
public ObjectOutputStream.PutField putFields() throws IOException {
if (curPut == null) {
- if (curObj == null || curDesc == null) {
+ if (curContext == null) {
throw new NotActiveException("not in call to writeObject");
}
+ Object curObj = curContext.getObj();
+ ObjectStreamClass curDesc = curContext.getDesc();
curPut = new PutFieldImpl(curDesc);
}
return curPut;
@@ -1420,17 +1427,15 @@
* writeExternal() method.
*/
private void writeExternalData(Externalizable obj) throws IOException {
- Object oldObj = curObj;
- ObjectStreamClass oldDesc = curDesc;
PutFieldImpl oldPut = curPut;
- curObj = obj;
- curDesc = null;
curPut = null;
if (extendedDebugInfo) {
debugInfoStack.push("writeExternal data");
}
+ SerialCallbackContext oldContext = curContext;
try {
+ curContext = null;
if (protocol == PROTOCOL_VERSION_1) {
obj.writeExternal(this);
} else {
@@ -1440,13 +1445,12 @@
bout.writeByte(TC_ENDBLOCKDATA);
}
} finally {
+ curContext = oldContext;
if (extendedDebugInfo) {
debugInfoStack.pop();
}
}
- curObj = oldObj;
- curDesc = oldDesc;
curPut = oldPut;
}
@@ -1461,12 +1465,9 @@
for (int i = 0; i < slots.length; i++) {
ObjectStreamClass slotDesc = slots[i].desc;
if (slotDesc.hasWriteObjectMethod()) {
- Object oldObj = curObj;
- ObjectStreamClass oldDesc = curDesc;
PutFieldImpl oldPut = curPut;
- curObj = obj;
- curDesc = slotDesc;
curPut = null;
+ SerialCallbackContext oldContext = curContext;
if (extendedDebugInfo) {
debugInfoStack.push(
@@ -1474,18 +1475,19 @@
slotDesc.getName() + "\")");
}
try {
+ curContext = new SerialCallbackContext(obj, slotDesc);
bout.setBlockDataMode(true);
slotDesc.invokeWriteObject(obj, this);
bout.setBlockDataMode(false);
bout.writeByte(TC_ENDBLOCKDATA);
} finally {
+ curContext.setUsed();
+ curContext = oldContext;
if (extendedDebugInfo) {
debugInfoStack.pop();
}
}
- curObj = oldObj;
- curDesc = oldDesc;
curPut = oldPut;
} else {
defaultWriteFields(obj, slotDesc);
--- a/jdk/src/share/classes/java/io/ObjectStreamClass.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/java/io/ObjectStreamClass.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, 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
@@ -1830,8 +1830,10 @@
private final ObjectStreamField[] fields;
/** number of primitive fields */
private final int numPrimFields;
- /** unsafe field keys */
- private final long[] keys;
+ /** unsafe field keys for reading fields - may contain dupes */
+ private final long[] readKeys;
+ /** unsafe fields keys for writing fields - no dupes */
+ private final long[] writeKeys;
/** field data offsets */
private final int[] offsets;
/** field type codes */
@@ -1849,16 +1851,22 @@
FieldReflector(ObjectStreamField[] fields) {
this.fields = fields;
int nfields = fields.length;
- keys = new long[nfields];
+ readKeys = new long[nfields];
+ writeKeys = new long[nfields];
offsets = new int[nfields];
typeCodes = new char[nfields];
ArrayList<Class<?>> typeList = new ArrayList<Class<?>>();
+ Set<Long> usedKeys = new HashSet<Long>();
+
for (int i = 0; i < nfields; i++) {
ObjectStreamField f = fields[i];
Field rf = f.getField();
- keys[i] = (rf != null) ?
+ long key = (rf != null) ?
unsafe.objectFieldOffset(rf) : Unsafe.INVALID_FIELD_OFFSET;
+ readKeys[i] = key;
+ writeKeys[i] = usedKeys.add(key) ?
+ key : Unsafe.INVALID_FIELD_OFFSET;
offsets[i] = f.getOffset();
typeCodes[i] = f.getTypeCode();
if (!f.isPrimitive()) {
@@ -1894,7 +1902,7 @@
* in array should be equal to Unsafe.INVALID_FIELD_OFFSET.
*/
for (int i = 0; i < numPrimFields; i++) {
- long key = keys[i];
+ long key = readKeys[i];
int off = offsets[i];
switch (typeCodes[i]) {
case 'Z':
@@ -1945,7 +1953,7 @@
throw new NullPointerException();
}
for (int i = 0; i < numPrimFields; i++) {
- long key = keys[i];
+ long key = writeKeys[i];
if (key == Unsafe.INVALID_FIELD_OFFSET) {
continue; // discard value
}
@@ -2006,7 +2014,7 @@
switch (typeCodes[i]) {
case 'L':
case '[':
- vals[offsets[i]] = unsafe.getObject(obj, keys[i]);
+ vals[offsets[i]] = unsafe.getObject(obj, readKeys[i]);
break;
default:
@@ -2027,7 +2035,7 @@
throw new NullPointerException();
}
for (int i = numPrimFields; i < fields.length; i++) {
- long key = keys[i];
+ long key = writeKeys[i];
if (key == Unsafe.INVALID_FIELD_OFFSET) {
continue; // discard value
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/io/SerialCallbackContext.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,58 @@
+ /*
+ * %W% %E%
+ *
+ * Copyright (c) 2006, 2010 Oracle and/or its affiliates. All rights reserved.
+ * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+
+ package java.io;
+
+ /**
+ * Context during upcalls from object stream to class-defined
+ * readObject/writeObject methods.
+ * Holds object currently being deserialized and descriptor for current class.
+ *
+ * This context keeps track of the thread it was constructed on, and allows
+ * only a single call of defaultReadObject, readFields, defaultWriteObject
+ * or writeFields which must be invoked on the same thread before the class's
+ * readObject/writeObject method has returned.
+ * If not set to the current thread, the getObj method throws NotActiveException.
+ */
+ final class SerialCallbackContext {
+ private final Object obj;
+ private final ObjectStreamClass desc;
+ /**
+ * Thread this context is in use by.
+ * As this only works in one thread, we do not need to worry about thread-safety.
+ */
+ private Thread thread;
+
+ public SerialCallbackContext(Object obj, ObjectStreamClass desc) {
+ this.obj = obj;
+ this.desc = desc;
+ this.thread = Thread.currentThread();
+ }
+
+ public Object getObj() throws NotActiveException {
+ checkAndSetUsed();
+ return obj;
+ }
+
+ public ObjectStreamClass getDesc() {
+ return desc;
+ }
+
+ private void checkAndSetUsed() throws NotActiveException {
+ if (thread != Thread.currentThread()) {
+ throw new NotActiveException(
+ "not in readObject invocation or fields already read");
+ }
+ thread = null;
+ }
+
+ public void setUsed() {
+ thread = null;
+ }
+ }
+
+
--- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java Tue Nov 02 19:40:45 2010 -0700
@@ -100,7 +100,8 @@
* @param minimumCapacity the minimum desired capacity.
*/
public void ensureCapacity(int minimumCapacity) {
- ensureCapacityInternal(minimumCapacity);
+ if (minimumCapacity > 0)
+ ensureCapacityInternal(minimumCapacity);
}
/**
@@ -108,6 +109,7 @@
* never synchronized.
*/
private void ensureCapacityInternal(int minimumCapacity) {
+ // overflow-conscious code
if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity);
}
--- a/jdk/src/share/classes/java/lang/ClassLoader.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/java/lang/ClassLoader.java Tue Nov 02 19:40:45 2010 -0700
@@ -553,6 +553,13 @@
* If either <tt>off</tt> or <tt>len</tt> is negative, or if
* <tt>off+len</tt> is greater than <tt>b.length</tt>.
*
+ * @throws SecurityException
+ * If an attempt is made to add this class to a package that
+ * contains classes that were signed by a different set of
+ * certificates than this class, or if an attempt is made
+ * to define a class in a package with a fully-qualified name
+ * that starts with "{@code java.}".
+ *
* @see #loadClass(String, boolean)
* @see #resolveClass(Class)
*
--- a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -28,9 +28,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.io.InterruptedIOException;
import java.io.FileDescriptor;
-import java.io.ByteArrayOutputStream;
import sun.net.ConnectionResetException;
import sun.net.NetHooks;
@@ -58,7 +56,7 @@
protected int fdUseCount = 0;
/* lock when increment/decrementing fdUseCount */
- protected Object fdLock = new Object();
+ protected final Object fdLock = new Object();
/* indicates a close is pending on the file descriptor */
protected boolean closePending = false;
@@ -68,7 +66,7 @@
private int CONNECTION_RESET_PENDING = 1;
private int CONNECTION_RESET = 2;
private int resetState;
- private Object resetLock = new Object();
+ private final Object resetLock = new Object();
/**
* Load net library into runtime.
@@ -100,25 +98,24 @@
protected void connect(String host, int port)
throws UnknownHostException, IOException
{
- IOException pending = null;
+ boolean connected = false;
try {
InetAddress address = InetAddress.getByName(host);
this.port = port;
this.address = address;
- try {
- connectToAddress(address, port, timeout);
- return;
- } catch (IOException e) {
- pending = e;
+ connectToAddress(address, port, timeout);
+ connected = true;
+ } finally {
+ if (!connected) {
+ try {
+ close();
+ } catch (IOException ioe) {
+ /* Do nothing. If connect threw an exception then
+ it will be passed up the call stack */
+ }
}
- } catch (UnknownHostException e) {
- pending = e;
}
-
- // everything failed
- close();
- throw pending;
}
/**
@@ -151,22 +148,29 @@
* SocketAddress subclass not supported by this socket
* @since 1.4
*/
- protected void connect(SocketAddress address, int timeout) throws IOException {
- if (address == null || !(address instanceof InetSocketAddress))
- throw new IllegalArgumentException("unsupported address type");
- InetSocketAddress addr = (InetSocketAddress) address;
- if (addr.isUnresolved())
- throw new UnknownHostException(addr.getHostName());
- this.port = addr.getPort();
- this.address = addr.getAddress();
+ protected void connect(SocketAddress address, int timeout)
+ throws IOException {
+ boolean connected = false;
+ try {
+ if (address == null || !(address instanceof InetSocketAddress))
+ throw new IllegalArgumentException("unsupported address type");
+ InetSocketAddress addr = (InetSocketAddress) address;
+ if (addr.isUnresolved())
+ throw new UnknownHostException(addr.getHostName());
+ this.port = addr.getPort();
+ this.address = addr.getAddress();
- try {
connectToAddress(this.address, port, timeout);
- return;
- } catch (IOException e) {
- // everything failed
- close();
- throw e;
+ connected = true;
+ } finally {
+ if (!connected) {
+ try {
+ close();
+ } catch (IOException ioe) {
+ /* Do nothing. If connect threw an exception then
+ it will be passed up the call stack */
+ }
+ }
}
}
@@ -311,7 +315,7 @@
}
}
try {
- FileDescriptor fd = acquireFD();
+ acquireFD();
try {
socketConnect(address, port, timeout);
/* socket may have been closed during poll/select */
@@ -370,7 +374,7 @@
* @param s the connection
*/
protected void accept(SocketImpl s) throws IOException {
- FileDescriptor fd = acquireFD();
+ acquireFD();
try {
socketAccept(s);
} finally {
@@ -562,7 +566,6 @@
close();
}
-
/*
* "Acquires" and returns the FileDescriptor for this impl
*
--- a/jdk/src/share/classes/java/nio/Direct-X-Buffer.java.template Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/java/nio/Direct-X-Buffer.java.template Tue Nov 02 19:40:45 2010 -0700
@@ -27,6 +27,7 @@
package java.nio;
+import java.io.FileDescriptor;
import sun.misc.Cleaner;
import sun.misc.Unsafe;
import sun.misc.VM;
@@ -114,7 +115,7 @@
//
Direct$Type$Buffer$RW$(int cap) { // package-private
#if[rw]
- super(-1, 0, cap, cap, false);
+ super(-1, 0, cap, cap);
boolean pa = VM.isDirectMemoryPageAligned();
int ps = Bits.pageSize();
long size = Math.max(1L, (long)cap + (pa ? ps : 0));
@@ -145,7 +146,7 @@
// Invoked only by JNI: NewDirectByteBuffer(void*, long)
//
private Direct$Type$Buffer(long addr, int cap) {
- super(-1, 0, cap, cap, false);
+ super(-1, 0, cap, cap);
address = addr;
cleaner = null;
}
@@ -154,14 +155,17 @@
// For memory-mapped buffers -- invoked by FileChannelImpl via reflection
//
- protected Direct$Type$Buffer$RW$(int cap, long addr, Runnable unmapper) {
+ protected Direct$Type$Buffer$RW$(int cap, long addr,
+ FileDescriptor fd,
+ Runnable unmapper)
+ {
#if[rw]
- super(-1, 0, cap, cap, true);
+ super(-1, 0, cap, cap, fd);
address = addr;
viewedBuffer = null;
cleaner = Cleaner.create(this, unmapper);
#else[rw]
- super(cap, addr, unmapper);
+ super(cap, addr, fd, unmapper);
#end[rw]
}
--- a/jdk/src/share/classes/java/nio/MappedByteBuffer.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/java/nio/MappedByteBuffer.java Tue Nov 02 19:40:45 2010 -0700
@@ -25,6 +25,7 @@
package java.nio;
+import java.io.FileDescriptor;
import sun.misc.Unsafe;
@@ -71,26 +72,26 @@
// for optimization purposes, it's easier to do it the other way around.
// This works because DirectByteBuffer is a package-private class.
- // Volatile to make sure that the finalization thread sees the current
- // value of this so that a region is not accidentally unmapped again later.
- volatile boolean isAMappedBuffer; // package-private
+ // For mapped buffers, a FileDescriptor that may be used for mapping
+ // operations if valid; null if the buffer is not mapped.
+ private final FileDescriptor fd;
// This should only be invoked by the DirectByteBuffer constructors
//
MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
- boolean mapped)
+ FileDescriptor fd)
{
super(mark, pos, lim, cap);
- isAMappedBuffer = mapped;
+ this.fd = fd;
}
MappedByteBuffer(int mark, int pos, int lim, int cap) { // package-private
super(mark, pos, lim, cap);
- isAMappedBuffer = false;
+ this.fd = null;
}
private void checkMapped() {
- if (!isAMappedBuffer)
+ if (fd == null)
// Can only happen if a luser explicitly casts a direct byte buffer
throw new UnsupportedOperationException();
}
@@ -191,13 +192,12 @@
checkMapped();
if ((address != 0) && (capacity() != 0)) {
long offset = mappingOffset();
- force0(mappingAddress(offset), mappingLength(offset));
+ force0(fd, mappingAddress(offset), mappingLength(offset));
}
return this;
}
private native boolean isLoaded0(long address, long length, int pageCount);
private native void load0(long address, long length);
- private native void force0(long address, long length);
-
+ private native void force0(FileDescriptor fd, long address, long length);
}
--- a/jdk/src/share/classes/java/nio/channels/AsynchronousDatagramChannel.java Tue Nov 02 12:45:49 2010 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,572 +0,0 @@
-/*
- * Copyright (c) 2007, 2009, 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 java.nio.channels;
-
-import java.nio.channels.spi.*;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.Future;
-import java.io.IOException;
-import java.net.SocketOption;
-import java.net.SocketAddress;
-import java.net.ProtocolFamily;
-import java.nio.ByteBuffer;
-
-/**
- * An asynchronous channel for datagram-oriented sockets.
- *
- * <p> An asynchronous datagram channel is created by invoking one of the {@link
- * #open open} methods defined by this class. It is not possible to create a channel
- * for an arbitrary, pre-existing datagram socket. A newly-created asynchronous
- * datagram channel is open but not connected. It need not be connected in order
- * for the {@link #send send} and {@link #receive receive} methods to be used.
- * A datagram channel may be connected, by invoking its {@link #connect connect}
- * method, in order to avoid the overhead of the security checks that are otherwise
- * performed as part of every send and receive operation when a security manager
- * is set. The channel must be connected in order to use the {@link #read read}
- * and {@link #write write} methods, since those methods do not accept or return
- * socket addresses. Once connected, an asynchronous datagram channel remains
- * connected until it is disconnected or closed.
- *
- * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
- * setOption} method. An asynchronous datagram channel to an Internet Protocol
- * (IP) socket supports the following options:
- * <blockquote>
- * <table border>
- * <tr>
- * <th>Option Name</th>
- * <th>Description</th>
- * </tr>
- * <tr>
- * <td> {@link java.net.StandardSocketOption#SO_SNDBUF SO_SNDBUF} </td>
- * <td> The size of the socket send buffer </td>
- * </tr>
- * <tr>
- * <td> {@link java.net.StandardSocketOption#SO_RCVBUF SO_RCVBUF} </td>
- * <td> The size of the socket receive buffer </td>
- * </tr>
- * <tr>
- * <td> {@link java.net.StandardSocketOption#SO_REUSEADDR SO_REUSEADDR} </td>
- * <td> Re-use address </td>
- * </tr>
- * <tr>
- * <td> {@link java.net.StandardSocketOption#SO_BROADCAST SO_BROADCAST} </td>
- * <td> Allow transmission of broadcast datagrams </td>
- * </tr>
- * <tr>
- * <td> {@link java.net.StandardSocketOption#IP_TOS IP_TOS} </td>
- * <td> The Type of Service (ToS) octet in the Internet Protocol (IP) header </td>
- * </tr>
- * <tr>
- * <td> {@link java.net.StandardSocketOption#IP_MULTICAST_IF IP_MULTICAST_IF} </td>
- * <td> The network interface for Internet Protocol (IP) multicast datagrams </td>
- * </tr>
- * <tr>
- * <td> {@link java.net.StandardSocketOption#IP_MULTICAST_TTL
- * IP_MULTICAST_TTL} </td>
- * <td> The <em>time-to-live</em> for Internet Protocol (IP) multicast
- * datagrams </td>
- * </tr>
- * <tr>
- * <td> {@link java.net.StandardSocketOption#IP_MULTICAST_LOOP
- * IP_MULTICAST_LOOP} </td>
- * <td> Loopback for Internet Protocol (IP) multicast datagrams </td>
- * </tr>
- * </table>
- * </blockquote>
- * Additional (implementation specific) options may also be supported.
- *
- * <p> Asynchronous datagram channels allow more than one read/receive and
- * write/send to be oustanding at any given time.
- *
- * <p> <b>Usage Example:</b>
- * <pre>
- * final AsynchronousDatagramChannel dc = AsynchronousDatagramChannel.open()
- * .bind(new InetSocketAddress(4000));
- *
- * // print the source address of all packets that we receive
- * dc.receive(buffer, buffer, new CompletionHandler<SocketAddress,ByteBuffer>() {
- * public void completed(SocketAddress sa, ByteBuffer buffer) {
- * System.out.println(sa);
- * buffer.clear();
- * dc.receive(buffer, buffer, this);
- * }
- * public void failed(Throwable exc, ByteBuffer buffer) {
- * ...
- * }
- * });
- * </pre>
- *
- * @since 1.7
- */
-
-public abstract class AsynchronousDatagramChannel
- implements AsynchronousByteChannel, MulticastChannel
-{
- private final AsynchronousChannelProvider provider;
-
- /**
- * Initializes a new instance of this class.
- */
- protected AsynchronousDatagramChannel(AsynchronousChannelProvider provider) {
- this.provider = provider;
- }
-
- /**
- * Returns the provider that created this channel.
- */
- public final AsynchronousChannelProvider provider() {
- return provider;
- }
-
- /**
- * Opens an asynchronous datagram channel.
- *
- * <p> The new channel is created by invoking the {@link
- * java.nio.channels.spi.AsynchronousChannelProvider#openAsynchronousDatagramChannel
- * openAsynchronousDatagramChannel} method on the {@link
- * java.nio.channels.spi.AsynchronousChannelProvider} object that created
- * the given group (or the default provider where {@code group} is {@code
- * null}).
- *
- * <p> The {@code family} parameter is used to specify the {@link ProtocolFamily}.
- * If the datagram channel is to be used for Internet Protocol {@link
- * MulticastChannel multicasting} then this parameter should correspond to
- * the address type of the multicast groups that this channel will join.
- *
- * @param family
- * The protocol family, or {@code null} to use the default protocol
- * family
- * @param group
- * The group to which the newly constructed channel should be bound,
- * or {@code null} for the default group
- *
- * @return A new asynchronous datagram channel
- *
- * @throws UnsupportedOperationException
- * If the specified protocol family is not supported. For example,
- * suppose the parameter is specified as {@link
- * java.net.StandardProtocolFamily#INET6 INET6} but IPv6 is not
- * enabled on the platform.
- * @throws ShutdownChannelGroupException
- * The specified group is shutdown
- * @throws IOException
- * If an I/O error occurs
- */
- public static AsynchronousDatagramChannel open(ProtocolFamily family,
- AsynchronousChannelGroup group)
- throws IOException
- {
- AsynchronousChannelProvider provider = (group == null) ?
- AsynchronousChannelProvider.provider() : group.provider();
- return provider.openAsynchronousDatagramChannel(family, group);
- }
-
- /**
- * Opens an asynchronous datagram channel.
- *
- * <p> This method returns an asynchronous datagram channel that is
- * bound to the <em>default group</em>. This method is equivalent to evaluating
- * the expression:
- * <blockquote><pre>
- * open((ProtocolFamily)null, (AsynchronousChannelGroup)null);
- * </pre></blockquote>
- *
- * @return A new asynchronous datagram channel
- *
- * @throws IOException
- * If an I/O error occurs
- */
- public static AsynchronousDatagramChannel open()
- throws IOException
- {
- return open(null, null);
- }
-
- // -- Socket-specific operations --
-
- /**
- * @throws AlreadyBoundException {@inheritDoc}
- * @throws UnsupportedAddressTypeException {@inheritDoc}
- * @throws ClosedChannelException {@inheritDoc}
- * @throws IOException {@inheritDoc}
- * @throws SecurityException
- * If a security manager has been installed and its {@link
- * SecurityManager#checkListen checkListen} method denies the
- * operation
- */
- @Override
- public abstract AsynchronousDatagramChannel bind(SocketAddress local)
- throws IOException;
-
- /**
- * @throws IllegalArgumentException {@inheritDoc}
- * @throws ClosedChannelException {@inheritDoc}
- * @throws IOException {@inheritDoc}
- */
- @Override
- public abstract <T> AsynchronousDatagramChannel setOption(SocketOption<T> name, T value)
- throws IOException;
-
- /**
- * Returns the remote address to which this channel is connected.
- *
- * <p> Where the channel is connected to an Internet Protocol socket address
- * then the return value from this method is of type {@link
- * java.net.InetSocketAddress}.
- *
- * @return The remote address; {@code null} if the channel's socket is not
- * connected
- *
- * @throws ClosedChannelException
- * If the channel is closed
- * @throws IOException
- * If an I/O error occurs
- */
- public abstract SocketAddress getRemoteAddress() throws IOException;
-
- /**
- * Connects this channel's socket.
- *
- * <p> The channel's socket is configured so that it only receives
- * datagrams from, and sends datagrams to, the given remote <i>peer</i>
- * address. Once connected, datagrams may not be received from or sent to
- * any other address. A datagram socket remains connected until it is
- * explicitly disconnected or until it is closed.
- *
- * <p> This method performs exactly the same security checks as the {@link
- * java.net.DatagramSocket#connect connect} method of the {@link
- * java.net.DatagramSocket} class. That is, if a security manager has been
- * installed then this method verifies that its {@link
- * java.lang.SecurityManager#checkAccept checkAccept} and {@link
- * java.lang.SecurityManager#checkConnect checkConnect} methods permit
- * datagrams to be received from and sent to, respectively, the given
- * remote address.
- *
- * <p> This method may be invoked at any time. Whether it has any effect
- * on outstanding read or write operations is implementation specific and
- * therefore not specified.
- *
- * @param remote
- * The remote address to which this channel is to be connected
- *
- * @return This datagram channel
- *
- * @throws ClosedChannelException
- * If this channel is closed
- *
- * @throws SecurityException
- * If a security manager has been installed
- * and it does not permit access to the given remote address
- *
- * @throws IOException
- * If some other I/O error occurs
- */
- public abstract AsynchronousDatagramChannel connect(SocketAddress remote)
- throws IOException;
-
- /**
- * Disconnects this channel's socket.
- *
- * <p> The channel's socket is configured so that it can receive datagrams
- * from, and sends datagrams to, any remote address so long as the security
- * manager, if installed, permits it.
- *
- * <p> This method may be invoked at any time. Whether it has any effect
- * on outstanding read or write operations is implementation specific and
- * therefore not specified.
- *
- * @return This datagram channel
- *
- * @throws IOException
- * If some other I/O error occurs
- */
- public abstract AsynchronousDatagramChannel disconnect() throws IOException;
-
- /**
- * Receives a datagram via this channel.
- *
- * <p> This method initiates the receiving of a datagram into the given
- * buffer. The {@code handler} parameter is a completion handler that is
- * invoked when the receive operation completes (or fails). The result
- * passed to the completion handler is the datagram's source address.
- *
- * <p> The datagram is transferred into the given byte buffer starting at
- * its current position, as if by a regular {@link AsynchronousByteChannel#read
- * read} operation. If there are fewer bytes remaining in the buffer
- * than are required to hold the datagram then the remainder of the datagram
- * is silently discarded.
- *
- * <p> If a timeout is specified and the timeout elapses before the operation
- * completes then the operation completes with the exception {@link
- * InterruptedByTimeoutException}. When a timeout elapses then the state of
- * the {@link ByteBuffer} is not defined. The buffers should be discarded or
- * at least care must be taken to ensure that the buffer is not accessed
- * while the channel remains open.
- *
- * <p> When a security manager has been installed and the channel is not
- * connected, then it verifies that the source's address and port number are
- * permitted by the security manager's {@link SecurityManager#checkAccept
- * checkAccept} method. The permission check is performed with privileges that
- * are restricted by the calling context of this method. If the permission
- * check fails then the operation completes with a {@link SecurityException}.
- * The overhead of this security check can be avoided by first connecting the
- * socket via the {@link #connect connect} method.
- *
- * @param dst
- * The buffer into which the datagram is to be transferred
- * @param timeout
- * The timeout, or {@code 0L} for no timeout
- * @param unit
- * The time unit of the {@code timeout} argument
- * @param attachment
- * The object to attach to the I/O operation; can be {@code null}
- * @param handler
- * The handler for consuming the result
- *
- * @throws IllegalArgumentException
- * If the timeout is negative or the buffer is read-only
- * @throws ShutdownChannelGroupException
- * If the channel group has terminated
- */
- public abstract <A> void receive(ByteBuffer dst,
- long timeout,
- TimeUnit unit,
- A attachment,
- CompletionHandler<SocketAddress,? super A> handler);
-
- /**
- * Receives a datagram via this channel.
- *
- * <p> This method initiates the receiving of a datagram into the given
- * buffer. The {@code handler} parameter is a completion handler that is
- * invoked when the receive operation completes (or fails). The result
- * passed to the completion handler is the datagram's source address.
- *
- * <p> This method is equivalent to invoking {@link
- * #receive(ByteBuffer,long,TimeUnit,Object,CompletionHandler)} with a
- * timeout of {@code 0L}.
- *
- * @param dst
- * The buffer into which the datagram is to be transferred
- * @param attachment
- * The object to attach to the I/O operation; can be {@code null}
- * @param handler
- * The handler for consuming the result
- *
- * @throws IllegalArgumentException
- * If the buffer is read-only
- * @throws ShutdownChannelGroupException
- * If the channel group has terminated
- */
- public final <A> void receive(ByteBuffer dst,
- A attachment,
- CompletionHandler<SocketAddress,? super A> handler)
- {
- receive(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
- }
-
- /**
- * Receives a datagram via this channel.
- *
- * <p> This method initiates the receiving of a datagram into the given
- * buffer. The method behaves in exactly the same manner as the {@link
- * #receive(ByteBuffer,Object,CompletionHandler)
- * receive(ByteBuffer,Object,CompletionHandler)} method except that instead
- * of specifying a completion handler, this method returns a {@code Future}
- * representing the pending result. The {@code Future}'s {@link Future#get()
- * get} method returns the datagram's source address.
- *
- * @param dst
- * The buffer into which the datagram is to be transferred
- *
- * @return a {@code Future} object representing the pending result
- *
- * @throws IllegalArgumentException
- * If the buffer is read-only
- */
- public abstract Future<SocketAddress> receive(ByteBuffer dst);
-
- /**
- * Sends a datagram via this channel.
- *
- * <p> This method initiates sending of a datagram from the given buffer to
- * the given address. The {@code handler} parameter is a completion handler
- * that is invoked when the send completes (or fails). The result passed to
- * the completion handler is the number of bytes sent.
- *
- * <p> Otherwise this method works in the same manner as the {@link
- * AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)}
- * method.
- *
- * @param src
- * The buffer containing the datagram to be sent
- * @param target
- * The address to which the datagram is to be sent
- * @param attachment
- * The object to attach to the I/O operation; can be {@code null}
- * @param handler
- * The handler for consuming the result
- *
- * @throws UnresolvedAddressException
- * If the given remote address is not fully resolved
- * @throws UnsupportedAddressTypeException
- * If the type of the given remote address is not supported
- * @throws IllegalArgumentException
- * If the channel's socket is connected and is connected to an
- * address that is not equal to {@code target}
- * @throws SecurityException
- * If a security manager has been installed and it does not permit
- * datagrams to be sent to the given address
- * @throws ShutdownChannelGroupException
- * If the channel group has terminated
- */
- public abstract <A> void send(ByteBuffer src,
- SocketAddress target,
- A attachment,
- CompletionHandler<Integer,? super A> handler);
-
- /**
- * Sends a datagram via this channel.
- *
- * <p> This method initiates sending of a datagram from the given buffer to
- * the given address. The method behaves in exactly the same manner as the
- * {@link #send(ByteBuffer,SocketAddress,Object,CompletionHandler)
- * send(ByteBuffer,SocketAddress,Object,CompletionHandler)} method except
- * that instead of specifying a completion handler, this method returns a
- * {@code Future} representing the pending result. The {@code Future}'s
- * {@link Future#get() get} method returns the number of bytes sent.
- *
- * @param src
- * The buffer containing the datagram to be sent
- * @param target
- * The address to which the datagram is to be sent
- *
- * @return a {@code Future} object representing the pending result
- *
- * @throws UnresolvedAddressException
- * If the given remote address is not fully resolved
- * @throws UnsupportedAddressTypeException
- * If the type of the given remote address is not supported
- * @throws IllegalArgumentException
- * If the channel's socket is connected and is connected to an
- * address that is not equal to {@code target}
- * @throws SecurityException
- * If a security manager has been installed and it does not permit
- * datagrams to be sent to the given address
- */
- public abstract Future<Integer> send(ByteBuffer src, SocketAddress target);
-
- /**
- * Receives a datagram via this channel.
- *
- * <p> This method initiates the receiving of a datagram into the given
- * buffer. The {@code handler} parameter is a completion handler that is
- * invoked when the receive operation completes (or fails). The result
- * passed to the completion handler is number of bytes read.
- *
- * <p> This method may only be invoked if this channel is connected, and it
- * only accepts datagrams from the peer that the channel is connected too.
- * The datagram is transferred into the given byte buffer starting at
- * its current position and exactly as specified in the {@link
- * AsynchronousByteChannel} interface. If there are fewer bytes
- * remaining in the buffer than are required to hold the datagram then the
- * remainder of the datagram is silently discarded.
- *
- * <p> If a timeout is specified and the timeout elapses before the operation
- * completes then the operation completes with the exception {@link
- * InterruptedByTimeoutException}. When a timeout elapses then the state of
- * the {@link ByteBuffer} is not defined. The buffers should be discarded or
- * at least care must be taken to ensure that the buffer is not accessed
- * while the channel remains open.
- *
- * @param dst
- * The buffer into which the datagram is to be transferred
- * @param timeout
- * The timeout, or {@code 0L} for no timeout
- * @param unit
- * The time unit of the {@code timeout} argument
- * @param attachment
- * The object to attach to the I/O operation; can be {@code null}
- * @param handler
- * The handler for consuming the result
- *
- * @throws IllegalArgumentException
- * If the timeout is negative or buffer is read-only
- * @throws NotYetConnectedException
- * If this channel is not connected
- * @throws ShutdownChannelGroupException
- * If the channel group has terminated
- */
- public abstract <A> void read(ByteBuffer dst,
- long timeout,
- TimeUnit unit,
- A attachment,
- CompletionHandler<Integer,? super A> handler);
-
- /**
- * @throws NotYetConnectedException
- * If this channel is not connected
- * @throws ShutdownChannelGroupException
- * If the channel group has terminated
- */
- @Override
- public final <A> void read(ByteBuffer dst,
- A attachment,
- CompletionHandler<Integer,? super A> handler)
- {
- read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
- }
-
- /**
- * @throws NotYetConnectedException
- * If this channel is not connected
- * @throws ShutdownChannelGroupException
- * If the channel group has terminated
- */
- @Override
- public abstract Future<Integer> read(ByteBuffer dst);
-
- /**
- * @throws NotYetConnectedException
- * If this channel is not connected
- * @throws ShutdownChannelGroupException
- * If the channel group has terminated
- */
- @Override
- public abstract <A> void write(ByteBuffer src,
- A attachment,
- CompletionHandler<Integer,? super A> handler);
-
-
- /**
- * @throws NotYetConnectedException
- * If this channel is not connected
- * @throws ShutdownChannelGroupException
- * If the channel group has terminated
- */
- @Override
- public abstract Future<Integer> write(ByteBuffer src);
-}
--- a/jdk/src/share/classes/java/nio/channels/package-info.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/java/nio/channels/package-info.java Tue Nov 02 19:40:45 2010 -0700
@@ -232,8 +232,6 @@
* <td>An asynchronous channel to a stream-oriented connecting socket</td></tr>
* <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousServerSocketChannel} </tt></td>
* <td>An asynchronous channel to a stream-oriented listening socket</td></tr>
- * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousDatagramChannel}</tt></td>
- * <td>An asynchronous channel to a datagram-oriented socket</td></tr>
* <tr><td valign=top><tt>{@link java.nio.channels.CompletionHandler}</tt></td>
* <td>A handler for consuming the result of an asynchronous operation</td></tr>
* <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousChannelGroup}</tt></td>
--- a/jdk/src/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java Tue Nov 02 19:40:45 2010 -0700
@@ -26,7 +26,6 @@
package java.nio.channels.spi;
import java.nio.channels.*;
-import java.net.ProtocolFamily;
import java.io.IOException;
import java.util.Iterator;
import java.util.ServiceLoader;
@@ -239,26 +238,4 @@
*/
public abstract AsynchronousSocketChannel openAsynchronousSocketChannel
(AsynchronousChannelGroup group) throws IOException;
-
- /**
- * Opens an asynchronous datagram channel.
- *
- * @param family
- * The protocol family, or {@code null} for the default protocol
- * family
- * @param group
- * The group to which the channel is bound, or {@code null} to
- * bind to the default group
- *
- * @return The new channel
- *
- * @throws IllegalChannelGroupException
- * If the provider that created the group differs from this provider
- * @throws ShutdownChannelGroupException
- * The group is shutdown
- * @throws IOException
- * If an I/O error occurs
- */
- public abstract AsynchronousDatagramChannel openAsynchronousDatagramChannel
- (ProtocolFamily family, AsynchronousChannelGroup group) throws IOException;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/security/AlgorithmConstraints.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2010, 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 java.security;
+
+import java.util.Set;
+
+/**
+ * This interface specifies constraints for cryptographic algorithms,
+ * keys (key sizes), and other algorithm parameters.
+ * <p>
+ * {@code AlgorithmConstraints} objects are immutable. An implementation
+ * of this interface should not provide methods that can change the state
+ * of an instance once it has been created.
+ * <p>
+ * Note that {@code AlgorithmConstraints} can be used to represent the
+ * restrictions described by the security properties
+ * {@code jdk.certpath.disabledAlgorithms} and
+ * {@code jdk.tls.disabledAlgorithms}, or could be used by a
+ * concrete {@code PKIXCertPathChecker} to check whether a specified
+ * certificate in the certification path contains the required algorithm
+ * constraints.
+ *
+ * @see javax.net.ssl.SSLParameters#getAlgorithmConstraints
+ * @see javax.net.ssl.SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
+ *
+ * @since 1.7
+ */
+
+public interface AlgorithmConstraints {
+
+ /**
+ * Determines whether an algorithm is granted permission for the
+ * specified cryptographic primitives.
+ *
+ * @param primitives a set of cryptographic primitives
+ * @param algorithm the algorithm name
+ * @param parameters the algorithm parameters, or null if no additional
+ * parameters
+ *
+ * @return true if the algorithm is permitted and can be used for all
+ * of the specified cryptographic primitives
+ *
+ * @throws IllegalArgumentException if primitives or algorithm is null
+ * or empty
+ */
+ public boolean permits(Set<CryptoPrimitive> primitives,
+ String algorithm, AlgorithmParameters parameters);
+
+ /**
+ * Determines whether a key is granted permission for the specified
+ * cryptographic primitives.
+ * <p>
+ * This method is usually used to check key size and key usage.
+ *
+ * @param primitives a set of cryptographic primitives
+ * @param key the key
+ *
+ * @return true if the key can be used for all of the specified
+ * cryptographic primitives
+ *
+ * @throws IllegalArgumentException if primitives is null or empty,
+ * or the key is null
+ */
+ public boolean permits(Set<CryptoPrimitive> primitives, Key key);
+
+ /**
+ * Determines whether an algorithm and the corresponding key are granted
+ * permission for the specified cryptographic primitives.
+ *
+ * @param primitives a set of cryptographic primitives
+ * @param algorithm the algorithm name
+ * @param key the key
+ * @param parameters the algorithm parameters, or null if no additional
+ * parameters
+ *
+ * @return true if the key and the algorithm can be used for all of the
+ * specified cryptographic primitives
+ *
+ * @throws IllegalArgumentException if primitives or algorithm is null
+ * or empty, or the key is null
+ */
+ public boolean permits(Set<CryptoPrimitive> primitives,
+ String algorithm, Key key, AlgorithmParameters parameters);
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/java/security/CryptoPrimitive.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2010, 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 java.security;
+
+/**
+ * An enumeration of cryptographic primitives.
+ *
+ * @since 1.7
+ */
+public enum CryptoPrimitive {
+ /**
+ * Hash function
+ */
+ MESSAGE_DIGEST,
+
+ /**
+ * Cryptographic random number generator
+ */
+ SECURE_RANDOM,
+
+ /**
+ * Symmetric primitive: block cipher
+ */
+ BLOCK_CIPHER,
+
+ /**
+ * Symmetric primitive: stream cipher
+ */
+ STREAM_CIPHER,
+
+ /**
+ * Symmetric primitive: message authentication code
+ */
+ MAC,
+
+ /**
+ * Symmetric primitive: key wrap
+ */
+ KEY_WRAP,
+
+ /**
+ * Asymmetric primitive: public key encryption
+ */
+ PUBLIC_KEY_ENCRYPTION,
+
+ /**
+ * Asymmetric primitive: signature scheme
+ */
+ SIGNATURE,
+
+ /**
+ * Asymmetric primitive: key encapsulation mechanism
+ */
+ KEY_ENCAPSULATION,
+
+ /**
+ * Asymmetric primitive: key agreement and key distribution
+ */
+ KEY_AGREEMENT
+}
--- a/jdk/src/share/classes/java/util/ArrayList.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/java/util/ArrayList.java Tue Nov 02 19:40:45 2010 -0700
@@ -176,6 +176,11 @@
* @param minCapacity the desired minimum capacity
*/
public void ensureCapacity(int minCapacity) {
+ if (minCapacity > 0)
+ ensureCapacityInternal(minCapacity);
+ }
+
+ private void ensureCapacityInternal(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
@@ -403,7 +408,7 @@
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
- ensureCapacity(size + 1); // Increments modCount!!
+ ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
@@ -420,7 +425,7 @@
public void add(int index, E element) {
rangeCheckForAdd(index);
- ensureCapacity(size + 1); // Increments modCount!!
+ ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
@@ -524,7 +529,7 @@
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
- ensureCapacity(size + numNew); // Increments modCount
+ ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
@@ -550,7 +555,7 @@
Object[] a = c.toArray();
int numNew = a.length;
- ensureCapacity(size + numNew); // Increments modCount
+ ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index;
if (numMoved > 0)
--- a/jdk/src/share/classes/java/util/Vector.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/java/util/Vector.java Tue Nov 02 19:40:45 2010 -0700
@@ -222,8 +222,10 @@
* @param minCapacity the desired minimum capacity
*/
public synchronized void ensureCapacity(int minCapacity) {
- modCount++;
- ensureCapacityHelper(minCapacity);
+ if (minCapacity > 0) {
+ modCount++;
+ ensureCapacityHelper(minCapacity);
+ }
}
/**
--- a/jdk/src/share/classes/java/util/logging/LogRecord.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/java/util/logging/LogRecord.java Tue Nov 02 19:40:45 2010 -0700
@@ -529,8 +529,6 @@
Throwable throwable = new Throwable();
int depth = access.getStackTraceDepth(throwable);
- String logClassName = "java.util.logging.Logger";
- String plogClassName = "sun.util.logging.PlatformLogger";
boolean lookingForLogger = true;
for (int ix = 0; ix < depth; ix++) {
// Calling getStackTraceElement directly prevents the VM
@@ -538,13 +536,14 @@
StackTraceElement frame =
access.getStackTraceElement(throwable, ix);
String cname = frame.getClassName();
+ boolean isLoggerImpl = isLoggerImplFrame(cname);
if (lookingForLogger) {
// Skip all frames until we have found the first logger frame.
- if (cname.equals(logClassName) || cname.startsWith(plogClassName)) {
+ if (isLoggerImpl) {
lookingForLogger = false;
}
} else {
- if (!cname.equals(logClassName) && !cname.startsWith(plogClassName)) {
+ if (!isLoggerImpl) {
// skip reflection call
if (!cname.startsWith("java.lang.reflect.") && !cname.startsWith("sun.reflect.")) {
// We've found the relevant frame.
@@ -558,4 +557,11 @@
// We haven't found a suitable frame, so just punt. This is
// OK as we are only committed to making a "best effort" here.
}
+
+ private boolean isLoggerImplFrame(String cname) {
+ // the log record could be created for a platform logger
+ return (cname.equals("java.util.logging.Logger") ||
+ cname.startsWith("java.util.logging.LoggingProxyImpl") ||
+ cname.startsWith("sun.util.logging."));
+ }
}
--- a/jdk/src/share/classes/javax/management/ObjectName.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/javax/management/ObjectName.java Tue Nov 02 19:40:45 2010 -0700
@@ -211,8 +211,8 @@
* reverse DNS name of the organization that specifies the MBeans,
* followed by a period and a string whose interpretation is
* determined by that organization. For example, MBeans specified by
- * Sun Microsystems Inc., DNS name <code>sun.com</code>, would have
- * domains such as <code>com.sun.MyDomain</code>. This is essentially
+ * <code>example.com</code> would have
+ * domains such as <code>com.example.MyDomain</code>. This is essentially
* the same convention as for Java-language package names.</p>
*
* <p>The <b>serialVersionUID</b> of this class is <code>1081892073854801359L</code>.
--- a/jdk/src/share/classes/javax/management/build.xml Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/javax/management/build.xml Tue Nov 02 19:40:45 2010 -0700
@@ -35,18 +35,18 @@
. Please also read the important comment on basedir definition below.
-->
-<project name="JMX API Version 1.4 - Java SE 6 implementation"
- default="jar"
- basedir="../../../../.."
+<project name="JMX API Version 1.4 - Java SE 6 implementation"
+ default="jar"
+ basedir="../../../../.."
>
- <!-- IMPORTANT: BASEDIR DEFINITION
- This file is assumed to be in:
- <src_bundle_dir>/j2se/src/share/classes/javax/management
- Thus the basedir for this project is defined above as:
- basedir="../../../../.."
+ <!-- IMPORTANT: BASEDIR DEFINITION
+ This file is assumed to be in:
+ <src_bundle_dir>/j2se/src/share/classes/javax/management
+ Thus the basedir for this project is defined above as:
+ basedir="../../../../.."
in order to be the parent dir of src subdir.
- Result of the build will be placed in ${basedir}/build_jmx
+ Result of the build will be placed in ${basedir}/build_jmx
as defined by ${dir.build} property below.
-->
@@ -163,14 +163,14 @@
<echo message=" BUILD_DATE = ${BUILD_DATE}" />
</target>
-
+
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- Call classes subtargets and rmic stubs generation -->
- <target name="classes" depends="init,classes-javac,classes-rmic"
- description="Call classes subtargets and rmic stubs generation"
+ <target name="classes" depends="init,classes-javac,classes-rmic"
+ description="Call classes subtargets and rmic stubs generation"
/>
@@ -183,13 +183,13 @@
<mkdir dir="${dir.build.classes}" />
<javac srcdir="${dir.src}"
- destdir="${dir.build.classes}"
+ destdir="${dir.build.classes}"
source="${flag.javac.source}"
debug="${flag.debug}"
debuglevel="${flag.debug.level}"
optimize="${flag.optimize}"
includeAntRuntime="no"
- includeJavaRuntime="no"
+ includeJavaRuntime="no"
>
<include name="javax/management/**"/>
<include name="com/sun/jmx/**"/>
@@ -253,7 +253,7 @@
<mkdir dir="${dir.build.lib}" />
- <jar jarfile="${dir.build.lib}/jmx.jar"
+ <jar jarfile="${dir.build.lib}/jmx.jar"
update="true"
>
@@ -269,10 +269,10 @@
<attribute name="Sealed" value="true" />
<attribute name="Specification-Title" value="JMX(TM) API" />
<attribute name="Specification-Version" value="1.4" />
- <attribute name="Specification-Vendor" value="Sun Microsystems, Inc." />
+ <attribute name="Specification-Vendor" value="Oracle Corporation" />
<attribute name="Implementation-Title" value="JMX(TM) API, Java SE 6 implementation" />
- <attribute name="Implementation-Version" value="${BUILD_DATE} rebuild of Mustang JMX sources" />
- <attribute name="Implementation-Vendor" value="Source bundle from Sun Microsystems, Inc. - Customer rebuilt" />
+ <attribute name="Implementation-Version" value="${BUILD_DATE} rebuild of Java SE JMX sources" />
+ <attribute name="Implementation-Vendor" value="Source bundle from Oracle Corporation - Customer rebuilt" />
</section>
</manifest>
</jar>
@@ -295,16 +295,16 @@
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- Delete build directory and all its contents -->
- <target name="clean-all"
+ <target name="clean-all"
description="Delete build directory and all its contents" >
<delete dir="${dir.build}" />
- </target>
-
-
+ </target>
+
+
<!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<!-- Clean all and build everything -->
- <target name="all" depends="clean-all,jar"
+ <target name="all" depends="clean-all,jar"
description="Clean all and build everything" />
--- a/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanNotificationInfo.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/javax/management/modelmbean/ModelMBeanNotificationInfo.java Tue Nov 02 19:40:45 2010 -0700
@@ -92,8 +92,6 @@
* @since 1.5
*/
-// Sun Microsystems, Sept. 2002: Revisited for JMX 1.2 (DF)
-//
@SuppressWarnings("serial") // serialVersionUID is not constant
public class ModelMBeanNotificationInfo
extends MBeanNotificationInfo
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/ExtendedSSLSession.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2010, 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 javax.net.ssl;
+
+/**
+ * Extends the <code>SSLSession</code> interface to support additional
+ * session attributes.
+ *
+ * @since 1.7
+ */
+public abstract class ExtendedSSLSession implements SSLSession {
+ /**
+ * Obtains an array of supported signature algorithms that the local side
+ * is willing to use.
+ * <p>
+ * Note: this method is used to indicate to the peer which signature
+ * algorithms may be used for digital signatures in TLS 1.2. It is
+ * not meaningful for TLS versions prior to 1.2.
+ * <p>
+ * The signature algorithm name must be a standard Java Security
+ * name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
+ * See Appendix A in the <a href=
+ * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
+ * Java Cryptography Architecture API Specification & Reference </a>
+ * for information about standard algorithm names.
+ * <p>
+ * Note: the local supported signature algorithms should conform to
+ * the algorithm constraints specified by
+ * {@link SSLParameters#getAlgorithmConstraints getAlgorithmConstraints()}
+ * method in <code>SSLParameters</code>.
+ *
+ * @return An array of supported signature algorithms, in descending
+ * order of preference. The return value is an empty array if
+ * no signature algorithm is supported.
+ *
+ * @see SSLParameters#getAlgorithmConstraints
+ */
+ public abstract String[] getLocalSupportedSignatureAlgorithms();
+
+ /**
+ * Obtains an array of supported signature algorithms that the peer is
+ * able to use.
+ * <p>
+ * Note: this method is used to indicate to the local side which signature
+ * algorithms may be used for digital signatures in TLS 1.2. It is
+ * not meaningful for TLS versions prior to 1.2.
+ * <p>
+ * The signature algorithm name must be a standard Java Security
+ * name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
+ * See Appendix A in the <a href=
+ * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
+ * Java Cryptography Architecture API Specification & Reference </a>
+ * for information about standard algorithm names.
+ *
+ * @return An array of supported signature algorithms, in descending
+ * order of preference. The return value is an empty array if
+ * the peer has not sent the supported signature algorithms.
+ *
+ * @see X509KeyManager
+ * @see X509ExtendedKeyManager
+ */
+ public abstract String[] getPeerSupportedSignatureAlgorithms();
+}
--- a/jdk/src/share/classes/javax/net/ssl/HttpsURLConnection.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/javax/net/ssl/HttpsURLConnection.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, 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
@@ -188,19 +188,8 @@
* <p>
* The default implementation will deny such connections.
*/
- private static HostnameVerifier defaultHostnameVerifier;
-
- /**
- * Initialize the default <code>HostnameVerifier</code>.
- */
- static {
- try {
- defaultHostnameVerifier =
- new sun.net.www.protocol.https.DefaultHostnameVerifier();
- } catch (NoClassDefFoundError e) {
- defaultHostnameVerifier = new DefaultHostnameVerifier();
- }
- }
+ private static HostnameVerifier defaultHostnameVerifier =
+ new DefaultHostnameVerifier();
/*
* The initial default <code>HostnameVerifier</code>. Should be
--- a/jdk/src/share/classes/javax/net/ssl/SSLEngine.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/javax/net/ssl/SSLEngine.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -968,6 +968,47 @@
/**
+ * Returns the {@code SSLSession} being constructed during a SSL/TLS
+ * handshake.
+ * <p>
+ * TLS protocols may negotiate parameters that are needed when using
+ * an instance of this class, but before the {@code SSLSession} has
+ * been completely initialized and made available via {@code getSession}.
+ * For example, the list of valid signature algorithms may restrict
+ * the type of certificates that can used during TrustManager
+ * decisions, or the maximum TLS fragment packet sizes can be
+ * resized to better support the network environment.
+ * <p>
+ * This method provides early access to the {@code SSLSession} being
+ * constructed. Depending on how far the handshake has progressed,
+ * some data may not yet be available for use. For example, if a
+ * remote server will be sending a Certificate chain, but that chain
+ * has yet not been processed, the {@code getPeerCertificates}
+ * method of {@code SSLSession} will throw a
+ * SSLPeerUnverifiedException. Once that chain has been processed,
+ * {@code getPeerCertificates} will return the proper value.
+ *
+ * @see SSLSocket
+ * @see SSLSession
+ * @see ExtendedSSLSession
+ * @see X509ExtendedKeyManager
+ * @see X509ExtendedTrustManager
+ *
+ * @return null if this instance is not currently handshaking, or
+ * if the current handshake has not progressed far enough to
+ * create a basic SSLSession. Otherwise, this method returns the
+ * {@code SSLSession} currently being negotiated.
+ * @throws UnsupportedOperationException if the underlying provider
+ * does not implement the operation.
+ *
+ * @since 1.7
+ */
+ public SSLSession getHandshakeSession() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ /**
* Initiates handshaking (initial or renegotiation) on this SSLEngine.
* <P>
* This method is not needed for the initial handshake, as the
--- a/jdk/src/share/classes/javax/net/ssl/SSLParameters.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/javax/net/ssl/SSLParameters.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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,24 +25,29 @@
package javax.net.ssl;
+import java.security.AlgorithmConstraints;
+
/**
* Encapsulates parameters for an SSL/TLS connection. The parameters
* are the list of ciphersuites to be accepted in an SSL/TLS handshake,
- * the list of protocols to be allowed, and whether SSL/TLS servers should
- * request or require client authentication.
- *
- * <p>SSLParameters can be created via the constructors in this class.
+ * the list of protocols to be allowed, the endpoint identification
+ * algorithm during SSL/TLS handshaking, the algorithm constraints and
+ * whether SSL/TLS servers should request or require client authentication.
+ * <p>
+ * SSLParameters can be created via the constructors in this class.
* Objects can also be obtained using the <code>getSSLParameters()</code>
* methods in
* {@link SSLSocket#getSSLParameters SSLSocket} and
+ * {@link SSLServerSocket#getSSLParameters SSLServerSocket} and
* {@link SSLEngine#getSSLParameters SSLEngine} or the
* {@link SSLContext#getDefaultSSLParameters getDefaultSSLParameters()} and
* {@link SSLContext#getSupportedSSLParameters getSupportedSSLParameters()}
* methods in <code>SSLContext</code>.
- *
- * <P>SSLParameters can be applied to a connection via the methods
+ * <p>
+ * SSLParameters can be applied to a connection via the methods
* {@link SSLSocket#setSSLParameters SSLSocket.setSSLParameters()} and
- * {@link SSLEngine#setSSLParameters SSLEngine.getSSLParameters()}.
+ * {@link SSLServerSocket#setSSLParameters SSLServerSocket.setSSLParameters()}
+ * and {@link SSLEngine#setSSLParameters SSLEngine.getSSLParameters()}.
*
* @see SSLSocket
* @see SSLEngine
@@ -56,11 +61,13 @@
private String[] protocols;
private boolean wantClientAuth;
private boolean needClientAuth;
+ private String identificationAlgorithm;
+ private AlgorithmConstraints algorithmConstraints;
/**
* Constructs SSLParameters.
- *
- * <p>The cipherSuites and protocols values are set to <code>null</code>,
+ * <p>
+ * The cipherSuites and protocols values are set to <code>null</code>,
* wantClientAuth and needClientAuth are set to <code>false</code>.
*/
public SSLParameters() {
@@ -69,6 +76,7 @@
/**
* Constructs SSLParameters from the specified array of ciphersuites.
+ * <p>
* Calling this constructor is equivalent to calling the no-args
* constructor followed by
* <code>setCipherSuites(cipherSuites);</code>.
@@ -82,6 +90,7 @@
/**
* Constructs SSLParameters from the specified array of ciphersuites
* and protocols.
+ * <p>
* Calling this constructor is equivalent to calling the no-args
* constructor followed by
* <code>setCipherSuites(cipherSuites); setProtocols(protocols);</code>.
@@ -178,4 +187,71 @@
this.needClientAuth = needClientAuth;
}
+ /**
+ * Returns the cryptographic algorithm constraints.
+ *
+ * @return the cryptographic algorithm constraints, or null if the
+ * constraints have not been set
+ *
+ * @see #setAlgorithmConstraints(AlgorithmConstraints)
+ *
+ * @since 1.7
+ */
+ public AlgorithmConstraints getAlgorithmConstraints() {
+ return algorithmConstraints;
+ }
+
+ /**
+ * Sets the cryptographic algorithm constraints, which will be used
+ * in addition to any configured by the runtime environment.
+ * <p>
+ * If the <code>constraints</code> parameter is non-null, every
+ * cryptographic algorithm, key and algorithm parameters used in the
+ * SSL/TLS handshake must be permitted by the constraints.
+ *
+ * @param constraints the algorithm constraints (or null)
+ *
+ * @since 1.7
+ */
+ public void setAlgorithmConstraints(AlgorithmConstraints constraints) {
+ // the constraints object is immutable
+ this.algorithmConstraints = constraints;
+ }
+
+ /**
+ * Gets the endpoint identification algorithm.
+ *
+ * @return the endpoint identification algorithm, or null if none
+ * has been set.
+ *
+ * @see X509ExtendedTrustManager
+ * @see #setEndpointIdentificationAlgorithm(String)
+ *
+ * @since 1.7
+ */
+ public String getEndpointIdentificationAlgorithm() {
+ return identificationAlgorithm;
+ }
+
+ /**
+ * Sets the endpoint identification algorithm.
+ * <p>
+ * If the <code>algorithm</code> parameter is non-null or non-empty, the
+ * endpoint identification/verification procedures must be handled during
+ * SSL/TLS handshaking. This is to prevent man-in-the-middle attacks.
+ *
+ * @param algorithm The standard string name of the endpoint
+ * identification algorithm (or null). See Appendix A in the <a href=
+ * "../../../technotes/guides/security/crypto/CryptoSpec.html#AppA">
+ * Java Cryptography Architecture API Specification & Reference </a>
+ * for information about standard algorithm names.
+ *
+ * @see X509ExtendedTrustManager
+ *
+ * @since 1.7
+ */
+ public void setEndpointIdentificationAlgorithm(String algorithm) {
+ this.identificationAlgorithm = algorithm;
+ }
+
}
--- a/jdk/src/share/classes/javax/net/ssl/SSLServerSocket.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/javax/net/ssl/SSLServerSocket.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -56,8 +56,8 @@
* @since 1.4
* @author David Brownell
*/
-public abstract class SSLServerSocket extends ServerSocket
-{
+public abstract class SSLServerSocket extends ServerSocket {
+
/**
* Used only by subclasses.
* <P>
@@ -449,8 +449,79 @@
*
* @return true indicates that sessions may be created; this
* is the default. false indicates that an existing
- * session must be resumed.
+ * session must be resumed
* @see #setEnableSessionCreation(boolean)
*/
public abstract boolean getEnableSessionCreation();
+
+ /**
+ * Returns the SSLParameters in effect for newly accepted connections.
+ * The ciphersuites and protocols of the returned SSLParameters
+ * are always non-null.
+ *
+ * @return the SSLParameters in effect for newly accepted connections
+ *
+ * @see #setSSLParameters(SSLParameters)
+ *
+ * @since 1.7
+ */
+ public SSLParameters getSSLParameters() {
+ SSLParameters parameters = new SSLParameters();
+
+ parameters.setCipherSuites(getEnabledCipherSuites());
+ parameters.setProtocols(getEnabledProtocols());
+ if (getNeedClientAuth()) {
+ parameters.setNeedClientAuth(true);
+ } else if (getWantClientAuth()) {
+ parameters.setWantClientAuth(true);
+ }
+
+ return parameters;
+ }
+
+ /**
+ * Applies SSLParameters to newly accepted connections.
+ *
+ * <p>This means:
+ * <ul>
+ * <li>if <code>params.getCipherSuites()</code> is non-null,
+ * <code>setEnabledCipherSuites()</code> is called with that value
+ * <li>if <code>params.getProtocols()</code> is non-null,
+ * <code>setEnabledProtocols()</code> is called with that value
+ * <li>if <code>params.getNeedClientAuth()</code> or
+ * <code>params.getWantClientAuth()</code> return <code>true</code>,
+ * <code>setNeedClientAuth(true)</code> and
+ * <code>setWantClientAuth(true)</code> are called, respectively;
+ * otherwise <code>setWantClientAuth(false)</code> is called.
+ * </ul>
+ *
+ * @param params the parameters
+ * @throws IllegalArgumentException if the setEnabledCipherSuites() or
+ * the setEnabledProtocols() call fails
+ *
+ * @see #getSSLParameters()
+ *
+ * @since 1.7
+ */
+ public void setSSLParameters(SSLParameters params) {
+ String[] s;
+ s = params.getCipherSuites();
+ if (s != null) {
+ setEnabledCipherSuites(s);
+ }
+
+ s = params.getProtocols();
+ if (s != null) {
+ setEnabledProtocols(s);
+ }
+
+ if (params.getNeedClientAuth()) {
+ setNeedClientAuth(true);
+ } else if (params.getWantClientAuth()) {
+ setWantClientAuth(true);
+ } else {
+ setWantClientAuth(false);
+ }
+ }
+
}
--- a/jdk/src/share/classes/javax/net/ssl/SSLSocket.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/javax/net/ssl/SSLSocket.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -371,6 +371,51 @@
/**
+ * Returns the {@code SSLSession} being constructed during a SSL/TLS
+ * handshake.
+ * <p>
+ * TLS protocols may negotiate parameters that are needed when using
+ * an instance of this class, but before the {@code SSLSession} has
+ * been completely initialized and made available via {@code getSession}.
+ * For example, the list of valid signature algorithms may restrict
+ * the type of certificates that can used during TrustManager
+ * decisions, or the maximum TLS fragment packet sizes can be
+ * resized to better support the network environment.
+ * <p>
+ * This method provides early access to the {@code SSLSession} being
+ * constructed. Depending on how far the handshake has progressed,
+ * some data may not yet be available for use. For example, if a
+ * remote server will be sending a Certificate chain, but that chain
+ * has yet not been processed, the {@code getPeerCertificates}
+ * method of {@code SSLSession} will throw a
+ * SSLPeerUnverifiedException. Once that chain has been processed,
+ * {@code getPeerCertificates} will return the proper value.
+ * <p>
+ * Unlike {@link #getSession()}, this method does not initiate the
+ * initial handshake and does not block until handshaking is
+ * complete.
+ *
+ * @see SSLEngine
+ * @see SSLSession
+ * @see ExtendedSSLSession
+ * @see X509ExtendedKeyManager
+ * @see X509ExtendedTrustManager
+ *
+ * @return null if this instance is not currently handshaking, or
+ * if the current handshake has not progressed far enough to
+ * create a basic SSLSession. Otherwise, this method returns the
+ * {@code SSLSession} currently being negotiated.
+ * @throws UnsupportedOperationException if the underlying provider
+ * does not implement the operation.
+ *
+ * @since 1.7
+ */
+ public SSLSession getHandshakeSession() {
+ throw new UnsupportedOperationException();
+ }
+
+
+ /**
* Registers an event listener to receive notifications that an
* SSL handshake has completed on this connection.
*
--- a/jdk/src/share/classes/javax/net/ssl/SSLSocketFactory.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/javax/net/ssl/SSLSocketFactory.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -30,6 +30,7 @@
import javax.net.SocketFactory;
import java.io.IOException;
import java.security.*;
+import java.util.Locale;
import sun.security.action.GetPropertyAction;
@@ -50,7 +51,8 @@
static {
String s = java.security.AccessController.doPrivileged(
- new GetPropertyAction("javax.net.debug", "")).toLowerCase();
+ new GetPropertyAction("javax.net.debug", "")).toLowerCase(
+ Locale.ENGLISH);
DEBUG = s.contains("all") || s.contains("ssl");
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/net/ssl/X509ExtendedTrustManager.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2010, 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 javax.net.ssl;
+
+import java.net.Socket;
+import javax.net.ssl.X509TrustManager;
+
+import java.security.cert.X509Certificate;
+import java.security.cert.CertificateException;
+
+/**
+ * Extensions to the <code>X509TrustManager</code> interface to support
+ * SSL/TLS connection sensitive trust management.
+ * <p>
+ * To prevent man-in-the-middle attacks, hostname checks can be done
+ * to verify that the hostname in an end-entity certificate matches the
+ * targeted hostname. TLS does not require such checks, but some protocols
+ * over TLS (such as HTTPS) do. In earlier versions of the JDK, the
+ * certificate chain checks were done at the SSL/TLS layer, and the hostname
+ * verification checks were done at the layer over TLS. This class allows
+ * for the checking to be done during a single call to this class.
+ * <p>
+ * RFC 2830 defines the server identification specification for the "LDAPS"
+ * algorithm. RFC 2818 defines both the server identification and the
+ * client identification specification for the "HTTPS" algorithm.
+ *
+ * @see X509TrustManager
+ * @see HostnameVerifier
+ *
+ * @since 1.7
+ */
+public abstract class X509ExtendedTrustManager implements X509TrustManager {
+ /**
+ * Given the partial or complete certificate chain provided by the
+ * peer, build and validate the certificate path based on the
+ * authentication type and ssl parameters.
+ * <p>
+ * The authentication type is determined by the actual certificate
+ * used. For instance, if RSAPublicKey is used, the authType
+ * should be "RSA". Checking is case-sensitive.
+ * <p>
+ * If the <code>socket</code> parameter is an instance of
+ * {@link javax.net.SSLSocket}, and the endpoint identification
+ * algorithm of the <code>SSLParameters</code> is non-empty, to prevent
+ * man-in-the-middle attacks, the address that the <code>socket</code>
+ * connected to should be checked against the peer's identity presented
+ * in the end-entity X509 certificate, as specified in the endpoint
+ * identification algorithm.
+ * <p>
+ * If the <code>socket</code> parameter is an instance of
+ * {@link javax.net.SSLSocket}, and the algorithm constraints of the
+ * <code>SSLParameters</code> is non-null, for every certificate in the
+ * certification path, fields such as subject public key, the signature
+ * algorithm, key usage, extended key usage, etc. need to conform to the
+ * algorithm constraints in place on this socket.
+ *
+ * @param chain the peer certificate chain
+ * @param authType the key exchange algorithm used
+ * @param socket the socket used for this connection. This parameter
+ * can be null, which indicates that implementations need not check
+ * the ssl parameters
+ * @throws IllegalArgumentException if null or zero-length array is passed
+ * in for the <code>chain</code> parameter or if null or zero-length
+ * string is passed in for the <code>authType</code> parameter
+ * @throws CertificateException if the certificate chain is not trusted
+ * by this TrustManager
+ *
+ * @see SSLParameters#getEndpointIdentificationProtocol
+ * @see SSLParameters#setEndpointIdentificationProtocol(String)
+ * @see SSLParameters#getAlgorithmConstraints
+ * @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
+ */
+ public abstract void checkClientTrusted(X509Certificate[] chain,
+ String authType, Socket socket) throws CertificateException;
+
+ /**
+ * Given the partial or complete certificate chain provided by the
+ * peer, build and validate the certificate path based on the
+ * authentication type and ssl parameters.
+ * <p>
+ * The authentication type is the key exchange algorithm portion
+ * of the cipher suites represented as a String, such as "RSA",
+ * "DHE_DSS". Note: for some exportable cipher suites, the key
+ * exchange algorithm is determined at run time during the
+ * handshake. For instance, for TLS_RSA_EXPORT_WITH_RC4_40_MD5,
+ * the authType should be RSA_EXPORT when an ephemeral RSA key is
+ * used for the key exchange, and RSA when the key from the server
+ * certificate is used. Checking is case-sensitive.
+ * <p>
+ * If the <code>socket</code> parameter is an instance of
+ * {@link javax.net.SSLSocket}, and the endpoint identification
+ * algorithm of the <code>SSLParameters</code> is non-empty, to prevent
+ * man-in-the-middle attacks, the address that the <code>socket</code>
+ * connected to should be checked against the peer's identity presented
+ * in the end-entity X509 certificate, as specified in the endpoint
+ * identification algorithm.
+ * <p>
+ * If the <code>socket</code> parameter is an instance of
+ * {@link javax.net.SSLSocket}, and the algorithm constraints of the
+ * <code>SSLParameters</code> is non-null, for every certificate in the
+ * certification path, fields such as subject public key, the signature
+ * algorithm, key usage, extended key usage, etc. need to conform to the
+ * algorithm constraints in place on this socket.
+ *
+ * @param chain the peer certificate chain
+ * @param authType the key exchange algorithm used
+ * @param socket the socket used for this connection. This parameter
+ * can be null, which indicates that implementations need not check
+ * the ssl parameters
+ * @throws IllegalArgumentException if null or zero-length array is passed
+ * in for the <code>chain</code> parameter or if null or zero-length
+ * string is passed in for the <code>authType</code> parameter
+ * @throws CertificateException if the certificate chain is not trusted
+ * by this TrustManager
+ *
+ * @see SSLParameters#getEndpointIdentificationProtocol
+ * @see SSLParameters#setEndpointIdentificationProtocol(String)
+ * @see SSLParameters#getAlgorithmConstraints
+ * @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
+ */
+ public abstract void checkServerTrusted(X509Certificate[] chain,
+ String authType, Socket socket) throws CertificateException;
+
+ /**
+ * Given the partial or complete certificate chain provided by the
+ * peer, build and validate the certificate path based on the
+ * authentication type and ssl parameters.
+ * <p>
+ * The authentication type is determined by the actual certificate
+ * used. For instance, if RSAPublicKey is used, the authType
+ * should be "RSA". Checking is case-sensitive.
+ * <p>
+ * If the <code>engine</code> parameter is available, and the endpoint
+ * identification algorithm of the <code>SSLParameters</code> is
+ * non-empty, to prevent man-in-the-middle attacks, the address that
+ * the <code>engine</code> connected to should be checked against
+ * the peer's identity presented in the end-entity X509 certificate,
+ * as specified in the endpoint identification algorithm.
+ * <p>
+ * If the <code>engine</code> parameter is available, and the algorithm
+ * constraints of the <code>SSLParameters</code> is non-null, for every
+ * certificate in the certification path, fields such as subject public
+ * key, the signature algorithm, key usage, extended key usage, etc.
+ * need to conform to the algorithm constraints in place on this engine.
+ *
+ * @param chain the peer certificate chain
+ * @param authType the key exchange algorithm used
+ * @param engine the engine used for this connection. This parameter
+ * can be null, which indicates that implementations need not check
+ * the ssl parameters
+ * @throws IllegalArgumentException if null or zero-length array is passed
+ * in for the <code>chain</code> parameter or if null or zero-length
+ * string is passed in for the <code>authType</code> parameter
+ * @throws CertificateException if the certificate chain is not trusted
+ * by this TrustManager
+ *
+ * @see SSLParameters#getEndpointIdentificationProtocol
+ * @see SSLParameters#setEndpointIdentificationProtocol(String)
+ * @see SSLParameters#getAlgorithmConstraints
+ * @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
+ */
+ public abstract void checkClientTrusted(X509Certificate[] chain,
+ String authType, SSLEngine engine) throws CertificateException;
+
+ /**
+ * Given the partial or complete certificate chain provided by the
+ * peer, build and validate the certificate path based on the
+ * authentication type and ssl parameters.
+ * <p>
+ * The authentication type is the key exchange algorithm portion
+ * of the cipher suites represented as a String, such as "RSA",
+ * "DHE_DSS". Note: for some exportable cipher suites, the key
+ * exchange algorithm is determined at run time during the
+ * handshake. For instance, for TLS_RSA_EXPORT_WITH_RC4_40_MD5,
+ * the authType should be RSA_EXPORT when an ephemeral RSA key is
+ * used for the key exchange, and RSA when the key from the server
+ * certificate is used. Checking is case-sensitive.
+ * <p>
+ * If the <code>engine</code> parameter is available, and the endpoint
+ * identification algorithm of the <code>SSLParameters</code> is
+ * non-empty, to prevent man-in-the-middle attacks, the address that
+ * the <code>engine</code> connected to should be checked against
+ * the peer's identity presented in the end-entity X509 certificate,
+ * as specified in the endpoint identification algorithm.
+ * <p>
+ * If the <code>engine</code> parameter is available, and the algorithm
+ * constraints of the <code>SSLParameters</code> is non-null, for every
+ * certificate in the certification path, fields such as subject public
+ * key, the signature algorithm, key usage, extended key usage, etc.
+ * need to conform to the algorithm constraints in place on this engine.
+ *
+ * @param chain the peer certificate chain
+ * @param authType the key exchange algorithm used
+ * @param engine the engine used for this connection. This parameter
+ * can be null, which indicates that implementations need not check
+ * the ssl parameters
+ * @throws IllegalArgumentException if null or zero-length array is passed
+ * in for the <code>chain</code> parameter or if null or zero-length
+ * string is passed in for the <code>authType</code> parameter
+ * @throws CertificateException if the certificate chain is not trusted
+ * by this TrustManager
+ *
+ * @see SSLParameters#getEndpointIdentificationProtocol
+ * @see SSLParameters#setEndpointIdentificationProtocol(String)
+ * @see SSLParameters#getAlgorithmConstraints
+ * @see SSLParameters#setAlgorithmConstraints(AlgorithmConstraints)
+ */
+ public abstract void checkServerTrusted(X509Certificate[] chain,
+ String authType, SSLEngine engine) throws CertificateException;
+
+}
--- a/jdk/src/share/classes/sun/net/InetAddressCachePolicy.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/net/InetAddressCachePolicy.java Tue Nov 02 19:40:45 2010 -0700
@@ -25,7 +25,6 @@
package sun.net;
-import java.net.InetAddress;
import java.security.PrivilegedAction;
import java.security.Security;
@@ -57,7 +56,7 @@
* caching. For security reasons, this caching is made forever when
* a security manager is set.
*/
- private static int cachePolicy;
+ private static int cachePolicy = FOREVER;
/* The Java-level namelookup cache policy for negative lookups:
*
@@ -67,31 +66,24 @@
* default value is 0. It can be set to some other value for
* performance reasons.
*/
- private static int negativeCachePolicy;
+ private static int negativeCachePolicy = NEVER;
/*
* Whether or not the cache policy for successful lookups was set
* using a property (cmd line).
*/
- private static boolean set = false;
+ private static boolean propertySet;
/*
* Whether or not the cache policy for negative lookups was set
* using a property (cmd line).
*/
- private static boolean negativeSet = false;
+ private static boolean propertyNegativeSet;
/*
* Initialize
*/
static {
-
- set = false;
- negativeSet = false;
-
- cachePolicy = FOREVER;
- negativeCachePolicy = 0;
-
Integer tmp = null;
try {
@@ -110,7 +102,7 @@
if (cachePolicy < 0) {
cachePolicy = FOREVER;
}
- set = true;
+ propertySet = true;
} else {
tmp = java.security.AccessController.doPrivileged
(new sun.security.action.GetIntegerAction(cachePolicyPropFallback));
@@ -119,7 +111,14 @@
if (cachePolicy < 0) {
cachePolicy = FOREVER;
}
- set = true;
+ propertySet = true;
+ } else {
+ /* No properties defined for positive caching. If there is no
+ * security manager then use the default positive cache value.
+ */
+ if (System.getSecurityManager() == null) {
+ cachePolicy = DEFAULT_POSITIVE;
+ }
}
}
@@ -140,7 +139,7 @@
if (negativeCachePolicy < 0) {
negativeCachePolicy = FOREVER;
}
- negativeSet = true;
+ propertyNegativeSet = true;
} else {
tmp = java.security.AccessController.doPrivileged
(new sun.security.action.GetIntegerAction(negativeCachePolicyPropFallback));
@@ -149,17 +148,13 @@
if (negativeCachePolicy < 0) {
negativeCachePolicy = FOREVER;
}
- negativeSet = true;
+ propertyNegativeSet = true;
}
}
}
public static synchronized int get() {
- if (!set && System.getSecurityManager() == null) {
- return DEFAULT_POSITIVE;
- } else {
- return cachePolicy;
- }
+ return cachePolicy;
}
public static synchronized int getNegative() {
@@ -174,21 +169,17 @@
* should be cached
*/
public static synchronized void setIfNotSet(int newPolicy) {
-
/*
* When setting the new value we may want to signal that the
* cache should be flushed, though this doesn't seem strictly
* necessary.
*/
-
- if (!set) {
+ if (!propertySet) {
checkValue(newPolicy, cachePolicy);
cachePolicy = newPolicy;
}
-
}
-
/**
* Sets the cache policy for negative lookups if the user has not
* already specified a cache policy for it using a
@@ -197,14 +188,12 @@
* should be cached
*/
public static synchronized void setNegativeIfNotSet(int newPolicy) {
-
/*
* When setting the new value we may want to signal that the
* cache should be flushed, though this doesn't seem strictly
* necessary.
*/
-
- if (!negativeSet) {
+ if (!propertyNegativeSet) {
// Negative caching does not seem to have any security
// implications.
// checkValue(newPolicy, negativeCachePolicy);
@@ -213,13 +202,11 @@
}
private static void checkValue(int newPolicy, int oldPolicy) {
-
/*
* If malicious code gets a hold of this method, prevent
* setting the cache policy to something laxer or some
* invalid negative value.
*/
-
if (newPolicy == FOREVER)
return;
@@ -229,7 +216,6 @@
throw new
SecurityException("can't make InetAddress cache more lax");
-
}
}
}
--- a/jdk/src/share/classes/sun/net/NetworkClient.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/net/NetworkClient.java Tue Nov 02 19:40:45 2010 -0700
@@ -40,6 +40,12 @@
* @author Jonathan Payne
*/
public class NetworkClient {
+ /* Default value of read timeout, if not specified (infinity) */
+ public static final int DEFAULT_READ_TIMEOUT = -1;
+
+ /* Default value of connect timeout, if not specified (infinity) */
+ public static final int DEFAULT_CONNECT_TIMEOUT = -1;
+
protected Proxy proxy = Proxy.NO_PROXY;
/** Socket for communicating with server. */
protected Socket serverSocket = null;
@@ -53,8 +59,8 @@
protected static int defaultSoTimeout;
protected static int defaultConnectTimeout;
- protected int readTimeout = -1;
- protected int connectTimeout = -1;
+ protected int readTimeout = DEFAULT_READ_TIMEOUT;
+ protected int connectTimeout = DEFAULT_CONNECT_TIMEOUT;
/* Name of encoding to use for output */
protected static String encoding;
@@ -71,16 +77,12 @@
return null;
}
});
- if (vals[0] == 0)
- defaultSoTimeout = -1;
- else
+ if (vals[0] != 0) {
defaultSoTimeout = vals[0];
-
- if (vals[1] == 0)
- defaultConnectTimeout = -1;
- else
+ }
+ if (vals[1] != 0) {
defaultConnectTimeout = vals[1];
-
+ }
encoding = encs[0];
try {
@@ -232,7 +234,23 @@
return connectTimeout;
}
+ /**
+ * Sets the read timeout.
+ *
+ * Note: Public URLConnection (and protocol specific implementations)
+ * protect against negative timeout values being set. This implemenation,
+ * and protocol specific implementations, use -1 to represent the default
+ * read timeout.
+ *
+ * This method may be invoked with the default timeout value when the
+ * protocol handler is trying to reset the timeout after doing a
+ * potentially blocking internal operation, e.g. cleaning up unread
+ * response data, buffering error stream response data, etc
+ */
public void setReadTimeout(int timeout) {
+ if (timeout == DEFAULT_READ_TIMEOUT)
+ timeout = defaultSoTimeout;
+
if (serverSocket != null && timeout >= 0) {
try {
serverSocket.setSoTimeout(timeout);
--- a/jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Tue Nov 02 19:40:45 2010 -0700
@@ -46,6 +46,7 @@
import java.util.StringTokenizer;
import java.util.Iterator;
import java.security.Permission;
+import sun.net.NetworkClient;
import sun.net.www.MessageHeader;
import sun.net.www.MeteredStream;
import sun.net.www.URLConnection;
@@ -102,11 +103,11 @@
static final int BIN = 2;
static final int DIR = 3;
int type = NONE;
- /* Redefine timeouts from java.net.URLConnection as we nee -1 to mean
+ /* Redefine timeouts from java.net.URLConnection as we need -1 to mean
* not set. This is to ensure backward compatibility.
*/
- private int connectTimeout = -1;
- private int readTimeout = -1;
+ private int connectTimeout = NetworkClient.DEFAULT_CONNECT_TIMEOUT;;
+ private int readTimeout = NetworkClient.DEFAULT_READ_TIMEOUT;;
/**
* For FTP URLs we need to have a special InputStream because we
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Tue Nov 02 19:40:45 2010 -0700
@@ -359,11 +359,11 @@
private TunnelState tunnelState = TunnelState.NONE;
- /* Redefine timeouts from java.net.URLConnection as we nee -1 to mean
+ /* Redefine timeouts from java.net.URLConnection as we need -1 to mean
* not set. This is to ensure backward compatibility.
*/
- private int connectTimeout = -1;
- private int readTimeout = -1;
+ private int connectTimeout = NetworkClient.DEFAULT_CONNECT_TIMEOUT;
+ private int readTimeout = NetworkClient.DEFAULT_READ_TIMEOUT;
/* Logging support */
private static final PlatformLogger logger =
@@ -1041,9 +1041,9 @@
throw new ProtocolException("Server rejected operation");
}
}
- if (oldTimeout > 0) {
- http.setReadTimeout(oldTimeout);
- }
+
+ http.setReadTimeout(oldTimeout);
+
responseCode = -1;
responses.reset();
// Proceed
--- a/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/net/www/protocol/https/HttpsClient.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2010, 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
@@ -109,6 +109,10 @@
// HTTPS uses a different default port number than HTTP.
private static final int httpsPortNumber = 443;
+ // default HostnameVerifier class canonical name
+ private static final String defaultHVCanonicalName =
+ "javax.net.ssl.HttpsURLConnection.DefaultHostnameVerifier";
+
/** Returns the default HTTPS port (443) */
@Override
protected int getDefaultPort() { return httpsPortNumber; }
@@ -427,13 +431,93 @@
}
s.addHandshakeCompletedListener(this);
- // if the HostnameVerifier is not set, try to enable endpoint
- // identification during handshaking
- boolean enabledIdentification = false;
- if (hv instanceof DefaultHostnameVerifier &&
- (s instanceof SSLSocketImpl) &&
- ((SSLSocketImpl)s).trySetHostnameVerification("HTTPS")) {
- enabledIdentification = true;
+ // We have two hostname verification approaches. One is in
+ // SSL/TLS socket layer, where the algorithm is configured with
+ // SSLParameters.setEndpointIdentificationAlgorithm(), and the
+ // hostname verification is done by X509ExtendedTrustManager when
+ // the algorithm is "HTTPS". The other one is in HTTPS layer,
+ // where the algorithm is customized by
+ // HttpsURLConnection.setHostnameVerifier(), and the hostname
+ // verification is done by HostnameVerifier when the default
+ // rules for hostname verification fail.
+ //
+ // The relationship between two hostname verification approaches
+ // likes the following:
+ //
+ // | EIA algorithm
+ // +----------------------------------------------
+ // | null | HTTPS | LDAP/other |
+ // -------------------------------------------------------------
+ // | |1 |2 |3 |
+ // HNV | default | Set HTTPS EIA | use EIA | HTTPS |
+ // |--------------------------------------------------------
+ // | non - |4 |5 |6 |
+ // | default | HTTPS/HNV | use EIA | HTTPS/HNV |
+ // -------------------------------------------------------------
+ //
+ // Abbreviation:
+ // EIA: the endpoint identification algorithm in SSL/TLS
+ // socket layer
+ // HNV: the hostname verification object in HTTPS layer
+ // Notes:
+ // case 1. default HNV and EIA is null
+ // Set EIA as HTTPS, hostname check done in SSL/TLS
+ // layer.
+ // case 2. default HNV and EIA is HTTPS
+ // Use existing EIA, hostname check done in SSL/TLS
+ // layer.
+ // case 3. default HNV and EIA is other than HTTPS
+ // Use existing EIA, EIA check done in SSL/TLS
+ // layer, then do HTTPS check in HTTPS layer.
+ // case 4. non-default HNV and EIA is null
+ // No EIA, no EIA check done in SSL/TLS layer, then do
+ // HTTPS check in HTTPS layer using HNV as override.
+ // case 5. non-default HNV and EIA is HTTPS
+ // Use existing EIA, hostname check done in SSL/TLS
+ // layer. No HNV override possible. We will review this
+ // decision and may update the architecture for JDK 7.
+ // case 6. non-default HNV and EIA is other than HTTPS
+ // Use existing EIA, EIA check done in SSL/TLS layer,
+ // then do HTTPS check in HTTPS layer as override.
+ boolean needToCheckSpoofing = true;
+ String identification =
+ s.getSSLParameters().getEndpointIdentificationAlgorithm();
+ if (identification != null && identification.length() != 0) {
+ if (identification.equalsIgnoreCase("HTTPS")) {
+ // Do not check server identity again out of SSLSocket,
+ // the endpoint will be identified during TLS handshaking
+ // in SSLSocket.
+ needToCheckSpoofing = false;
+ } // else, we don't understand the identification algorithm,
+ // need to check URL spoofing here.
+ } else {
+ boolean isDefaultHostnameVerifier = false;
+
+ // We prefer to let the SSLSocket do the spoof checks, but if
+ // the application has specified a HostnameVerifier (HNV),
+ // we will always use that.
+ if (hv != null) {
+ String canonicalName = hv.getClass().getCanonicalName();
+ if (canonicalName != null &&
+ canonicalName.equalsIgnoreCase(defaultHVCanonicalName)) {
+ isDefaultHostnameVerifier = true;
+ }
+ } else {
+ // Unlikely to happen! As the behavior is the same as the
+ // default hostname verifier, so we prefer to let the
+ // SSLSocket do the spoof checks.
+ isDefaultHostnameVerifier = true;
+ }
+
+ if (isDefaultHostnameVerifier) {
+ // If the HNV is the default from HttpsURLConnection, we
+ // will do the spoof checks in SSLSocket.
+ SSLParameters paramaters = s.getSSLParameters();
+ paramaters.setEndpointIdentificationAlgorithm("HTTPS");
+ s.setSSLParameters(paramaters);
+
+ needToCheckSpoofing = false;
+ }
}
s.startHandshake();
@@ -449,7 +533,7 @@
}
// check URL spoofing if it has not been checked under handshaking
- if (!enabledIdentification) {
+ if (needToCheckSpoofing) {
checkURLSpoofing(hv);
}
} else {
@@ -463,8 +547,7 @@
// Server identity checking is done according to RFC 2818: HTTP over TLS
// Section 3.1 Server Identity
private void checkURLSpoofing(HostnameVerifier hostnameVerifier)
- throws IOException
- {
+ throws IOException {
//
// Get authenticated server name, if any
//
--- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -711,10 +711,8 @@
cachedSenderInetAddress = isa.getAddress();
cachedSenderPort = isa.getPort();
- // Socket was not bound before connecting,
- if (localAddress == null) {
- localAddress = Net.localAddress(fd);
- }
+ // set or refresh local address
+ localAddress = Net.localAddress(fd);
}
}
}
@@ -735,6 +733,9 @@
disconnect0(fd);
remoteAddress = null;
state = ST_UNCONNECTED;
+
+ // refresh local address
+ localAddress = Net.localAddress(fd);
}
}
}
--- a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -699,15 +699,19 @@
static volatile long totalSize;
static volatile long totalCapacity;
- private long address;
- private long size;
- private int cap;
+ private volatile long address;
+ private final long size;
+ private final int cap;
+ private final FileDescriptor fd;
- private Unmapper(long address, long size, int cap) {
+ private Unmapper(long address, long size, int cap,
+ FileDescriptor fd)
+ {
assert (address != 0);
this.address = address;
this.size = size;
this.cap = cap;
+ this.fd = fd;
synchronized (Unmapper.class) {
count++;
@@ -722,6 +726,15 @@
unmap0(address, size);
address = 0;
+ // if this mapping has a valid file descriptor then we close it
+ if (fd.valid()) {
+ try {
+ nd.close(fd);
+ } catch (IOException ignore) {
+ // nothing we can do
+ }
+ }
+
synchronized (Unmapper.class) {
count--;
totalSize -= size;
@@ -784,10 +797,12 @@
}
if (size == 0) {
addr = 0;
+ // a valid file descriptor is not required
+ FileDescriptor dummy = new FileDescriptor();
if ((!writable) || (imode == MAP_RO))
- return Util.newMappedByteBufferR(0, 0, null);
+ return Util.newMappedByteBufferR(0, 0, dummy, null);
else
- return Util.newMappedByteBuffer(0, 0, null);
+ return Util.newMappedByteBuffer(0, 0, dummy, null);
}
int pagePosition = (int)(position % allocationGranularity);
@@ -813,14 +828,31 @@
}
}
+ // On Windows, and potentially other platforms, we need an open
+ // file descriptor for some mapping operations.
+ FileDescriptor mfd;
+ try {
+ mfd = nd.duplicateForMapping(fd);
+ } catch (IOException ioe) {
+ unmap0(addr, mapSize);
+ throw ioe;
+ }
+
assert (IOStatus.checkAll(addr));
assert (addr % allocationGranularity == 0);
int isize = (int)size;
- Unmapper um = new Unmapper(addr, size + pagePosition, isize);
- if ((!writable) || (imode == MAP_RO))
- return Util.newMappedByteBufferR(isize, addr + pagePosition, um);
- else
- return Util.newMappedByteBuffer(isize, addr + pagePosition, um);
+ Unmapper um = new Unmapper(addr, mapSize, isize, mfd);
+ if ((!writable) || (imode == MAP_RO)) {
+ return Util.newMappedByteBufferR(isize,
+ addr + pagePosition,
+ mfd,
+ um);
+ } else {
+ return Util.newMappedByteBuffer(isize,
+ addr + pagePosition,
+ mfd,
+ um);
+ }
} finally {
threads.remove(ti);
end(IOStatus.checkAll(addr));
--- a/jdk/src/share/classes/sun/nio/ch/FileDispatcher.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/FileDispatcher.java Tue Nov 02 19:40:45 2010 -0700
@@ -45,4 +45,12 @@
abstract void release(FileDescriptor fd, long pos, long size)
throws IOException;
+
+ /**
+ * Returns a dup of fd if a file descriptor is required for
+ * memory-mapping operations, otherwise returns an invalid
+ * FileDescriptor (meaning a newly allocated FileDescriptor)
+ */
+ abstract FileDescriptor duplicateForMapping(FileDescriptor fd)
+ throws IOException;
}
--- a/jdk/src/share/classes/sun/nio/ch/SimpleAsynchronousDatagramChannelImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,667 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, 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.nio.ch;
-
-import java.nio.ByteBuffer;
-import java.nio.channels.*;
-import java.net.*;
-import java.io.IOException;
-import java.util.*;
-import java.util.concurrent.*;
-import java.security.AccessController;
-import java.security.AccessControlContext;
-import java.security.PrivilegedExceptionAction;
-import java.security.PrivilegedActionException;
-
-/**
- * A prototype implementation of AsynchronousDatagramChannel, used to aid
- * test and spec development.
- */
-
-class SimpleAsynchronousDatagramChannelImpl
- extends AsynchronousDatagramChannel implements Groupable, Cancellable
-{
- private final DatagramChannel dc;
- private final AsynchronousChannelGroupImpl group;
- private final Object attachKey;
- private boolean closed;
-
- // used to coordinate timed and blocking reads
- private final Object readLock = new Object();
-
- // channel blocking mode (requires readLock)
- private boolean isBlocking = true;
-
- // number of blocking readers (requires readLock)
- private int blockingReaderCount;
-
- // true if timed read attempted while blocking read in progress (requires readLock)
- private boolean transitionToNonBlocking;
-
- // true if a blocking read is cancelled (requires readLock)
- private boolean blockingReadKilledByCancel;
-
- // temporary Selectors used by timed reads (requires readLock)
- private Selector firstReader;
- private Set<Selector> otherReaders;
-
- SimpleAsynchronousDatagramChannelImpl(ProtocolFamily family,
- AsynchronousChannelGroupImpl group)
- throws IOException
- {
- super(group.provider());
- this.dc = (family == null) ?
- DatagramChannel.open() : DatagramChannel.open(family);
- this.group = group;
-
- // attach this channel to the group as foreign channel
- boolean registered = false;
- try {
- if (!(dc instanceof DatagramChannelImpl))
- throw new UnsupportedOperationException();
- attachKey = group
- .attachForeignChannel(this, ((DatagramChannelImpl)dc).getFD());
- registered = true;
- } finally {
- if (!registered)
- dc.close();
- }
- }
-
- // throws RuntimeException if blocking read has been cancelled
- private void ensureBlockingReadNotKilled() {
- assert Thread.holdsLock(readLock);
- if (blockingReadKilledByCancel)
- throw new RuntimeException("Reading not allowed due to cancellation");
- }
-
- // invoke prior to non-timed read/receive
- private void beginNoTimeoutRead() {
- synchronized (readLock) {
- ensureBlockingReadNotKilled();
- if (isBlocking)
- blockingReaderCount++;
- }
- }
-
- // invoke after non-timed read/receive has completed
- private void endNoTimeoutRead() {
- synchronized (readLock) {
- if (isBlocking) {
- if (--blockingReaderCount == 0 && transitionToNonBlocking) {
- // notify any threads waiting to make channel non-blocking
- readLock.notifyAll();
- }
- }
- }
- }
-
- // invoke prior to timed read
- // returns the timeout remaining
- private long prepareForTimedRead(PendingFuture<?,?> result, long timeout)
- throws IOException
- {
- synchronized (readLock) {
- ensureBlockingReadNotKilled();
- if (isBlocking) {
- transitionToNonBlocking = true;
- while (blockingReaderCount > 0 &&
- timeout > 0L &&
- !result.isCancelled())
- {
- long st = System.currentTimeMillis();
- try {
- readLock.wait(timeout);
- } catch (InterruptedException e) { }
- timeout -= System.currentTimeMillis() - st;
- }
- if (blockingReaderCount == 0) {
- // re-check that blocked read wasn't cancelled
- ensureBlockingReadNotKilled();
- // no blocking reads so change channel to non-blocking
- dc.configureBlocking(false);
- isBlocking = false;
- }
- }
- return timeout;
- }
- }
-
- // returns a temporary Selector
- private Selector getSelector() throws IOException {
- Selector sel = Util.getTemporarySelector(dc);
- synchronized (readLock) {
- if (firstReader == null) {
- firstReader = sel;
- } else {
- if (otherReaders == null)
- otherReaders = new HashSet<Selector>();
- otherReaders.add(sel);
- }
- }
- return sel;
- }
-
- // releases a temporary Selector
- private void releaseSelector(Selector sel) throws IOException {
- synchronized (readLock) {
- if (firstReader == sel) {
- firstReader = null;
- } else {
- otherReaders.remove(sel);
- }
- }
- Util.releaseTemporarySelector(sel);
- }
-
- // wakeup all Selectors currently in use
- private void wakeupSelectors() {
- synchronized (readLock) {
- if (firstReader != null)
- firstReader.wakeup();
- if (otherReaders != null) {
- for (Selector sel: otherReaders) {
- sel.wakeup();
- }
- }
- }
- }
-
- @Override
- public AsynchronousChannelGroupImpl group() {
- return group;
- }
-
- @Override
- public boolean isOpen() {
- return dc.isOpen();
- }
-
- @Override
- public void onCancel(PendingFuture<?,?> task) {
- synchronized (readLock) {
- if (blockingReaderCount > 0) {
- blockingReadKilledByCancel = true;
- readLock.notifyAll();
- return;
- }
- }
- wakeupSelectors();
- }
-
- @Override
- public void close() throws IOException {
- synchronized (dc) {
- if (closed)
- return;
- closed = true;
- }
- // detach from group and close underlying channel
- group.detachForeignChannel(attachKey);
- dc.close();
-
- // wakeup any threads blocked in timed read/receives
- wakeupSelectors();
- }
-
- @Override
- public AsynchronousDatagramChannel connect(SocketAddress remote)
- throws IOException
- {
- dc.connect(remote);
- return this;
- }
-
- @Override
- public AsynchronousDatagramChannel disconnect() throws IOException {
- dc.disconnect();
- return this;
- }
-
- private static class WrappedMembershipKey extends MembershipKey {
- private final MulticastChannel channel;
- private final MembershipKey key;
-
- WrappedMembershipKey(MulticastChannel channel, MembershipKey key) {
- this.channel = channel;
- this.key = key;
- }
-
- @Override
- public boolean isValid() {
- return key.isValid();
- }
-
- @Override
- public void drop() {
- key.drop();
- }
-
- @Override
- public MulticastChannel channel() {
- return channel;
- }
-
- @Override
- public InetAddress group() {
- return key.group();
- }
-
- @Override
- public NetworkInterface networkInterface() {
- return key.networkInterface();
- }
-
- @Override
- public InetAddress sourceAddress() {
- return key.sourceAddress();
- }
-
- @Override
- public MembershipKey block(InetAddress toBlock) throws IOException {
- key.block(toBlock);
- return this;
- }
-
- @Override
- public MembershipKey unblock(InetAddress toUnblock) {
- key.unblock(toUnblock);
- return this;
- }
-
- @Override
- public String toString() {
- return key.toString();
- }
- }
-
- @Override
- public MembershipKey join(InetAddress group,
- NetworkInterface interf)
- throws IOException
- {
- MembershipKey key = ((MulticastChannel)dc).join(group, interf);
- return new WrappedMembershipKey(this, key);
- }
-
- @Override
- public MembershipKey join(InetAddress group,
- NetworkInterface interf,
- InetAddress source)
- throws IOException
- {
- MembershipKey key = ((MulticastChannel)dc).join(group, interf, source);
- return new WrappedMembershipKey(this, key);
- }
-
- private <A> Future<Integer> implSend(ByteBuffer src,
- SocketAddress target,
- A attachment,
- CompletionHandler<Integer,? super A> handler)
- {
- int n = 0;
- Throwable exc = null;
- try {
- n = dc.send(src, target);
- } catch (IOException ioe) {
- exc = ioe;
- }
- if (handler == null)
- return CompletedFuture.withResult(n, exc);
- Invoker.invoke(this, handler, attachment, n, exc);
- return null;
- }
-
- @Override
- public Future<Integer> send(ByteBuffer src, SocketAddress target) {
- return implSend(src, target, null, null);
- }
-
- @Override
- public <A> void send(ByteBuffer src,
- SocketAddress target,
- A attachment,
- CompletionHandler<Integer,? super A> handler)
- {
- if (handler == null)
- throw new NullPointerException("'handler' is null");
- implSend(src, target, attachment, handler);
- }
-
- private <A> Future<Integer> implWrite(ByteBuffer src,
- A attachment,
- CompletionHandler<Integer,? super A> handler)
- {
- int n = 0;
- Throwable exc = null;
- try {
- n = dc.write(src);
- } catch (IOException ioe) {
- exc = ioe;
- }
- if (handler == null)
- return CompletedFuture.withResult(n, exc);
- Invoker.invoke(this, handler, attachment, n, exc);
- return null;
-
- }
-
- @Override
- public Future<Integer> write(ByteBuffer src) {
- return implWrite(src, null, null);
- }
-
- @Override
- public <A> void write(ByteBuffer src,
- A attachment,
- CompletionHandler<Integer,? super A> handler)
- {
- if (handler == null)
- throw new NullPointerException("'handler' is null");
- implWrite(src, attachment, handler);
- }
-
- /**
- * Receive into the given buffer with privileges enabled and restricted by
- * the given AccessControlContext (can be null).
- */
- private SocketAddress doRestrictedReceive(final ByteBuffer dst,
- AccessControlContext acc)
- throws IOException
- {
- if (acc == null) {
- return dc.receive(dst);
- } else {
- try {
- return AccessController.doPrivileged(
- new PrivilegedExceptionAction<SocketAddress>() {
- public SocketAddress run() throws IOException {
- return dc.receive(dst);
- }}, acc);
- } catch (PrivilegedActionException pae) {
- Exception cause = pae.getException();
- if (cause instanceof SecurityException)
- throw (SecurityException)cause;
- throw (IOException)cause;
- }
- }
- }
-
- private <A> Future<SocketAddress> implReceive(final ByteBuffer dst,
- final long timeout,
- final TimeUnit unit,
- A attachment,
- final CompletionHandler<SocketAddress,? super A> handler)
- {
- if (dst.isReadOnly())
- throw new IllegalArgumentException("Read-only buffer");
- if (timeout < 0L)
- throw new IllegalArgumentException("Negative timeout");
- if (unit == null)
- throw new NullPointerException();
-
- // complete immediately if channel closed
- if (!isOpen()) {
- Throwable exc = new ClosedChannelException();
- if (handler == null)
- return CompletedFuture.withFailure(exc);
- Invoker.invoke(this, handler, attachment, null, exc);
- return null;
- }
-
- final AccessControlContext acc = (System.getSecurityManager() == null) ?
- null : AccessController.getContext();
- final PendingFuture<SocketAddress,A> result =
- new PendingFuture<SocketAddress,A>(this, handler, attachment);
- Runnable task = new Runnable() {
- public void run() {
- try {
- SocketAddress remote = null;
- long to;
- if (timeout == 0L) {
- beginNoTimeoutRead();
- try {
- remote = doRestrictedReceive(dst, acc);
- } finally {
- endNoTimeoutRead();
- }
- to = 0L;
- } else {
- to = prepareForTimedRead(result, unit.toMillis(timeout));
- if (to <= 0L)
- throw new InterruptedByTimeoutException();
- remote = doRestrictedReceive(dst, acc);
- }
- if (remote == null) {
- Selector sel = getSelector();
- SelectionKey sk = null;
- try {
- sk = dc.register(sel, SelectionKey.OP_READ);
- for (;;) {
- if (!dc.isOpen())
- throw new AsynchronousCloseException();
- if (result.isCancelled())
- break;
- long st = System.currentTimeMillis();
- int ns = sel.select(to);
- if (ns > 0) {
- remote = doRestrictedReceive(dst, acc);
- if (remote != null)
- break;
- }
- sel.selectedKeys().remove(sk);
- if (timeout != 0L) {
- to -= System.currentTimeMillis() - st;
- if (to <= 0)
- throw new InterruptedByTimeoutException();
- }
- }
- } finally {
- if (sk != null)
- sk.cancel();
- releaseSelector(sel);
- }
- }
- result.setResult(remote);
- } catch (Throwable x) {
- if (x instanceof ClosedChannelException)
- x = new AsynchronousCloseException();
- result.setFailure(x);
- }
- Invoker.invokeUnchecked(result);
- }
- };
- try {
- group.executeOnPooledThread(task);
- } catch (RejectedExecutionException ree) {
- throw new ShutdownChannelGroupException();
- }
- return result;
- }
-
- @Override
- public Future<SocketAddress> receive(ByteBuffer dst) {
- return implReceive(dst, 0L, TimeUnit.MILLISECONDS, null, null);
- }
-
- @Override
- public <A> void receive(ByteBuffer dst,
- long timeout,
- TimeUnit unit,
- A attachment,
- CompletionHandler<SocketAddress,? super A> handler)
- {
- if (handler == null)
- throw new NullPointerException("'handler' is null");
- implReceive(dst, timeout, unit, attachment, handler);
- }
-
- private <A> Future<Integer> implRead(final ByteBuffer dst,
- final long timeout,
- final TimeUnit unit,
- A attachment,
- final CompletionHandler<Integer,? super A> handler)
- {
- if (dst.isReadOnly())
- throw new IllegalArgumentException("Read-only buffer");
- if (timeout < 0L)
- throw new IllegalArgumentException("Negative timeout");
- if (unit == null)
- throw new NullPointerException();
-
- // complete immediately if channel closed
- if (!isOpen()) {
- Throwable exc = new ClosedChannelException();
- if (handler == null)
- return CompletedFuture.withFailure(exc);
- Invoker.invoke(this, handler, attachment, null, exc);
- return null;
- }
-
- // another thread may disconnect before read is initiated
- if (!dc.isConnected())
- throw new NotYetConnectedException();
-
- final PendingFuture<Integer,A> result =
- new PendingFuture<Integer,A>(this, handler, attachment);
- Runnable task = new Runnable() {
- public void run() {
- try {
- int n = 0;
- long to;
- if (timeout == 0L) {
- beginNoTimeoutRead();
- try {
- n = dc.read(dst);
- } finally {
- endNoTimeoutRead();
- }
- to = 0L;
- } else {
- to = prepareForTimedRead(result, unit.toMillis(timeout));
- if (to <= 0L)
- throw new InterruptedByTimeoutException();
- n = dc.read(dst);
- }
- if (n == 0) {
- Selector sel = getSelector();
- SelectionKey sk = null;
- try {
- sk = dc.register(sel, SelectionKey.OP_READ);
- for (;;) {
- if (!dc.isOpen())
- throw new AsynchronousCloseException();
- if (result.isCancelled())
- break;
- long st = System.currentTimeMillis();
- int ns = sel.select(to);
- if (ns > 0) {
- if ((n = dc.read(dst)) != 0)
- break;
- }
- sel.selectedKeys().remove(sk);
- if (timeout != 0L) {
- to -= System.currentTimeMillis() - st;
- if (to <= 0)
- throw new InterruptedByTimeoutException();
- }
- }
- } finally {
- if (sk != null)
- sk.cancel();
- releaseSelector(sel);
- }
- }
- result.setResult(n);
- } catch (Throwable x) {
- if (x instanceof ClosedChannelException)
- x = new AsynchronousCloseException();
- result.setFailure(x);
- }
- Invoker.invokeUnchecked(result);
- }
- };
- try {
- group.executeOnPooledThread(task);
- } catch (RejectedExecutionException ree) {
- throw new ShutdownChannelGroupException();
- }
- return result;
- }
-
- @Override
- public Future<Integer> read(ByteBuffer dst) {
- return implRead(dst, 0L, TimeUnit.MILLISECONDS, null, null);
- }
-
- @Override
- public <A> void read(ByteBuffer dst,
- long timeout,
- TimeUnit unit,
- A attachment,
- CompletionHandler<Integer,? super A> handler)
- {
- if (handler == null)
- throw new NullPointerException("'handler' is null");
- implRead(dst, timeout, unit, attachment, handler);
- }
-
- @Override
- public AsynchronousDatagramChannel bind(SocketAddress local)
- throws IOException
- {
- dc.bind(local);
- return this;
- }
-
- @Override
- public SocketAddress getLocalAddress() throws IOException {
- return dc.getLocalAddress();
- }
-
- @Override
- public <T> AsynchronousDatagramChannel setOption(SocketOption<T> name, T value)
- throws IOException
- {
- dc.setOption(name, value);
- return this;
- }
-
- @Override
- public <T> T getOption(SocketOption<T> name) throws IOException {
- return dc.getOption(name);
- }
-
- @Override
- public Set<SocketOption<?>> supportedOptions() {
- return dc.supportedOptions();
- }
-
- @Override
- public SocketAddress getRemoteAddress() throws IOException {
- return dc.getRemoteAddress();
- }
-}
--- a/jdk/src/share/classes/sun/nio/ch/Util.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/Util.java Tue Nov 02 19:40:45 2010 -0700
@@ -28,6 +28,7 @@
import java.lang.ref.SoftReference;
import java.lang.reflect.*;
import java.io.IOException;
+import java.io.FileDescriptor;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.*;
@@ -364,6 +365,7 @@
Constructor ctor = cl.getDeclaredConstructor(
new Class[] { int.class,
long.class,
+ FileDescriptor.class,
Runnable.class });
ctor.setAccessible(true);
directByteBufferConstructor = ctor;
@@ -381,6 +383,7 @@
}
static MappedByteBuffer newMappedByteBuffer(int size, long addr,
+ FileDescriptor fd,
Runnable unmapper)
{
MappedByteBuffer dbb;
@@ -390,6 +393,7 @@
dbb = (MappedByteBuffer)directByteBufferConstructor.newInstance(
new Object[] { new Integer(size),
new Long(addr),
+ fd,
unmapper });
} catch (InstantiationException e) {
throw new InternalError();
@@ -411,6 +415,7 @@
Constructor ctor = cl.getDeclaredConstructor(
new Class[] { int.class,
long.class,
+ FileDescriptor.class,
Runnable.class });
ctor.setAccessible(true);
directByteBufferRConstructor = ctor;
@@ -428,6 +433,7 @@
}
static MappedByteBuffer newMappedByteBufferR(int size, long addr,
+ FileDescriptor fd,
Runnable unmapper)
{
MappedByteBuffer dbb;
@@ -437,6 +443,7 @@
dbb = (MappedByteBuffer)directByteBufferRConstructor.newInstance(
new Object[] { new Integer(size),
new Long(addr),
+ fd,
unmapper });
} catch (InstantiationException e) {
throw new InternalError();
--- a/jdk/src/share/classes/sun/security/internal/interfaces/TlsMasterSecret.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/internal/interfaces/TlsMasterSecret.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -38,7 +38,8 @@
*
* @since 1.6
* @author Andreas Sterbenz
- * @deprecated Sun JDK internal use only --- WILL BE REMOVED in Dolphin (JDK 7)
+ * @deprecated Sun JDK internal use only --- WILL BE REMOVED in a future
+ * release.
*/
@Deprecated
public interface TlsMasterSecret extends SecretKey {
--- a/jdk/src/share/classes/sun/security/internal/spec/TlsKeyMaterialParameterSpec.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/internal/spec/TlsKeyMaterialParameterSpec.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -39,7 +39,8 @@
*
* @since 1.6
* @author Andreas Sterbenz
- * @deprecated Sun JDK internal use only --- WILL BE REMOVED in Dolphin (JDK 7)
+ * @deprecated Sun JDK internal use only --- WILL BE REMOVED in a future
+ * release.
*/
@Deprecated
public class TlsKeyMaterialParameterSpec implements AlgorithmParameterSpec {
@@ -50,6 +51,9 @@
private final String cipherAlgorithm;
private final int cipherKeyLength, ivLength, macKeyLength;
private final int expandedCipherKeyLength; // == 0 for domestic ciphersuites
+ private final String prfHashAlg;
+ private final int prfHashLength;
+ private final int prfBlockSize;
/**
* Constructs a new TlsKeyMaterialParameterSpec.
@@ -71,6 +75,12 @@
* @param ivLength the length in bytes of the initialization vector
* to be generated, or 0 if no initialization vector is required
* @param macKeyLength the length in bytes of the MAC key to be generated
+ * @param prfHashAlg the name of the TLS PRF hash algorithm to use.
+ * Used only for TLS 1.2+. TLS1.1 and earlier use a fixed PRF.
+ * @param prfHashLength the output length of the TLS PRF hash algorithm.
+ * Used only for TLS 1.2+.
+ * @param prfBlockSize the input block size of the TLS PRF hash algorithm.
+ * Used only for TLS 1.2+.
*
* @throws NullPointerException if masterSecret, clientRandom,
* serverRandom, or cipherAlgorithm are null
@@ -82,7 +92,8 @@
public TlsKeyMaterialParameterSpec(SecretKey masterSecret,
int majorVersion, int minorVersion, byte[] clientRandom,
byte[] serverRandom, String cipherAlgorithm, int cipherKeyLength,
- int expandedCipherKeyLength, int ivLength, int macKeyLength) {
+ int expandedCipherKeyLength, int ivLength, int macKeyLength,
+ String prfHashAlg, int prfHashLength, int prfBlockSize) {
if (masterSecret.getAlgorithm().equals("TlsMasterSecret") == false) {
throw new IllegalArgumentException("Not a TLS master secret");
}
@@ -90,8 +101,10 @@
throw new NullPointerException();
}
this.masterSecret = masterSecret;
- this.majorVersion = TlsMasterSecretParameterSpec.checkVersion(majorVersion);
- this.minorVersion = TlsMasterSecretParameterSpec.checkVersion(minorVersion);
+ this.majorVersion =
+ TlsMasterSecretParameterSpec.checkVersion(majorVersion);
+ this.minorVersion =
+ TlsMasterSecretParameterSpec.checkVersion(minorVersion);
this.clientRandom = clientRandom.clone();
this.serverRandom = serverRandom.clone();
this.cipherAlgorithm = cipherAlgorithm;
@@ -99,6 +112,9 @@
this.expandedCipherKeyLength = checkSign(expandedCipherKeyLength);
this.ivLength = checkSign(ivLength);
this.macKeyLength = checkSign(macKeyLength);
+ this.prfHashAlg = prfHashAlg;
+ this.prfHashLength = prfHashLength;
+ this.prfBlockSize = prfBlockSize;
}
private static int checkSign(int k) {
@@ -172,20 +188,36 @@
}
/**
- * Returns the length in bytes of the expanded encryption key to be generated.
+ * Returns the length in bytes of the expanded encryption key to be
+ * generated. Returns zero if the expanded encryption key is not
+ * supposed to be generated.
*
- * @return the length in bytes of the expanded encryption key to be generated.
+ * @return the length in bytes of the expanded encryption key to be
+ * generated.
*/
public int getExpandedCipherKeyLength() {
+ // TLS v1.1 disables the exportable weak cipher suites.
+ if (majorVersion >= 0x03 && minorVersion >= 0x02) {
+ return 0;
+ }
return expandedCipherKeyLength;
}
/**
- * Returns the length in bytes of the initialization vector to be generated.
+ * Returns the length in bytes of the initialization vector to be
+ * generated. Returns zero if the initialization vector is not
+ * supposed to be generated.
*
- * @return the length in bytes of the initialization vector to be generated.
+ * @return the length in bytes of the initialization vector to be
+ * generated.
*/
public int getIvLength() {
+ // TLS v1.1 or later uses an explicit IV to protect against
+ // the CBC attacks.
+ if (majorVersion >= 0x03 && minorVersion >= 0x02) {
+ return 0;
+ }
+
return ivLength;
}
@@ -198,4 +230,30 @@
return macKeyLength;
}
+ /**
+ * Obtains the PRF hash algorithm to use in the PRF calculation.
+ *
+ * @return the hash algorithm.
+ */
+ public String getPRFHashAlg() {
+ return prfHashAlg;
+ }
+
+ /**
+ * Obtains the length of the PRF hash algorithm.
+ *
+ * @return the hash algorithm length.
+ */
+ public int getPRFHashLength() {
+ return prfHashLength;
+ }
+
+ /**
+ * Obtains the block size of the PRF hash algorithm.
+ *
+ * @return the hash algorithm block size
+ */
+ public int getPRFBlockSize() {
+ return prfBlockSize;
+ }
}
--- a/jdk/src/share/classes/sun/security/internal/spec/TlsKeyMaterialSpec.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/internal/spec/TlsKeyMaterialSpec.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -39,7 +39,8 @@
*
* @since 1.6
* @author Andreas Sterbenz
- * @deprecated Sun JDK internal use only --- WILL BE REMOVED in Dolphin (JDK 7)
+ * @deprecated Sun JDK internal use only --- WILL BE REMOVED in a future
+ * release.
*/
@Deprecated
public class TlsKeyMaterialSpec implements KeySpec, SecretKey {
@@ -80,7 +81,8 @@
*/
public TlsKeyMaterialSpec(SecretKey clientMacKey, SecretKey serverMacKey,
SecretKey clientCipherKey, SecretKey serverCipherKey) {
- this(clientMacKey, serverMacKey, clientCipherKey, null, serverCipherKey, null);
+ this(clientMacKey, serverMacKey, clientCipherKey, null,
+ serverCipherKey, null);
}
/**
--- a/jdk/src/share/classes/sun/security/internal/spec/TlsMasterSecretParameterSpec.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/internal/spec/TlsMasterSecretParameterSpec.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -39,7 +39,8 @@
*
* @since 1.6
* @author Andreas Sterbenz
- * @deprecated Sun JDK internal use only --- WILL BE REMOVED in Dolphin (JDK 7)
+ * @deprecated Sun JDK internal use only --- WILL BE REMOVED in a future
+ * release.
*/
@Deprecated
public class TlsMasterSecretParameterSpec implements AlgorithmParameterSpec {
@@ -47,6 +48,9 @@
private final SecretKey premasterSecret;
private final int majorVersion, minorVersion;
private final byte[] clientRandom, serverRandom;
+ private final String prfHashAlg;
+ private final int prfHashLength;
+ private final int prfBlockSize;
/**
* Constructs a new TlsMasterSecretParameterSpec.
@@ -60,6 +64,12 @@
* @param minorVersion the minor number of the protocol version
* @param clientRandom the client's random value
* @param serverRandom the server's random value
+ * @param prfHashAlg the name of the TLS PRF hash algorithm to use.
+ * Used only for TLS 1.2+. TLS1.1 and earlier use a fixed PRF.
+ * @param prfHashLength the output length of the TLS PRF hash algorithm.
+ * Used only for TLS 1.2+.
+ * @param prfBlockSize the input block size of the TLS PRF hash algorithm.
+ * Used only for TLS 1.2+.
*
* @throws NullPointerException if premasterSecret, clientRandom,
* or serverRandom are null
@@ -67,7 +77,9 @@
* negative or larger than 255
*/
public TlsMasterSecretParameterSpec(SecretKey premasterSecret,
- int majorVersion, int minorVersion, byte[] clientRandom, byte[] serverRandom) {
+ int majorVersion, int minorVersion,
+ byte[] clientRandom, byte[] serverRandom,
+ String prfHashAlg, int prfHashLength, int prfBlockSize) {
if (premasterSecret == null) {
throw new NullPointerException("premasterSecret must not be null");
}
@@ -76,11 +88,15 @@
this.minorVersion = checkVersion(minorVersion);
this.clientRandom = clientRandom.clone();
this.serverRandom = serverRandom.clone();
+ this.prfHashAlg = prfHashAlg;
+ this.prfHashLength = prfHashLength;
+ this.prfBlockSize = prfBlockSize;
}
static int checkVersion(int version) {
if ((version < 0) || (version > 255)) {
- throw new IllegalArgumentException("Version must be between 0 and 255");
+ throw new IllegalArgumentException(
+ "Version must be between 0 and 255");
}
return version;
}
@@ -130,4 +146,30 @@
return serverRandom.clone();
}
+ /**
+ * Obtains the PRF hash algorithm to use in the PRF calculation.
+ *
+ * @return the hash algorithm.
+ */
+ public String getPRFHashAlg() {
+ return prfHashAlg;
+ }
+
+ /**
+ * Obtains the length of the PRF hash algorithm.
+ *
+ * @return the hash algorithm length.
+ */
+ public int getPRFHashLength() {
+ return prfHashLength;
+ }
+
+ /**
+ * Obtains the block size of the PRF hash algorithm.
+ *
+ * @return the hash algorithm block size.
+ */
+ public int getPRFBlockSize() {
+ return prfBlockSize;
+ }
}
--- a/jdk/src/share/classes/sun/security/internal/spec/TlsPrfParameterSpec.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/internal/spec/TlsPrfParameterSpec.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -38,7 +38,8 @@
*
* @since 1.6
* @author Andreas Sterbenz
- * @deprecated Sun JDK internal use only --- WILL BE REMOVED in Dolphin (JDK 7)
+ * @deprecated Sun JDK internal use only --- WILL BE REMOVED in a future
+ * release.
*/
@Deprecated
public class TlsPrfParameterSpec implements AlgorithmParameterSpec {
@@ -47,6 +48,9 @@
private final String label;
private final byte[] seed;
private final int outputLength;
+ private final String prfHashAlg;
+ private final int prfHashLength;
+ private final int prfBlockSize;
/**
* Constructs a new TlsPrfParameterSpec.
@@ -55,11 +59,19 @@
* @param label the label to use in the calculation
* @param seed the random seed to use in the calculation
* @param outputLength the length in bytes of the output key to be produced
+ * @param prfHashAlg the name of the TLS PRF hash algorithm to use.
+ * Used only for TLS 1.2+. TLS1.1 and earlier use a fixed PRF.
+ * @param prfHashLength the output length of the TLS PRF hash algorithm.
+ * Used only for TLS 1.2+.
+ * @param prfBlockSize the input block size of the TLS PRF hash algorithm.
+ * Used only for TLS 1.2+.
*
* @throws NullPointerException if label or seed is null
* @throws IllegalArgumentException if outputLength is negative
*/
- public TlsPrfParameterSpec(SecretKey secret, String label, byte[] seed, int outputLength) {
+ public TlsPrfParameterSpec(SecretKey secret, String label,
+ byte[] seed, int outputLength,
+ String prfHashAlg, int prfHashLength, int prfBlockSize) {
if ((label == null) || (seed == null)) {
throw new NullPointerException("label and seed must not be null");
}
@@ -70,6 +82,9 @@
this.label = label;
this.seed = seed.clone();
this.outputLength = outputLength;
+ this.prfHashAlg = prfHashAlg;
+ this.prfHashLength = prfHashLength;
+ this.prfBlockSize = prfBlockSize;
}
/**
@@ -110,4 +125,33 @@
return outputLength;
}
+ /**
+ * Obtains the PRF hash algorithm to use in the PRF calculation.
+ *
+ * @return the hash algorithm, or null if no algorithm was specified.
+ */
+ public String getPRFHashAlg() {
+ return prfHashAlg;
+ }
+
+ /**
+ * Obtains the length of PRF hash algorithm.
+ *
+ * It would have been preferred to use MessageDigest.getDigestLength(),
+ * but the API does not require implementations to support the method.
+ *
+ * @return the hash algorithm length.
+ */
+ public int getPRFHashLength() {
+ return prfHashLength;
+ }
+
+ /**
+ * Obtains the length of PRF hash algorithm.
+ *
+ * @return the hash algorithm length.
+ */
+ public int getPRFBlockSize() {
+ return prfBlockSize;
+ }
}
--- a/jdk/src/share/classes/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,10 +36,12 @@
*
* @since 1.6
* @author Andreas Sterbenz
- * @deprecated Sun JDK internal use only --- WILL BE REMOVED in Dolphin (JDK 7)
+ * @deprecated Sun JDK internal use only --- WILL BE REMOVED in a future
+ * release.
*/
@Deprecated
-public class TlsRsaPremasterSecretParameterSpec implements AlgorithmParameterSpec {
+public class TlsRsaPremasterSecretParameterSpec
+ implements AlgorithmParameterSpec {
private final int majorVersion;
private final int minorVersion;
@@ -58,10 +60,12 @@
* @throws IllegalArgumentException if minorVersion or majorVersion are
* negative or larger than 255
*/
- public TlsRsaPremasterSecretParameterSpec(int majorVersion, int minorVersion) {
- this.majorVersion = TlsMasterSecretParameterSpec.checkVersion(majorVersion);
- this.minorVersion = TlsMasterSecretParameterSpec.checkVersion(minorVersion);
- }
+ public TlsRsaPremasterSecretParameterSpec(int majorVersion,
+ int minorVersion) {
+ this.majorVersion =
+ TlsMasterSecretParameterSpec.checkVersion(majorVersion);
+ this.minorVersion =
+ TlsMasterSecretParameterSpec.checkVersion(minorVersion); }
/**
* Returns the major version.
--- a/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java Tue Nov 02 19:40:45 2010 -0700
@@ -34,7 +34,6 @@
import sun.security.krb5.*;
import sun.security.krb5.internal.*;
import sun.security.krb5.internal.crypto.*;
-import java.util.Vector;
import java.util.ArrayList;
import java.util.Arrays;
import java.io.IOException;
@@ -42,7 +41,10 @@
import java.io.FileOutputStream;
import java.io.File;
import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
import java.util.StringTokenizer;
+import java.util.Vector;
/**
* This class represents key table. The key table functions deal with storing
@@ -239,23 +241,22 @@
EncryptionKey key;
int size = entries.size();
ArrayList<EncryptionKey> keys = new ArrayList<EncryptionKey> (size);
- if (entries != null) {
- for (int i = size-1; i >= 0; i--) {
- entry = entries.elementAt(i);
- if (entry.service.match(service)) {
- if (EType.isSupported(entry.keyType)) {
- key = new EncryptionKey(entry.keyblock,
- entry.keyType,
- new Integer(entry.keyVersion));
- keys.add(key);
- if (DEBUG) {
- System.out.println("Added key: " + entry.keyType +
- "version: " + entry.keyVersion);
- }
- } else if (DEBUG) {
- System.out.println("Found unsupported keytype (" +
- entry.keyType + ") for " + service);
+
+ for (int i = size-1; i >= 0; i--) {
+ entry = entries.elementAt(i);
+ if (entry.service.match(service)) {
+ if (EType.isSupported(entry.keyType)) {
+ key = new EncryptionKey(entry.keyblock,
+ entry.keyType,
+ new Integer(entry.keyVersion));
+ keys.add(key);
+ if (DEBUG) {
+ System.out.println("Added key: " + entry.keyType +
+ "version: " + entry.keyVersion);
}
+ } else if (DEBUG) {
+ System.out.println("Found unsupported keytype (" +
+ entry.keyType + ") for " + service);
}
}
}
@@ -313,16 +314,14 @@
*/
public boolean findServiceEntry(PrincipalName service) {
KeyTabEntry entry;
- if (entries != null) {
- for (int i = 0; i < entries.size(); i++) {
- entry = entries.elementAt(i);
- if (entry.service.match(service)) {
- if (EType.isSupported(entry.keyType)) {
- return true;
- } else if (DEBUG) {
- System.out.println("Found unsupported keytype (" +
- entry.keyType + ") for " + service);
- }
+ for (int i = 0; i < entries.size(); i++) {
+ entry = entries.elementAt(i);
+ if (entry.service.match(service)) {
+ if (EType.isSupported(entry.keyType)) {
+ return true;
+ } else if (DEBUG) {
+ System.out.println("Found unsupported keytype (" +
+ entry.keyType + ") for " + service);
}
}
}
@@ -337,94 +336,57 @@
* Adds a new entry in the key table.
* @param service the service which will have a new entry in the key table.
* @param psswd the password which generates the key.
+ * @param kvno the kvno to use, -1 means automatic increasing
+ * @param append false if entries with old kvno would be removed.
+ * Note: if kvno is not -1, entries with the same kvno are always removed
*/
- public void addEntry(PrincipalName service, char[] psswd)
- throws KrbException {
+ public void addEntry(PrincipalName service, char[] psswd,
+ int kvno, boolean append) throws KrbException {
EncryptionKey[] encKeys = EncryptionKey.acquireSecretKeys(
psswd, service.getSalt());
+ // There should be only one maximum KVNO value for all etypes, so that
+ // all added keys can have the same KVNO.
+
+ int maxKvno = 0; // only useful when kvno == -1
+ for (int i = entries.size()-1; i >= 0; i--) {
+ KeyTabEntry e = entries.get(i);
+ if (e.service.match(service)) {
+ if (e.keyVersion > maxKvno) {
+ maxKvno = e.keyVersion;
+ }
+ if (!append || e.keyVersion == kvno) {
+ entries.removeElementAt(i);
+ }
+ }
+ }
+ if (kvno == -1) {
+ kvno = maxKvno + 1;
+ }
+
for (int i = 0; encKeys != null && i < encKeys.length; i++) {
int keyType = encKeys[i].getEType();
byte[] keyValue = encKeys[i].getBytes();
- int result = retrieveEntry(service, keyType);
- int kvno = 1;
- if (result != -1) {
- KeyTabEntry oldEntry = entries.elementAt(result);
- kvno = oldEntry.keyVersion;
- entries.removeElementAt(result);
- kvno += 1;
- } else
- kvno = 1;
KeyTabEntry newEntry = new KeyTabEntry(service,
service.getRealm(),
new KerberosTime(System.currentTimeMillis()),
kvno, keyType, keyValue);
- if (entries == null)
- entries = new Vector<KeyTabEntry> ();
entries.addElement(newEntry);
}
}
/**
- * Only used by KDC test. This method can specify kvno and does not
- * remove any old keys.
- */
- public void addEntry(PrincipalName service, char[] psswd, int kvno)
- throws KrbException {
-
- EncryptionKey[] encKeys = EncryptionKey.acquireSecretKeys(
- psswd, service.getSalt());
-
- for (int i = 0; encKeys != null && i < encKeys.length; i++) {
- int keyType = encKeys[i].getEType();
- byte[] keyValue = encKeys[i].getBytes();
- KeyTabEntry newEntry = new KeyTabEntry(service,
- service.getRealm(),
- new KerberosTime(System.currentTimeMillis()),
- kvno, keyType, keyValue);
- if (entries == null)
- entries = new Vector<KeyTabEntry> ();
- entries.addElement(newEntry);
- }
- }
-
- /**
- * Retrieves the key table entry with the specified service name.
- * @param service the service which may have an entry in the key table.
- * @param keyType the etype to match, returns the 1st one if -1 provided
- * @return -1 if the entry is not found, else return the entry index
- * in the list.
- */
- private int retrieveEntry(PrincipalName service, int keyType) {
- KeyTabEntry e;
- if (entries != null) {
- for (int i = 0; i < entries.size(); i++) {
- e = entries.elementAt(i);
- if (service.match(e.getService()) &&
- (keyType == -1 || e.keyType == keyType)) {
- return i;
- }
- }
- }
- return -1;
- }
-
- /**
* Gets the list of service entries in key table.
* @return array of <code>KeyTabEntry</code>.
*/
public KeyTabEntry[] getEntries() {
- if (entries != null) {
- KeyTabEntry[] kentries = new KeyTabEntry[entries.size()];
- for (int i = 0; i < kentries.length; i++) {
- kentries[i] = entries.elementAt(i);
- }
- return kentries;
- } else {
- return null;
+ KeyTabEntry[] kentries = new KeyTabEntry[entries.size()];
+ for (int i = 0; i < kentries.length; i++) {
+ kentries[i] = entries.elementAt(i);
}
+ return kentries;
}
/**
@@ -464,29 +426,55 @@
}
/**
- * Removes an entry from the key table.
+ * Removes entries from the key table.
* @param service the service <code>PrincipalName</code>.
- * @param etype the etype to match, first one if -1 provided
- * @return 1 if removed successfully, 0 otherwise
+ * @param etype the etype to match, remove all if -1
+ * @param kvno what kvno to remove, -1 for all, -2 for old
+ * @return the number of entries deleted
*/
- public int deleteEntry(PrincipalName service, int etype) {
- int result = retrieveEntry(service, etype);
- if (result != -1) {
- entries.removeElementAt(result);
- return 1;
+ public int deleteEntries(PrincipalName service, int etype, int kvno) {
+ int count = 0;
+
+ // Remember the highest KVNO for each etype. Used for kvno == -2
+ Map<Integer,Integer> highest = new HashMap<>();
+
+ for (int i = entries.size()-1; i >= 0; i--) {
+ KeyTabEntry e = entries.get(i);
+ if (service.match(e.getService())) {
+ if (etype == -1 || e.keyType == etype) {
+ if (kvno == -2) {
+ // Two rounds for kvno == -2. In the first round (here),
+ // only find out highest KVNO for each etype
+ if (highest.containsKey(e.keyType)) {
+ int n = highest.get(e.keyType);
+ if (e.keyVersion > n) {
+ highest.put(e.keyType, e.keyVersion);
+ }
+ } else {
+ highest.put(e.keyType, e.keyVersion);
+ }
+ } else if (kvno == -1 || e.keyVersion == kvno) {
+ entries.removeElementAt(i);
+ count++;
+ }
+ }
+ }
}
- return 0;
- }
- /**
- * Removes an entry from the key table.
- * @param service the service <code>PrincipalName</code>.
- * @return number of entries removed
- */
- public int deleteEntry(PrincipalName service) {
- int count = 0;
- while (deleteEntry(service, -1) > 0) {
- count++;
+ // Second round for kvno == -2, remove old entries
+ if (kvno == -2) {
+ for (int i = entries.size()-1; i >= 0; i--) {
+ KeyTabEntry e = entries.get(i);
+ if (service.match(e.getService())) {
+ if (etype == -1 || e.keyType == etype) {
+ int n = highest.get(e.keyType);
+ if (e.keyVersion != n) {
+ entries.removeElementAt(i);
+ count++;
+ }
+ }
+ }
+ }
}
return count;
}
--- a/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs11/SunPKCS11.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -655,6 +655,25 @@
d(SIG, "SHA512withRSA", P11Signature,
m(CKM_SHA512_RSA_PKCS, CKM_RSA_PKCS, CKM_RSA_X_509));
+ /*
+ * TLS 1.2 uses a different hash algorithm than 1.0/1.1 for the
+ * PRF calculations. As of 2010, there is no PKCS11-level
+ * support for TLS 1.2 PRF calculations, and no known OS's have
+ * an internal variant we could use. Therefore for TLS 1.2, we
+ * are updating JSSE to request different provider algorithms
+ * (e.g. "SunTls12Prf"), and currently only SunJCE has these
+ * TLS 1.2 algorithms.
+ *
+ * If we reused the names such as "SunTlsPrf", the PKCS11
+ * providers would need be updated to fail correctly when
+ * presented with the wrong version number (via
+ * Provider.Service.supportsParameters()), and we would also
+ * need to add the appropriate supportsParamters() checks into
+ * KeyGenerators (not currently there).
+ *
+ * In the future, if PKCS11 support is added, we will restructure
+ * this.
+ */
d(KG, "SunTlsRsaPremasterSecret",
"sun.security.pkcs11.P11TlsRsaPremasterSecretGenerator",
m(CKM_SSL3_PRE_MASTER_KEY_GEN, CKM_TLS_PRE_MASTER_KEY_GEN));
@@ -887,7 +906,8 @@
return (aliases == null) ? null : Arrays.asList(aliases);
}
- public Object newInstance(Object param) throws NoSuchAlgorithmException {
+ public Object newInstance(Object param)
+ throws NoSuchAlgorithmException {
if (token.isValid() == false) {
throw new NoSuchAlgorithmException("Token has been removed");
}
--- a/jdk/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2010, 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,95 +25,336 @@
package sun.security.provider.certpath;
-import java.util.Set;
+import java.security.AlgorithmConstraints;
+import java.security.CryptoPrimitive;
import java.util.Collection;
-import java.util.Locale;
+import java.util.Collections;
+import java.util.Set;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.math.BigInteger;
+import java.security.PublicKey;
+import java.security.KeyFactory;
+import java.security.AlgorithmParameters;
+import java.security.NoSuchAlgorithmException;
+import java.security.GeneralSecurityException;
import java.security.cert.Certificate;
+import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
-import java.security.cert.X509CRL;
+import java.security.cert.PKIXCertPathChecker;
+import java.security.cert.TrustAnchor;
+import java.security.cert.CRLException;
+import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException;
-import java.security.cert.PKIXCertPathChecker;
+import java.io.IOException;
+import java.security.interfaces.*;
+import java.security.spec.*;
+import sun.security.util.DisabledAlgorithmConstraints;
+import sun.security.x509.X509CertImpl;
+import sun.security.x509.X509CRLImpl;
import sun.security.x509.AlgorithmId;
/**
- * AlgorithmChecker is a <code>PKIXCertPathChecker</code> that checks that
- * the signature algorithm of the specified certificate is not disabled.
+ * A <code>PKIXCertPathChecker</code> implementation to check whether a
+ * specified certificate contains the required algorithm constraints.
+ * <p>
+ * Certificate fields such as the subject public key, the signature
+ * algorithm, key usage, extended key usage, etc. need to conform to
+ * the specified algorithm constraints.
*
- * @author Xuelei Fan
+ * @see PKIXCertPathChecker
+ * @see PKIXParameters
*/
final public class AlgorithmChecker extends PKIXCertPathChecker {
- // the disabled algorithms
- private static final String[] disabledAlgorithms = new String[] {"md2"};
+ private final AlgorithmConstraints constraints;
+ private final PublicKey trustedPubKey;
+ private PublicKey prevPubKey;
- // singleton instance
- static final AlgorithmChecker INSTANCE = new AlgorithmChecker();
+ private final static Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
+ EnumSet.of(CryptoPrimitive.SIGNATURE);
+
+ private final static DisabledAlgorithmConstraints
+ certPathDefaultConstraints = new DisabledAlgorithmConstraints(
+ DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
/**
- * Default Constructor
+ * Create a new <code>AlgorithmChecker</code> with the algorithm
+ * constraints specified in security property
+ * "jdk.certpath.disabledAlgorithms".
+ *
+ * @param anchor the trust anchor selected to validate the target
+ * certificate
*/
- private AlgorithmChecker() {
- // do nothing
+ public AlgorithmChecker(TrustAnchor anchor) {
+ this(anchor, certPathDefaultConstraints);
+ }
+
+ /**
+ * Create a new <code>AlgorithmChecker</code> with the
+ * given {@code AlgorithmConstraints}.
+ * <p>
+ * Note that this constructor will be used to check a certification
+ * path where the trust anchor is unknown, or a certificate list which may
+ * contain the trust anchor. This constructor is used by SunJSSE.
+ *
+ * @param constraints the algorithm constraints (or null)
+ */
+ public AlgorithmChecker(AlgorithmConstraints constraints) {
+ this.prevPubKey = null;
+ this.trustedPubKey = null;
+ this.constraints = constraints;
}
/**
- * Return a AlgorithmChecker instance.
+ * Create a new <code>AlgorithmChecker</code> with the
+ * given <code>TrustAnchor</code> and <code>AlgorithmConstraints</code>.
+ *
+ * @param anchor the trust anchor selected to validate the target
+ * certificate
+ * @param constraints the algorithm constraints (or null)
+ *
+ * @throws IllegalArgumentException if the <code>anchor</code> is null
*/
- static AlgorithmChecker getInstance() {
- return INSTANCE;
+ public AlgorithmChecker(TrustAnchor anchor,
+ AlgorithmConstraints constraints) {
+
+ if (anchor == null) {
+ throw new IllegalArgumentException(
+ "The trust anchor cannot be null");
+ }
+
+ if (anchor.getTrustedCert() != null) {
+ this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
+ } else {
+ this.trustedPubKey = anchor.getCAPublicKey();
+ }
+
+ this.prevPubKey = trustedPubKey;
+ this.constraints = constraints;
}
- /**
- * Initializes the internal state of the checker from parameters
- * specified in the constructor.
- */
+ @Override
public void init(boolean forward) throws CertPathValidatorException {
- // do nothing
+ // Note that this class does not support forward mode.
+ if (!forward) {
+ if (trustedPubKey != null) {
+ prevPubKey = trustedPubKey;
+ } else {
+ prevPubKey = null;
+ }
+ } else {
+ throw new
+ CertPathValidatorException("forward checking not supported");
+ }
}
+ @Override
public boolean isForwardCheckingSupported() {
+ // Note that as this class does not support forward mode, the method
+ // will always returns false.
return false;
}
+ @Override
public Set<String> getSupportedExtensions() {
return null;
}
- /**
- * Checks the signature algorithm of the specified certificate.
- */
- public void check(Certificate cert, Collection<String> unresolvedCritExts)
+ @Override
+ public void check(Certificate cert,
+ Collection<String> unresolvedCritExts)
throws CertPathValidatorException {
- check(cert);
- }
+
+ if (!(cert instanceof X509Certificate) || constraints == null) {
+ // ignore the check for non-x.509 certificate or null constraints
+ return;
+ }
+
+ X509CertImpl x509Cert = null;
+ try {
+ x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
+ } catch (CertificateException ce) {
+ throw new CertPathValidatorException(ce);
+ }
+
+ PublicKey currPubKey = x509Cert.getPublicKey();
+ String currSigAlg = x509Cert.getSigAlgName();
+
+ AlgorithmId algorithmId = null;
+ try {
+ algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
+ } catch (CertificateException ce) {
+ throw new CertPathValidatorException(ce);
+ }
+
+ AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
+
+ // Check the current signature algorithm
+ if (!constraints.permits(
+ SIGNATURE_PRIMITIVE_SET,
+ currSigAlg, currSigAlgParams)) {
+ throw new CertPathValidatorException(
+ "Algorithm constraints check failed: " + currSigAlg);
+ }
+
+ // check the key usage and key size
+ boolean[] keyUsage = x509Cert.getKeyUsage();
+ if (keyUsage != null && keyUsage.length < 9) {
+ throw new CertPathValidatorException(
+ "incorrect KeyUsage extension");
+ }
+
+ if (keyUsage != null) {
+ Set<CryptoPrimitive> primitives =
+ EnumSet.noneOf(CryptoPrimitive.class);
+
+ if (keyUsage[0] || keyUsage[1] || keyUsage[5] || keyUsage[6]) {
+ // keyUsage[0]: KeyUsage.digitalSignature
+ // keyUsage[1]: KeyUsage.nonRepudiation
+ // keyUsage[5]: KeyUsage.keyCertSign
+ // keyUsage[6]: KeyUsage.cRLSign
+ primitives.add(CryptoPrimitive.SIGNATURE);
+ }
+
+ if (keyUsage[2]) { // KeyUsage.keyEncipherment
+ primitives.add(CryptoPrimitive.KEY_ENCAPSULATION);
+ }
+
+ if (keyUsage[3]) { // KeyUsage.dataEncipherment
+ primitives.add(CryptoPrimitive.PUBLIC_KEY_ENCRYPTION);
+ }
- public static void check(Certificate cert)
- throws CertPathValidatorException {
- X509Certificate xcert = (X509Certificate)cert;
- check(xcert.getSigAlgName());
+ if (keyUsage[4]) { // KeyUsage.keyAgreement
+ primitives.add(CryptoPrimitive.KEY_AGREEMENT);
+ }
+
+ // KeyUsage.encipherOnly and KeyUsage.decipherOnly are
+ // undefined in the absence of the keyAgreement bit.
+
+ if (!primitives.isEmpty()) {
+ if (!constraints.permits(primitives, currPubKey)) {
+ throw new CertPathValidatorException(
+ "algorithm constraints check failed");
+ }
+ }
+ }
+
+ // Check with previous cert for signature algorithm and public key
+ if (prevPubKey != null) {
+ if (currSigAlg != null) {
+ if (!constraints.permits(
+ SIGNATURE_PRIMITIVE_SET,
+ currSigAlg, prevPubKey, currSigAlgParams)) {
+ throw new CertPathValidatorException(
+ "Algorithm constraints check failed: " + currSigAlg);
+ }
+ }
+
+ // Inherit key parameters from previous key
+ if (currPubKey instanceof DSAPublicKey &&
+ ((DSAPublicKey)currPubKey).getParams() == null) {
+ // Inherit DSA parameters from previous key
+ if (!(prevPubKey instanceof DSAPublicKey)) {
+ throw new CertPathValidatorException("Input key is not " +
+ "of a appropriate type for inheriting parameters");
+ }
+
+ DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
+ if (params == null) {
+ throw new CertPathValidatorException(
+ "Key parameters missing");
+ }
+
+ try {
+ BigInteger y = ((DSAPublicKey)currPubKey).getY();
+ KeyFactory kf = KeyFactory.getInstance("DSA");
+ DSAPublicKeySpec ks = new DSAPublicKeySpec(y,
+ params.getP(),
+ params.getQ(),
+ params.getG());
+ currPubKey = kf.generatePublic(ks);
+ } catch (GeneralSecurityException e) {
+ throw new CertPathValidatorException("Unable to generate " +
+ "key with inherited parameters: " + e.getMessage(), e);
+ }
+ }
+ }
+
+ // reset the previous public key
+ prevPubKey = currPubKey;
+
+ // check the extended key usage, ignore the check now
+ // List<String> extendedKeyUsages = x509Cert.getExtendedKeyUsage();
+
+ // DO NOT remove any unresolved critical extensions
}
- static void check(AlgorithmId aid) throws CertPathValidatorException {
- check(aid.getName());
- }
-
- static void check(X509CRL crl) throws CertPathValidatorException {
- check(crl.getSigAlgName());
- }
+ /**
+ * Try to set the trust anchor of the checker.
+ * <p>
+ * If there is no trust anchor specified and the checker has not started,
+ * set the trust anchor.
+ *
+ * @param anchor the trust anchor selected to validate the target
+ * certificate
+ */
+ void trySetTrustAnchor(TrustAnchor anchor) {
+ // Don't bother if the check has started or trust anchor has already
+ // specified.
+ if (prevPubKey == null) {
+ if (anchor == null) {
+ throw new IllegalArgumentException(
+ "The trust anchor cannot be null");
+ }
- private static void check(String algName)
- throws CertPathValidatorException {
-
- String lowerCaseAlgName = algName.toLowerCase(Locale.ENGLISH);
-
- for (String disabled : disabledAlgorithms) {
- // checking the signature algorithm name
- if (lowerCaseAlgName.indexOf(disabled) != -1) {
- throw new CertPathValidatorException(
- "algorithm check failed: " + algName + " is disabled");
+ // Don't bother to change the trustedPubKey.
+ if (anchor.getTrustedCert() != null) {
+ prevPubKey = anchor.getTrustedCert().getPublicKey();
+ } else {
+ prevPubKey = anchor.getCAPublicKey();
}
}
}
+ /**
+ * Check the signature algorithm with the specified public key.
+ *
+ * @param key the public key to verify the CRL signature
+ * @param crl the target CRL
+ */
+ static void check(PublicKey key, X509CRL crl)
+ throws CertPathValidatorException {
+
+ X509CRLImpl x509CRLImpl = null;
+ try {
+ x509CRLImpl = X509CRLImpl.toImpl(crl);
+ } catch (CRLException ce) {
+ throw new CertPathValidatorException(ce);
+ }
+
+ AlgorithmId algorithmId = x509CRLImpl.getSigAlgId();
+ check(key, algorithmId);
+ }
+
+ /**
+ * Check the signature algorithm with the specified public key.
+ *
+ * @param key the public key to verify the CRL signature
+ * @param crl the target CRL
+ */
+ static void check(PublicKey key, AlgorithmId algorithmId)
+ throws CertPathValidatorException {
+ String sigAlgName = algorithmId.getName();
+ AlgorithmParameters sigAlgParams = algorithmId.getParameters();
+
+ if (!certPathDefaultConstraints.permits(
+ SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
+ throw new CertPathValidatorException(
+ "algorithm check failed: " + sigAlgName + " is disabled");
+ }
+ }
+
}
+
--- a/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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
@@ -289,16 +289,6 @@
X500Name certIssuer = (X500Name) certImpl.getIssuerDN();
X500Name crlIssuer = (X500Name) crlImpl.getIssuerDN();
- // check the crl signature algorithm
- try {
- AlgorithmChecker.check(crl);
- } catch (CertPathValidatorException cpve) {
- if (debug != null) {
- debug.println("CRL signature algorithm check failed: " + cpve);
- }
- return false;
- }
-
// if crlIssuer is set, verify that it matches the issuer of the
// CRL and the CRL contains an IDP extension with the indirectCRL
// boolean asserted. Otherwise, verify that the CRL issuer matches the
@@ -637,6 +627,16 @@
}
}
+ // check the crl signature algorithm
+ try {
+ AlgorithmChecker.check(prevKey, crl);
+ } catch (CertPathValidatorException cpve) {
+ if (debug != null) {
+ debug.println("CRL signature algorithm check failed: " + cpve);
+ }
+ return false;
+ }
+
// validate the signature on the CRL
try {
crl.verify(prevKey, provider);
--- a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -719,11 +719,6 @@
/* we don't perform any validation of the trusted cert */
if (!isTrustedCert) {
/*
- * check that the signature algorithm is not disabled.
- */
- AlgorithmChecker.check(cert);
-
- /*
* Check CRITICAL private extensions for user checkers that
* support forward checking (forwardCheckers) and remove
* ones we know how to check.
--- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -327,6 +327,10 @@
"(set using the OCSP security properties).");
}
+ // The algorithm constraints of the OCSP trusted responder certificate
+ // does not need to be checked in this code. The constraints will be
+ // checked when the responder's certificate is validated.
+
CertId certId = null;
OCSPResponse response = null;
try {
--- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -32,6 +32,7 @@
import java.security.cert.CertificateParsingException;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CRLReason;
+import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.Date;
@@ -371,6 +372,13 @@
"OCSP responses", cpe);
}
+ // Check algorithm constraints specified in security property
+ // "jdk.certpath.disabledAlgorithms".
+ AlgorithmChecker algChecker = new AlgorithmChecker(
+ new TrustAnchor(responderCert, null));
+ algChecker.init(false);
+ algChecker.check(cert, Collections.<String>emptySet());
+
// check the validity
try {
if (dateCheckedAgainst == null) {
@@ -422,6 +430,10 @@
// Confirm that the signed response was generated using the public
// key from the trusted responder cert
if (responderCert != null) {
+ // Check algorithm constraints specified in security property
+ // "jdk.certpath.disabledAlgorithms".
+ AlgorithmChecker.check(responderCert.getPublicKey(), sigAlgId);
+
if (!verifyResponse(responseDataDer, responderCert,
sigAlgId, signature)) {
throw new CertPathValidatorException(
--- a/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -275,7 +275,7 @@
int certPathLen = certList.size();
basicChecker = new BasicChecker(anchor, testDate, sigProvider, false);
- AlgorithmChecker algorithmChecker= AlgorithmChecker.getInstance();
+ AlgorithmChecker algorithmChecker = new AlgorithmChecker(anchor);
KeyChecker keyChecker = new KeyChecker(certPathLen,
pkixParam.getTargetCertConstraints());
ConstraintsChecker constraintsChecker =
--- a/jdk/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -347,9 +347,6 @@
return;
}
- /* check that the signature algorithm is not disabled. */
- AlgorithmChecker.check(cert);
-
/*
* check for looping - abort a loop if
* ((we encounter the same certificate twice) AND
@@ -470,9 +467,16 @@
if (unresolvedCritExts == null) {
unresolvedCritExts = Collections.<String>emptySet();
}
+
+ /*
+ * Check that the signature algorithm is not disabled.
+ */
+ currentState.algorithmChecker.check(cert, unresolvedCritExts);
+
for (PKIXCertPathChecker checker : currentState.userCheckers) {
checker.check(cert, unresolvedCritExts);
}
+
/*
* Look at the remaining extensions and remove any ones we have
* already checked. If there are any left, throw an exception!
--- a/jdk/src/share/classes/sun/security/provider/certpath/ReverseState.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/ReverseState.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -96,6 +96,9 @@
/* the checker used for revocation status */
public CrlRevocationChecker crlChecker;
+ /* the algorithm checker */
+ AlgorithmChecker algorithmChecker;
+
/* the trust anchor used to validate the path */
TrustAnchor trustAnchor;
@@ -241,6 +244,14 @@
updateState(anchor.getCAPublicKey(), caName);
}
+ // The user specified AlgorithmChecker may not be
+ // able to set the trust anchor until now.
+ for (PKIXCertPathChecker checker : userCheckers) {
+ if (checker instanceof AlgorithmChecker) {
+ ((AlgorithmChecker)checker).trySetTrustAnchor(anchor);
+ }
+ }
+
init = false;
}
--- a/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2010, 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
@@ -302,6 +302,7 @@
// init the crl checker
currentState.crlChecker =
new CrlRevocationChecker(null, buildParams, null, onlyEECert);
+ currentState.algorithmChecker = new AlgorithmChecker(anchor);
try {
depthFirstSearchReverse(null, currentState,
new ReverseBuilder(buildParams, targetSubjectDN), adjacencyList,
@@ -475,29 +476,41 @@
userCheckers.add(mustCheck, policyChecker);
mustCheck++;
+ // add the algorithm checker
+ userCheckers.add(mustCheck,
+ new AlgorithmChecker(builder.trustAnchor));
+ mustCheck++;
+
if (nextState.keyParamsNeeded()) {
PublicKey rootKey = cert.getPublicKey();
if (builder.trustAnchor.getTrustedCert() == null) {
rootKey = builder.trustAnchor.getCAPublicKey();
if (debug != null)
- debug.println("SunCertPathBuilder.depthFirstSearchForward" +
- " using buildParams public key: " +
- rootKey.toString());
+ debug.println(
+ "SunCertPathBuilder.depthFirstSearchForward " +
+ "using buildParams public key: " +
+ rootKey.toString());
}
TrustAnchor anchor = new TrustAnchor
(cert.getSubjectX500Principal(), rootKey, null);
+
+ // add the basic checker
basicChecker = new BasicChecker(anchor,
builder.date,
buildParams.getSigProvider(),
true);
userCheckers.add(mustCheck, basicChecker);
mustCheck++;
+
+ // add the crl revocation checker
if (buildParams.isRevocationEnabled()) {
userCheckers.add(mustCheck, new CrlRevocationChecker
(anchor, buildParams, null, onlyEECert));
mustCheck++;
}
}
+ // Why we don't need BasicChecker and CrlRevocationChecker
+ // if nextState.keyParamsNeeded() is false?
for (int i=0; i<appendedCerts.size(); i++) {
X509Certificate currCert = appendedCerts.get(i);
@@ -513,10 +526,18 @@
for (int j=0; j<userCheckers.size(); j++) {
PKIXCertPathChecker currChecker = userCheckers.get(j);
if (j < mustCheck ||
- !currChecker.isForwardCheckingSupported())
- {
+ !currChecker.isForwardCheckingSupported()) {
if (i == 0) {
currChecker.init(false);
+
+ // The user specified
+ // AlgorithmChecker may not be
+ // able to set the trust anchor until now.
+ if (j >= mustCheck &&
+ currChecker instanceof AlgorithmChecker) {
+ ((AlgorithmChecker)currChecker).
+ trySetTrustAnchor(builder.trustAnchor);
+ }
}
try {
--- a/jdk/src/share/classes/sun/security/rsa/RSASignature.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/rsa/RSASignature.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -49,7 +49,7 @@
public abstract class RSASignature extends SignatureSpi {
// we sign an ASN.1 SEQUENCE of AlgorithmId and digest
- // it has the form 30:xx:30:0c:[digestOID]:05:00:04:xx:[digest]
+ // it has the form 30:xx:30:xx:[digestOID]:05:00:04:xx:[digest]
// this means the encoded length is (8 + digestOID.length + digest.length)
private static final int baseLength = 8;
@@ -104,7 +104,8 @@
// initialize for signing. See JCA doc
protected void engineInitSign(PrivateKey privateKey, SecureRandom random)
throws InvalidKeyException {
- RSAPrivateKey rsaKey = (RSAPrivateKey)RSAKeyFactory.toRSAKey(privateKey);
+ RSAPrivateKey rsaKey =
+ (RSAPrivateKey)RSAKeyFactory.toRSAKey(privateKey);
this.privateKey = rsaKey;
this.publicKey = null;
initCommon(rsaKey, random);
@@ -212,7 +213,8 @@
DerOutputStream out = new DerOutputStream();
new AlgorithmId(oid).encode(out);
out.putOctetString(digest);
- DerValue result = new DerValue(DerValue.tag_Sequence, out.toByteArray());
+ DerValue result =
+ new DerValue(DerValue.tag_Sequence, out.toByteArray());
return result.toByteArray();
}
@@ -229,7 +231,8 @@
}
AlgorithmId algId = AlgorithmId.parse(values[0]);
if (algId.getOID().equals(oid) == false) {
- throw new IOException("ObjectIdentifier mismatch: " + algId.getOID());
+ throw new IOException("ObjectIdentifier mismatch: "
+ + algId.getOID());
}
if (algId.getEncodedParams() != null) {
throw new IOException("Unexpected AlgorithmId parameters");
--- a/jdk/src/share/classes/sun/security/ssl/CipherBox.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/CipherBox.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, 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
@@ -28,6 +28,7 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.util.Hashtable;
import java.security.*;
import javax.crypto.*;
@@ -50,6 +51,37 @@
* Individual instances are obtained by calling the static method
* newCipherBox(), which should only be invoked by BulkCipher.newCipher().
*
+ * In RFC 2246, with bock ciphers in CBC mode, the Initialization
+ * Vector (IV) for the first record is generated with the other keys
+ * and secrets when the security parameters are set. The IV for
+ * subsequent records is the last ciphertext block from the previous
+ * record.
+ *
+ * In RFC 4346, the implicit Initialization Vector (IV) is replaced
+ * with an explicit IV to protect against CBC attacks. RFC 4346
+ * recommends two algorithms used to generated the per-record IV.
+ * The implementation uses the algorithm (2)(b), as described at
+ * section 6.2.3.2 of RFC 4346.
+ *
+ * The usage of IV in CBC block cipher can be illustrated in
+ * the following diagrams.
+ *
+ * (random)
+ * R P1 IV C1
+ * | | | |
+ * SIV---+ |-----+ |-... |----- |------
+ * | | | | | | | |
+ * +----+ | +----+ | +----+ | +----+ |
+ * | Ek | | + Ek + | | Dk | | | Dk | |
+ * +----+ | +----+ | +----+ | +----+ |
+ * | | | | | | | |
+ * |----| |----| SIV--+ |----| |-...
+ * | | | |
+ * IV C1 R P1
+ * (discard)
+ *
+ * CBC Encryption CBC Decryption
+ *
* NOTE that any ciphering involved in key exchange (e.g. with RSA) is
* handled separately.
*
@@ -76,6 +108,21 @@
private int blockSize;
/**
+ * secure random
+ */
+ private SecureRandom random;
+
+ /**
+ * Fixed masks of various block size, as the initial decryption IVs
+ * for TLS 1.1 or later.
+ *
+ * For performance, we do not use random IVs. As the initial decryption
+ * IVs will be discarded by TLS decryption processes, so the fixed masks
+ * do not hurt cryptographic strength.
+ */
+ private static Hashtable<Integer, IvParameterSpec> masks;
+
+ /**
* NULL cipherbox. Identity operation, no encryption.
*/
private CipherBox() {
@@ -90,14 +137,37 @@
* implementation could be found.
*/
private CipherBox(ProtocolVersion protocolVersion, BulkCipher bulkCipher,
- SecretKey key, IvParameterSpec iv, boolean encrypt)
- throws NoSuchAlgorithmException {
+ SecretKey key, IvParameterSpec iv, SecureRandom random,
+ boolean encrypt) throws NoSuchAlgorithmException {
try {
this.protocolVersion = protocolVersion;
this.cipher = JsseJce.getCipher(bulkCipher.transformation);
int mode = encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE;
- cipher.init(mode, key, iv);
- // do not call getBlockSize until after init()
+
+ if (random == null) {
+ random = JsseJce.getSecureRandom();
+ }
+ this.random = random;
+
+ /*
+ * RFC 4346 recommends two algorithms used to generated the
+ * per-record IV. The implementation uses the algorithm (2)(b),
+ * as described at section 6.2.3.2 of RFC 4346.
+ *
+ * As we don't care about the initial IV value for TLS 1.1 or
+ * later, so if the "iv" parameter is null, we use the default
+ * value generated by Cipher.init() for encryption, and a fixed
+ * mask for decryption.
+ */
+ if (iv == null && bulkCipher.ivSize != 0 &&
+ mode == Cipher.DECRYPT_MODE &&
+ protocolVersion.v >= ProtocolVersion.TLS11.v) {
+ iv = getFixedMask(bulkCipher.ivSize);
+ }
+
+ cipher.init(mode, key, iv, random);
+
+ // Do not call getBlockSize until after init()
// otherwise we would disrupt JCE delayed provider selection
blockSize = cipher.getBlockSize();
// some providers implement getBlockSize() incorrectly
@@ -119,19 +189,37 @@
* Factory method to obtain a new CipherBox object.
*/
static CipherBox newCipherBox(ProtocolVersion version, BulkCipher cipher,
- SecretKey key, IvParameterSpec iv, boolean encrypt)
- throws NoSuchAlgorithmException {
+ SecretKey key, IvParameterSpec iv, SecureRandom random,
+ boolean encrypt) throws NoSuchAlgorithmException {
if (cipher.allowed == false) {
throw new NoSuchAlgorithmException("Unsupported cipher " + cipher);
}
+
if (cipher == B_NULL) {
return NULL;
} else {
- return new CipherBox(version, cipher, key, iv, encrypt);
+ return new CipherBox(version, cipher, key, iv, random, encrypt);
}
}
/*
+ * Get a fixed mask, as the initial decryption IVs for TLS 1.1 or later.
+ */
+ private static IvParameterSpec getFixedMask(int ivSize) {
+ if (masks == null) {
+ masks = new Hashtable<Integer, IvParameterSpec>(5);
+ }
+
+ IvParameterSpec iv = masks.get(ivSize);
+ if (iv == null) {
+ iv = new IvParameterSpec(new byte[ivSize]);
+ masks.put(ivSize, iv);
+ }
+
+ return iv;
+ }
+
+ /*
* Encrypts a block of data, returning the size of the
* resulting block.
*/
@@ -139,8 +227,26 @@
if (cipher == null) {
return len;
}
+
try {
if (blockSize != 0) {
+ // TLSv1.1 needs a IV block
+ if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
+ // generate a random number
+ byte[] prefix = new byte[blockSize];
+ random.nextBytes(prefix);
+
+ // move forward the plaintext
+ System.arraycopy(buf, offset,
+ buf, offset + prefix.length, len);
+
+ // prefix the plaintext
+ System.arraycopy(prefix, 0,
+ buf, offset, prefix.length);
+
+ len += prefix.length;
+ }
+
len = addPadding(buf, offset, len, blockSize);
}
if (debug != null && Debug.isOn("plaintext")) {
@@ -189,6 +295,34 @@
int pos = bb.position();
if (blockSize != 0) {
+ // TLSv1.1 needs a IV block
+ if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
+ // generate a random number
+ byte[] prefix = new byte[blockSize];
+ random.nextBytes(prefix);
+
+ // move forward the plaintext
+ byte[] buf = null;
+ int limit = bb.limit();
+ if (bb.hasArray()) {
+ buf = bb.array();
+ System.arraycopy(buf, pos,
+ buf, pos + prefix.length, limit - pos);
+ bb.limit(limit + prefix.length);
+ } else {
+ buf = new byte[limit - pos];
+ bb.get(buf, 0, limit - pos);
+ bb.position(pos + prefix.length);
+ bb.limit(limit + prefix.length);
+ bb.put(buf);
+ }
+ bb.position(pos);
+
+ // prefix the plaintext
+ bb.put(prefix);
+ bb.position(pos);
+ }
+
// addPadding adjusts pos/limit
len = addPadding(bb, blockSize);
bb.position(pos);
@@ -236,11 +370,25 @@
/*
* Decrypts a block of data, returning the size of the
* resulting block if padding was required.
+ *
+ * For SSLv3 and TLSv1.0, with block ciphers in CBC mode the
+ * Initialization Vector (IV) for the first record is generated by
+ * the handshake protocol, the IV for subsequent records is the
+ * last ciphertext block from the previous record.
+ *
+ * From TLSv1.1, the implicit IV is replaced with an explicit IV to
+ * protect against CBC attacks.
+ *
+ * Differentiating between bad_record_mac and decryption_failed alerts
+ * may permit certain attacks against CBC mode. It is preferable to
+ * uniformly use the bad_record_mac alert to hide the specific type of
+ * the error.
*/
int decrypt(byte[] buf, int offset, int len) throws BadPaddingException {
if (cipher == null) {
return len;
}
+
try {
int newLen = cipher.update(buf, offset, len, buf, offset);
if (newLen != len) {
@@ -263,6 +411,18 @@
if (blockSize != 0) {
newLen = removePadding(buf, offset, newLen,
blockSize, protocolVersion);
+
+ if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
+ if (newLen < blockSize) {
+ throw new BadPaddingException("invalid explicit IV");
+ }
+
+ // discards the first cipher block, the IV component.
+ System.arraycopy(buf, offset + blockSize,
+ buf, offset, newLen - blockSize);
+
+ newLen -= blockSize;
+ }
}
return newLen;
} catch (ShortBufferException e) {
@@ -277,6 +437,8 @@
* point to the end of the decrypted/depadded data. The initial
* limit and new limit may be different, given we may
* have stripped off some padding bytes.
+ *
+ * @see decrypt(byte[], int, int)
*/
int decrypt(ByteBuffer bb) throws BadPaddingException {
@@ -292,7 +454,6 @@
* Decrypt "in-place".
*/
int pos = bb.position();
-
ByteBuffer dup = bb.duplicate();
int newLen = cipher.update(dup, bb);
if (newLen != len) {
@@ -320,6 +481,33 @@
if (blockSize != 0) {
bb.position(pos);
newLen = removePadding(bb, blockSize, protocolVersion);
+
+ if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
+ if (newLen < blockSize) {
+ throw new BadPaddingException("invalid explicit IV");
+ }
+
+ // discards the first cipher block, the IV component.
+ byte[] buf = null;
+ int limit = bb.limit();
+ if (bb.hasArray()) {
+ buf = bb.array();
+ System.arraycopy(buf, pos + blockSize,
+ buf, pos, limit - pos - blockSize);
+ bb.limit(limit - blockSize);
+ } else {
+ buf = new byte[limit - pos - blockSize];
+ bb.position(pos + blockSize);
+ bb.get(buf);
+ bb.position(pos);
+ bb.put(buf);
+ bb.limit(limit - blockSize);
+ }
+
+ // reset the position to the end of the decrypted data
+ limit = bb.limit();
+ bb.position(limit);
+ }
}
return newLen;
} catch (ShortBufferException e) {
--- a/jdk/src/share/classes/sun/security/ssl/CipherSuite.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/CipherSuite.java Tue Nov 02 19:40:45 2010 -0700
@@ -30,6 +30,7 @@
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
+import java.security.SecureRandom;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
@@ -37,6 +38,7 @@
import sun.security.ssl.CipherSuite.*;
import static sun.security.ssl.CipherSuite.KeyExchange.*;
+import static sun.security.ssl.CipherSuite.PRF.*;
import static sun.security.ssl.JsseJce.*;
/**
@@ -101,19 +103,32 @@
// by default
final int priority;
- // key exchange, bulk cipher, and mac algorithms. See those classes below.
+ // key exchange, bulk cipher, mac and prf algorithms. See those
+ // classes below.
final KeyExchange keyExchange;
final BulkCipher cipher;
final MacAlg macAlg;
+ final PRF prfAlg;
// whether a CipherSuite qualifies as exportable under 512/40 bit rules.
+ // TLS 1.1+ (RFC 4346) must not negotiate to these suites.
final boolean exportable;
// true iff implemented and enabled at compile time
final boolean allowed;
+ // obsoleted since protocol version
+ final int obsoleted;
+
+ // supported since protocol version
+ final int supported;
+
+ /**
+ * Constructor for implemented CipherSuites.
+ */
private CipherSuite(String name, int id, int priority,
- KeyExchange keyExchange, BulkCipher cipher, boolean allowed) {
+ KeyExchange keyExchange, BulkCipher cipher,
+ boolean allowed, int obsoleted, int supported, PRF prfAlg) {
this.name = name;
this.id = id;
this.priority = priority;
@@ -124,6 +139,10 @@
macAlg = M_MD5;
} else if (name.endsWith("_SHA")) {
macAlg = M_SHA;
+ } else if (name.endsWith("_SHA256")) {
+ macAlg = M_SHA256;
+ } else if (name.endsWith("_SHA384")) {
+ macAlg = M_SHA384;
} else if (name.endsWith("_NULL")) {
macAlg = M_NULL;
} else if (name.endsWith("_SCSV")) {
@@ -136,8 +155,14 @@
allowed &= keyExchange.allowed;
allowed &= cipher.allowed;
this.allowed = allowed;
+ this.obsoleted = obsoleted;
+ this.supported = supported;
+ this.prfAlg = prfAlg;
}
+ /**
+ * Constructor for unimplemented CipherSuites.
+ */
private CipherSuite(String name, int id) {
this.name = name;
this.id = id;
@@ -148,6 +173,9 @@
this.cipher = null;
this.macAlg = null;
this.exportable = false;
+ this.obsoleted = ProtocolVersion.LIMIT_MAX_VALUE;
+ this.supported = ProtocolVersion.LIMIT_MIN_VALUE;
+ this.prfAlg = P_NONE;
}
/**
@@ -197,10 +225,12 @@
if (s == null) {
throw new IllegalArgumentException("Name must not be null");
}
+
CipherSuite c = nameMap.get(s);
if ((c == null) || (c.allowed == false)) {
throw new IllegalArgumentException("Unsupported ciphersuite " + s);
}
+
return c;
}
@@ -227,10 +257,17 @@
return nameMap.values();
}
+ /*
+ * Use this method when all of the values need to be specified.
+ * This is primarily used when defining a new ciphersuite for
+ * TLS 1.2+ that doesn't use the "default" PRF.
+ */
private static void add(String name, int id, int priority,
- KeyExchange keyExchange, BulkCipher cipher, boolean allowed) {
+ KeyExchange keyExchange, BulkCipher cipher,
+ boolean allowed, int obsoleted, int supported, PRF prf) {
+
CipherSuite c = new CipherSuite(name, id, priority, keyExchange,
- cipher, allowed);
+ cipher, allowed, obsoleted, supported, prf);
if (idMap.put(id, c) != null) {
throw new RuntimeException("Duplicate ciphersuite definition: "
+ id + ", " + name);
@@ -243,6 +280,41 @@
}
}
+ /*
+ * Use this method when there is no lower protocol limit where this
+ * suite can be used, and the PRF is P_SHA256. That is, the
+ * existing ciphersuites. From RFC 5246:
+ *
+ * All cipher suites in this document use P_SHA256.
+ */
+ private static void add(String name, int id, int priority,
+ KeyExchange keyExchange, BulkCipher cipher,
+ boolean allowed, int obsoleted) {
+ // If this is an obsoleted suite, then don't let the TLS 1.2
+ // protocol have a valid PRF value.
+ PRF prf = P_SHA256;
+ if (obsoleted < ProtocolVersion.TLS12.v) {
+ prf = P_NONE;
+ }
+
+ add(name, id, priority, keyExchange, cipher, allowed, obsoleted,
+ ProtocolVersion.LIMIT_MIN_VALUE, prf);
+ }
+
+ /*
+ * Use this method when there is no upper protocol limit. That is,
+ * suites which have not been obsoleted.
+ */
+ private static void add(String name, int id, int priority,
+ KeyExchange keyExchange, BulkCipher cipher, boolean allowed) {
+ add(name, id, priority, keyExchange,
+ cipher, allowed, ProtocolVersion.LIMIT_MAX_VALUE);
+ }
+
+ /*
+ * Use this method to define an unimplemented suite. This provides
+ * a number<->name mapping that can be used for debugging.
+ */
private static void add(String name, int id) {
CipherSuite c = new CipherSuite(name, id);
if (idMap.put(id, c) != null) {
@@ -380,10 +452,11 @@
*
* @exception NoSuchAlgorithmException if anything goes wrong
*/
- CipherBox newCipher(ProtocolVersion version,
- SecretKey key, IvParameterSpec iv,
+ CipherBox newCipher(ProtocolVersion version, SecretKey key,
+ IvParameterSpec iv, SecureRandom random,
boolean encrypt) throws NoSuchAlgorithmException {
- return CipherBox.newCipherBox(version, this, key, iv, encrypt);
+ return CipherBox.newCipherBox(version, this,
+ key, iv, random, encrypt);
}
/**
@@ -402,6 +475,7 @@
if (this == B_AES_256) {
return isAvailable(this);
}
+
// always available
return true;
}
@@ -421,7 +495,8 @@
(new byte[cipher.expandedKeySize], cipher.algorithm);
IvParameterSpec iv =
new IvParameterSpec(new byte[cipher.ivSize]);
- cipher.newCipher(ProtocolVersion.DEFAULT, key, iv, true);
+ cipher.newCipher(ProtocolVersion.DEFAULT,
+ key, iv, null, true);
b = Boolean.TRUE;
} catch (NoSuchAlgorithmException e) {
b = Boolean.FALSE;
@@ -439,7 +514,7 @@
/**
* An SSL/TLS key MAC algorithm.
*
- * Also contains a factory method to obtain in initialized MAC
+ * Also contains a factory method to obtain an initialized MAC
* for this algorithm.
*/
final static class MacAlg {
@@ -499,6 +574,48 @@
final static MacAlg M_NULL = new MacAlg("NULL", 0);
final static MacAlg M_MD5 = new MacAlg("MD5", 16);
final static MacAlg M_SHA = new MacAlg("SHA", 20);
+ final static MacAlg M_SHA256 = new MacAlg("SHA256", 32);
+ final static MacAlg M_SHA384 = new MacAlg("SHA384", 48);
+
+ // PRFs (PseudoRandom Function) from TLS specifications.
+ //
+ // TLS 1.1- uses a single MD5/SHA1-based PRF algorithm for generating
+ // the necessary material.
+ //
+ // In TLS 1.2+, all existing/known CipherSuites use SHA256, however
+ // new Ciphersuites (e.g. RFC 5288) can define specific PRF hash
+ // algorithms.
+ static enum PRF {
+
+ // PRF algorithms
+ P_NONE( "NONE", 0, 0),
+ P_SHA256("SHA-256", 32, 64),
+ P_SHA384("SHA-384", 48, 128),
+ P_SHA512("SHA-512", 64, 128); // not currently used.
+
+ // PRF characteristics
+ private final String prfHashAlg;
+ private final int prfHashLength;
+ private final int prfBlockSize;
+
+ PRF(String prfHashAlg, int prfHashLength, int prfBlockSize) {
+ this.prfHashAlg = prfHashAlg;
+ this.prfHashLength = prfHashLength;
+ this.prfBlockSize = prfBlockSize;
+ }
+
+ String getPRFHashAlg() {
+ return prfHashAlg;
+ }
+
+ int getPRFHashLength() {
+ return prfHashLength;
+ }
+
+ int getPRFBlockSize() {
+ return prfBlockSize;
+ }
+ }
static {
idMap = new HashMap<Integer,CipherSuite>();
@@ -509,6 +626,239 @@
// N: ciphersuites only allowed if we are not in FIPS mode
final boolean N = (SunJSSE.isFIPS() == false);
+ /*
+ * TLS Cipher Suite Registry, as of August 2010.
+ *
+ * http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
+ *
+ * Range Registration Procedures Notes
+ * 000-191 Standards Action Refers to value of first byte
+ * 192-254 Specification Required Refers to value of first byte
+ * 255 Reserved for Private Use Refers to value of first byte
+ *
+ * Value Description Reference
+ * 0x00,0x00 TLS_NULL_WITH_NULL_NULL [RFC5246]
+ * 0x00,0x01 TLS_RSA_WITH_NULL_MD5 [RFC5246]
+ * 0x00,0x02 TLS_RSA_WITH_NULL_SHA [RFC5246]
+ * 0x00,0x03 TLS_RSA_EXPORT_WITH_RC4_40_MD5 [RFC4346]
+ * 0x00,0x04 TLS_RSA_WITH_RC4_128_MD5 [RFC5246]
+ * 0x00,0x05 TLS_RSA_WITH_RC4_128_SHA [RFC5246]
+ * 0x00,0x06 TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 [RFC4346]
+ * 0x00,0x07 TLS_RSA_WITH_IDEA_CBC_SHA [RFC5469]
+ * 0x00,0x08 TLS_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x09 TLS_RSA_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x0A TLS_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x0B TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x0C TLS_DH_DSS_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x0D TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x0E TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x0F TLS_DH_RSA_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x10 TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x11 TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x12 TLS_DHE_DSS_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x13 TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x14 TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x15 TLS_DHE_RSA_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x16 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x17 TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 [RFC4346]
+ * 0x00,0x18 TLS_DH_anon_WITH_RC4_128_MD5 [RFC5246]
+ * 0x00,0x19 TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA [RFC4346]
+ * 0x00,0x1A TLS_DH_anon_WITH_DES_CBC_SHA [RFC5469]
+ * 0x00,0x1B TLS_DH_anon_WITH_3DES_EDE_CBC_SHA [RFC5246]
+ * 0x00,0x1C-1D Reserved to avoid conflicts with SSLv3 [RFC5246]
+ * 0x00,0x1E TLS_KRB5_WITH_DES_CBC_SHA [RFC2712]
+ * 0x00,0x1F TLS_KRB5_WITH_3DES_EDE_CBC_SHA [RFC2712]
+ * 0x00,0x20 TLS_KRB5_WITH_RC4_128_SHA [RFC2712]
+ * 0x00,0x21 TLS_KRB5_WITH_IDEA_CBC_SHA [RFC2712]
+ * 0x00,0x22 TLS_KRB5_WITH_DES_CBC_MD5 [RFC2712]
+ * 0x00,0x23 TLS_KRB5_WITH_3DES_EDE_CBC_MD5 [RFC2712]
+ * 0x00,0x24 TLS_KRB5_WITH_RC4_128_MD5 [RFC2712]
+ * 0x00,0x25 TLS_KRB5_WITH_IDEA_CBC_MD5 [RFC2712]
+ * 0x00,0x26 TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA [RFC2712]
+ * 0x00,0x27 TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA [RFC2712]
+ * 0x00,0x28 TLS_KRB5_EXPORT_WITH_RC4_40_SHA [RFC2712]
+ * 0x00,0x29 TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 [RFC2712]
+ * 0x00,0x2A TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 [RFC2712]
+ * 0x00,0x2B TLS_KRB5_EXPORT_WITH_RC4_40_MD5 [RFC2712]
+ * 0x00,0x2C TLS_PSK_WITH_NULL_SHA [RFC4785]
+ * 0x00,0x2D TLS_DHE_PSK_WITH_NULL_SHA [RFC4785]
+ * 0x00,0x2E TLS_RSA_PSK_WITH_NULL_SHA [RFC4785]
+ * 0x00,0x2F TLS_RSA_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x30 TLS_DH_DSS_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x31 TLS_DH_RSA_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x32 TLS_DHE_DSS_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x33 TLS_DHE_RSA_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x34 TLS_DH_anon_WITH_AES_128_CBC_SHA [RFC5246]
+ * 0x00,0x35 TLS_RSA_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x36 TLS_DH_DSS_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x37 TLS_DH_RSA_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x38 TLS_DHE_DSS_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x39 TLS_DHE_RSA_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x3A TLS_DH_anon_WITH_AES_256_CBC_SHA [RFC5246]
+ * 0x00,0x3B TLS_RSA_WITH_NULL_SHA256 [RFC5246]
+ * 0x00,0x3C TLS_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x3D TLS_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x3E TLS_DH_DSS_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x3F TLS_DH_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x40 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x41 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x42 TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x43 TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x44 TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x45 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x46 TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA [RFC5932]
+ * 0x00,0x47-4F Reserved to avoid conflicts with
+ * deployed implementations [Pasi_Eronen]
+ * 0x00,0x50-58 Reserved to avoid conflicts [Pasi Eronen]
+ * 0x00,0x59-5C Reserved to avoid conflicts with
+ * deployed implementations [Pasi_Eronen]
+ * 0x00,0x5D-5F Unassigned
+ * 0x00,0x60-66 Reserved to avoid conflicts with widely
+ * deployed implementations [Pasi_Eronen]
+ * 0x00,0x67 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x68 TLS_DH_DSS_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x69 TLS_DH_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x6A TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x6B TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x6C TLS_DH_anon_WITH_AES_128_CBC_SHA256 [RFC5246]
+ * 0x00,0x6D TLS_DH_anon_WITH_AES_256_CBC_SHA256 [RFC5246]
+ * 0x00,0x6E-83 Unassigned
+ * 0x00,0x84 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x85 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x86 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x87 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x88 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x89 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA [RFC5932]
+ * 0x00,0x8A TLS_PSK_WITH_RC4_128_SHA [RFC4279]
+ * 0x00,0x8B TLS_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
+ * 0x00,0x8C TLS_PSK_WITH_AES_128_CBC_SHA [RFC4279]
+ * 0x00,0x8D TLS_PSK_WITH_AES_256_CBC_SHA [RFC4279]
+ * 0x00,0x8E TLS_DHE_PSK_WITH_RC4_128_SHA [RFC4279]
+ * 0x00,0x8F TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
+ * 0x00,0x90 TLS_DHE_PSK_WITH_AES_128_CBC_SHA [RFC4279]
+ * 0x00,0x91 TLS_DHE_PSK_WITH_AES_256_CBC_SHA [RFC4279]
+ * 0x00,0x92 TLS_RSA_PSK_WITH_RC4_128_SHA [RFC4279]
+ * 0x00,0x93 TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA [RFC4279]
+ * 0x00,0x94 TLS_RSA_PSK_WITH_AES_128_CBC_SHA [RFC4279]
+ * 0x00,0x95 TLS_RSA_PSK_WITH_AES_256_CBC_SHA [RFC4279]
+ * 0x00,0x96 TLS_RSA_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x97 TLS_DH_DSS_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x98 TLS_DH_RSA_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x99 TLS_DHE_DSS_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x9A TLS_DHE_RSA_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x9B TLS_DH_anon_WITH_SEED_CBC_SHA [RFC4162]
+ * 0x00,0x9C TLS_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0x9D TLS_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0x9E TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0x9F TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA0 TLS_DH_RSA_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0xA1 TLS_DH_RSA_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA2 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0xA3 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA4 TLS_DH_DSS_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0xA5 TLS_DH_DSS_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA6 TLS_DH_anon_WITH_AES_128_GCM_SHA256 [RFC5288]
+ * 0x00,0xA7 TLS_DH_anon_WITH_AES_256_GCM_SHA384 [RFC5288]
+ * 0x00,0xA8 TLS_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
+ * 0x00,0xA9 TLS_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
+ * 0x00,0xAA TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
+ * 0x00,0xAB TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
+ * 0x00,0xAC TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 [RFC5487]
+ * 0x00,0xAD TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 [RFC5487]
+ * 0x00,0xAE TLS_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
+ * 0x00,0xAF TLS_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
+ * 0x00,0xB0 TLS_PSK_WITH_NULL_SHA256 [RFC5487]
+ * 0x00,0xB1 TLS_PSK_WITH_NULL_SHA384 [RFC5487]
+ * 0x00,0xB2 TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
+ * 0x00,0xB3 TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
+ * 0x00,0xB4 TLS_DHE_PSK_WITH_NULL_SHA256 [RFC5487]
+ * 0x00,0xB5 TLS_DHE_PSK_WITH_NULL_SHA384 [RFC5487]
+ * 0x00,0xB6 TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 [RFC5487]
+ * 0x00,0xB7 TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 [RFC5487]
+ * 0x00,0xB8 TLS_RSA_PSK_WITH_NULL_SHA256 [RFC5487]
+ * 0x00,0xB9 TLS_RSA_PSK_WITH_NULL_SHA384 [RFC5487]
+ * 0x00,0xBA TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBB TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBC TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBD TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBE TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xBF TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 [RFC5932]
+ * 0x00,0xC0 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC1 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC2 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC3 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC4 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC5 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 [RFC5932]
+ * 0x00,0xC6-FE Unassigned
+ * 0x00,0xFF TLS_EMPTY_RENEGOTIATION_INFO_SCSV [RFC5746]
+ * 0x01-BF,* Unassigned
+ * 0xC0,0x01 TLS_ECDH_ECDSA_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x02 TLS_ECDH_ECDSA_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x03 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x04 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x05 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x06 TLS_ECDHE_ECDSA_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x07 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x08 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x09 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x0A TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x0B TLS_ECDH_RSA_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x0C TLS_ECDH_RSA_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x0D TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x0E TLS_ECDH_RSA_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x0F TLS_ECDH_RSA_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x10 TLS_ECDHE_RSA_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x11 TLS_ECDHE_RSA_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x12 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x13 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x14 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x15 TLS_ECDH_anon_WITH_NULL_SHA [RFC4492]
+ * 0xC0,0x16 TLS_ECDH_anon_WITH_RC4_128_SHA [RFC4492]
+ * 0xC0,0x17 TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA [RFC4492]
+ * 0xC0,0x18 TLS_ECDH_anon_WITH_AES_128_CBC_SHA [RFC4492]
+ * 0xC0,0x19 TLS_ECDH_anon_WITH_AES_256_CBC_SHA [RFC4492]
+ * 0xC0,0x1A TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA [RFC5054]
+ * 0xC0,0x1B TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA [RFC5054]
+ * 0xC0,0x1C TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA [RFC5054]
+ * 0xC0,0x1D TLS_SRP_SHA_WITH_AES_128_CBC_SHA [RFC5054]
+ * 0xC0,0x1E TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA [RFC5054]
+ * 0xC0,0x1F TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA [RFC5054]
+ * 0xC0,0x20 TLS_SRP_SHA_WITH_AES_256_CBC_SHA [RFC5054]
+ * 0xC0,0x21 TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA [RFC5054]
+ * 0xC0,0x22 TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA [RFC5054]
+ * 0xC0,0x23 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 [RFC5289]
+ * 0xC0,0x24 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 [RFC5289]
+ * 0xC0,0x25 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 [RFC5289]
+ * 0xC0,0x26 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 [RFC5289]
+ * 0xC0,0x27 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 [RFC5289]
+ * 0xC0,0x28 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 [RFC5289]
+ * 0xC0,0x29 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 [RFC5289]
+ * 0xC0,0x2A TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 [RFC5289]
+ * 0xC0,0x2B TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 [RFC5289]
+ * 0xC0,0x2C TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 [RFC5289]
+ * 0xC0,0x2D TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 [RFC5289]
+ * 0xC0,0x2E TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 [RFC5289]
+ * 0xC0,0x2F TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 [RFC5289]
+ * 0xC0,0x30 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 [RFC5289]
+ * 0xC0,0x31 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 [RFC5289]
+ * 0xC0,0x32 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 [RFC5289]
+ * 0xC0,0x33 TLS_ECDHE_PSK_WITH_RC4_128_SHA [RFC5489]
+ * 0xC0,0x34 TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA [RFC5489]
+ * 0xC0,0x35 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA [RFC5489]
+ * 0xC0,0x36 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA [RFC5489]
+ * 0xC0,0x37 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 [RFC5489]
+ * 0xC0,0x38 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 [RFC5489]
+ * 0xC0,0x39 TLS_ECDHE_PSK_WITH_NULL_SHA [RFC5489]
+ * 0xC0,0x3A TLS_ECDHE_PSK_WITH_NULL_SHA256 [RFC5489]
+ * 0xC0,0x3B TLS_ECDHE_PSK_WITH_NULL_SHA384 [RFC5489]
+ * 0xC0,0x3C-FF Unassigned
+ * 0xC1-FD,* Unassigned
+ * 0xFE,0x00-FD Unassigned
+ * 0xFE,0xFE-FF Reserved to avoid conflicts with widely
+ * deployed implementations [Pasi_Eronen]
+ * 0xFF,0x00-FF Reserved for Private Use [RFC5246]
+ */
+
add("SSL_NULL_WITH_NULL_NULL",
0x0000, 1, K_NULL, B_NULL, F);
@@ -516,191 +866,377 @@
// They are listed in preference order, most preferred first.
int p = DEFAULT_SUITES_PRIORITY * 2;
+ // shorten names to fit the following table cleanly.
+ int max = ProtocolVersion.LIMIT_MAX_VALUE;
+ int tls11 = ProtocolVersion.TLS11.v;
+ int tls12 = ProtocolVersion.TLS12.v;
+
+ // ID Key Exchange Cipher A obs suprt PRF
+ // ====== ============ ========= = === ===== ========
+ add("TLS_RSA_WITH_AES_128_CBC_SHA256",
+ 0x003c, --p, K_RSA, B_AES_128, T, max, tls12, P_SHA256);
+ add("TLS_RSA_WITH_AES_256_CBC_SHA256",
+ 0x003d, --p, K_RSA, B_AES_256, T, max, tls12, P_SHA256);
+ add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA256",
+ 0x0040, --p, K_DHE_DSS, B_AES_128, T, max, tls12, P_SHA256);
+ add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA256",
+ 0x0067, --p, K_DHE_RSA, B_AES_128, T, max, tls12, P_SHA256);
+ add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA256",
+ 0x006a, --p, K_DHE_DSS, B_AES_256, T, max, tls12, P_SHA256);
+ add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA256",
+ 0x006b, --p, K_DHE_RSA, B_AES_256, T, max, tls12, P_SHA256);
+
+ add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
+ 0xc023, --p, K_ECDHE_ECDSA, B_AES_128, T, max, tls12, P_SHA256);
+ add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384",
+ 0xc024, --p, K_ECDHE_ECDSA, B_AES_256, T, max, tls12, P_SHA384);
+ add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256",
+ 0xc025, --p, K_ECDH_ECDSA, B_AES_128, T, max, tls12, P_SHA256);
+ add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384",
+ 0xc026, --p, K_ECDH_ECDSA, B_AES_256, T, max, tls12, P_SHA384);
+ add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
+ 0xc027, --p, K_ECDHE_RSA, B_AES_128, T, max, tls12, P_SHA256);
+ add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384",
+ 0xc028, --p, K_ECDHE_RSA, B_AES_256, T, max, tls12, P_SHA384);
+ add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256",
+ 0xc029, --p, K_ECDH_RSA, B_AES_128, T, max, tls12, P_SHA256);
+ add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384",
+ 0xc02a, --p, K_ECDH_RSA, B_AES_256, T, max, tls12, P_SHA384);
+
add("SSL_RSA_WITH_RC4_128_MD5",
- 0x0004, --p, K_RSA, B_RC4_128, N);
+ 0x0004, --p, K_RSA, B_RC4_128, N);
add("SSL_RSA_WITH_RC4_128_SHA",
- 0x0005, --p, K_RSA, B_RC4_128, N);
+ 0x0005, --p, K_RSA, B_RC4_128, N);
add("TLS_RSA_WITH_AES_128_CBC_SHA",
- 0x002f, --p, K_RSA, B_AES_128, T);
+ 0x002f, --p, K_RSA, B_AES_128, T);
add("TLS_RSA_WITH_AES_256_CBC_SHA",
- 0x0035, --p, K_RSA, B_AES_256, T);
+ 0x0035, --p, K_RSA, B_AES_256, T);
add("TLS_ECDH_ECDSA_WITH_RC4_128_SHA",
- 0xC002, --p, K_ECDH_ECDSA, B_RC4_128, N);
+ 0xC002, --p, K_ECDH_ECDSA, B_RC4_128, N);
add("TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA",
- 0xC004, --p, K_ECDH_ECDSA, B_AES_128, T);
+ 0xC004, --p, K_ECDH_ECDSA, B_AES_128, T);
add("TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA",
- 0xC005, --p, K_ECDH_ECDSA, B_AES_256, T);
+ 0xC005, --p, K_ECDH_ECDSA, B_AES_256, T);
add("TLS_ECDH_RSA_WITH_RC4_128_SHA",
- 0xC00C, --p, K_ECDH_RSA, B_RC4_128, N);
+ 0xC00C, --p, K_ECDH_RSA, B_RC4_128, N);
add("TLS_ECDH_RSA_WITH_AES_128_CBC_SHA",
- 0xC00E, --p, K_ECDH_RSA, B_AES_128, T);
+ 0xC00E, --p, K_ECDH_RSA, B_AES_128, T);
add("TLS_ECDH_RSA_WITH_AES_256_CBC_SHA",
- 0xC00F, --p, K_ECDH_RSA, B_AES_256, T);
+ 0xC00F, --p, K_ECDH_RSA, B_AES_256, T);
add("TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
- 0xC007, --p, K_ECDHE_ECDSA,B_RC4_128, N);
+ 0xC007, --p, K_ECDHE_ECDSA, B_RC4_128, N);
add("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
- 0xC009, --p, K_ECDHE_ECDSA,B_AES_128, T);
+ 0xC009, --p, K_ECDHE_ECDSA, B_AES_128, T);
add("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
- 0xC00A, --p, K_ECDHE_ECDSA,B_AES_256, T);
+ 0xC00A, --p, K_ECDHE_ECDSA, B_AES_256, T);
add("TLS_ECDHE_RSA_WITH_RC4_128_SHA",
- 0xC011, --p, K_ECDHE_RSA, B_RC4_128, N);
+ 0xC011, --p, K_ECDHE_RSA, B_RC4_128, N);
add("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
- 0xC013, --p, K_ECDHE_RSA, B_AES_128, T);
+ 0xC013, --p, K_ECDHE_RSA, B_AES_128, T);
add("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
- 0xC014, --p, K_ECDHE_RSA, B_AES_256, T);
+ 0xC014, --p, K_ECDHE_RSA, B_AES_256, T);
add("TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
- 0x0033, --p, K_DHE_RSA, B_AES_128, T);
+ 0x0033, --p, K_DHE_RSA, B_AES_128, T);
add("TLS_DHE_RSA_WITH_AES_256_CBC_SHA",
- 0x0039, --p, K_DHE_RSA, B_AES_256, T);
+ 0x0039, --p, K_DHE_RSA, B_AES_256, T);
add("TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
- 0x0032, --p, K_DHE_DSS, B_AES_128, T);
+ 0x0032, --p, K_DHE_DSS, B_AES_128, T);
add("TLS_DHE_DSS_WITH_AES_256_CBC_SHA",
- 0x0038, --p, K_DHE_DSS, B_AES_256, T);
+ 0x0038, --p, K_DHE_DSS, B_AES_256, T);
add("SSL_RSA_WITH_3DES_EDE_CBC_SHA",
- 0x000a, --p, K_RSA, B_3DES, T);
+ 0x000a, --p, K_RSA, B_3DES, T);
add("TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA",
- 0xC003, --p, K_ECDH_ECDSA, B_3DES, T);
+ 0xC003, --p, K_ECDH_ECDSA, B_3DES, T);
add("TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA",
- 0xC00D, --p, K_ECDH_RSA, B_3DES, T);
+ 0xC00D, --p, K_ECDH_RSA, B_3DES, T);
add("TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA",
- 0xC008, --p, K_ECDHE_ECDSA,B_3DES, T);
+ 0xC008, --p, K_ECDHE_ECDSA, B_3DES, T);
add("TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
- 0xC012, --p, K_ECDHE_RSA, B_3DES, T);
+ 0xC012, --p, K_ECDHE_RSA, B_3DES, T);
add("SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
- 0x0016, --p, K_DHE_RSA, B_3DES, T);
+ 0x0016, --p, K_DHE_RSA, B_3DES, T);
add("SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
- 0x0013, --p, K_DHE_DSS, B_3DES, N);
-
- add("SSL_RSA_WITH_DES_CBC_SHA",
- 0x0009, --p, K_RSA, B_DES, N);
- add("SSL_DHE_RSA_WITH_DES_CBC_SHA",
- 0x0015, --p, K_DHE_RSA, B_DES, N);
- add("SSL_DHE_DSS_WITH_DES_CBC_SHA",
- 0x0012, --p, K_DHE_DSS, B_DES, N);
- add("SSL_RSA_EXPORT_WITH_RC4_40_MD5",
- 0x0003, --p, K_RSA_EXPORT, B_RC4_40, N);
- add("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
- 0x0008, --p, K_RSA_EXPORT, B_DES_40, N);
- add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
- 0x0014, --p, K_DHE_RSA, B_DES_40, N);
- add("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
- 0x0011, --p, K_DHE_DSS, B_DES_40, N);
+ 0x0013, --p, K_DHE_DSS, B_3DES, N);
// Renegotiation protection request Signalling Cipher Suite Value (SCSV)
add("TLS_EMPTY_RENEGOTIATION_INFO_SCSV",
- 0x00ff, --p, K_SCSV, B_NULL, T);
+ 0x00ff, --p, K_SCSV, B_NULL, T);
// Definition of the CipherSuites that are supported but not enabled
// by default.
// They are listed in preference order, preferred first.
p = DEFAULT_SUITES_PRIORITY;
+ // weak single-DES cipher suites
+ add("SSL_RSA_WITH_DES_CBC_SHA",
+ 0x0009, --p, K_RSA, B_DES, N, tls12);
+ add("SSL_DHE_RSA_WITH_DES_CBC_SHA",
+ 0x0015, --p, K_DHE_RSA, B_DES, N, tls12);
+ add("SSL_DHE_DSS_WITH_DES_CBC_SHA",
+ 0x0012, --p, K_DHE_DSS, B_DES, N, tls12);
+
// Anonymous key exchange and the NULL ciphers
add("SSL_RSA_WITH_NULL_MD5",
- 0x0001, --p, K_RSA, B_NULL, N);
+ 0x0001, --p, K_RSA, B_NULL, N);
add("SSL_RSA_WITH_NULL_SHA",
- 0x0002, --p, K_RSA, B_NULL, N);
+ 0x0002, --p, K_RSA, B_NULL, N);
+ add("TLS_RSA_WITH_NULL_SHA256",
+ 0x003b, --p, K_RSA, B_NULL, N, max, tls12, P_SHA256);
+
add("TLS_ECDH_ECDSA_WITH_NULL_SHA",
- 0xC001, --p, K_ECDH_ECDSA, B_NULL, N);
+ 0xC001, --p, K_ECDH_ECDSA, B_NULL, N);
add("TLS_ECDH_RSA_WITH_NULL_SHA",
- 0xC00B, --p, K_ECDH_RSA, B_NULL, N);
+ 0xC00B, --p, K_ECDH_RSA, B_NULL, N);
add("TLS_ECDHE_ECDSA_WITH_NULL_SHA",
- 0xC006, --p, K_ECDHE_ECDSA,B_NULL, N);
+ 0xC006, --p, K_ECDHE_ECDSA, B_NULL, N);
add("TLS_ECDHE_RSA_WITH_NULL_SHA",
- 0xC010, --p, K_ECDHE_RSA, B_NULL, N);
+ 0xC010, --p, K_ECDHE_RSA, B_NULL, N);
add("SSL_DH_anon_WITH_RC4_128_MD5",
- 0x0018, --p, K_DH_ANON, B_RC4_128, N);
+ 0x0018, --p, K_DH_ANON, B_RC4_128, N);
add("TLS_DH_anon_WITH_AES_128_CBC_SHA",
- 0x0034, --p, K_DH_ANON, B_AES_128, N);
+ 0x0034, --p, K_DH_ANON, B_AES_128, N);
add("TLS_DH_anon_WITH_AES_256_CBC_SHA",
- 0x003a, --p, K_DH_ANON, B_AES_256, N);
+ 0x003a, --p, K_DH_ANON, B_AES_256, N);
add("SSL_DH_anon_WITH_3DES_EDE_CBC_SHA",
- 0x001b, --p, K_DH_ANON, B_3DES, N);
+ 0x001b, --p, K_DH_ANON, B_3DES, N);
add("SSL_DH_anon_WITH_DES_CBC_SHA",
- 0x001a, --p, K_DH_ANON, B_DES, N);
+ 0x001a, --p, K_DH_ANON, B_DES, N, tls12);
+
+ add("TLS_DH_anon_WITH_AES_128_CBC_SHA256",
+ 0x006c, --p, K_DH_ANON, B_AES_128, N, max, tls12, P_SHA256);
+ add("TLS_DH_anon_WITH_AES_256_CBC_SHA256",
+ 0x006d, --p, K_DH_ANON, B_AES_256, N, max, tls12, P_SHA256);
add("TLS_ECDH_anon_WITH_RC4_128_SHA",
- 0xC016, --p, K_ECDH_ANON, B_RC4_128, N);
+ 0xC016, --p, K_ECDH_ANON, B_RC4_128, N);
add("TLS_ECDH_anon_WITH_AES_128_CBC_SHA",
- 0xC018, --p, K_ECDH_ANON, B_AES_128, T);
+ 0xC018, --p, K_ECDH_ANON, B_AES_128, T);
add("TLS_ECDH_anon_WITH_AES_256_CBC_SHA",
- 0xC019, --p, K_ECDH_ANON, B_AES_256, T);
+ 0xC019, --p, K_ECDH_ANON, B_AES_256, T);
add("TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA",
- 0xC017, --p, K_ECDH_ANON, B_3DES, T);
+ 0xC017, --p, K_ECDH_ANON, B_3DES, T);
add("SSL_DH_anon_EXPORT_WITH_RC4_40_MD5",
- 0x0017, --p, K_DH_ANON, B_RC4_40, N);
+ 0x0017, --p, K_DH_ANON, B_RC4_40, N, tls11);
add("SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA",
- 0x0019, --p, K_DH_ANON, B_DES_40, N);
+ 0x0019, --p, K_DH_ANON, B_DES_40, N, tls11);
add("TLS_ECDH_anon_WITH_NULL_SHA",
- 0xC015, --p, K_ECDH_ANON, B_NULL, N);
+ 0xC015, --p, K_ECDH_ANON, B_NULL, N);
+
+ add("SSL_RSA_EXPORT_WITH_RC4_40_MD5",
+ 0x0003, --p, K_RSA_EXPORT, B_RC4_40, N, tls11);
+ add("SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ 0x0008, --p, K_RSA_EXPORT, B_DES_40, N, tls11);
+ add("SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
+ 0x0014, --p, K_DHE_RSA, B_DES_40, N, tls11);
+ add("SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA",
+ 0x0011, --p, K_DHE_DSS, B_DES_40, N, tls11);
// Supported Kerberos ciphersuites from RFC2712
add("TLS_KRB5_WITH_RC4_128_SHA",
- 0x0020, --p, K_KRB5, B_RC4_128, N);
+ 0x0020, --p, K_KRB5, B_RC4_128, N);
add("TLS_KRB5_WITH_RC4_128_MD5",
- 0x0024, --p, K_KRB5, B_RC4_128, N);
+ 0x0024, --p, K_KRB5, B_RC4_128, N);
add("TLS_KRB5_WITH_3DES_EDE_CBC_SHA",
- 0x001f, --p, K_KRB5, B_3DES, N);
+ 0x001f, --p, K_KRB5, B_3DES, N);
add("TLS_KRB5_WITH_3DES_EDE_CBC_MD5",
- 0x0023, --p, K_KRB5, B_3DES, N);
+ 0x0023, --p, K_KRB5, B_3DES, N);
add("TLS_KRB5_WITH_DES_CBC_SHA",
- 0x001e, --p, K_KRB5, B_DES, N);
+ 0x001e, --p, K_KRB5, B_DES, N, tls12);
add("TLS_KRB5_WITH_DES_CBC_MD5",
- 0x0022, --p, K_KRB5, B_DES, N);
+ 0x0022, --p, K_KRB5, B_DES, N, tls12);
add("TLS_KRB5_EXPORT_WITH_RC4_40_SHA",
- 0x0028, --p, K_KRB5_EXPORT, B_RC4_40, N);
+ 0x0028, --p, K_KRB5_EXPORT, B_RC4_40, N, tls11);
add("TLS_KRB5_EXPORT_WITH_RC4_40_MD5",
- 0x002b, --p, K_KRB5_EXPORT, B_RC4_40, N);
+ 0x002b, --p, K_KRB5_EXPORT, B_RC4_40, N, tls11);
add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA",
- 0x0026, --p, K_KRB5_EXPORT, B_DES_40, N);
+ 0x0026, --p, K_KRB5_EXPORT, B_DES_40, N, tls11);
add("TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5",
- 0x0029, --p, K_KRB5_EXPORT, B_DES_40, N);
+ 0x0029, --p, K_KRB5_EXPORT, B_DES_40, N, tls11);
+
+ /*
+ * Other values from the TLS Cipher Suite Registry, as of August 2010.
+ *
+ * http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
+ *
+ * Range Registration Procedures Notes
+ * 000-191 Standards Action Refers to value of first byte
+ * 192-254 Specification Required Refers to value of first byte
+ * 255 Reserved for Private Use Refers to value of first byte
+ */
// Register the names of a few additional CipherSuites.
// Makes them show up as names instead of numbers in
// the debug output.
// remaining unsupported ciphersuites defined in RFC2246.
- add("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", 0x0006);
- add("SSL_RSA_WITH_IDEA_CBC_SHA", 0x0007);
- add("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", 0x000b);
- add("SSL_DH_DSS_WITH_DES_CBC_SHA", 0x000c);
- add("SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", 0x000d);
- add("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x000e);
- add("SSL_DH_RSA_WITH_DES_CBC_SHA", 0x000f);
- add("SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", 0x0010);
+ add("SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5", 0x0006);
+ add("SSL_RSA_WITH_IDEA_CBC_SHA", 0x0007);
+ add("SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", 0x000b);
+ add("SSL_DH_DSS_WITH_DES_CBC_SHA", 0x000c);
+ add("SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA", 0x000d);
+ add("SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", 0x000e);
+ add("SSL_DH_RSA_WITH_DES_CBC_SHA", 0x000f);
+ add("SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA", 0x0010);
// SSL 3.0 Fortezza ciphersuites
- add("SSL_FORTEZZA_DMS_WITH_NULL_SHA", 0x001c);
- add("SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA", 0x001d);
+ add("SSL_FORTEZZA_DMS_WITH_NULL_SHA", 0x001c);
+ add("SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA", 0x001d);
// 1024/56 bit exportable ciphersuites from expired internet draft
- add("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA", 0x0062);
- add("SSL_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA", 0x0063);
- add("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA", 0x0064);
- add("SSL_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA", 0x0065);
- add("SSL_DHE_DSS_WITH_RC4_128_SHA", 0x0066);
+ add("SSL_RSA_EXPORT1024_WITH_DES_CBC_SHA", 0x0062);
+ add("SSL_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA", 0x0063);
+ add("SSL_RSA_EXPORT1024_WITH_RC4_56_SHA", 0x0064);
+ add("SSL_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA", 0x0065);
+ add("SSL_DHE_DSS_WITH_RC4_128_SHA", 0x0066);
// Netscape old and new SSL 3.0 FIPS ciphersuites
// see http://www.mozilla.org/projects/security/pki/nss/ssl/fips-ssl-ciphersuites.html
- add("NETSCAPE_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", 0xffe0);
- add("NETSCAPE_RSA_FIPS_WITH_DES_CBC_SHA", 0xffe1);
- add("SSL_RSA_FIPS_WITH_DES_CBC_SHA", 0xfefe);
- add("SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", 0xfeff);
+ add("NETSCAPE_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", 0xffe0);
+ add("NETSCAPE_RSA_FIPS_WITH_DES_CBC_SHA", 0xffe1);
+ add("SSL_RSA_FIPS_WITH_DES_CBC_SHA", 0xfefe);
+ add("SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", 0xfeff);
// Unsupported Kerberos cipher suites from RFC 2712
- add("TLS_KRB5_WITH_IDEA_CBC_SHA", 0x0021);
- add("TLS_KRB5_WITH_IDEA_CBC_MD5", 0x0025);
- add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", 0x0027);
- add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", 0x002a);
+ add("TLS_KRB5_WITH_IDEA_CBC_SHA", 0x0021);
+ add("TLS_KRB5_WITH_IDEA_CBC_MD5", 0x0025);
+ add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", 0x0027);
+ add("TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", 0x002a);
+
+ // Unsupported cipher suites from RFC 4162
+ add("TLS_RSA_WITH_SEED_CBC_SHA", 0x0096);
+ add("TLS_DH_DSS_WITH_SEED_CBC_SHA", 0x0097);
+ add("TLS_DH_RSA_WITH_SEED_CBC_SHA", 0x0098);
+ add("TLS_DHE_DSS_WITH_SEED_CBC_SHA", 0x0099);
+ add("TLS_DHE_RSA_WITH_SEED_CBC_SHA", 0x009a);
+ add("TLS_DH_anon_WITH_SEED_CBC_SHA", 0x009b);
+
+ // Unsupported cipher suites from RFC 4279
+ add("TLS_PSK_WITH_RC4_128_SHA", 0x008a);
+ add("TLS_PSK_WITH_3DES_EDE_CBC_SHA", 0x008b);
+ add("TLS_PSK_WITH_AES_128_CBC_SHA", 0x008c);
+ add("TLS_PSK_WITH_AES_256_CBC_SHA", 0x008d);
+ add("TLS_DHE_PSK_WITH_RC4_128_SHA", 0x008e);
+ add("TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA", 0x008f);
+ add("TLS_DHE_PSK_WITH_AES_128_CBC_SHA", 0x0090);
+ add("TLS_DHE_PSK_WITH_AES_256_CBC_SHA", 0x0091);
+ add("TLS_RSA_PSK_WITH_RC4_128_SHA", 0x0092);
+ add("TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA", 0x0093);
+ add("TLS_RSA_PSK_WITH_AES_128_CBC_SHA", 0x0094);
+ add("TLS_RSA_PSK_WITH_AES_256_CBC_SHA", 0x0095);
+
+ // Unsupported cipher suites from RFC 4785
+ add("TLS_PSK_WITH_NULL_SHA", 0x002c);
+ add("TLS_DHE_PSK_WITH_NULL_SHA", 0x002d);
+ add("TLS_RSA_PSK_WITH_NULL_SHA", 0x002e);
+
+ // Unsupported cipher suites from RFC 5246
+ add("TLS_DH_DSS_WITH_AES_128_CBC_SHA", 0x0030);
+ add("TLS_DH_RSA_WITH_AES_128_CBC_SHA", 0x0031);
+ add("TLS_DH_DSS_WITH_AES_256_CBC_SHA", 0x0036);
+ add("TLS_DH_RSA_WITH_AES_256_CBC_SHA", 0x0037);
+ add("TLS_DH_DSS_WITH_AES_128_CBC_SHA256", 0x003e);
+ add("TLS_DH_RSA_WITH_AES_128_CBC_SHA256", 0x003f);
+ add("TLS_DH_DSS_WITH_AES_256_CBC_SHA256", 0x0068);
+ add("TLS_DH_RSA_WITH_AES_256_CBC_SHA256", 0x0069);
+
+ // Unsupported cipher suites from RFC 5288
+ add("TLS_RSA_WITH_AES_128_GCM_SHA256", 0x009c);
+ add("TLS_RSA_WITH_AES_256_GCM_SHA384", 0x009d);
+ add("TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", 0x009e);
+ add("TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", 0x009f);
+ add("TLS_DH_RSA_WITH_AES_128_GCM_SHA256", 0x00a0);
+ add("TLS_DH_RSA_WITH_AES_256_GCM_SHA384", 0x00a1);
+ add("TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", 0x00a2);
+ add("TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", 0x00a3);
+ add("TLS_DH_DSS_WITH_AES_128_GCM_SHA256", 0x00a4);
+ add("TLS_DH_DSS_WITH_AES_256_GCM_SHA384", 0x00a5);
+ add("TLS_DH_anon_WITH_AES_128_GCM_SHA256", 0x00a6);
+ add("TLS_DH_anon_WITH_AES_256_GCM_SHA384", 0x00a7);
+ // Unsupported cipher suites from RFC 5487
+ add("TLS_PSK_WITH_AES_128_GCM_SHA256", 0x00a8);
+ add("TLS_PSK_WITH_AES_256_GCM_SHA384", 0x00a9);
+ add("TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", 0x00aa);
+ add("TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", 0x00ab);
+ add("TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", 0x00ac);
+ add("TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", 0x00ad);
+ add("TLS_PSK_WITH_AES_128_CBC_SHA256", 0x00ae);
+ add("TLS_PSK_WITH_AES_256_CBC_SHA384", 0x00af);
+ add("TLS_PSK_WITH_NULL_SHA256", 0x00b0);
+ add("TLS_PSK_WITH_NULL_SHA384", 0x00b1);
+ add("TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", 0x00b2);
+ add("TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", 0x00b3);
+ add("TLS_DHE_PSK_WITH_NULL_SHA256", 0x00b4);
+ add("TLS_DHE_PSK_WITH_NULL_SHA384", 0x00b5);
+ add("TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", 0x00b6);
+ add("TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", 0x00b7);
+ add("TLS_RSA_PSK_WITH_NULL_SHA256", 0x00b8);
+ add("TLS_RSA_PSK_WITH_NULL_SHA384", 0x00b9);
+
+ // Unsupported cipher suites from RFC 5932
+ add("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0041);
+ add("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", 0x0042);
+ add("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0043);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", 0x0044);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", 0x0045);
+ add("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA", 0x0046);
+ add("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0084);
+ add("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", 0x0085);
+ add("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0086);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", 0x0087);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", 0x0088);
+ add("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA", 0x0089);
+ add("TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00ba);
+ add("TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256", 0x00bb);
+ add("TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00bc);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", 0x00bd);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", 0x00be);
+ add("TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256", 0x00bf);
+ add("TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c0);
+ add("TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256", 0x00c1);
+ add("TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c2);
+ add("TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", 0x00c3);
+ add("TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", 0x00c4);
+ add("TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256", 0x00c5);
+
+ // Unsupported cipher suites from RFC 5054
+ add("TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", 0xc01a);
+ add("TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", 0xc01b);
+ add("TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", 0xc01c);
+ add("TLS_SRP_SHA_WITH_AES_128_CBC_SHA", 0xc01d);
+ add("TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", 0xc01e);
+ add("TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", 0xc01f);
+ add("TLS_SRP_SHA_WITH_AES_256_CBC_SHA", 0xc020);
+ add("TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", 0xc021);
+ add("TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", 0xc022);
+
+ // Unsupported cipher suites from RFC 5289
+ add("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 0xc02b);
+ add("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", 0xc02c);
+ add("TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", 0xc02d);
+ add("TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", 0xc02e);
+ add("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 0xc02f);
+ add("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", 0xc030);
+ add("TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", 0xc031);
+ add("TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", 0xc032);
+
+ // Unsupported cipher suites from RFC 5489
+ add("TLS_ECDHE_PSK_WITH_RC4_128_SHA", 0xc033);
+ add("TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", 0xc034);
+ add("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", 0xc035);
+ add("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", 0xc036);
+ add("TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", 0xc037);
+ add("TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", 0xc038);
+ add("TLS_ECDHE_PSK_WITH_NULL_SHA", 0xc039);
+ add("TLS_ECDHE_PSK_WITH_NULL_SHA256", 0xc03a);
+ add("TLS_ECDHE_PSK_WITH_NULL_SHA384", 0xc03b);
}
// ciphersuite SSL_NULL_WITH_NULL_NULL
--- a/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java Tue Nov 02 19:40:45 2010 -0700
@@ -23,7 +23,6 @@
* questions.
*/
-
package sun.security.ssl;
import java.io.*;
@@ -45,12 +44,12 @@
import javax.security.auth.Subject;
-import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;
-
import sun.security.ssl.HandshakeMessage.*;
import sun.security.ssl.CipherSuite.*;
import static sun.security.ssl.CipherSuite.KeyExchange.*;
+import sun.net.util.IPAddressUtil;
+
/**
* ClientHandshaker does the protocol handshaking from the point
* of view of a client. It is driven asychronously by handshake messages
@@ -89,6 +88,10 @@
*/
private ProtocolVersion maxProtocolVersion;
+ // To switch off the SNI extension.
+ private final static boolean enableSNIExtension =
+ Debug.getBooleanProperty("jsse.enableSNIExtension", true);
+
/*
* Constructors
*/
@@ -190,7 +193,8 @@
}
break;
case K_DH_ANON:
- this.serverKeyExchange(new DH_ServerKeyExchange(input));
+ this.serverKeyExchange(new DH_ServerKeyExchange(
+ input, protocolVersion));
break;
case K_DHE_DSS:
case K_DHE_RSA:
@@ -198,7 +202,8 @@
this.serverKeyExchange(new DH_ServerKeyExchange(
input, serverKey,
clnt_random.random_bytes, svr_random.random_bytes,
- messageLen));
+ messageLen,
+ localSupportedSignAlgs, protocolVersion));
} catch (GeneralSecurityException e) {
throwSSLException("Server key", e);
}
@@ -209,7 +214,8 @@
try {
this.serverKeyExchange(new ECDH_ServerKeyExchange
(input, serverKey, clnt_random.random_bytes,
- svr_random.random_bytes));
+ svr_random.random_bytes,
+ localSupportedSignAlgs, protocolVersion));
} catch (GeneralSecurityException e) {
throwSSLException("Server key", e);
}
@@ -219,8 +225,9 @@
case K_DH_DSS:
case K_ECDH_ECDSA:
case K_ECDH_RSA:
- throw new SSLProtocolException("Protocol violation: server sent"
- + " a server key exchange message for key exchange " + keyExchange);
+ throw new SSLProtocolException(
+ "Protocol violation: server sent a server key exchange"
+ + "message for key exchange " + keyExchange);
case K_KRB5:
case K_KRB5_EXPORT:
throw new SSLProtocolException(
@@ -243,10 +250,32 @@
"Client certificate requested for "+
"kerberos cipher suite.");
}
- certRequest = new CertificateRequest(input);
+ certRequest = new CertificateRequest(input, protocolVersion);
if (debug != null && Debug.isOn("handshake")) {
certRequest.print(System.out);
}
+
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ Collection<SignatureAndHashAlgorithm> peerSignAlgs =
+ certRequest.getSignAlgorithms();
+ if (peerSignAlgs == null || peerSignAlgs.isEmpty()) {
+ throw new SSLHandshakeException(
+ "No peer supported signature algorithms");
+ }
+
+ Collection<SignatureAndHashAlgorithm> supportedPeerSignAlgs =
+ SignatureAndHashAlgorithm.getSupportedAlgorithms(
+ peerSignAlgs);
+ if (supportedPeerSignAlgs.isEmpty()) {
+ throw new SSLHandshakeException(
+ "No supported signature and hash algorithm in common");
+ }
+
+ setPeerSupportedSignAlgs(supportedPeerSignAlgs);
+ session.setPeerSupportedSignatureAlgorithms(
+ supportedPeerSignAlgs);
+ }
+
break;
case HandshakeMessage.ht_server_hello_done:
@@ -254,7 +283,8 @@
break;
case HandshakeMessage.ht_finished:
- this.serverFinished(new Finished(protocolVersion, input));
+ this.serverFinished(
+ new Finished(protocolVersion, input, cipherSuite));
break;
default:
@@ -345,11 +375,15 @@
// check if the server selected protocol version is OK for us
ProtocolVersion mesgVersion = mesg.protocolVersion;
- if (enabledProtocols.contains(mesgVersion) == false) {
- throw new SSLHandshakeException
- ("Server chose unsupported or disabled protocol: " + mesgVersion);
+ if (!isNegotiable(mesgVersion)) {
+ throw new SSLHandshakeException(
+ "Server chose unsupported or disabled protocol: " +
+ mesgVersion);
}
+ handshakeHash.protocolDetermined(
+ mesgVersion.v >= ProtocolVersion.TLS12.v);
+
// Set protocolVersion and propagate to SSLSocket and the
// Handshake streams
setVersion(mesgVersion);
@@ -425,10 +459,13 @@
if (isNegotiable(mesg.cipherSuite) == false) {
fatalSE(Alerts.alert_illegal_parameter,
- "Server selected improper ciphersuite " + cipherSuite);
+ "Server selected improper ciphersuite " + mesg.cipherSuite);
}
setCipherSuite(mesg.cipherSuite);
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg());
+ }
if (mesg.compression_method != 0) {
fatalSE(Alerts.alert_illegal_parameter,
@@ -507,7 +544,6 @@
if (debug != null && Debug.isOn("session")) {
System.out.println("%% Server resumed " + session);
}
- return;
} else {
// we wanted to resume, but the server refused
session = null;
@@ -518,11 +554,21 @@
}
}
+ if (resumingSession && session != null) {
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ handshakeHash.setCertificateVerifyAlg(null);
+ }
+
+ setHandshakeSessionSE(session);
+ return;
+ }
+
// check extensions
for (HelloExtension ext : mesg.extensions.list()) {
ExtensionType type = ext.type;
if ((type != ExtensionType.EXT_ELLIPTIC_CURVES)
&& (type != ExtensionType.EXT_EC_POINT_FORMATS)
+ && (type != ExtensionType.EXT_SERVER_NAME)
&& (type != ExtensionType.EXT_RENEGOTIATION_INFO)) {
fatalSE(Alerts.alert_unsupported_extension,
"Server sent an unsupported extension: " + type);
@@ -531,7 +577,9 @@
// Create a new session, we need to do the full handshake
session = new SSLSessionImpl(protocolVersion, cipherSuite,
+ getLocalSupportedSignAlgs(),
mesg.sessionId, getHostSE(), getPortSE());
+ setHandshakeSessionSE(session);
if (debug != null && Debug.isOn("handshake")) {
System.out.println("** " + cipherSuite);
}
@@ -567,11 +615,13 @@
if (debug != null && Debug.isOn("handshake")) {
mesg.print(System.out);
}
- dh = new DHCrypt(mesg.getModulus(), mesg.getBase(), sslContext.getSecureRandom());
+ dh = new DHCrypt(mesg.getModulus(), mesg.getBase(),
+ sslContext.getSecureRandom());
serverDH = mesg.getServerPublicKey();
}
- private void serverKeyExchange(ECDH_ServerKeyExchange mesg) throws IOException {
+ private void serverKeyExchange(ECDH_ServerKeyExchange mesg)
+ throws IOException {
if (debug != null && Debug.isOn("handshake")) {
mesg.print(System.out);
}
@@ -665,9 +715,13 @@
PublicKey publicKey = certs[0].getPublicKey();
// for EC, make sure we use a supported named curve
if (publicKey instanceof ECPublicKey) {
- ECParameterSpec params = ((ECPublicKey)publicKey).getParams();
- int index = SupportedEllipticCurvesExtension.getCurveIndex(params);
- if (!SupportedEllipticCurvesExtension.isSupported(index)) {
+ ECParameterSpec params =
+ ((ECPublicKey)publicKey).getParams();
+ int index =
+ SupportedEllipticCurvesExtension.getCurveIndex(
+ params);
+ if (!SupportedEllipticCurvesExtension.isSupported(
+ index)) {
publicKey = null;
}
}
@@ -813,8 +867,9 @@
throw new IOException("Hostname is required" +
" to use Kerberos cipher suites");
}
- KerberosClientKeyExchange kerberosMsg = new KerberosClientKeyExchange
- (hostname, isLoopbackSE(), getAccSE(), protocolVersion,
+ KerberosClientKeyExchange kerberosMsg =
+ new KerberosClientKeyExchange(
+ hostname, isLoopbackSE(), getAccSE(), protocolVersion,
sslContext.getSecureRandom());
// Record the principals involved in exchange
session.setPeerPrincipal(kerberosMsg.getPeerPrincipal());
@@ -861,7 +916,8 @@
case K_KRB5_EXPORT:
byte[] secretBytes =
((KerberosClientKeyExchange)m2).getUnencryptedPreMasterSecret();
- preMasterSecret = new SecretKeySpec(secretBytes, "TlsPremasterSecret");
+ preMasterSecret = new SecretKeySpec(secretBytes,
+ "TlsPremasterSecret");
break;
case K_DHE_RSA:
case K_DHE_DSS:
@@ -878,7 +934,8 @@
preMasterSecret = ecdh.getAgreedSecret(serverKey);
break;
default:
- throw new IOException("Internal error: unknown key exchange " + keyExchange);
+ throw new IOException("Internal error: unknown key exchange "
+ + keyExchange);
}
calculateKeys(preMasterSecret, null);
@@ -896,9 +953,32 @@
if (signingKey != null) {
CertificateVerify m3;
try {
+ SignatureAndHashAlgorithm preferableSignatureAlgorithm = null;
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ preferableSignatureAlgorithm =
+ SignatureAndHashAlgorithm.getPreferableAlgorithm(
+ peerSupportedSignAlgs, signingKey.getAlgorithm());
+
+ if (preferableSignatureAlgorithm == null) {
+ throw new SSLHandshakeException(
+ "No supported signature algorithm");
+ }
+
+ String hashAlg =
+ SignatureAndHashAlgorithm.getHashAlgorithmName(
+ preferableSignatureAlgorithm);
+ if (hashAlg == null || hashAlg.length() == 0) {
+ throw new SSLHandshakeException(
+ "No supported hash algorithm");
+ }
+
+ handshakeHash.setCertificateVerifyAlg(hashAlg);
+ }
+
m3 = new CertificateVerify(protocolVersion, handshakeHash,
signingKey, session.getMasterSecret(),
- sslContext.getSecureRandom());
+ sslContext.getSecureRandom(),
+ preferableSignatureAlgorithm);
} catch (GeneralSecurityException e) {
fatalSE(Alerts.alert_handshake_failure,
"Error signing certificate verify", e);
@@ -910,6 +990,10 @@
}
m3.write(output);
output.doHashes();
+ } else {
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ handshakeHash.setCertificateVerifyAlg(null);
+ }
}
/*
@@ -930,8 +1014,8 @@
mesg.print(System.out);
}
- boolean verified = mesg.verify(protocolVersion, handshakeHash,
- Finished.SERVER, session.getMasterSecret());
+ boolean verified = mesg.verify(handshakeHash, Finished.SERVER,
+ session.getMasterSecret());
if (!verified) {
fatalSE(Alerts.alert_illegal_parameter,
@@ -988,7 +1072,7 @@
private void sendChangeCipherAndFinish(boolean finishedTag)
throws IOException {
Finished mesg = new Finished(protocolVersion, handshakeHash,
- Finished.CLIENT, session.getMasterSecret());
+ Finished.CLIENT, session.getMasterSecret(), cipherSuite);
/*
* Send the change_cipher_spec message, then the Finished message
@@ -1022,7 +1106,7 @@
SessionId sessionId = SSLSessionImpl.nullSession.getSessionId();
// a list of cipher suites sent by the client
- CipherSuiteList cipherSuites = enabledCipherSuites;
+ CipherSuiteList cipherSuites = getActiveCipherSuites();
// set the max protocol version this client is supporting.
maxProtocolVersion = protocolVersion;
@@ -1057,8 +1141,7 @@
session = null;
}
- if ((session != null) &&
- (enabledProtocols.contains(sessionVersion) == false)) {
+ if ((session != null) && !isNegotiable(sessionVersion)) {
if (debug != null && Debug.isOn("session")) {
System.out.println("%% can't resume, protocol disabled");
}
@@ -1088,7 +1171,7 @@
*/
if (!enableNewSession) {
if (session == null) {
- throw new SSLException(
+ throw new SSLHandshakeException(
"Can't reuse existing SSL client session");
}
@@ -1105,7 +1188,7 @@
}
if (session == null && !enableNewSession) {
- throw new SSLException("No existing session to resume");
+ throw new SSLHandshakeException("No existing session to resume");
}
// exclude SCSV for secure renegotiation
@@ -1131,14 +1214,52 @@
}
if (!negotiable) {
- throw new SSLException("No negotiable cipher suite");
+ throw new SSLHandshakeException("No negotiable cipher suite");
}
+ // Not a TLS1.2+ handshake
+ // For SSLv2Hello, HandshakeHash.reset() will be called, so we
+ // cannot call HandshakeHash.protocolDetermined() here. As it does
+ // not follow the spec that HandshakeHash.reset() can be only be
+ // called before protocolDetermined.
+ // if (maxProtocolVersion.v < ProtocolVersion.TLS12.v) {
+ // handshakeHash.protocolDetermined(false);
+ // }
+
// create the ClientHello message
ClientHello clientHelloMessage = new ClientHello(
sslContext.getSecureRandom(), maxProtocolVersion,
sessionId, cipherSuites);
+ // add signature_algorithm extension
+ if (maxProtocolVersion.v >= ProtocolVersion.TLS12.v) {
+ // we will always send the signature_algorithm extension
+ Collection<SignatureAndHashAlgorithm> localSignAlgs =
+ getLocalSupportedSignAlgs();
+ if (localSignAlgs.isEmpty()) {
+ throw new SSLHandshakeException(
+ "No supported signature algorithm");
+ }
+
+ clientHelloMessage.addSignatureAlgorithmsExtension(localSignAlgs);
+ }
+
+ // add server_name extension
+ if (enableSNIExtension) {
+ // We cannot use the hostname resolved from name services. For
+ // virtual hosting, multiple hostnames may be bound to the same IP
+ // address, so the hostname resolved from name services is not
+ // reliable.
+ String hostname = getRawHostnameSE();
+
+ // we only allow FQDN
+ if (hostname != null && hostname.indexOf('.') > 0 &&
+ !IPAddressUtil.isIPv4LiteralAddress(hostname) &&
+ !IPAddressUtil.isIPv6LiteralAddress(hostname)) {
+ clientHelloMessage.addServerNameIndicationExtension(hostname);
+ }
+ }
+
// reset the client random cookie
clnt_random = clientHelloMessage.clnt_random;
@@ -1194,26 +1315,23 @@
keyExchangeString = keyExchange.name;
}
- String identificator = getHostnameVerificationSE();
if (tm instanceof X509ExtendedTrustManager) {
- ((X509ExtendedTrustManager)tm).checkServerTrusted(
- (peerCerts != null ?
- peerCerts.clone() :
- null),
+ if (conn != null) {
+ ((X509ExtendedTrustManager)tm).checkServerTrusted(
+ peerCerts.clone(),
keyExchangeString,
- getHostSE(),
- identificator);
+ conn);
+ } else {
+ ((X509ExtendedTrustManager)tm).checkServerTrusted(
+ peerCerts.clone(),
+ keyExchangeString,
+ engine);
+ }
} else {
- if (identificator != null) {
- throw new RuntimeException(
- "trust manager does not support peer identification");
- }
-
- tm.checkServerTrusted(
- (peerCerts != null ?
- peerCerts.clone() :
- peerCerts),
- keyExchangeString);
+ // Unlikely to happen, because we have wrapped the old
+ // X509TrustManager with the new X509ExtendedTrustManager.
+ throw new CertificateException(
+ "Improper X509TrustManager implementation");
}
} catch (CertificateException e) {
// This will throw an exception, so include the original error.
--- a/jdk/src/share/classes/sun/security/ssl/Debug.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/Debug.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, 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.io.PrintStream;
import java.security.AccessController;
+import java.util.Locale;
import sun.security.action.GetPropertyAction;
@@ -44,7 +45,7 @@
static {
args = java.security.AccessController.doPrivileged(
new GetPropertyAction("javax.net.debug", ""));
- args = args.toLowerCase();
+ args = args.toLowerCase(Locale.ENGLISH);
if (args.equals("help")) {
Help();
}
@@ -114,7 +115,7 @@
return false;
} else {
int n = 0;
- option = option.toLowerCase();
+ option = option.toLowerCase(Locale.ENGLISH);
if (args.indexOf("all") != -1) {
return true;
--- a/jdk/src/share/classes/sun/security/ssl/HandshakeHash.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/HandshakeHash.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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
@@ -26,7 +26,13 @@
package sun.security.ssl;
+import java.io.ByteArrayOutputStream;
import java.security.*;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
/**
* Abstraction for the SSL/TLS hash of all handshake messages that is
@@ -36,51 +42,161 @@
*
* This class transparently deals with cloneable and non-cloneable digests.
*
+ * This class now supports TLS 1.2 also. The key difference for TLS 1.2
+ * is that you cannot determine the hash algorithms for CertificateVerify
+ * at a early stage. On the other hand, it's simpler than TLS 1.1 (and earlier)
+ * that there is no messy MD5+SHA1 digests.
+ *
+ * You need to obey these conventions when using this class:
+ *
+ * 1. protocolDetermined(boolean isTLS12) should be called when the negotiated
+ * protocol version is determined.
+ *
+ * 2. Before protocolDetermined() is called, only update(), reset(),
+ * restrictCertificateVerifyAlgs(), setFinishedAlg(), and
+ * setCertificateVerifyAlg() can be called.
+ *
+ * 3. After protocolDetermined(*) is called. reset() cannot be called.
+ *
+ * 4. After protocolDetermined(false) is called, getFinishedHash() and
+ * getCertificateVerifyHash() cannot be called. After protocolDetermined(true)
+ * is called, getMD5Clone() and getSHAClone() cannot be called.
+ *
+ * 5. getMD5Clone() and getSHAClone() can only be called after
+ * protocolDetermined(false) is called.
+ *
+ * 6. getFinishedHash() and getCertificateVerifyHash() can only be called after
+ * all protocolDetermined(true), setCertificateVerifyAlg() and setFinishedAlg()
+ * have been called. If a CertificateVerify message is to be used, call
+ * setCertificateVerifyAlg() with the hash algorithm as the argument.
+ * Otherwise, you still must call setCertificateVerifyAlg(null) before
+ * calculating any hash value.
+ *
+ * Suggestions: Call protocolDetermined(), restrictCertificateVerifyAlgs(),
+ * setFinishedAlg(), and setCertificateVerifyAlg() as early as possible.
+ *
+ * Example:
+ * <pre>
+ * HandshakeHash hh = new HandshakeHash(...)
+ * hh.update(clientHelloBytes);
+ * hh.setFinishedAlg("SHA-256");
+ * hh.update(serverHelloBytes);
+ * ...
+ * hh.setCertificateVerifyAlg("SHA-384");
+ * hh.update(CertificateVerifyBytes);
+ * byte[] cvDigest = hh.getCertificateVerifyHash();
+ * ...
+ * hh.update(finished1);
+ * byte[] finDigest1 = hh.getFinishedHash();
+ * hh.update(finished2);
+ * byte[] finDigest2 = hh.getFinishedHash();
+ * </pre>
+ * If no CertificateVerify message is to be used, call
+ * <pre>
+ * hh.setCertificateVerifyAlg(null);
+ * </pre>
+ * This call can be made once you are certain that this message
+ * will never be used.
*/
final class HandshakeHash {
- private final MessageDigest md5, sha;
+ // Common
+
+ // -1: unknown
+ // 1: <=TLS 1.1
+ // 2: TLS 1.2
+ private int version = -1;
+ private ByteArrayOutputStream data = new ByteArrayOutputStream();
+ private final boolean isServer;
+
+ // For TLS 1.1
+ private MessageDigest md5, sha;
+ private final int clonesNeeded; // needs to be saved for later use
+
+ // For TLS 1.2
+ // cvAlgDetermined == true means setCertificateVerifyAlg() is called
+ private boolean cvAlgDetermined = false;
+ private String cvAlg;
+ private MessageDigest finMD;
/**
* Create a new HandshakeHash. needCertificateVerify indicates whether
- * a hash for the certificate verify message is required.
+ * a hash for the certificate verify message is required. The argument
+ * algs is a set of all possible hash algorithms that might be used in
+ * TLS 1.2. If the caller is sure that TLS 1.2 won't be used or no
+ * CertificateVerify message will be used, leave it null or empty.
*/
- HandshakeHash(boolean needCertificateVerify) {
- int n = needCertificateVerify ? 3 : 2;
- try {
- md5 = CloneableDigest.getDigest("MD5", n);
- sha = CloneableDigest.getDigest("SHA", n);
- } catch (NoSuchAlgorithmException e) {
- throw new RuntimeException
- ("Algorithm MD5 or SHA not available", e);
+ HandshakeHash(boolean isServer, boolean needCertificateVerify,
+ Set<String> algs) {
+ this.isServer = isServer;
+ clonesNeeded = needCertificateVerify ? 3 : 2;
+ }
+ void update(byte[] b, int offset, int len) {
+ switch (version) {
+ case 1:
+ md5.update(b, offset, len);
+ sha.update(b, offset, len);
+ break;
+ default:
+ if (finMD != null) {
+ finMD.update(b, offset, len);
+ }
+ data.write(b, offset, len);
+ break;
}
}
- void update(byte b) {
- md5.update(b);
- sha.update(b);
- }
-
- void update(byte[] b, int offset, int len) {
- md5.update(b, offset, len);
- sha.update(b, offset, len);
- }
-
/**
- * Reset the remaining digests. Note this does *not* reset the numbe of
+ * Reset the remaining digests. Note this does *not* reset the number of
* digest clones that can be obtained. Digests that have already been
* cloned and are gone remain gone.
*/
void reset() {
- md5.reset();
- sha.reset();
+ if (version != -1) {
+ throw new RuntimeException(
+ "reset() can be only be called before protocolDetermined");
+ }
+ data.reset();
}
+
+ void protocolDetermined(boolean isTLS12) {
+
+ // Do not set again, will ignore
+ if (version != -1) return;
+
+ version = isTLS12 ? 2 : 1;
+ switch (version) {
+ case 1:
+ // initiate md5, sha and call update on saved array
+ try {
+ md5 = CloneableDigest.getDigest("MD5", clonesNeeded);
+ sha = CloneableDigest.getDigest("SHA", clonesNeeded);
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException
+ ("Algorithm MD5 or SHA not available", e);
+ }
+ byte[] bytes = data.toByteArray();
+ update(bytes, 0, bytes.length);
+ break;
+ case 2:
+ break;
+ }
+ }
+
+ /////////////////////////////////////////////////////////////
+ // Below are old methods for pre-TLS 1.1
+ /////////////////////////////////////////////////////////////
+
/**
* Return a new MD5 digest updated with all data hashed so far.
*/
MessageDigest getMD5Clone() {
+ if (version != 1) {
+ throw new RuntimeException(
+ "getMD5Clone() can be only be called for TLS 1.1");
+ }
return cloneDigest(md5);
}
@@ -88,6 +204,10 @@
* Return a new SHA digest updated with all data hashed so far.
*/
MessageDigest getSHAClone() {
+ if (version != 1) {
+ throw new RuntimeException(
+ "getSHAClone() can be only be called for TLS 1.1");
+ }
return cloneDigest(sha);
}
@@ -100,6 +220,181 @@
}
}
+ /////////////////////////////////////////////////////////////
+ // Below are new methods for TLS 1.2
+ /////////////////////////////////////////////////////////////
+
+ private static String normalizeAlgName(String alg) {
+ alg = alg.toUpperCase(Locale.US);
+ if (alg.startsWith("SHA")) {
+ if (alg.length() == 3) {
+ return "SHA-1";
+ }
+ if (alg.charAt(3) != '-') {
+ return "SHA-" + alg.substring(3);
+ }
+ }
+ return alg;
+ }
+ /**
+ * Specifies the hash algorithm used in Finished. This should be called
+ * based in info in ServerHello.
+ * Can be called multiple times.
+ */
+ void setFinishedAlg(String s) {
+ if (s == null) {
+ throw new RuntimeException(
+ "setFinishedAlg's argument cannot be null");
+ }
+
+ // Can be called multiple times, but only set once
+ if (finMD != null) return;
+
+ try {
+ finMD = CloneableDigest.getDigest(normalizeAlgName(s), 2);
+ } catch (NoSuchAlgorithmException e) {
+ throw new Error(e);
+ }
+ finMD.update(data.toByteArray());
+ }
+
+ /**
+ * Restricts the possible algorithms for the CertificateVerify. Called by
+ * the server based on info in CertRequest. The argument must be a subset
+ * of the argument with the same name in the constructor. The method can be
+ * called multiple times. If the caller is sure that no CertificateVerify
+ * message will be used, leave this argument null or empty.
+ */
+ void restrictCertificateVerifyAlgs(Set<String> algs) {
+ if (version == 1) {
+ throw new RuntimeException(
+ "setCertificateVerifyAlg() cannot be called for TLS 1.1");
+ }
+ // Not used yet
+ }
+
+ /**
+ * Specifies the hash algorithm used in CertificateVerify.
+ * Can be called multiple times.
+ */
+ void setCertificateVerifyAlg(String s) {
+
+ // Can be called multiple times, but only set once
+ if (cvAlgDetermined) return;
+
+ cvAlg = s == null ? null : normalizeAlgName(s);
+ cvAlgDetermined = true;
+ }
+
+ byte[] getAllHandshakeMessages() {
+ return data.toByteArray();
+ }
+
+ /**
+ * Calculates the hash in the CertificateVerify. Must be called right
+ * after setCertificateVerifyAlg()
+ */
+ /*byte[] getCertificateVerifyHash() {
+ throw new Error("Do not call getCertificateVerifyHash()");
+ }*/
+
+ /**
+ * Calculates the hash in Finished. Must be called after setFinishedAlg().
+ * This method can be called twice, for Finished messages of the server
+ * side and client side respectively.
+ */
+ byte[] getFinishedHash() {
+ try {
+ return cloneDigest(finMD).digest();
+ } catch (Exception e) {
+ throw new Error("BAD");
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////
+ // TEST
+ ////////////////////////////////////////////////////////////////
+
+ public static void main(String[] args) throws Exception {
+ Test t = new Test();
+ t.test(null, "SHA-256");
+ t.test("", "SHA-256");
+ t.test("SHA-1", "SHA-256");
+ t.test("SHA-256", "SHA-256");
+ t.test("SHA-384", "SHA-256");
+ t.test("SHA-512", "SHA-256");
+ t.testSame("sha", "SHA-1");
+ t.testSame("SHA", "SHA-1");
+ t.testSame("SHA1", "SHA-1");
+ t.testSame("SHA-1", "SHA-1");
+ t.testSame("SHA256", "SHA-256");
+ t.testSame("SHA-256", "SHA-256");
+ }
+
+ static class Test {
+ void update(HandshakeHash hh, String s) {
+ hh.update(s.getBytes(), 0, s.length());
+ }
+ static byte[] digest(String alg, String data) throws Exception {
+ return MessageDigest.getInstance(alg).digest(data.getBytes());
+ }
+ static void equals(byte[] b1, byte[] b2) {
+ if (!Arrays.equals(b1, b2)) {
+ throw new RuntimeException("Bad");
+ }
+ }
+ void testSame(String a, String a2) {
+ System.out.println("testSame: " + a + " " + a2);
+ if (!HandshakeHash.normalizeAlgName(a).equals(a2)) {
+ throw new RuntimeException("Bad");
+ }
+ }
+ /**
+ * Special convention: when it's certain that CV will not be used at the
+ * very beginning, use null as cvAlg. If known at a late stage, use "".
+ */
+ void test(String cvAlg, String finAlg) throws Exception {
+ System.out.println("test: " + cvAlg + " " + finAlg);
+ byte[] cv = null, f1, f2;
+ HandshakeHash hh = new HandshakeHash(true, true, null);
+ if (cvAlg == null) {
+ hh.setCertificateVerifyAlg(cvAlg);
+ }
+
+ update(hh, "ClientHello,");
+ hh.reset();
+ update(hh, "ClientHellov2,");
+ hh.setFinishedAlg(finAlg);
+
+ // Useless calls
+ hh.setFinishedAlg("SHA-1");
+ hh.setFinishedAlg("SHA-512");
+
+ update(hh, "More,");
+ if (cvAlg != null) {
+ if (cvAlg.isEmpty()) cvAlg = null;
+ hh.setCertificateVerifyAlg(cvAlg);
+ }
+
+ // Useless calls
+ hh.setCertificateVerifyAlg("SHA-1");
+ hh.setCertificateVerifyAlg(null);
+
+ hh.protocolDetermined(true);
+
+ if (cvAlg != null) {
+ cv = hh.getAllHandshakeMessages();
+ equals(cv, "ClientHellov2,More,".getBytes());
+ }
+
+ update(hh, "FIN1,");
+ f1 = hh.getFinishedHash();
+ equals(f1, digest(finAlg, "ClientHellov2,More,FIN1,"));
+ update(hh, "FIN2,");
+ f2 = hh.getFinishedHash();
+ equals(f2, digest(finAlg, "ClientHellov2,More,FIN1,FIN2,"));
+ }
+ }
}
/**
--- a/jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * copyright (c) 1996, 2010, 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
@@ -41,15 +41,12 @@
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
import javax.net.ssl.*;
-import sun.security.action.GetPropertyAction;
-
import sun.security.internal.spec.TlsPrfParameterSpec;
-
import sun.security.ssl.CipherSuite.*;
+import static sun.security.ssl.CipherSuite.PRF.*;
/**
* Many data structures are involved in the handshake messages. These
@@ -258,6 +255,27 @@
extensions.add(renegotiationInfo);
}
+ // add server_name extension
+ void addServerNameIndicationExtension(String hostname) {
+ // We would have checked that the hostname ia a FQDN.
+ ArrayList<String> hostnames = new ArrayList<String>(1);
+ hostnames.add(hostname);
+
+ try {
+ extensions.add(new ServerNameExtension(hostnames));
+ } catch (IOException ioe) {
+ // ignore the exception and return
+ }
+ }
+
+ // add signature_algorithm extension
+ void addSignatureAlgorithmsExtension(
+ Collection<SignatureAndHashAlgorithm> algorithms) {
+ HelloExtension signatureAlgorithm =
+ new SignatureAlgorithmsExtension(algorithms);
+ extensions.add(signatureAlgorithm);
+ }
+
@Override
int messageType() { return ht_client_hello; }
@@ -290,7 +308,8 @@
s.println("*** ClientHello, " + protocolVersion);
if (debug != null && Debug.isOn("verbose")) {
- s.print ("RandomCookie: "); clnt_random.print(s);
+ s.print("RandomCookie: ");
+ clnt_random.print(s);
s.print("Session ID: ");
s.println(sessionId);
@@ -327,7 +346,8 @@
// empty
}
- ServerHello(HandshakeInStream input, int messageLength) throws IOException {
+ ServerHello(HandshakeInStream input, int messageLength)
+ throws IOException {
protocolVersion = ProtocolVersion.valueOf(input.getInt8(),
input.getInt8());
svr_random = new RandomCookie(input);
@@ -367,7 +387,8 @@
s.println("*** ServerHello, " + protocolVersion);
if (debug != null && Debug.isOn("verbose")) {
- s.print ("RandomCookie: "); svr_random.print(s);
+ s.print("RandomCookie: ");
+ svr_random.print(s);
int i;
@@ -425,8 +446,8 @@
}
v.add(cf.generateCertificate(new ByteArrayInputStream(cert)));
} catch (CertificateException e) {
- throw (SSLProtocolException)new SSLProtocolException
- (e.getMessage()).initCause(e);
+ throw (SSLProtocolException)new SSLProtocolException(
+ e.getMessage()).initCause(e);
}
}
@@ -469,7 +490,7 @@
}
X509Certificate[] getCertificateChain() {
- return chain;
+ return chain.clone();
}
}
@@ -597,9 +618,9 @@
try {
KeyFactory kfac = JsseJce.getKeyFactory("RSA");
// modulus and exponent are always positive
- RSAPublicKeySpec kspec = new RSAPublicKeySpec
- (new BigInteger(1, rsa_modulus),
- new BigInteger(1, rsa_exponent));
+ RSAPublicKeySpec kspec = new RSAPublicKeySpec(
+ new BigInteger(1, rsa_modulus),
+ new BigInteger(1, rsa_exponent));
return kfac.generatePublic(kspec);
} catch (Exception e) {
throw new RuntimeException(e);
@@ -667,6 +688,12 @@
private byte signature [];
+ // protocol version being established using this ServerKeyExchange message
+ ProtocolVersion protocolVersion;
+
+ // the preferable signature algorithm used by this ServerKeyExchange message
+ private SignatureAndHashAlgorithm preferableSignatureAlgorithm;
+
/* Return the Diffie-Hellman modulus */
BigInteger getModulus() {
return new BigInteger(1, dh_p);
@@ -712,8 +739,11 @@
* Construct from initialized DH key object, for DH_anon
* key exchange.
*/
- DH_ServerKeyExchange(DHCrypt obj) {
- getValues(obj);
+ DH_ServerKeyExchange(DHCrypt obj, ProtocolVersion protocolVersion) {
+ this.protocolVersion = protocolVersion;
+ this.preferableSignatureAlgorithm = null;
+
+ setValues(obj);
signature = null;
}
@@ -723,22 +753,33 @@
* key exchange. (Constructor called by server.)
*/
DH_ServerKeyExchange(DHCrypt obj, PrivateKey key, byte clntNonce[],
- byte svrNonce[], SecureRandom sr) throws GeneralSecurityException {
+ byte svrNonce[], SecureRandom sr,
+ SignatureAndHashAlgorithm signAlgorithm,
+ ProtocolVersion protocolVersion) throws GeneralSecurityException {
- getValues(obj);
+ this.protocolVersion = protocolVersion;
+
+ setValues(obj);
Signature sig;
- if (key.getAlgorithm().equals("DSA")) {
- sig = JsseJce.getSignature(JsseJce.SIGNATURE_DSA);
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ this.preferableSignatureAlgorithm = signAlgorithm;
+ sig = JsseJce.getSignature(signAlgorithm.getAlgorithmName());
} else {
- sig = RSASignature.getInstance();
+ this.preferableSignatureAlgorithm = null;
+ if (key.getAlgorithm().equals("DSA")) {
+ sig = JsseJce.getSignature(JsseJce.SIGNATURE_DSA);
+ } else {
+ sig = RSASignature.getInstance();
+ }
}
+
sig.initSign(key, sr);
updateSignature(sig, clntNonce, svrNonce);
signature = sig.sign();
}
- private void getValues(DHCrypt obj) {
+ private void setValues(DHCrypt obj) {
dh_p = toByteArray(obj.getModulus());
dh_g = toByteArray(obj.getBase());
dh_Ys = toByteArray(obj.getPublicKey());
@@ -749,7 +790,12 @@
* stream, as if sent from server to client for use with
* DH_anon key exchange
*/
- DH_ServerKeyExchange(HandshakeInStream input) throws IOException {
+ DH_ServerKeyExchange(HandshakeInStream input,
+ ProtocolVersion protocolVersion) throws IOException {
+
+ this.protocolVersion = protocolVersion;
+ this.preferableSignatureAlgorithm = null;
+
dh_p = input.getBytes16();
dh_g = input.getBytes16();
dh_Ys = input.getBytes16();
@@ -762,13 +808,38 @@
* DHE_DSS or DHE_RSA key exchange. (Called by client.)
*/
DH_ServerKeyExchange(HandshakeInStream input, PublicKey publicKey,
- byte clntNonce[], byte svrNonce[], int messageSize)
+ byte clntNonce[], byte svrNonce[], int messageSize,
+ Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs,
+ ProtocolVersion protocolVersion)
throws IOException, GeneralSecurityException {
+ this.protocolVersion = protocolVersion;
+
+ // read params: ServerDHParams
dh_p = input.getBytes16();
dh_g = input.getBytes16();
dh_Ys = input.getBytes16();
+ // read the signature and hash algorithm
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ int hash = input.getInt8(); // hash algorithm
+ int signature = input.getInt8(); // signature algorithm
+
+ preferableSignatureAlgorithm =
+ SignatureAndHashAlgorithm.valueOf(hash, signature, 0);
+
+ // Is it a local supported signature algorithm?
+ if (!localSupportedSignAlgs.contains(
+ preferableSignatureAlgorithm)) {
+ throw new SSLHandshakeException(
+ "Unsupported SignatureAndHashAlgorithm in " +
+ "ServerKeyExchange message");
+ }
+ } else {
+ this.preferableSignatureAlgorithm = null;
+ }
+
+ // read the signature
byte signature[];
if (dhKeyExchangeFix) {
signature = input.getBytes16();
@@ -783,12 +854,17 @@
Signature sig;
String algorithm = publicKey.getAlgorithm();
- if (algorithm.equals("DSA")) {
- sig = JsseJce.getSignature(JsseJce.SIGNATURE_DSA);
- } else if (algorithm.equals("RSA")) {
- sig = RSASignature.getInstance();
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ sig = JsseJce.getSignature(
+ preferableSignatureAlgorithm.getAlgorithmName());
} else {
- throw new SSLKeyException("neither an RSA or a DSA key");
+ if (algorithm.equals("DSA")) {
+ sig = JsseJce.getSignature(JsseJce.SIGNATURE_DSA);
+ } else if (algorithm.equals("RSA")) {
+ sig = RSASignature.getInstance();
+ } else {
+ throw new SSLKeyException("neither an RSA or a DSA key");
+ }
}
sig.initVerify(publicKey);
@@ -805,12 +881,18 @@
temp += dh_p.length;
temp += dh_g.length;
temp += dh_Ys.length;
+
if (signature != null) {
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ temp += SignatureAndHashAlgorithm.sizeInRecord();
+ }
+
temp += signature.length;
if (dhKeyExchangeFix) {
temp += 2;
}
}
+
return temp;
}
@@ -818,7 +900,13 @@
s.putBytes16(dh_p);
s.putBytes16(dh_g);
s.putBytes16(dh_Ys);
+
if (signature != null) {
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ s.putInt8(preferableSignatureAlgorithm.getHashValue());
+ s.putInt8(preferableSignatureAlgorithm.getSignatureValue());
+ }
+
if (dhKeyExchangeFix) {
s.putBytes16(signature);
} else {
@@ -838,6 +926,11 @@
if (signature == null) {
s.println("Anonymous");
} else {
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ s.println("Signature Algorithm " +
+ preferableSignatureAlgorithm.getAlgorithmName());
+ }
+
s.println("Signed with a DSA or RSA public key");
}
}
@@ -871,9 +964,19 @@
// public key object encapsulated in this message
private ECPublicKey publicKey;
+ // protocol version being established using this ServerKeyExchange message
+ ProtocolVersion protocolVersion;
+
+ // the preferable signature algorithm used by this ServerKeyExchange message
+ private SignatureAndHashAlgorithm preferableSignatureAlgorithm;
+
ECDH_ServerKeyExchange(ECDHCrypt obj, PrivateKey privateKey,
- byte[] clntNonce, byte[] svrNonce, SecureRandom sr)
- throws GeneralSecurityException {
+ byte[] clntNonce, byte[] svrNonce, SecureRandom sr,
+ SignatureAndHashAlgorithm signAlgorithm,
+ ProtocolVersion protocolVersion) throws GeneralSecurityException {
+
+ this.protocolVersion = protocolVersion;
+
publicKey = (ECPublicKey)obj.getPublicKey();
ECParameterSpec params = publicKey.getParams();
ECPoint point = publicKey.getW();
@@ -885,8 +988,14 @@
return;
}
- Signature sig = getSignature(privateKey.getAlgorithm());
- sig.initSign(privateKey);
+ Signature sig;
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ this.preferableSignatureAlgorithm = signAlgorithm;
+ sig = JsseJce.getSignature(signAlgorithm.getAlgorithmName());
+ } else {
+ sig = getSignature(privateKey.getAlgorithm());
+ }
+ sig.initSign(privateKey); // where is the SecureRandom?
updateSignature(sig, clntNonce, svrNonce);
signatureBytes = sig.sign();
@@ -896,49 +1005,87 @@
* Parse an ECDH server key exchange message.
*/
ECDH_ServerKeyExchange(HandshakeInStream input, PublicKey signingKey,
- byte[] clntNonce, byte[] svrNonce)
+ byte[] clntNonce, byte[] svrNonce,
+ Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs,
+ ProtocolVersion protocolVersion)
throws IOException, GeneralSecurityException {
+
+ this.protocolVersion = protocolVersion;
+
+ // read params: ServerECDHParams
int curveType = input.getInt8();
ECParameterSpec parameters;
// These parsing errors should never occur as we negotiated
// the supported curves during the exchange of the Hello messages.
if (curveType == CURVE_NAMED_CURVE) {
curveId = input.getInt16();
- if (SupportedEllipticCurvesExtension.isSupported(curveId) == false) {
- throw new SSLHandshakeException("Unsupported curveId: " + curveId);
+ if (SupportedEllipticCurvesExtension.isSupported(curveId)
+ == false) {
+ throw new SSLHandshakeException(
+ "Unsupported curveId: " + curveId);
}
- String curveOid = SupportedEllipticCurvesExtension.getCurveOid(curveId);
+ String curveOid =
+ SupportedEllipticCurvesExtension.getCurveOid(curveId);
if (curveOid == null) {
- throw new SSLHandshakeException("Unknown named curve: " + curveId);
+ throw new SSLHandshakeException(
+ "Unknown named curve: " + curveId);
}
parameters = JsseJce.getECParameterSpec(curveOid);
if (parameters == null) {
- throw new SSLHandshakeException("Unsupported curve: " + curveOid);
+ throw new SSLHandshakeException(
+ "Unsupported curve: " + curveOid);
}
} else {
- throw new SSLHandshakeException("Unsupported ECCurveType: " + curveType);
+ throw new SSLHandshakeException(
+ "Unsupported ECCurveType: " + curveType);
}
pointBytes = input.getBytes8();
ECPoint point = JsseJce.decodePoint(pointBytes, parameters.getCurve());
KeyFactory factory = JsseJce.getKeyFactory("EC");
- publicKey = (ECPublicKey)factory.generatePublic(new ECPublicKeySpec(point, parameters));
+ publicKey = (ECPublicKey)factory.generatePublic(
+ new ECPublicKeySpec(point, parameters));
if (signingKey == null) {
// ECDH_anon
return;
}
- // verify the signature
+ // read the signature and hash algorithm
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ int hash = input.getInt8(); // hash algorithm
+ int signature = input.getInt8(); // signature algorithm
+
+ preferableSignatureAlgorithm =
+ SignatureAndHashAlgorithm.valueOf(hash, signature, 0);
+
+ // Is it a local supported signature algorithm?
+ if (!localSupportedSignAlgs.contains(
+ preferableSignatureAlgorithm)) {
+ throw new SSLHandshakeException(
+ "Unsupported SignatureAndHashAlgorithm in " +
+ "ServerKeyExchange message");
+ }
+ }
+
+ // read the signature
signatureBytes = input.getBytes16();
- Signature sig = getSignature(signingKey.getAlgorithm());
+
+ // verify the signature
+ Signature sig;
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ sig = JsseJce.getSignature(
+ preferableSignatureAlgorithm.getAlgorithmName());
+ } else {
+ sig = getSignature(signingKey.getAlgorithm());
+ }
sig.initVerify(signingKey);
updateSignature(sig, clntNonce, svrNonce);
if (sig.verify(signatureBytes) == false ) {
- throw new SSLKeyException
- ("Invalid signature on ECDH server key exchange message");
+ throw new SSLKeyException(
+ "Invalid signature on ECDH server key exchange message");
}
}
@@ -949,7 +1096,8 @@
return publicKey;
}
- private static Signature getSignature(String keyAlgorithm) throws NoSuchAlgorithmException {
+ private static Signature getSignature(String keyAlgorithm)
+ throws NoSuchAlgorithmException {
if (keyAlgorithm.equals("EC")) {
return JsseJce.getSignature(JsseJce.SIGNATURE_ECDSA);
} else if (keyAlgorithm.equals("RSA")) {
@@ -973,6 +1121,11 @@
int messageLength() {
int sigLen = (signatureBytes == null) ? 0 : 2 + signatureBytes.length;
+
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ sigLen += SignatureAndHashAlgorithm.sizeInRecord();
+ }
+
return 4 + pointBytes.length + sigLen;
}
@@ -980,6 +1133,11 @@
s.putInt8(CURVE_NAMED_CURVE);
s.putInt16(curveId);
s.putBytes8(pointBytes);
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ s.putInt8(preferableSignatureAlgorithm.getHashValue());
+ s.putInt8(preferableSignatureAlgorithm.getSignatureValue());
+ }
+
if (signatureBytes != null) {
s.putBytes16(signatureBytes);
}
@@ -989,6 +1147,11 @@
s.println("*** ECDH ServerKeyExchange");
if (debug != null && Debug.isOn("verbose")) {
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ s.println("Signature Algorithm " +
+ preferableSignatureAlgorithm.getAlgorithmName());
+ }
+
s.println("Server key: " + publicKey);
}
}
@@ -1014,8 +1177,8 @@
try {
return new X500Principal(name);
} catch (IllegalArgumentException e) {
- throw (SSLProtocolException)new SSLProtocolException
- (e.getMessage()).initCause(e);
+ throw (SSLProtocolException)new SSLProtocolException(
+ e.getMessage()).initCause(e);
}
}
@@ -1038,12 +1201,25 @@
*
* Authenticated servers may ask clients to authenticate themselves
* in turn, using this message.
+ *
+ * Prior to TLS 1.2, the structure of the message is defined as:
+ * struct {
+ * ClientCertificateType certificate_types<1..2^8-1>;
+ * DistinguishedName certificate_authorities<0..2^16-1>;
+ * } CertificateRequest;
+ *
+ * In TLS 1.2, the structure is changed to:
+ * struct {
+ * ClientCertificateType certificate_types<1..2^8-1>;
+ * SignatureAndHashAlgorithm
+ * supported_signature_algorithms<2^16-1>;
+ * DistinguishedName certificate_authorities<0..2^16-1>;
+ * } CertificateRequest;
+ *
*/
static final
class CertificateRequest extends HandshakeMessage
{
- int messageType() { return ht_certificate_request; }
-
// enum ClientCertificateType
static final int cct_rsa_sign = 1;
static final int cct_dss_sign = 2;
@@ -1068,8 +1244,21 @@
DistinguishedName authorities []; // 3 to 2^16 - 1
// ... "3" because that's the smallest DER-encoded X500 DN
- CertificateRequest(X509Certificate ca[], KeyExchange keyExchange)
- throws IOException {
+ // protocol version being established using this CertificateRequest message
+ ProtocolVersion protocolVersion;
+
+ // supported_signature_algorithms for TLS 1.2 or later
+ private Collection<SignatureAndHashAlgorithm> algorithms;
+
+ // length of supported_signature_algorithms
+ private int algorithmsLen;
+
+ CertificateRequest(X509Certificate ca[], KeyExchange keyExchange,
+ Collection<SignatureAndHashAlgorithm> signAlgs,
+ ProtocolVersion protocolVersion) throws IOException {
+
+ this.protocolVersion = protocolVersion;
+
// always use X500Principal
authorities = new DistinguishedName[ca.length];
for (int i = 0; i < ca.length; i++) {
@@ -1081,10 +1270,63 @@
// needs to be adapted to take keyExchange into account.
// We only request ECDSA client auth if we have ECC crypto available.
this.types = JsseJce.isEcAvailable() ? TYPES_ECC : TYPES_NO_ECC;
+
+ // Use supported_signature_algorithms for TLS 1.2 or later.
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ if (signAlgs == null || signAlgs.isEmpty()) {
+ throw new SSLProtocolException(
+ "No supported signature algorithms");
+ }
+
+ algorithms = new ArrayList<SignatureAndHashAlgorithm>(signAlgs);
+ algorithmsLen =
+ SignatureAndHashAlgorithm.sizeInRecord() * algorithms.size();
+ } else {
+ algorithms = new ArrayList<SignatureAndHashAlgorithm>();
+ algorithmsLen = 0;
+ }
}
- CertificateRequest(HandshakeInStream input) throws IOException {
+ CertificateRequest(HandshakeInStream input,
+ ProtocolVersion protocolVersion) throws IOException {
+
+ this.protocolVersion = protocolVersion;
+
+ // Read the certificate_types.
types = input.getBytes8();
+
+ // Read the supported_signature_algorithms for TLS 1.2 or later.
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ algorithmsLen = input.getInt16();
+ if (algorithmsLen < 2) {
+ throw new SSLProtocolException(
+ "Invalid supported_signature_algorithms field");
+ }
+
+ algorithms = new ArrayList<SignatureAndHashAlgorithm>();
+ int remains = algorithmsLen;
+ int sequence = 0;
+ while (remains > 1) { // needs at least two bytes
+ int hash = input.getInt8(); // hash algorithm
+ int signature = input.getInt8(); // signature algorithm
+
+ SignatureAndHashAlgorithm algorithm =
+ SignatureAndHashAlgorithm.valueOf(hash, signature,
+ ++sequence);
+ algorithms.add(algorithm);
+ remains -= 2; // one byte for hash, one byte for signature
+ }
+
+ if (remains != 0) {
+ throw new SSLProtocolException(
+ "Invalid supported_signature_algorithms field");
+ }
+ } else {
+ algorithms = new ArrayList<SignatureAndHashAlgorithm>();
+ algorithmsLen = 0;
+ }
+
+ // read the certificate_authorities
int len = input.getInt16();
ArrayList<DistinguishedName> v = new ArrayList<DistinguishedName>();
while (len >= 3) {
@@ -1108,31 +1350,58 @@
return ret;
}
- int messageLength()
- {
- int len;
+ Collection<SignatureAndHashAlgorithm> getSignAlgorithms() {
+ return algorithms;
+ }
+
+ @Override
+ int messageType() {
+ return ht_certificate_request;
+ }
- len = 1 + types.length + 2;
- for (int i = 0; i < authorities.length; i++)
+ @Override
+ int messageLength() {
+ int len = 1 + types.length + 2;
+
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ len += algorithmsLen + 2;
+ }
+
+ for (int i = 0; i < authorities.length; i++) {
len += authorities[i].length();
+ }
+
return len;
}
- void send(HandshakeOutStream output) throws IOException
- {
- int len = 0;
+ @Override
+ void send(HandshakeOutStream output) throws IOException {
+ // put certificate_types
+ output.putBytes8(types);
- for (int i = 0; i < authorities.length; i++)
+ // put supported_signature_algorithms
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ output.putInt16(algorithmsLen);
+ for (SignatureAndHashAlgorithm algorithm : algorithms) {
+ output.putInt8(algorithm.getHashValue()); // hash
+ output.putInt8(algorithm.getSignatureValue()); // signature
+ }
+ }
+
+ // put certificate_authorities
+ int len = 0;
+ for (int i = 0; i < authorities.length; i++) {
len += authorities[i].length();
+ }
- output.putBytes8(types);
output.putInt16(len);
- for (int i = 0; i < authorities.length; i++)
+ for (int i = 0; i < authorities.length; i++) {
authorities[i].send(output);
+ }
}
- void print(PrintStream s) throws IOException
- {
+ @Override
+ void print(PrintStream s) throws IOException {
s.println("*** CertificateRequest");
if (debug != null && Debug.isOn("verbose")) {
@@ -1166,9 +1435,28 @@
}
s.println();
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ StringBuffer buffer = new StringBuffer();
+ boolean opened = false;
+ for (SignatureAndHashAlgorithm signAlg : algorithms) {
+ if (opened) {
+ buffer.append(", " + signAlg.getAlgorithmName());
+ } else {
+ buffer.append(signAlg.getAlgorithmName());
+ opened = true;
+ }
+ }
+ s.println("Supported Signature Algorithms: " + buffer);
+ }
+
s.println("Cert Authorities:");
- for (int i = 0; i < authorities.length; i++)
- authorities[i].print(s);
+ if (authorities.length == 0) {
+ s.println("<Empty>");
+ } else {
+ for (int i = 0; i < authorities.length; i++) {
+ authorities[i].print(s);
+ }
+ }
}
}
}
@@ -1219,18 +1507,34 @@
*/
static final class CertificateVerify extends HandshakeMessage {
- int messageType() { return ht_certificate_verify; }
+ // the signature bytes
+ private byte[] signature;
- private byte[] signature;
+ // protocol version being established using this ServerKeyExchange message
+ ProtocolVersion protocolVersion;
+
+ // the preferable signature algorithm used by this CertificateVerify message
+ private SignatureAndHashAlgorithm preferableSignatureAlgorithm = null;
/*
* Create an RSA or DSA signed certificate verify message.
*/
- CertificateVerify(ProtocolVersion protocolVersion, HandshakeHash
- handshakeHash, PrivateKey privateKey, SecretKey masterSecret,
- SecureRandom sr) throws GeneralSecurityException {
+ CertificateVerify(ProtocolVersion protocolVersion,
+ HandshakeHash handshakeHash, PrivateKey privateKey,
+ SecretKey masterSecret, SecureRandom sr,
+ SignatureAndHashAlgorithm signAlgorithm)
+ throws GeneralSecurityException {
+
+ this.protocolVersion = protocolVersion;
+
String algorithm = privateKey.getAlgorithm();
- Signature sig = getSignature(protocolVersion, algorithm);
+ Signature sig = null;
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ this.preferableSignatureAlgorithm = signAlgorithm;
+ sig = JsseJce.getSignature(signAlgorithm.getAlgorithmName());
+ } else {
+ sig = getSignature(protocolVersion, algorithm);
+ }
sig.initSign(privateKey, sr);
updateSignature(sig, protocolVersion, handshakeHash, algorithm,
masterSecret);
@@ -1240,11 +1544,41 @@
//
// Unmarshal the signed data from the input stream.
//
- CertificateVerify(HandshakeInStream input) throws IOException {
+ CertificateVerify(HandshakeInStream input,
+ Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs,
+ ProtocolVersion protocolVersion) throws IOException {
+
+ this.protocolVersion = protocolVersion;
+
+ // read the signature and hash algorithm
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ int hashAlg = input.getInt8(); // hash algorithm
+ int signAlg = input.getInt8(); // signature algorithm
+
+ preferableSignatureAlgorithm =
+ SignatureAndHashAlgorithm.valueOf(hashAlg, signAlg, 0);
+
+ // Is it a local supported signature algorithm?
+ if (!localSupportedSignAlgs.contains(
+ preferableSignatureAlgorithm)) {
+ throw new SSLHandshakeException(
+ "Unsupported SignatureAndHashAlgorithm in " +
+ "ServerKeyExchange message");
+ }
+ }
+
+ // read the signature
signature = input.getBytes16();
}
/*
+ * Get the preferable signature algorithm used by this message
+ */
+ SignatureAndHashAlgorithm getPreferableSignatureAlgorithm() {
+ return preferableSignatureAlgorithm;
+ }
+
+ /*
* Verify a certificate verify message. Return the result of verification,
* if there is a problem throw a GeneralSecurityException.
*/
@@ -1252,7 +1586,13 @@
HandshakeHash handshakeHash, PublicKey publicKey,
SecretKey masterSecret) throws GeneralSecurityException {
String algorithm = publicKey.getAlgorithm();
- Signature sig = getSignature(protocolVersion, algorithm);
+ Signature sig = null;
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ sig = JsseJce.getSignature(
+ preferableSignatureAlgorithm.getAlgorithmName());
+ } else {
+ sig = getSignature(protocolVersion, algorithm);
+ }
sig.initVerify(publicKey);
updateSignature(sig, protocolVersion, handshakeHash, algorithm,
masterSecret);
@@ -1286,25 +1626,35 @@
ProtocolVersion protocolVersion,
HandshakeHash handshakeHash, String algorithm, SecretKey masterKey)
throws SignatureException {
- MessageDigest md5Clone = handshakeHash.getMD5Clone();
- MessageDigest shaClone = handshakeHash.getSHAClone();
- boolean tls = protocolVersion.v >= ProtocolVersion.TLS10.v;
+
if (algorithm.equals("RSA")) {
- if (tls) {
- // nothing to do
- } else { // SSLv3
- updateDigest(md5Clone, MD5_pad1, MD5_pad2, masterKey);
- updateDigest(shaClone, SHA_pad1, SHA_pad2, masterKey);
+ if (protocolVersion.v < ProtocolVersion.TLS12.v) { // TLS1.1-
+ MessageDigest md5Clone = handshakeHash.getMD5Clone();
+ MessageDigest shaClone = handshakeHash.getSHAClone();
+
+ if (protocolVersion.v < ProtocolVersion.TLS10.v) { // SSLv3
+ updateDigest(md5Clone, MD5_pad1, MD5_pad2, masterKey);
+ updateDigest(shaClone, SHA_pad1, SHA_pad2, masterKey);
+ }
+
+ // The signature must be an instance of RSASignature, need
+ // to use these hashes directly.
+ RSASignature.setHashes(sig, md5Clone, shaClone);
+ } else { // TLS1.2+
+ sig.update(handshakeHash.getAllHandshakeMessages());
}
- // need to use these hashes directly
- RSASignature.setHashes(sig, md5Clone, shaClone);
} else { // DSA, ECDSA
- if (tls) {
- // nothing to do
- } else { // SSLv3
- updateDigest(shaClone, SHA_pad1, SHA_pad2, masterKey);
+ if (protocolVersion.v < ProtocolVersion.TLS12.v) { // TLS1.1-
+ MessageDigest shaClone = handshakeHash.getSHAClone();
+
+ if (protocolVersion.v < ProtocolVersion.TLS10.v) { // SSLv3
+ updateDigest(shaClone, SHA_pad1, SHA_pad2, masterKey);
+ }
+
+ sig.update(shaClone.digest());
+ } else { // TLS1.2+
+ sig.update(handshakeHash.getAllHandshakeMessages());
}
- sig.update(shaClone.digest());
}
}
@@ -1314,7 +1664,8 @@
* all preceding handshake messages.
* Used by the Finished class as well.
*/
- static void updateDigest(MessageDigest md, byte[] pad1, byte[] pad2,
+ private static void updateDigest(MessageDigest md,
+ byte[] pad1, byte[] pad2,
SecretKey masterSecret) {
// Digest the key bytes if available.
// Otherwise (sensitive key), try digesting the key directly.
@@ -1390,26 +1741,54 @@
methodCache.put(clazz, r);
}
if (r == NULL_OBJECT) {
- throw new Exception("Digest does not support implUpdate(SecretKey)");
+ throw new Exception(
+ "Digest does not support implUpdate(SecretKey)");
}
Method update = (Method)r;
update.invoke(spi, key);
} catch (Exception e) {
- throw new RuntimeException
- ("Could not obtain encoded key and MessageDigest cannot digest key", e);
+ throw new RuntimeException(
+ "Could not obtain encoded key and "
+ + "MessageDigest cannot digest key", e);
}
}
- int messageLength() {
- return 2 + signature.length;
+ @Override
+ int messageType() {
+ return ht_certificate_verify;
}
+ @Override
+ int messageLength() {
+ int temp = 2;
+
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ temp += SignatureAndHashAlgorithm.sizeInRecord();
+ }
+
+ return temp + signature.length;
+ }
+
+ @Override
void send(HandshakeOutStream s) throws IOException {
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ s.putInt8(preferableSignatureAlgorithm.getHashValue());
+ s.putInt8(preferableSignatureAlgorithm.getSignatureValue());
+ }
+
s.putBytes16(signature);
}
+ @Override
void print(PrintStream s) throws IOException {
s.println("*** CertificateVerify");
+
+ if (debug != null && Debug.isOn("verbose")) {
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ s.println("Signature Algorithm " +
+ preferableSignatureAlgorithm.getAlgorithmName());
+ }
+ }
}
}
@@ -1448,19 +1827,29 @@
private byte[] verifyData;
/*
+ * Current cipher suite we are negotiating. TLS 1.2 has
+ * ciphersuite-defined PRF algorithms.
+ */
+ private ProtocolVersion protocolVersion;
+ private CipherSuite cipherSuite;
+
+ /*
* Create a finished message to send to the remote peer.
*/
Finished(ProtocolVersion protocolVersion, HandshakeHash handshakeHash,
- int sender, SecretKey master) {
- verifyData = getFinished(protocolVersion, handshakeHash, sender,
- master);
+ int sender, SecretKey master, CipherSuite cipherSuite) {
+ this.protocolVersion = protocolVersion;
+ this.cipherSuite = cipherSuite;
+ verifyData = getFinished(handshakeHash, sender, master);
}
/*
* Constructor that reads FINISHED message from stream.
*/
- Finished(ProtocolVersion protocolVersion, HandshakeInStream input)
- throws IOException {
+ Finished(ProtocolVersion protocolVersion, HandshakeInStream input,
+ CipherSuite cipherSuite) throws IOException {
+ this.protocolVersion = protocolVersion;
+ this.cipherSuite = cipherSuite;
int msgLen = (protocolVersion.v >= ProtocolVersion.TLS10.v) ? 12 : 36;
verifyData = new byte[msgLen];
input.read(verifyData);
@@ -1472,18 +1861,16 @@
* both client and server are fully in sync, and that the handshake
* computations have been successful.
*/
- boolean verify(ProtocolVersion protocolVersion,
- HandshakeHash handshakeHash, int sender, SecretKey master) {
- byte[] myFinished = getFinished(protocolVersion, handshakeHash,
- sender, master);
+ boolean verify(HandshakeHash handshakeHash, int sender, SecretKey master) {
+ byte[] myFinished = getFinished(handshakeHash, sender, master);
return Arrays.equals(myFinished, verifyData);
}
/*
* Perform the actual finished message calculation.
*/
- private static byte[] getFinished(ProtocolVersion protocolVersion,
- HandshakeHash handshakeHash, int sender, SecretKey masterKey) {
+ private byte[] getFinished(HandshakeHash handshakeHash,
+ int sender, SecretKey masterKey) {
byte[] sslLabel;
String tlsLabel;
if (sender == CLIENT) {
@@ -1495,23 +1882,53 @@
} else {
throw new RuntimeException("Invalid sender: " + sender);
}
- MessageDigest md5Clone = handshakeHash.getMD5Clone();
- MessageDigest shaClone = handshakeHash.getSHAClone();
+
if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
- // TLS
+ // TLS 1.0+
try {
- byte[] seed = new byte[36];
- md5Clone.digest(seed, 0, 16);
- shaClone.digest(seed, 16, 20);
+ byte [] seed;
+ String prfAlg;
+ PRF prf;
+
+ // Get the KeyGenerator alg and calculate the seed.
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ // TLS 1.2
+ seed = handshakeHash.getFinishedHash();
+
+ prfAlg = "SunTls12Prf";
+ prf = cipherSuite.prfAlg;
+ } else {
+ // TLS 1.0/1.1
+ MessageDigest md5Clone = handshakeHash.getMD5Clone();
+ MessageDigest shaClone = handshakeHash.getSHAClone();
+ seed = new byte[36];
+ md5Clone.digest(seed, 0, 16);
+ shaClone.digest(seed, 16, 20);
- TlsPrfParameterSpec spec = new TlsPrfParameterSpec
- (masterKey, tlsLabel, seed, 12);
- KeyGenerator prf = JsseJce.getKeyGenerator("SunTlsPrf");
- prf.init(spec);
- SecretKey prfKey = prf.generateKey();
+ prfAlg = "SunTlsPrf";
+ prf = P_NONE;
+ }
+
+ String prfHashAlg = prf.getPRFHashAlg();
+ int prfHashLength = prf.getPRFHashLength();
+ int prfBlockSize = prf.getPRFBlockSize();
+
+ /*
+ * RFC 5246/7.4.9 says that finished messages can
+ * be ciphersuite-specific in both length/PRF hash
+ * algorithm. If we ever run across a different
+ * length, this call will need to be updated.
+ */
+ TlsPrfParameterSpec spec = new TlsPrfParameterSpec(
+ masterKey, tlsLabel, seed, 12,
+ prfHashAlg, prfHashLength, prfBlockSize);
+
+ KeyGenerator kg = JsseJce.getKeyGenerator(prfAlg);
+ kg.init(spec);
+ SecretKey prfKey = kg.generateKey();
if ("RAW".equals(prfKey.getFormat()) == false) {
- throw new ProviderException
- ("Invalid PRF output, format must be RAW");
+ throw new ProviderException(
+ "Invalid PRF output, format must be RAW");
}
byte[] finished = prfKey.getEncoded();
return finished;
@@ -1520,6 +1937,8 @@
}
} else {
// SSLv3
+ MessageDigest md5Clone = handshakeHash.getMD5Clone();
+ MessageDigest shaClone = handshakeHash.getSHAClone();
updateDigest(md5Clone, sslLabel, MD5_pad1, MD5_pad2, masterKey);
updateDigest(shaClone, sslLabel, SHA_pad1, SHA_pad2, masterKey);
byte[] finished = new byte[36];
--- a/jdk/src/share/classes/sun/security/ssl/Handshaker.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/Handshaker.java Tue Nov 02 19:40:45 2010 -0700
@@ -29,13 +29,12 @@
import java.io.*;
import java.util.*;
import java.security.*;
-import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.AccessController;
+import java.security.AlgorithmConstraints;
import java.security.AccessControlContext;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException;
-import java.security.cert.X509Certificate;
import javax.crypto.*;
import javax.crypto.spec.*;
@@ -49,6 +48,8 @@
import sun.security.ssl.HandshakeMessage.*;
import sun.security.ssl.CipherSuite.*;
+import static sun.security.ssl.CipherSuite.PRF.*;
+
/**
* Handshaker ... processes handshake records from an SSL V3.0
* data stream, handling all the details of the handshake protocol.
@@ -71,13 +72,48 @@
byte[] clientVerifyData;
byte[] serverVerifyData;
- // is it an initial negotiation or a renegotiation?
+ // Is it an initial negotiation or a renegotiation?
boolean isInitialHandshake;
- // list of enabled protocols
- ProtocolList enabledProtocols;
+ // List of enabled protocols
+ private ProtocolList enabledProtocols;
+
+ // List of enabled CipherSuites
+ private CipherSuiteList enabledCipherSuites;
+
+ // The endpoint identification protocol
+ String identificationProtocol;
+
+ // The cryptographic algorithm constraints
+ private AlgorithmConstraints algorithmConstraints = null;
+
+ // Local supported signature and algorithms
+ Collection<SignatureAndHashAlgorithm> localSupportedSignAlgs;
+
+ // Peer supported signature and algorithms
+ Collection<SignatureAndHashAlgorithm> peerSupportedSignAlgs;
+
+ /*
+
+ /*
+ * List of active protocols
+ *
+ * Active protocols is a subset of enabled protocols, and will
+ * contain only those protocols that have vaild cipher suites
+ * enabled.
+ */
+ private ProtocolList activeProtocols;
+
+ /*
+ * List of active cipher suites
+ *
+ * Active cipher suites is a subset of enabled cipher suites, and will
+ * contain only those cipher suites available for the active protocols.
+ */
+ private CipherSuiteList activeCipherSuites;
private boolean isClient;
+ private boolean needCertVerify;
SSLSocketImpl conn = null;
SSLEngineImpl engine = null;
@@ -90,13 +126,6 @@
RandomCookie clnt_random, svr_random;
SSLSessionImpl session;
- // Temporary MD5 and SHA message digests. Must always be left
- // in reset state after use.
- private MessageDigest md5Tmp, shaTmp;
-
- // list of enabled CipherSuites
- CipherSuiteList enabledCipherSuites;
-
// current CipherSuite. Never null, initially SSL_NULL_WITH_NULL_NULL
CipherSuite cipherSuite;
@@ -191,6 +220,7 @@
this.sslContext = context;
this.isClient = isClient;
+ this.needCertVerify = needCertVerify;
this.activeProtocolVersion = activeProtocolVersion;
this.isInitialHandshake = isInitialHandshake;
this.secureRenegotiation = secureRenegotiation;
@@ -200,23 +230,12 @@
invalidated = false;
setCipherSuite(CipherSuite.C_NULL);
-
- md5Tmp = JsseJce.getMD5();
- shaTmp = JsseJce.getSHA();
-
- //
- // We accumulate digests of the handshake messages so that
- // we can read/write CertificateVerify and Finished messages,
- // getting assurance against some particular active attacks.
- //
- handshakeHash = new HandshakeHash(needCertVerify);
-
setEnabledProtocols(enabledProtocols);
if (conn != null) {
- conn.getAppInputStream().r.setHandshakeHash(handshakeHash);
+ algorithmConstraints = new SSLAlgorithmConstraints(conn, true);
} else { // engine != null
- engine.inputRecord.setHandshakeHash(handshakeHash);
+ algorithmConstraints = new SSLAlgorithmConstraints(engine, true);
}
@@ -233,7 +252,7 @@
// client's cert verify, those constants are in a convenient
// order to drastically simplify state machine checking.
//
- state = -1;
+ state = -2; // initialized but not activated
}
/*
@@ -268,6 +287,14 @@
}
}
+ String getRawHostnameSE() {
+ if (conn != null) {
+ return conn.getRawHostname();
+ } else {
+ return engine.getPeerHost();
+ }
+ }
+
String getHostSE() {
if (conn != null) {
return conn.getHost();
@@ -313,14 +340,6 @@
}
}
- String getHostnameVerificationSE() {
- if (conn != null) {
- return conn.getHostnameVerification();
- } else {
- return engine.getHostnameVerification();
- }
- }
-
AccessControlContext getAccSE() {
if (conn != null) {
return conn.getAcc();
@@ -345,39 +364,139 @@
void setVersion(ProtocolVersion protocolVersion) {
this.protocolVersion = protocolVersion;
setVersionSE(protocolVersion);
+
output.r.setVersion(protocolVersion);
}
+ /**
+ * Set the enabled protocols. Called from the constructor or
+ * SSLSocketImpl/SSLEngineImpl.setEnabledProtocols() (if the
+ * handshake is not yet in progress).
+ */
+ void setEnabledProtocols(ProtocolList enabledProtocols) {
+ activeCipherSuites = null;
+ activeProtocols = null;
+
+ this.enabledProtocols = enabledProtocols;
+ }
+
+ /**
+ * Set the enabled cipher suites. Called from
+ * SSLSocketImpl/SSLEngineImpl.setEnabledCipherSuites() (if the
+ * handshake is not yet in progress).
+ */
+ void setEnabledCipherSuites(CipherSuiteList enabledCipherSuites) {
+ activeCipherSuites = null;
+ activeProtocols = null;
+ this.enabledCipherSuites = enabledCipherSuites;
+ }
+
+ /**
+ * Set the algorithm constraints. Called from the constructor or
+ * SSLSocketImpl/SSLEngineImpl.setAlgorithmConstraints() (if the
+ * handshake is not yet in progress).
+ */
+ void setAlgorithmConstraints(AlgorithmConstraints algorithmConstraints) {
+ activeCipherSuites = null;
+ activeProtocols = null;
+
+ this.algorithmConstraints =
+ new SSLAlgorithmConstraints(algorithmConstraints);
+ this.localSupportedSignAlgs = null;
+ }
+
+ Collection<SignatureAndHashAlgorithm> getLocalSupportedSignAlgs() {
+ if (localSupportedSignAlgs == null) {
+ localSupportedSignAlgs =
+ SignatureAndHashAlgorithm.getSupportedAlgorithms(
+ algorithmConstraints);
+ }
+
+ return localSupportedSignAlgs;
+ }
+
+ void setPeerSupportedSignAlgs(
+ Collection<SignatureAndHashAlgorithm> algorithms) {
+ peerSupportedSignAlgs =
+ new ArrayList<SignatureAndHashAlgorithm>(algorithms);
+ }
+
+ Collection<SignatureAndHashAlgorithm> getPeerSupportedSignAlgs() {
+ return peerSupportedSignAlgs;
+ }
+
/**
- * Set the enabled protocols. Called from the constructor or
- * SSLSocketImpl.setEnabledProtocols() (if the handshake is not yet
- * in progress).
+ * Set the identification protocol. Called from the constructor or
+ * SSLSocketImpl/SSLEngineImpl.setIdentificationProtocol() (if the
+ * handshake is not yet in progress).
+ */
+ void setIdentificationProtocol(String protocol) {
+ this.identificationProtocol = protocol;
+ }
+
+ /**
+ * Prior to handshaking, activate the handshake and initialize the version,
+ * input stream and output stream.
*/
- void setEnabledProtocols(ProtocolList enabledProtocols) {
- this.enabledProtocols = enabledProtocols;
+ void activate(ProtocolVersion helloVersion) throws IOException {
+ if (activeProtocols == null) {
+ activeProtocols = getActiveProtocols();
+ }
+
+ if (activeProtocols.collection().isEmpty() ||
+ activeProtocols.max.v == ProtocolVersion.NONE.v) {
+ throw new SSLHandshakeException("No appropriate protocol");
+ }
+
+ if (activeCipherSuites == null) {
+ activeCipherSuites = getActiveCipherSuites();
+ }
+
+ if (activeCipherSuites.collection().isEmpty()) {
+ throw new SSLHandshakeException("No appropriate cipher suite");
+ }
// temporary protocol version until the actual protocol version
// is negotiated in the Hello exchange. This affects the record
- // version we sent with the ClientHello. Using max() as the record
- // version is not really correct but some implementations fail to
- // correctly negotiate TLS otherwise.
- protocolVersion = enabledProtocols.max;
+ // version we sent with the ClientHello.
+ if (!isInitialHandshake) {
+ protocolVersion = activeProtocolVersion;
+ } else {
+ protocolVersion = activeProtocols.max;
+ }
+
+ if (helloVersion == null || helloVersion.v == ProtocolVersion.NONE.v) {
+ helloVersion = activeProtocols.helloVersion;
+ }
- ProtocolVersion helloVersion = enabledProtocols.helloVersion;
+ // We accumulate digests of the handshake messages so that
+ // we can read/write CertificateVerify and Finished messages,
+ // getting assurance against some particular active attacks.
+ Set<String> localSupportedHashAlgorithms =
+ SignatureAndHashAlgorithm.getHashAlgorithmNames(
+ getLocalSupportedSignAlgs());
+ handshakeHash = new HandshakeHash(!isClient, needCertVerify,
+ localSupportedHashAlgorithms);
+ // Generate handshake input/output stream.
input = new HandshakeInStream(handshakeHash);
-
if (conn != null) {
output = new HandshakeOutStream(protocolVersion, helloVersion,
handshakeHash, conn);
+ conn.getAppInputStream().r.setHandshakeHash(handshakeHash);
conn.getAppInputStream().r.setHelloVersion(helloVersion);
+ conn.getAppOutputStream().r.setHelloVersion(helloVersion);
} else {
output = new HandshakeOutStream(protocolVersion, helloVersion,
handshakeHash, engine);
+ engine.inputRecord.setHandshakeHash(handshakeHash);
+ engine.inputRecord.setHelloVersion(helloVersion);
engine.outputRecord.setHelloVersion(helloVersion);
}
+ // move state to activated
+ state = -1;
}
/**
@@ -392,20 +511,150 @@
/**
* Check if the given ciphersuite is enabled and available.
- * (Enabled ciphersuites are always available unless the status has
- * changed due to change in JCE providers since it was enabled).
* Does not check if the required server certificates are available.
*/
boolean isNegotiable(CipherSuite s) {
- return enabledCipherSuites.contains(s) && s.isNegotiable();
+ if (activeCipherSuites == null) {
+ activeCipherSuites = getActiveCipherSuites();
+ }
+
+ return activeCipherSuites.contains(s) && s.isNegotiable();
+ }
+
+ /**
+ * Check if the given protocol version is enabled and available.
+ */
+ boolean isNegotiable(ProtocolVersion protocolVersion) {
+ if (activeProtocols == null) {
+ activeProtocols = getActiveProtocols();
+ }
+
+ return activeProtocols.contains(protocolVersion);
+ }
+
+ /**
+ * Select a protocol version from the list. Called from
+ * ServerHandshaker to negotiate protocol version.
+ *
+ * Return the lower of the protocol version suggested in the
+ * clien hello and the highest supported by the server.
+ */
+ ProtocolVersion selectProtocolVersion(ProtocolVersion protocolVersion) {
+ if (activeProtocols == null) {
+ activeProtocols = getActiveProtocols();
+ }
+
+ return activeProtocols.selectProtocolVersion(protocolVersion);
}
/**
- * As long as handshaking has not started, we can
+ * Get the active cipher suites.
+ *
+ * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
+ * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT
+ * negotiate these cipher suites in TLS 1.1 or later mode.
+ *
+ * Therefore, when the active protocols only include TLS 1.1 or later,
+ * the client cannot request to negotiate those obsoleted cipher
+ * suites. That is, the obsoleted suites should not be included in the
+ * client hello. So we need to create a subset of the enabled cipher
+ * suites, the active cipher suites, which does not contain obsoleted
+ * cipher suites of the minimum active protocol.
+ *
+ * Return empty list instead of null if no active cipher suites.
+ */
+ CipherSuiteList getActiveCipherSuites() {
+ if (activeCipherSuites == null) {
+ if (activeProtocols == null) {
+ activeProtocols = getActiveProtocols();
+ }
+
+ ArrayList<CipherSuite> suites = new ArrayList<CipherSuite>();
+ if (!(activeProtocols.collection().isEmpty()) &&
+ activeProtocols.min.v != ProtocolVersion.NONE.v) {
+ for (CipherSuite suite : enabledCipherSuites.collection()) {
+ if (suite.obsoleted > activeProtocols.min.v &&
+ suite.supported <= activeProtocols.max.v) {
+ if (algorithmConstraints.permits(
+ EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
+ suite.name, null)) {
+ suites.add(suite);
+ }
+ } else if (debug != null && Debug.isOn("verbose")) {
+ if (suite.obsoleted <= activeProtocols.min.v) {
+ System.out.println(
+ "Ignoring obsoleted cipher suite: " + suite);
+ } else {
+ System.out.println(
+ "Ignoring unsupported cipher suite: " + suite);
+ }
+ }
+ }
+ }
+ activeCipherSuites = new CipherSuiteList(suites);
+ }
+
+ return activeCipherSuites;
+ }
+
+ /*
+ * Get the active protocol versions.
+ *
+ * In TLS 1.1, many weak or vulnerable cipher suites were obsoleted,
+ * such as TLS_RSA_EXPORT_WITH_RC4_40_MD5. The implementation MUST NOT
+ * negotiate these cipher suites in TLS 1.1 or later mode.
+ *
+ * For example, if "TLS_RSA_EXPORT_WITH_RC4_40_MD5" is the
+ * only enabled cipher suite, the client cannot request TLS 1.1 or
+ * later, even though TLS 1.1 or later is enabled. We need to create a
+ * subset of the enabled protocols, called the active protocols, which
+ * contains protocols appropriate to the list of enabled Ciphersuites.
+ *
+ * Return empty list instead of null if no active protocol versions.
+ */
+ ProtocolList getActiveProtocols() {
+ if (activeProtocols == null) {
+ ArrayList<ProtocolVersion> protocols =
+ new ArrayList<ProtocolVersion>(4);
+ for (ProtocolVersion protocol : enabledProtocols.collection()) {
+ boolean found = false;
+ for (CipherSuite suite : enabledCipherSuites.collection()) {
+ if (suite.isAvailable() && suite.obsoleted > protocol.v &&
+ suite.supported <= protocol.v) {
+ if (algorithmConstraints.permits(
+ EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
+ suite.name, null)) {
+ protocols.add(protocol);
+ found = true;
+ break;
+ } else if (debug != null && Debug.isOn("verbose")) {
+ System.out.println(
+ "Ignoring disabled cipher suite: " + suite +
+ " for " + protocol);
+ }
+ } else if (debug != null && Debug.isOn("verbose")) {
+ System.out.println(
+ "Ignoring unsupported cipher suite: " + suite +
+ " for " + protocol);
+ }
+ }
+ if (!found && (debug != null) && Debug.isOn("handshake")) {
+ System.out.println(
+ "No available cipher suite for " + protocol);
+ }
+ }
+ activeProtocols = new ProtocolList(protocols);
+ }
+
+ return activeProtocols;
+ }
+
+ /**
+ * As long as handshaking has not activated, we can
* change whether session creations are allowed.
*
* Callers should do their own checking if handshaking
- * has started.
+ * has activated.
*/
void setEnableSessionCreation(boolean newSessions) {
enableNewSession = newSessions;
@@ -419,12 +668,12 @@
CipherBox box;
if (isClient) {
box = cipher.newCipher(protocolVersion, svrWriteKey, svrWriteIV,
- false);
+ sslContext.getSecureRandom(), false);
svrWriteKey = null;
svrWriteIV = null;
} else {
box = cipher.newCipher(protocolVersion, clntWriteKey, clntWriteIV,
- false);
+ sslContext.getSecureRandom(), false);
clntWriteKey = null;
clntWriteIV = null;
}
@@ -439,12 +688,12 @@
CipherBox box;
if (isClient) {
box = cipher.newCipher(protocolVersion, clntWriteKey, clntWriteIV,
- true);
+ sslContext.getSecureRandom(), true);
clntWriteKey = null;
clntWriteIV = null;
} else {
box = cipher.newCipher(protocolVersion, svrWriteKey, svrWriteIV,
- true);
+ sslContext.getSecureRandom(), true);
svrWriteKey = null;
svrWriteIV = null;
}
@@ -502,6 +751,17 @@
}
/*
+ * Set the handshake session
+ */
+ void setHandshakeSessionSE(SSLSessionImpl handshakeSession) {
+ if (conn != null) {
+ conn.setHandshakeSession(handshakeSession);
+ } else {
+ engine.setHandshakeSession(handshakeSession);
+ }
+ }
+
+ /*
* Returns true if renegotiation is in use for this connection.
*/
boolean isSecureRenegotiation() {
@@ -614,13 +874,20 @@
/**
+ * Returns true iff the handshaker has been activated.
+ *
+ * In activated state, the handshaker may not send any messages out.
+ */
+ boolean activated() {
+ return state >= -1;
+ }
+
+ /**
* Returns true iff the handshaker has sent any messages.
- * Server kickstarting is not as neat as it should be; we
- * need to create a new handshaker, this method lets us
- * know if we should.
*/
boolean started() {
- return state >= 0;
+ return state >= 0; // 0: HandshakeMessage.ht_hello_request
+ // 1: HandshakeMessage.ht_client_hello
}
@@ -633,6 +900,7 @@
if (state >= 0) {
return;
}
+
HandshakeMessage m = getKickstartMessage();
if (debug != null && Debug.isOn("handshake")) {
@@ -746,9 +1014,6 @@
*/
private SecretKey calculateMasterSecret(SecretKey preMasterSecret,
ProtocolVersion requestedVersion) {
- TlsMasterSecretParameterSpec spec = new TlsMasterSecretParameterSpec
- (preMasterSecret, protocolVersion.major, protocolVersion.minor,
- clnt_random.random_bytes, svr_random.random_bytes);
if (debug != null && Debug.isOn("keygen")) {
HexDumpEncoder dump = new HexDumpEncoder();
@@ -762,33 +1027,70 @@
// benefit to doing it twice
}
+ // What algs/params do we need to use?
+ String masterAlg;
+ PRF prf;
+
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ masterAlg = "SunTls12MasterSecret";
+ prf = cipherSuite.prfAlg;
+ } else {
+ masterAlg = "SunTlsMasterSecret";
+ prf = P_NONE;
+ }
+
+ String prfHashAlg = prf.getPRFHashAlg();
+ int prfHashLength = prf.getPRFHashLength();
+ int prfBlockSize = prf.getPRFBlockSize();
+
+ TlsMasterSecretParameterSpec spec = new TlsMasterSecretParameterSpec(
+ preMasterSecret, protocolVersion.major, protocolVersion.minor,
+ clnt_random.random_bytes, svr_random.random_bytes,
+ prfHashAlg, prfHashLength, prfBlockSize);
+
SecretKey masterSecret;
try {
- KeyGenerator kg = JsseJce.getKeyGenerator("SunTlsMasterSecret");
+ KeyGenerator kg = JsseJce.getKeyGenerator(masterAlg);
kg.init(spec);
masterSecret = kg.generateKey();
} catch (GeneralSecurityException e) {
// For RSA premaster secrets, do not signal a protocol error
// due to the Bleichenbacher attack. See comments further down.
- if (!preMasterSecret.getAlgorithm().equals("TlsRsaPremasterSecret")) {
+ if (!preMasterSecret.getAlgorithm().equals(
+ "TlsRsaPremasterSecret")) {
throw new ProviderException(e);
}
+
if (debug != null && Debug.isOn("handshake")) {
System.out.println("RSA master secret generation error:");
e.printStackTrace(System.out);
System.out.println("Generating new random premaster secret");
}
- preMasterSecret = RSAClientKeyExchange.generateDummySecret(protocolVersion);
+
+ if (requestedVersion != null) {
+ preMasterSecret =
+ RSAClientKeyExchange.generateDummySecret(requestedVersion);
+ } else {
+ preMasterSecret =
+ RSAClientKeyExchange.generateDummySecret(protocolVersion);
+ }
+
// recursive call with new premaster secret
return calculateMasterSecret(preMasterSecret, null);
}
- // if no version check requested (client side handshake),
- // or version information is not available (not an RSA premaster secret),
+ // if no version check requested (client side handshake), or version
+ // information is not available (not an RSA premaster secret),
// return master secret immediately.
- if ((requestedVersion == null) || !(masterSecret instanceof TlsMasterSecret)) {
+ if ((requestedVersion == null) ||
+ !(masterSecret instanceof TlsMasterSecret)) {
return masterSecret;
}
+
+ // we have checked the ClientKeyExchange message when reading TLS
+ // record, the following check is necessary to ensure that
+ // JCE provider does not ignore the checking, or the previous
+ // checking process bypassed the premaster secret version checking.
TlsMasterSecret tlsKey = (TlsMasterSecret)masterSecret;
int major = tlsKey.getMajorVersion();
int minor = tlsKey.getMinorVersion();
@@ -800,13 +1102,21 @@
// the specification says that it must be the maximum version supported
// by the client from its ClientHello message. However, many
// implementations send the negotiated version, so accept both
- // NOTE that we may be comparing two unsupported version numbers in
- // the second case, which is why we cannot use object reference
- // equality in this special case
- ProtocolVersion premasterVersion = ProtocolVersion.valueOf(major, minor);
- boolean versionMismatch = (premasterVersion != protocolVersion) &&
- (premasterVersion.v != requestedVersion.v);
+ // for SSL v3.0 and TLS v1.0.
+ // NOTE that we may be comparing two unsupported version numbers, which
+ // is why we cannot use object reference equality in this special case.
+ ProtocolVersion premasterVersion =
+ ProtocolVersion.valueOf(major, minor);
+ boolean versionMismatch = (premasterVersion.v != requestedVersion.v);
+ /*
+ * we never checked the client_version in server side
+ * for TLS v1.0 and SSL v3.0. For compatibility, we
+ * maintain this behavior.
+ */
+ if (versionMismatch && requestedVersion.v <= ProtocolVersion.TLS10.v) {
+ versionMismatch = (premasterVersion.v != protocolVersion.v);
+ }
if (versionMismatch == false) {
// check passed, return key
@@ -823,7 +1133,9 @@
+ premasterVersion);
System.out.println("Generating new random premaster secret");
}
- preMasterSecret = RSAClientKeyExchange.generateDummySecret(protocolVersion);
+ preMasterSecret =
+ RSAClientKeyExchange.generateDummySecret(requestedVersion);
+
// recursive call with new premaster secret
return calculateMasterSecret(preMasterSecret, null);
}
@@ -849,24 +1161,41 @@
int hashSize = cipherSuite.macAlg.size;
boolean is_exportable = cipherSuite.exportable;
BulkCipher cipher = cipherSuite.cipher;
- int keySize = cipher.keySize;
- int ivSize = cipher.ivSize;
int expandedKeySize = is_exportable ? cipher.expandedKeySize : 0;
- TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec
- (masterKey, protocolVersion.major, protocolVersion.minor,
+ // Which algs/params do we need to use?
+ String keyMaterialAlg;
+ PRF prf;
+
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ keyMaterialAlg = "SunTls12KeyMaterial";
+ prf = cipherSuite.prfAlg;
+ } else {
+ keyMaterialAlg = "SunTlsKeyMaterial";
+ prf = P_NONE;
+ }
+
+ String prfHashAlg = prf.getPRFHashAlg();
+ int prfHashLength = prf.getPRFHashLength();
+ int prfBlockSize = prf.getPRFBlockSize();
+
+ TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec(
+ masterKey, protocolVersion.major, protocolVersion.minor,
clnt_random.random_bytes, svr_random.random_bytes,
cipher.algorithm, cipher.keySize, expandedKeySize,
- cipher.ivSize, hashSize);
+ cipher.ivSize, hashSize,
+ prfHashAlg, prfHashLength, prfBlockSize);
try {
- KeyGenerator kg = JsseJce.getKeyGenerator("SunTlsKeyMaterial");
+ KeyGenerator kg = JsseJce.getKeyGenerator(keyMaterialAlg);
kg.init(spec);
TlsKeyMaterialSpec keySpec = (TlsKeyMaterialSpec)kg.generateKey();
clntWriteKey = keySpec.getClientCipherKey();
svrWriteKey = keySpec.getServerCipherKey();
+ // Return null if IVs are not supposed to be generated.
+ // e.g. TLS 1.1+.
clntWriteIV = keySpec.getClientIv();
svrWriteIV = keySpec.getServerIv();
@@ -914,7 +1243,12 @@
System.out.println("Server write IV:");
printHex(dump, svrWriteIV.getIV());
} else {
- System.out.println("... no IV used for this cipher");
+ if (protocolVersion.v >= ProtocolVersion.TLS11.v) {
+ System.out.println(
+ "... no IV derived for this protocol");
+ } else {
+ System.out.println("... no IV used for this cipher");
+ }
}
System.out.flush();
}
--- a/jdk/src/share/classes/sun/security/ssl/HelloExtensions.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/HelloExtensions.java Tue Nov 02 19:40:45 2010 -0700
@@ -50,7 +50,8 @@
*
* . UnknownExtension: used to represent all parsed extensions that we do not
* explicitly support.
- * . ServerNameExtension: partially implemented server_name extension.
+ * . ServerNameExtension: the server_name extension.
+ * . SignatureAlgorithmsExtension: the signature_algorithms extension.
* . SupportedEllipticCurvesExtension: the ECC supported curves extension.
* . SupportedEllipticPointFormatsExtension: the ECC supported point formats
* (compressed/uncompressed) extension.
@@ -78,6 +79,8 @@
HelloExtension extension;
if (extType == ExtensionType.EXT_SERVER_NAME) {
extension = new ServerNameExtension(s, extlen);
+ } else if (extType == ExtensionType.EXT_SIGNATURE_ALGORITHMS) {
+ extension = new SignatureAlgorithmsExtension(s, extlen);
} else if (extType == ExtensionType.EXT_ELLIPTIC_CURVES) {
extension = new SupportedEllipticCurvesExtension(s, extlen);
} else if (extType == ExtensionType.EXT_EC_POINT_FORMATS) {
@@ -266,31 +269,102 @@
}
public String toString() {
- return "Unsupported extension " + type + ", data: " + Debug.toString(data);
+ return "Unsupported extension " + type + ", data: " +
+ Debug.toString(data);
}
}
/*
- * Support for the server_name extension is incomplete. Parsing is implemented
- * so that we get nicer debug output, but we neither send it nor do we do
- * act on it if we receive it.
+ * [RFC4366] To facilitate secure connections to servers that host multiple
+ * 'virtual' servers at a single underlying network address, clients MAY
+ * include an extension of type "server_name" in the (extended) client hello.
+ * The "extension_data" field of this extension SHALL contain "ServerNameList"
+ * where:
+ *
+ * struct {
+ * NameType name_type;
+ * select (name_type) {
+ * case host_name: HostName;
+ * } name;
+ * } ServerName;
+ *
+ * enum {
+ * host_name(0), (255)
+ * } NameType;
+ *
+ * opaque HostName<1..2^16-1>;
+ *
+ * struct {
+ * ServerName server_name_list<1..2^16-1>
+ * } ServerNameList;
*/
final class ServerNameExtension extends HelloExtension {
final static int NAME_HOST_NAME = 0;
private List<ServerName> names;
+ private int listLength; // ServerNameList length
+
+ ServerNameExtension(List<String> hostnames) throws IOException {
+ super(ExtensionType.EXT_SERVER_NAME);
+
+ listLength = 0;
+ names = new ArrayList<ServerName>(hostnames.size());
+ for (String hostname : hostnames) {
+ if (hostname != null && hostname.length() != 0) {
+ // we only support DNS hostname now.
+ ServerName serverName =
+ new ServerName(NAME_HOST_NAME, hostname);
+ names.add(serverName);
+ listLength += serverName.length;
+ }
+ }
+
+ // As we only support DNS hostname now, the hostname list must
+ // not contain more than one hostname
+ if (names.size() > 1) {
+ throw new SSLProtocolException(
+ "The ServerNameList MUST NOT contain more than " +
+ "one name of the same name_type");
+ }
+
+ // We only need to add "server_name" extension in ClientHello unless
+ // we support SNI in server side in the future. It is possible that
+ // the SNI is empty in ServerHello. As we don't support SNI in
+ // ServerHello now, we will throw exception for empty list for now.
+ if (listLength == 0) {
+ throw new SSLProtocolException(
+ "The ServerNameList cannot be empty");
+ }
+ }
ServerNameExtension(HandshakeInStream s, int len)
throws IOException {
super(ExtensionType.EXT_SERVER_NAME);
- names = new ArrayList<ServerName>();
- while (len > 0) {
- ServerName name = new ServerName(s);
- names.add(name);
- len -= name.length + 2;
+
+ int remains = len;
+ if (len >= 2) { // "server_name" extension in ClientHello
+ listLength = s.getInt16(); // ServerNameList length
+ if (listLength == 0 || listLength + 2 != len) {
+ throw new SSLProtocolException(
+ "Invalid " + type + " extension");
+ }
+
+ remains -= 2;
+ names = new ArrayList<ServerName>();
+ while (remains > 0) {
+ ServerName name = new ServerName(s);
+ names.add(name);
+ remains -= name.length;
+
+ // we may need to check the duplicated ServerName type
+ }
+ } else if (len == 0) { // "server_name" extension in ServerHello
+ listLength = 0;
+ names = Collections.<ServerName>emptyList();
}
- if (len != 0) {
+
+ if (remains != 0) {
throw new SSLProtocolException("Invalid server_name extension");
}
}
@@ -301,10 +375,19 @@
final byte[] data;
final String hostname;
+ ServerName(int type, String hostname) throws IOException {
+ this.type = type; // NameType
+ this.hostname = hostname;
+ this.data = hostname.getBytes("UTF8"); // HostName
+ this.length = data.length + 3; // NameType: 1 byte
+ // HostName length: 2 bytes
+ }
+
ServerName(HandshakeInStream s) throws IOException {
- length = s.getInt16(); // ServerNameList length
type = s.getInt8(); // NameType
data = s.getBytes16(); // HostName (length read in getBytes16)
+ length = data.length + 3; // NameType: 1 byte
+ // HostName length: 2 bytes
if (type == NAME_HOST_NAME) {
hostname = new String(data, "UTF8");
} else {
@@ -322,15 +405,29 @@
}
int length() {
- throw new RuntimeException("not yet supported");
+ return listLength == 0 ? 4 : 6 + listLength;
}
void send(HandshakeOutStream s) throws IOException {
- throw new RuntimeException("not yet supported");
+ s.putInt16(type.id);
+ s.putInt16(listLength + 2);
+ if (listLength != 0) {
+ s.putInt16(listLength);
+
+ for (ServerName name : names) {
+ s.putInt8(name.type); // NameType
+ s.putBytes16(name.data); // HostName
+ }
+ }
}
public String toString() {
- return "Unsupported extension " + type + ", " + names.toString();
+ StringBuffer buffer = new StringBuffer();
+ for (ServerName name : names) {
+ buffer.append("[" + name + "]");
+ }
+
+ return "Extension " + type + ", server_name: " + buffer;
}
}
@@ -523,7 +620,8 @@
final static int FMT_ANSIX962_COMPRESSED_CHAR2 = 2;
static final HelloExtension DEFAULT =
- new SupportedEllipticPointFormatsExtension(new byte[] {FMT_UNCOMPRESSED});
+ new SupportedEllipticPointFormatsExtension(
+ new byte[] {FMT_UNCOMPRESSED});
private final byte[] formats;
@@ -665,3 +763,105 @@
}
}
+
+/*
+ * [RFC5246] The client uses the "signature_algorithms" extension to
+ * indicate to the server which signature/hash algorithm pairs may be
+ * used in digital signatures. The "extension_data" field of this
+ * extension contains a "supported_signature_algorithms" value.
+ *
+ * enum {
+ * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
+ * sha512(6), (255)
+ * } HashAlgorithm;
+ *
+ * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
+ * SignatureAlgorithm;
+ *
+ * struct {
+ * HashAlgorithm hash;
+ * SignatureAlgorithm signature;
+ * } SignatureAndHashAlgorithm;
+ *
+ * SignatureAndHashAlgorithm
+ * supported_signature_algorithms<2..2^16-2>;
+ */
+final class SignatureAlgorithmsExtension extends HelloExtension {
+
+ private Collection<SignatureAndHashAlgorithm> algorithms;
+ private int algorithmsLen; // length of supported_signature_algorithms
+
+ SignatureAlgorithmsExtension(
+ Collection<SignatureAndHashAlgorithm> signAlgs) {
+
+ super(ExtensionType.EXT_SIGNATURE_ALGORITHMS);
+
+ algorithms = new ArrayList<SignatureAndHashAlgorithm>(signAlgs);
+ algorithmsLen =
+ SignatureAndHashAlgorithm.sizeInRecord() * algorithms.size();
+ }
+
+ SignatureAlgorithmsExtension(HandshakeInStream s, int len)
+ throws IOException {
+ super(ExtensionType.EXT_SIGNATURE_ALGORITHMS);
+
+ algorithmsLen = s.getInt16();
+ if (algorithmsLen == 0 || algorithmsLen + 2 != len) {
+ throw new SSLProtocolException("Invalid " + type + " extension");
+ }
+
+ algorithms = new ArrayList<SignatureAndHashAlgorithm>();
+ int remains = algorithmsLen;
+ int sequence = 0;
+ while (remains > 1) { // needs at least two bytes
+ int hash = s.getInt8(); // hash algorithm
+ int signature = s.getInt8(); // signature algorithm
+
+ SignatureAndHashAlgorithm algorithm =
+ SignatureAndHashAlgorithm.valueOf(hash, signature, ++sequence);
+ algorithms.add(algorithm);
+ remains -= 2; // one byte for hash, one byte for signature
+ }
+
+ if (remains != 0) {
+ throw new SSLProtocolException("Invalid server_name extension");
+ }
+ }
+
+ Collection<SignatureAndHashAlgorithm> getSignAlgorithms() {
+ return algorithms;
+ }
+
+ @Override
+ int length() {
+ return 6 + algorithmsLen;
+ }
+
+ @Override
+ void send(HandshakeOutStream s) throws IOException {
+ s.putInt16(type.id);
+ s.putInt16(algorithmsLen + 2);
+ s.putInt16(algorithmsLen);
+
+ for (SignatureAndHashAlgorithm algorithm : algorithms) {
+ s.putInt8(algorithm.getHashValue()); // HashAlgorithm
+ s.putInt8(algorithm.getSignatureValue()); // SignatureAlgorithm
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buffer = new StringBuffer();
+ boolean opened = false;
+ for (SignatureAndHashAlgorithm signAlg : algorithms) {
+ if (opened) {
+ buffer.append(", " + signAlg.getAlgorithmName());
+ } else {
+ buffer.append(signAlg.getAlgorithmName());
+ opened = true;
+ }
+ }
+
+ return "Extension " + type + ", signature_algorithms: " + buffer;
+ }
+}
--- a/jdk/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/KerberosClientKeyExchange.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -69,6 +69,7 @@
}
public KerberosClientKeyExchange() {
+ // empty
}
public KerberosClientKeyExchange(String serverName, boolean isLoopback,
@@ -93,14 +94,17 @@
}
}
+ @Override
int messageType() {
return ht_client_key_exchange;
}
+ @Override
public int messageLength() {
return impl.messageLength();
}
+ @Override
public void send(HandshakeOutStream s) throws IOException {
impl.send(s);
}
--- a/jdk/src/share/classes/sun/security/ssl/MAC.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/MAC.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, 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
@@ -105,6 +105,10 @@
algorithm = tls ? "HmacMD5" : "SslMacMD5";
} else if (macAlg == M_SHA) {
algorithm = tls ? "HmacSHA1" : "SslMacSHA1";
+ } else if (macAlg == M_SHA256) {
+ algorithm = "HmacSHA256"; // TLS 1.2+
+ } else if (macAlg == M_SHA384) {
+ algorithm = "HmacSHA384"; // TLS 1.2+
} else {
throw new RuntimeException("Unknown Mac " + macAlg);
}
@@ -155,6 +159,42 @@
return compute(type, bb, null, 0, bb.remaining());
}
+ /**
+ * Check whether the sequence number is close to wrap
+ *
+ * Sequence numbers are of type uint64 and may not exceed 2^64-1.
+ * Sequence numbers do not wrap. When the sequence number is near
+ * to wrap, we need to close the connection immediately.
+ */
+ final boolean seqNumOverflow() {
+ /*
+ * Conservatively, we don't allow more records to be generated
+ * when there are only 2^8 sequence numbers left.
+ */
+ return (block != null && mac != null &&
+ block[0] == 0xFF && block[1] == 0xFF &&
+ block[2] == 0xFF && block[3] == 0xFF &&
+ block[4] == 0xFF && block[5] == 0xFF &&
+ block[6] == 0xFF);
+ }
+
+ /*
+ * Check whether to renew the sequence number
+ *
+ * Sequence numbers are of type uint64 and may not exceed 2^64-1.
+ * Sequence numbers do not wrap. If a TLS
+ * implementation would need to wrap a sequence number, it must
+ * renegotiate instead.
+ */
+ final boolean seqNumIsHuge() {
+ /*
+ * Conservatively, we should ask for renegotiation when there are
+ * only 2^48 sequence numbers left.
+ */
+ return (block != null && mac != null &&
+ block[0] == 0xFF && block[1] == 0xFF);
+ }
+
// increment the sequence number in the block array
// it is a 64-bit number stored in big-endian format
private void incrementSequenceNumber() {
@@ -168,7 +208,8 @@
* Compute based on either buffer type, either bb.position/limit
* or buf/offset/len.
*/
- private byte[] compute(byte type, ByteBuffer bb, byte[] buf, int offset, int len) {
+ private byte[] compute(byte type, ByteBuffer bb, byte[] buf,
+ int offset, int len) {
if (macSize == 0) {
return nullMAC;
--- a/jdk/src/share/classes/sun/security/ssl/ProtocolList.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/ProtocolList.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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
@@ -38,8 +38,12 @@
final class ProtocolList {
private static final ProtocolList SUPPORTED;
+ private static final ProtocolList CLIENT_DEFAULT;
+ private static final ProtocolList SERVER_DEFAULT;
- private final Collection<ProtocolVersion> protocols;
+ // the sorted protocol version list
+ private final ArrayList<ProtocolVersion> protocols;
+
private String[] protocolNames;
// the minimum and maximum ProtocolVersions in this list
@@ -49,30 +53,45 @@
final ProtocolVersion helloVersion;
ProtocolList(String[] names) {
+ this(convert(names));
+ }
+
+ ProtocolList(ArrayList<ProtocolVersion> versions) {
+ this.protocols = versions;
+
+ if ((protocols.size() == 1) &&
+ protocols.contains(ProtocolVersion.SSL20Hello)) {
+ throw new IllegalArgumentException("SSLv2Hello cannot be " +
+ "enabled unless at least one other supported version " +
+ "is also enabled.");
+ }
+
+ if (protocols.size() != 0) {
+ Collections.sort(protocols);
+ min = protocols.get(0);
+ max = protocols.get(protocols.size() - 1);
+ helloVersion = protocols.get(0);
+ } else {
+ min = ProtocolVersion.NONE;
+ max = ProtocolVersion.NONE;
+ helloVersion = ProtocolVersion.NONE;
+ }
+ }
+
+ private static ArrayList<ProtocolVersion> convert(String[] names) {
if (names == null) {
throw new IllegalArgumentException("Protocols may not be null");
}
- protocols = new ArrayList<ProtocolVersion>(3);
+
+ ArrayList<ProtocolVersion> versions = new ArrayList<ProtocolVersion>(3);
for (int i = 0; i < names.length; i++ ) {
ProtocolVersion version = ProtocolVersion.valueOf(names[i]);
- if (protocols.contains(version) == false) {
- protocols.add(version);
+ if (versions.contains(version) == false) {
+ versions.add(version);
}
}
- if ((protocols.size() == 1)
- && protocols.contains(ProtocolVersion.SSL20Hello)) {
- throw new IllegalArgumentException("SSLv2Hello" +
- "cannot be enabled unless TLSv1 or SSLv3 is also enabled");
- }
- min = contains(ProtocolVersion.SSL30) ? ProtocolVersion.SSL30
- : ProtocolVersion.TLS10;
- max = contains(ProtocolVersion.TLS10) ? ProtocolVersion.TLS10
- : ProtocolVersion.SSL30;
- if (protocols.contains(ProtocolVersion.SSL20Hello)) {
- helloVersion = ProtocolVersion.SSL20Hello;
- } else {
- helloVersion = min;
- }
+
+ return versions;
}
/**
@@ -88,6 +107,37 @@
}
/**
+ * Return a reference to the internal Collection of CipherSuites.
+ * The Collection MUST NOT be modified.
+ */
+ Collection<ProtocolVersion> collection() {
+ return protocols;
+ }
+
+ /**
+ * Select a protocol version from the list.
+ *
+ * Return the lower of the protocol version of that suggested by
+ * the <code>protocolVersion</code> and the highest version of this
+ * protocol list, or null if no protocol version is available.
+ *
+ * The method is used by TLS server to negotiated the protocol
+ * version between client suggested protocol version in the
+ * client hello and protocol versions supported by the server.
+ */
+ ProtocolVersion selectProtocolVersion(ProtocolVersion protocolVersion) {
+ ProtocolVersion selectedVersion = null;
+ for (ProtocolVersion pv : protocols) {
+ if (pv.v > protocolVersion.v) {
+ break; // Safe to break here as this.protocols is sorted
+ }
+ selectedVersion = pv;
+ }
+
+ return selectedVersion;
+ }
+
+ /**
* Return an array with the names of the ProtocolVersions in this list.
*/
synchronized String[] toStringArray() {
@@ -106,11 +156,18 @@
}
/**
- * Return the list of default enabled protocols. Currently, this
- * is identical to the supported protocols.
+ * Return the list of default enabled protocols.
*/
- static ProtocolList getDefault() {
- return SUPPORTED;
+ static ProtocolList getDefault(boolean isServer) {
+ return isServer ? SERVER_DEFAULT : CLIENT_DEFAULT;
+ }
+
+ /**
+ * Return whether a protocol list is the original default enabled
+ * protocols. See: SSLSocket/SSLEngine.setEnabledProtocols()
+ */
+ static boolean isDefaultProtocolList(ProtocolList protocols) {
+ return protocols == CLIENT_DEFAULT || protocols == SERVER_DEFAULT;
}
/**
@@ -123,6 +180,13 @@
static {
if (SunJSSE.isFIPS()) {
SUPPORTED = new ProtocolList(new String[] {
+ ProtocolVersion.TLS10.name,
+ ProtocolVersion.TLS11.name,
+ ProtocolVersion.TLS12.name
+ });
+
+ SERVER_DEFAULT = SUPPORTED;
+ CLIENT_DEFAULT = new ProtocolList(new String[] {
ProtocolVersion.TLS10.name
});
} else {
@@ -130,6 +194,24 @@
ProtocolVersion.SSL20Hello.name,
ProtocolVersion.SSL30.name,
ProtocolVersion.TLS10.name,
+ ProtocolVersion.TLS11.name,
+ ProtocolVersion.TLS12.name
+ });
+
+ SERVER_DEFAULT = SUPPORTED;
+
+ /*
+ * RFC 5246 says that sending SSLv2 backward-compatible
+ * hello SHOULD NOT be done any longer.
+ *
+ * We are not enabling TLS 1.1/1.2 by default yet on clients
+ * out of concern for interop with existing
+ * SSLv3/TLS1.0-only servers. When these versions of TLS
+ * gain more traction, we'll enable them.
+ */
+ CLIENT_DEFAULT = new ProtocolList(new String[] {
+ ProtocolVersion.SSL30.name,
+ ProtocolVersion.TLS10.name
});
}
}
--- a/jdk/src/share/classes/sun/security/ssl/ProtocolVersion.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/ProtocolVersion.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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
@@ -45,9 +45,15 @@
* @author Andreas Sterbenz
* @since 1.4.1
*/
-public final class ProtocolVersion {
+public final class ProtocolVersion implements Comparable<ProtocolVersion> {
+
+ // The limit of maximum protocol version
+ final static int LIMIT_MAX_VALUE = 0xFFFF;
- // dummy protocol version value for invalid SSLSession
+ // The limit of minimum protocol version
+ final static int LIMIT_MIN_VALUE = 0x0000;
+
+ // Dummy protocol version value for invalid SSLSession
final static ProtocolVersion NONE = new ProtocolVersion(-1, "NONE");
// If enabled, send/ accept SSLv2 hello messages
@@ -61,22 +67,24 @@
final static ProtocolVersion TLS10 = new ProtocolVersion(0x0301, "TLSv1");
// TLS 1.1
- // not supported yet, but added for better readability of the debug trace
final static ProtocolVersion TLS11 = new ProtocolVersion(0x0302, "TLSv1.1");
+ // TLS 1.2
+ final static ProtocolVersion TLS12 = new ProtocolVersion(0x0303, "TLSv1.2");
+
private static final boolean FIPS = SunJSSE.isFIPS();
// minimum version we implement (SSL 3.0)
final static ProtocolVersion MIN = FIPS ? TLS10 : SSL30;
- // maximum version we implement (TLS 1.0)
- final static ProtocolVersion MAX = TLS10;
+ // maximum version we implement (TLS 1.2)
+ final static ProtocolVersion MAX = TLS12;
// ProtocolVersion to use by default (TLS 1.0)
final static ProtocolVersion DEFAULT = TLS10;
// Default version for hello messages (SSLv2Hello)
- final static ProtocolVersion DEFAULT_HELLO = FIPS ? TLS10 : SSL20Hello;
+ final static ProtocolVersion DEFAULT_HELLO = FIPS ? TLS10 : SSL30;
// version in 16 bit MSB format as it appears in records and
// messages, i.e. 0x0301 for TLS 1.0
@@ -104,6 +112,8 @@
return TLS10;
} else if (v == TLS11.v) {
return TLS11;
+ } else if (v == TLS12.v) {
+ return TLS12;
} else if (v == SSL20Hello.v) {
return SSL20Hello;
} else {
@@ -134,18 +144,20 @@
if (name == null) {
throw new IllegalArgumentException("Protocol cannot be null");
}
- if (FIPS) {
- if (name.equals(TLS10.name)) {
- return TLS10;
- } else {
- throw new IllegalArgumentException
- ("Only TLS 1.0 allowed in FIPS mode");
- }
+
+ if (FIPS && (name.equals(SSL30.name) || name.equals(SSL20Hello.name))) {
+ throw new IllegalArgumentException
+ ("Only TLS 1.0 or later allowed in FIPS mode");
}
+
if (name.equals(SSL30.name)) {
return SSL30;
} else if (name.equals(TLS10.name)) {
return TLS10;
+ } else if (name.equals(TLS11.name)) {
+ return TLS11;
+ } else if (name.equals(TLS12.name)) {
+ return TLS12;
} else if (name.equals(SSL20Hello.name)) {
return SSL20Hello;
} else {
@@ -157,4 +169,10 @@
return name;
}
+ /**
+ * Compares this object with the specified object for order.
+ */
+ public int compareTo(ProtocolVersion protocolVersion) {
+ return this.v - protocolVersion.v;
+ }
}
--- a/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, 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
@@ -55,20 +55,17 @@
* requested in its client hello version). However, we (and other
* implementations) used to send the active negotiated version. The
* system property below allows to toggle the behavior.
- *
- * Default is "false" (old behavior) for compatibility reasons. This
- * will be changed in the future.
*/
private final static String PROP_NAME =
"com.sun.net.ssl.rsaPreMasterSecretFix";
+ /*
+ * Default is "false" (old behavior) for compatibility reasons in
+ * SSLv3/TLSv1. Later protocols (TLSv1.1+) do not use this property.
+ */
private final static boolean rsaPreMasterSecretFix =
Debug.getBooleanProperty(PROP_NAME, false);
- int messageType() {
- return ht_client_key_exchange;
- }
-
/*
* The following field values were encrypted with the server's public
* key (or temp key from server key exchange msg) and are presented
@@ -78,14 +75,14 @@
SecretKey preMaster;
private byte[] encrypted; // same size as public modulus
-
/*
* Client randomly creates a pre-master secret and encrypts it
* using the server's RSA public key; only the server can decrypt
* it, using its RSA private key. Result is the same size as the
* server's public key, and uses PKCS #1 block format 02.
*/
- RSAClientKeyExchange(ProtocolVersion protocolVersion, ProtocolVersion maxVersion,
+ RSAClientKeyExchange(ProtocolVersion protocolVersion,
+ ProtocolVersion maxVersion,
SecureRandom generator, PublicKey publicKey) throws IOException {
if (publicKey.getAlgorithm().equals("RSA") == false) {
throw new SSLKeyException("Public key not of type RSA");
@@ -94,7 +91,7 @@
int major, minor;
- if (rsaPreMasterSecretFix) {
+ if (rsaPreMasterSecretFix || maxVersion.v >= ProtocolVersion.TLS11.v) {
major = maxVersion.major;
minor = maxVersion.minor;
} else {
@@ -103,7 +100,9 @@
}
try {
- KeyGenerator kg = JsseJce.getKeyGenerator("SunTlsRsaPremasterSecret");
+ String s = ((protocolVersion.v >= ProtocolVersion.TLS12.v) ?
+ "SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret");
+ KeyGenerator kg = JsseJce.getKeyGenerator(s);
kg.init(new TlsRsaPremasterSecretParameterSpec(major, minor));
preMaster = kg.generateKey();
@@ -120,14 +119,15 @@
* Server gets the PKCS #1 (block format 02) data, decrypts
* it with its private key.
*/
- RSAClientKeyExchange(ProtocolVersion currentVersion, HandshakeInStream input,
+ RSAClientKeyExchange(ProtocolVersion currentVersion,
+ ProtocolVersion maxVersion,
+ SecureRandom generator, HandshakeInStream input,
int messageSize, PrivateKey privateKey) throws IOException {
if (privateKey.getAlgorithm().equals("RSA") == false) {
throw new SSLKeyException("Private key not of type RSA");
}
- this.protocolVersion = currentVersion;
if (currentVersion.v >= ProtocolVersion.TLS10.v) {
encrypted = input.getBytes16();
} else {
@@ -143,31 +143,109 @@
cipher.init(Cipher.UNWRAP_MODE, privateKey);
preMaster = (SecretKey)cipher.unwrap(encrypted,
"TlsRsaPremasterSecret", Cipher.SECRET_KEY);
+
+ // polish the premaster secret
+ preMaster = polishPreMasterSecretKey(currentVersion, maxVersion,
+ generator, preMaster, null);
} catch (Exception e) {
- /*
- * Bogus decrypted ClientKeyExchange? If so, conjure a
- * a random preMaster secret that will fail later during
- * Finished message processing. This is a countermeasure against
- * the "interactive RSA PKCS#1 encryption envelop attack" reported
- * in June 1998. Preserving the executation path will
- * mitigate timing attacks and force consistent error handling
- * that will prevent an attacking client from differentiating
- * different kinds of decrypted ClientKeyExchange bogosities.
- */
- if (debug != null && Debug.isOn("handshake")) {
+ // polish the premaster secret
+ preMaster =
+ polishPreMasterSecretKey(currentVersion, maxVersion,
+ generator, null, e);
+ }
+ }
+
+ /**
+ * To avoid vulnerabilities described by section 7.4.7.1, RFC 5246,
+ * treating incorrectly formatted message blocks and/or mismatched
+ * version numbers in a manner indistinguishable from correctly
+ * formatted RSA blocks.
+ *
+ * RFC 5246 describes the approach as :
+ *
+ * 1. Generate a string R of 46 random bytes
+ *
+ * 2. Decrypt the message to recover the plaintext M
+ *
+ * 3. If the PKCS#1 padding is not correct, or the length of message
+ * M is not exactly 48 bytes:
+ * pre_master_secret = ClientHello.client_version || R
+ * else If ClientHello.client_version <= TLS 1.0, and version
+ * number check is explicitly disabled:
+ * pre_master_secret = M
+ * else:
+ * pre_master_secret = ClientHello.client_version || M[2..47]
+ */
+ private SecretKey polishPreMasterSecretKey(ProtocolVersion currentVersion,
+ ProtocolVersion clientHelloVersion, SecureRandom generator,
+ SecretKey secretKey, Exception failoverException) {
+
+ this.protocolVersion = clientHelloVersion;
+
+ if (failoverException == null && secretKey != null) {
+ // check the length
+ byte[] encoded = secretKey.getEncoded();
+ if (encoded == null) { // unable to get the encoded key
+ if (debug != null && Debug.isOn("handshake")) {
+ System.out.println(
+ "unable to get the plaintext of the premaster secret");
+ }
+
+ // We are not always able to get the encoded key of the
+ // premaster secret. Pass the cheking to master secret
+ // calculation.
+ return secretKey;
+ } else if (encoded.length == 48) {
+ // check the version
+ if (clientHelloVersion.major == encoded[0] &&
+ clientHelloVersion.minor == encoded[1]) {
+ return secretKey;
+ } else if (clientHelloVersion.v <= ProtocolVersion.TLS10.v) {
+ /*
+ * we never checked the client_version in server side
+ * for TLS v1.0 and SSL v3.0. For compatibility, we
+ * maintain this behavior.
+ */
+ if (currentVersion.major == encoded[0] &&
+ currentVersion.minor == encoded[1]) {
+ this.protocolVersion = currentVersion;
+ return secretKey;
+ }
+ }
+
+ if (debug != null && Debug.isOn("handshake")) {
+ System.out.println("Mismatching Protocol Versions, " +
+ "ClientHello.client_version is " + clientHelloVersion +
+ ", while PreMasterSecret.client_version is " +
+ ProtocolVersion.valueOf(encoded[0], encoded[1]));
+ }
+ } else {
+ if (debug != null && Debug.isOn("handshake")) {
+ System.out.println(
+ "incorrect length of premaster secret: " +
+ encoded.length);
+ }
+ }
+ }
+
+ if (debug != null && Debug.isOn("handshake")) {
+ if (failoverException != null) {
System.out.println("Error decrypting premaster secret:");
- e.printStackTrace(System.out);
- System.out.println("Generating random secret");
+ failoverException.printStackTrace(System.out);
}
- preMaster = generateDummySecret(currentVersion);
+
+ System.out.println("Generating random secret");
}
+
+ return generateDummySecret(clientHelloVersion);
}
// generate a premaster secret with the specified version number
static SecretKey generateDummySecret(ProtocolVersion version) {
try {
- KeyGenerator kg =
- JsseJce.getKeyGenerator("SunTlsRsaPremasterSecret");
+ String s = ((version.v >= ProtocolVersion.TLS12.v) ?
+ "SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret");
+ KeyGenerator kg = JsseJce.getKeyGenerator(s);
kg.init(new TlsRsaPremasterSecretParameterSpec
(version.major, version.minor));
return kg.generateKey();
@@ -176,6 +254,12 @@
}
}
+ @Override
+ int messageType() {
+ return ht_client_key_exchange;
+ }
+
+ @Override
int messageLength() {
if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
return encrypted.length + 2;
@@ -184,6 +268,7 @@
}
}
+ @Override
void send(HandshakeOutStream s) throws IOException {
if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
s.putBytes16(encrypted);
@@ -192,7 +277,9 @@
}
}
+ @Override
void print(PrintStream s) throws IOException {
- s.println("*** ClientKeyExchange, RSA PreMasterSecret, " + protocolVersion);
+ s.println("*** ClientKeyExchange, RSA PreMasterSecret, " +
+ protocolVersion);
}
}
--- a/jdk/src/share/classes/sun/security/ssl/Record.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/Record.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, 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
@@ -47,11 +47,12 @@
static final byte ct_handshake = 22;
static final byte ct_application_data = 23;
- static final int headerSize = 5; // SSLv3 record header
- static final int maxExpansion = 1024; // for bad compression
- static final int trailerSize = 20; // SHA1 hash size
- static final int maxDataSize = 16384; // 2^14 bytes of data
- static final int maxPadding = 256; // block cipher padding
+ static final int headerSize = 5; // SSLv3 record header
+ static final int maxExpansion = 1024; // for bad compression
+ static final int trailerSize = 20; // SHA1 hash size
+ static final int maxDataSize = 16384; // 2^14 bytes of data
+ static final int maxPadding = 256; // block cipher padding
+ static final int maxIVLength = 256; // block length
/*
* SSL has a maximum record size. It's header, (compressed) data,
@@ -59,8 +60,9 @@
* Some compression algorithms have rare cases where they expand the data.
* As we don't support compression at this time, leave that out.
*/
- static final int maxRecordSize =
+ static final int maxRecordSize =
headerSize // header
+ + maxIVLength // iv
+ maxDataSize // data
+ maxPadding // padding
+ trailerSize; // MAC
@@ -74,7 +76,7 @@
* The maximum large record size is defined as maxRecordSize plus 2^14,
* this is the amount OpenSSL is using.
*/
- static final int maxLargeRecordSize =
+ static final int maxLargeRecordSize =
maxRecordSize // Max size with a conforming implemenation
+ maxDataSize; // extra 2^14 bytes for large data packets.
@@ -84,7 +86,11 @@
* They only contain 2 and 1 bytes of data, respectively.
* Allocate a smaller array.
*/
- static final int maxAlertRecordSize =
- headerSize + 2 + maxPadding + trailerSize;
+ static final int maxAlertRecordSize =
+ headerSize // header
+ + maxIVLength // iv
+ + 2 // alert
+ + maxPadding // padding
+ + trailerSize; // MAC
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/ssl/SSLAlgorithmConstraints.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,469 @@
+/*
+ * Copyright (c) 2010, 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.ssl;
+
+import java.security.AlgorithmConstraints;
+import java.security.CryptoPrimitive;
+import java.security.AlgorithmParameters;
+
+import javax.net.ssl.*;
+
+import java.security.Key;
+
+import java.util.Set;
+import java.util.HashSet;
+
+import sun.security.util.DisabledAlgorithmConstraints;
+import sun.security.ssl.CipherSuite.*;
+
+/**
+ * Algorithm constraints for disabled algorithms property
+ *
+ * See the "jdk.certpath.disabledAlgorithms" specification in java.security
+ * for the syntax of the disabled algorithm string.
+ */
+final class SSLAlgorithmConstraints implements AlgorithmConstraints {
+ private final static AlgorithmConstraints tlsDisabledAlgConstraints =
+ new TLSDisabledAlgConstraints();
+ private final static AlgorithmConstraints x509DisabledAlgConstraints =
+ new X509DisabledAlgConstraints();
+ private AlgorithmConstraints userAlgConstraints = null;
+ private AlgorithmConstraints peerAlgConstraints = null;
+
+ private boolean enabledX509DisabledAlgConstraints = true;
+
+ SSLAlgorithmConstraints(AlgorithmConstraints algorithmConstraints) {
+ userAlgConstraints = algorithmConstraints;
+ }
+
+ SSLAlgorithmConstraints(SSLSocket socket,
+ boolean withDefaultCertPathConstraints) {
+ if (socket != null) {
+ userAlgConstraints =
+ socket.getSSLParameters().getAlgorithmConstraints();
+ }
+
+ if (!withDefaultCertPathConstraints) {
+ enabledX509DisabledAlgConstraints = false;
+ }
+ }
+
+ SSLAlgorithmConstraints(SSLEngine engine,
+ boolean withDefaultCertPathConstraints) {
+ if (engine != null) {
+ userAlgConstraints =
+ engine.getSSLParameters().getAlgorithmConstraints();
+ }
+
+ if (!withDefaultCertPathConstraints) {
+ enabledX509DisabledAlgConstraints = false;
+ }
+ }
+
+ SSLAlgorithmConstraints(SSLSocket socket, String[] supportedAlgorithms,
+ boolean withDefaultCertPathConstraints) {
+ if (socket != null) {
+ userAlgConstraints =
+ socket.getSSLParameters().getAlgorithmConstraints();
+ peerAlgConstraints =
+ new SupportedSignatureAlgorithmConstraints(supportedAlgorithms);
+ }
+
+ if (!withDefaultCertPathConstraints) {
+ enabledX509DisabledAlgConstraints = false;
+ }
+ }
+
+ SSLAlgorithmConstraints(SSLEngine engine, String[] supportedAlgorithms,
+ boolean withDefaultCertPathConstraints) {
+ if (engine != null) {
+ userAlgConstraints =
+ engine.getSSLParameters().getAlgorithmConstraints();
+ peerAlgConstraints =
+ new SupportedSignatureAlgorithmConstraints(supportedAlgorithms);
+ }
+
+ if (!withDefaultCertPathConstraints) {
+ enabledX509DisabledAlgConstraints = false;
+ }
+ }
+
+ public boolean permits(Set<CryptoPrimitive> primitives,
+ String algorithm, AlgorithmParameters parameters) {
+
+ boolean permitted = true;
+
+ if (peerAlgConstraints != null) {
+ permitted = peerAlgConstraints.permits(
+ primitives, algorithm, parameters);
+ }
+
+ if (permitted && userAlgConstraints != null) {
+ permitted = userAlgConstraints.permits(
+ primitives, algorithm, parameters);
+ }
+
+ if (permitted) {
+ permitted = tlsDisabledAlgConstraints.permits(
+ primitives, algorithm, parameters);
+ }
+
+ if (permitted && enabledX509DisabledAlgConstraints) {
+ permitted = x509DisabledAlgConstraints.permits(
+ primitives, algorithm, parameters);
+ }
+
+ return permitted;
+ }
+
+ public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
+
+ boolean permitted = true;
+
+ if (peerAlgConstraints != null) {
+ permitted = peerAlgConstraints.permits(primitives, key);
+ }
+
+ if (permitted && userAlgConstraints != null) {
+ permitted = userAlgConstraints.permits(primitives, key);
+ }
+
+ if (permitted) {
+ permitted = tlsDisabledAlgConstraints.permits(primitives, key);
+ }
+
+ if (permitted && enabledX509DisabledAlgConstraints) {
+ permitted = x509DisabledAlgConstraints.permits(primitives, key);
+ }
+
+ return permitted;
+ }
+
+ public boolean permits(Set<CryptoPrimitive> primitives,
+ String algorithm, Key key, AlgorithmParameters parameters) {
+
+ boolean permitted = true;
+
+ if (peerAlgConstraints != null) {
+ permitted = peerAlgConstraints.permits(
+ primitives, algorithm, key, parameters);
+ }
+
+ if (permitted && userAlgConstraints != null) {
+ permitted = userAlgConstraints.permits(
+ primitives, algorithm, key, parameters);
+ }
+
+ if (permitted) {
+ permitted = tlsDisabledAlgConstraints.permits(
+ primitives, algorithm, key, parameters);
+ }
+
+ if (permitted && enabledX509DisabledAlgConstraints) {
+ permitted = x509DisabledAlgConstraints.permits(
+ primitives, algorithm, key, parameters);
+ }
+
+ return permitted;
+ }
+
+
+ static private class SupportedSignatureAlgorithmConstraints
+ implements AlgorithmConstraints {
+ // supported signature algorithms
+ private String[] supportedAlgorithms;
+
+ SupportedSignatureAlgorithmConstraints(String[] supportedAlgorithms) {
+ if (supportedAlgorithms != null) {
+ this.supportedAlgorithms = supportedAlgorithms.clone();
+ } else {
+ this.supportedAlgorithms = null;
+ }
+ }
+
+ public boolean permits(Set<CryptoPrimitive> primitives,
+ String algorithm, AlgorithmParameters parameters) {
+
+ if (algorithm == null || algorithm.length() == 0) {
+ throw new IllegalArgumentException(
+ "No algorithm name specified");
+ }
+
+ if (primitives == null || primitives.isEmpty()) {
+ throw new IllegalArgumentException(
+ "No cryptographic primitive specified");
+ }
+
+ if (supportedAlgorithms == null ||
+ supportedAlgorithms.length == 0) {
+ return false;
+ }
+
+ // trim the MGF part: <digest>with<encryption>and<mgf>
+ int position = algorithm.indexOf("and");
+ if (position > 0) {
+ algorithm = algorithm.substring(0, position);
+ }
+
+ for (String supportedAlgorithm : supportedAlgorithms) {
+ if (algorithm.equalsIgnoreCase(supportedAlgorithm)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ final public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
+ return true;
+ }
+
+ final public boolean permits(Set<CryptoPrimitive> primitives,
+ String algorithm, Key key, AlgorithmParameters parameters) {
+
+ if (algorithm == null || algorithm.length() == 0) {
+ throw new IllegalArgumentException(
+ "No algorithm name specified");
+ }
+
+ return permits(primitives, algorithm, parameters);
+ }
+ }
+
+ static private class BasicDisabledAlgConstraints
+ extends DisabledAlgorithmConstraints {
+ BasicDisabledAlgConstraints(String propertyName) {
+ super(propertyName);
+ }
+
+ protected Set<String> decomposes(KeyExchange keyExchange,
+ boolean forCertPathOnly) {
+ Set<String> components = new HashSet<String>();
+ switch (keyExchange) {
+ case K_NULL:
+ if (!forCertPathOnly) {
+ components.add("NULL");
+ }
+ break;
+ case K_RSA:
+ components.add("RSA");
+ break;
+ case K_RSA_EXPORT:
+ components.add("RSA");
+ components.add("RSA_EXPORT");
+ break;
+ case K_DH_RSA:
+ components.add("RSA");
+ components.add("DH");
+ components.add("DiffieHellman");
+ components.add("DH_RSA");
+ break;
+ case K_DH_DSS:
+ components.add("DSA");
+ components.add("DSS");
+ components.add("DH");
+ components.add("DiffieHellman");
+ components.add("DH_DSS");
+ break;
+ case K_DHE_DSS:
+ components.add("DSA");
+ components.add("DSS");
+ components.add("DH");
+ components.add("DHE");
+ components.add("DiffieHellman");
+ components.add("DHE_DSS");
+ break;
+ case K_DHE_RSA:
+ components.add("RSA");
+ components.add("DH");
+ components.add("DHE");
+ components.add("DiffieHellman");
+ components.add("DHE_RSA");
+ break;
+ case K_DH_ANON:
+ if (!forCertPathOnly) {
+ components.add("ANON");
+ components.add("DH");
+ components.add("DiffieHellman");
+ components.add("DH_ANON");
+ }
+ break;
+ case K_ECDH_ECDSA:
+ components.add("ECDH");
+ components.add("ECDSA");
+ components.add("ECDH_ECDSA");
+ break;
+ case K_ECDH_RSA:
+ components.add("ECDH");
+ components.add("RSA");
+ components.add("ECDH_RSA");
+ break;
+ case K_ECDHE_ECDSA:
+ components.add("ECDHE");
+ components.add("ECDSA");
+ components.add("ECDHE_ECDSA");
+ break;
+ case K_ECDHE_RSA:
+ components.add("ECDHE");
+ components.add("RSA");
+ components.add("ECDHE_RSA");
+ break;
+ case K_ECDH_ANON:
+ if (!forCertPathOnly) {
+ components.add("ECDH");
+ components.add("ANON");
+ components.add("ECDH_ANON");
+ }
+ break;
+ case K_KRB5:
+ if (!forCertPathOnly) {
+ components.add("KRB5");
+ }
+ break;
+ case K_KRB5_EXPORT:
+ if (!forCertPathOnly) {
+ components.add("KRB5_EXPORT");
+ }
+ break;
+ default:
+ // ignore
+ }
+
+ return components;
+ }
+
+ protected Set<String> decomposes(BulkCipher bulkCipher) {
+ Set<String> components = new HashSet<String>();
+
+ if (bulkCipher.transformation != null) {
+ components.addAll(super.decomposes(bulkCipher.transformation));
+ }
+
+ return components;
+ }
+
+ protected Set<String> decomposes(MacAlg macAlg) {
+ Set<String> components = new HashSet<String>();
+
+ if (macAlg == CipherSuite.M_MD5) {
+ components.add("MD5");
+ components.add("HmacMD5");
+ } else if (macAlg == CipherSuite.M_SHA) {
+ components.add("SHA1");
+ components.add("SHA-1");
+ components.add("HmacSHA1");
+ } else if (macAlg == CipherSuite.M_SHA256) {
+ components.add("SHA256");
+ components.add("SHA-256");
+ components.add("HmacSHA256");
+ } else if (macAlg == CipherSuite.M_SHA384) {
+ components.add("SHA384");
+ components.add("SHA-384");
+ components.add("HmacSHA384");
+ }
+
+ return components;
+ }
+ }
+
+ static private class TLSDisabledAlgConstraints
+ extends BasicDisabledAlgConstraints {
+
+ TLSDisabledAlgConstraints() {
+ super(DisabledAlgorithmConstraints.PROPERTY_TLS_DISABLED_ALGS);
+ }
+
+ @Override
+ protected Set<String> decomposes(String algorithm) {
+ if (algorithm.startsWith("SSL_") || algorithm.startsWith("TLS_")) {
+ CipherSuite cipherSuite = null;
+ try {
+ cipherSuite = CipherSuite.valueOf(algorithm);
+ } catch (IllegalArgumentException iae) {
+ // ignore: unknown or unsupported ciphersuite
+ }
+
+ if (cipherSuite != null) {
+ Set<String> components = new HashSet<String>();
+
+ if(cipherSuite.keyExchange != null) {
+ components.addAll(
+ decomposes(cipherSuite.keyExchange, false));
+ }
+
+ if (cipherSuite.cipher != null) {
+ components.addAll(decomposes(cipherSuite.cipher));
+ }
+
+ if (cipherSuite.macAlg != null) {
+ components.addAll(decomposes(cipherSuite.macAlg));
+ }
+
+ return components;
+ }
+ }
+
+ return super.decomposes(algorithm);
+ }
+ }
+
+ static private class X509DisabledAlgConstraints
+ extends BasicDisabledAlgConstraints {
+
+ X509DisabledAlgConstraints() {
+ super(DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
+ }
+
+ @Override
+ protected Set<String> decomposes(String algorithm) {
+ if (algorithm.startsWith("SSL_") || algorithm.startsWith("TLS_")) {
+ CipherSuite cipherSuite = null;
+ try {
+ cipherSuite = CipherSuite.valueOf(algorithm);
+ } catch (IllegalArgumentException iae) {
+ // ignore: unknown or unsupported ciphersuite
+ }
+
+ if (cipherSuite != null) {
+ Set<String> components = new HashSet<String>();
+
+ if(cipherSuite.keyExchange != null) {
+ components.addAll(
+ decomposes(cipherSuite.keyExchange, true));
+ }
+
+ // Certification path algorithm constraints do not apply
+ // to cipherSuite.cipher and cipherSuite.macAlg.
+
+ return components;
+ }
+ }
+
+ return super.decomposes(algorithm);
+ }
+ }
+}
+
--- a/jdk/src/share/classes/sun/security/ssl/SSLContextImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLContextImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, 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,11 +27,15 @@
import java.net.Socket;
+import java.util.*;
import java.security.*;
import java.security.cert.*;
+import java.security.cert.Certificate;
import javax.net.ssl.*;
+import sun.security.provider.certpath.AlgorithmChecker;
+
public class SSLContextImpl extends SSLContextSpi {
private static final Debug debug = Debug.getInstance("ssl");
@@ -82,7 +86,8 @@
if (sr == null) {
secureRandom = JsseJce.getSecureRandom();
} else {
- if (SunJSSE.isFIPS() && (sr.getProvider() != SunJSSE.cryptoProvider)) {
+ if (SunJSSE.isFIPS() &&
+ (sr.getProvider() != SunJSSE.cryptoProvider)) {
throw new KeyManagementException
("FIPS mode: SecureRandom must be from provider "
+ SunJSSE.cryptoProvider.getName());
@@ -111,11 +116,18 @@
// We only use the first instance of X509TrustManager passed to us.
for (int i = 0; tm != null && i < tm.length; i++) {
if (tm[i] instanceof X509TrustManager) {
- if (SunJSSE.isFIPS() && !(tm[i] instanceof X509TrustManagerImpl)) {
+ if (SunJSSE.isFIPS() &&
+ !(tm[i] instanceof X509TrustManagerImpl)) {
throw new KeyManagementException
("FIPS mode: only SunJSSE TrustManagers may be used");
}
- return (X509TrustManager)tm[i];
+
+ if (tm[i] instanceof X509ExtendedTrustManager) {
+ return (X509TrustManager)tm[i];
+ } else {
+ return new AbstractTrustManagerWrapper(
+ (X509TrustManager)tm[i]);
+ }
}
}
@@ -153,7 +165,7 @@
"SSLContext.init(): need an " +
"X509ExtendedKeyManager for SSLEngine use");
}
- return new AbstractWrapper((X509KeyManager)km);
+ return new AbstractKeyManagerWrapper((X509KeyManager)km);
}
// nothing found, return a dummy X509ExtendedKeyManager
@@ -217,9 +229,179 @@
}
+
+final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
+ implements X509TrustManager {
+
+ private final X509TrustManager tm;
+
+ AbstractTrustManagerWrapper(X509TrustManager tm) {
+ this.tm = tm;
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType)
+ throws CertificateException {
+ tm.checkClientTrusted(chain, authType);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType)
+ throws CertificateException {
+ tm.checkServerTrusted(chain, authType);
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ return tm.getAcceptedIssuers();
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType,
+ Socket socket) throws CertificateException {
+ tm.checkClientTrusted(chain, authType);
+ checkAdditionalTrust(chain, authType, socket, true);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType,
+ Socket socket) throws CertificateException {
+ tm.checkServerTrusted(chain, authType);
+ checkAdditionalTrust(chain, authType, socket, false);
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType,
+ SSLEngine engine) throws CertificateException {
+ tm.checkClientTrusted(chain, authType);
+ checkAdditionalTrust(chain, authType, engine, true);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType,
+ SSLEngine engine) throws CertificateException {
+ tm.checkServerTrusted(chain, authType);
+ checkAdditionalTrust(chain, authType, engine, false);
+ }
+
+ private void checkAdditionalTrust(X509Certificate[] chain, String authType,
+ Socket socket, boolean isClient) throws CertificateException {
+ if (socket != null && socket.isConnected() &&
+ socket instanceof SSLSocket) {
+
+ SSLSocket sslSocket = (SSLSocket)socket;
+ SSLSession session = sslSocket.getHandshakeSession();
+ if (session == null) {
+ throw new CertificateException("No handshake session");
+ }
+
+ // check endpoint identity
+ String identityAlg = sslSocket.getSSLParameters().
+ getEndpointIdentificationAlgorithm();
+ if (identityAlg != null && identityAlg.length() != 0) {
+ String hostname = session.getPeerHost();
+ X509TrustManagerImpl.checkIdentity(
+ hostname, chain[0], identityAlg);
+ }
+
+ // try the best to check the algorithm constraints
+ ProtocolVersion protocolVersion =
+ ProtocolVersion.valueOf(session.getProtocol());
+ AlgorithmConstraints constraints = null;
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ if (session instanceof ExtendedSSLSession) {
+ ExtendedSSLSession extSession =
+ (ExtendedSSLSession)session;
+ String[] peerSupportedSignAlgs =
+ extSession.getLocalSupportedSignatureAlgorithms();
+
+ constraints = new SSLAlgorithmConstraints(
+ sslSocket, peerSupportedSignAlgs, true);
+ } else {
+ constraints =
+ new SSLAlgorithmConstraints(sslSocket, true);
+ }
+ } else {
+ constraints = new SSLAlgorithmConstraints(sslSocket, true);
+ }
+
+ AlgorithmChecker checker = new AlgorithmChecker(constraints);
+ try {
+ checker.init(false);
+
+ // a forward checker, need to check from trust to target
+ for (int i = chain.length - 1; i >= 0; i--) {
+ Certificate cert = chain[i];
+ // We don't care about the unresolved critical extensions.
+ checker.check(cert, Collections.<String>emptySet());
+ }
+ } catch (CertPathValidatorException cpve) {
+ throw new CertificateException(
+ "Certificates does not conform to algorithm constraints");
+ }
+ }
+ }
+
+ private void checkAdditionalTrust(X509Certificate[] chain, String authType,
+ SSLEngine engine, boolean isClient) throws CertificateException {
+ if (engine != null) {
+ SSLSession session = engine.getHandshakeSession();
+ if (session == null) {
+ throw new CertificateException("No handshake session");
+ }
+
+ // check endpoint identity
+ String identityAlg = engine.getSSLParameters().
+ getEndpointIdentificationAlgorithm();
+ if (identityAlg != null && identityAlg.length() != 0) {
+ String hostname = session.getPeerHost();
+ X509TrustManagerImpl.checkIdentity(
+ hostname, chain[0], identityAlg);
+ }
+
+ // try the best to check the algorithm constraints
+ ProtocolVersion protocolVersion =
+ ProtocolVersion.valueOf(session.getProtocol());
+ AlgorithmConstraints constraints = null;
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ if (session instanceof ExtendedSSLSession) {
+ ExtendedSSLSession extSession =
+ (ExtendedSSLSession)session;
+ String[] peerSupportedSignAlgs =
+ extSession.getLocalSupportedSignatureAlgorithms();
+
+ constraints = new SSLAlgorithmConstraints(
+ engine, peerSupportedSignAlgs, true);
+ } else {
+ constraints =
+ new SSLAlgorithmConstraints(engine, true);
+ }
+ } else {
+ constraints = new SSLAlgorithmConstraints(engine, true);
+ }
+
+ AlgorithmChecker checker = new AlgorithmChecker(constraints);
+ try {
+ checker.init(false);
+
+ // A forward checker, need to check from trust to target
+ for (int i = chain.length - 1; i >= 0; i--) {
+ Certificate cert = chain[i];
+ // We don't care about the unresolved critical extensions.
+ checker.check(cert, Collections.<String>emptySet());
+ }
+ } catch (CertPathValidatorException cpve) {
+ throw new CertificateException(
+ "Certificates does not conform to algorithm constraints");
+ }
+ }
+ }
+}
+
// Dummy X509TrustManager implementation, rejects all peer certificates.
// Used if the application did not specify a proper X509TrustManager.
-final class DummyX509TrustManager implements X509TrustManager {
+final class DummyX509TrustManager extends X509ExtendedTrustManager
+ implements X509TrustManager {
static final X509TrustManager INSTANCE = new DummyX509TrustManager();
@@ -234,6 +416,7 @@
* validated and is trusted for client SSL authentication.
* If not, it throws an exception.
*/
+ @Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
throw new CertificateException(
@@ -247,6 +430,7 @@
* validated and is trusted for server SSL authentication.
* If not, it throws an exception.
*/
+ @Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
throw new CertificateException(
@@ -257,19 +441,48 @@
* Return an array of issuer certificates which are trusted
* for authenticating peers.
*/
+ @Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType,
+ Socket socket) throws CertificateException {
+ throw new CertificateException(
+ "No X509TrustManager implementation available");
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType,
+ Socket socket) throws CertificateException {
+ throw new CertificateException(
+ "No X509TrustManager implementation available");
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType,
+ SSLEngine engine) throws CertificateException {
+ throw new CertificateException(
+ "No X509TrustManager implementation available");
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType,
+ SSLEngine engine) throws CertificateException {
+ throw new CertificateException(
+ "No X509TrustManager implementation available");
+ }
}
/*
* A wrapper class to turn a X509KeyManager into an X509ExtendedKeyManager
*/
-final class AbstractWrapper extends X509ExtendedKeyManager {
+final class AbstractKeyManagerWrapper extends X509ExtendedKeyManager {
private final X509KeyManager km;
- AbstractWrapper(X509KeyManager km) {
+ AbstractKeyManagerWrapper(X509KeyManager km) {
this.km = km;
}
--- a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -200,8 +200,10 @@
* is associated with a session at the same time. (TLS/IETF may
* change that to add client authentication w/o new key exchg.)
*/
- private SSLSessionImpl sess;
- private Handshaker handshaker;
+ private Handshaker handshaker;
+ private SSLSessionImpl sess;
+ private volatile SSLSessionImpl handshakeSession;
+
/*
* Client authentication be off, requested, or required.
@@ -240,26 +242,30 @@
* session is changed.
*/
private byte doClientAuth;
- private CipherSuiteList enabledCipherSuites;
private boolean enableSessionCreation = true;
EngineInputRecord inputRecord;
EngineOutputRecord outputRecord;
private AccessControlContext acc;
- // hostname identification algorithm, the hostname identification is
- // disabled by default.
- private String identificationAlg = null;
+ // The cipher suites enabled for use on this connection.
+ private CipherSuiteList enabledCipherSuites;
+
+ // the endpoint identification protocol
+ private String identificationProtocol = null;
+
+ // The cryptographic algorithm constraints
+ private AlgorithmConstraints algorithmConstraints = null;
// Have we been told whether we're client or server?
private boolean serverModeSet = false;
private boolean roleIsServer;
/*
- * The protocols we support are SSL Version 3.0) and
- * TLS (version 3.1).
- * In addition we support a pseudo protocol called
- * SSLv2Hello which when set will result in an SSL v2 Hello
- * being sent with SSLv3 or TLSv1 version info.
+ * The protocol versions enabled for use on this connection.
+ *
+ * Note: we support a pseudo protocol called SSLv2Hello which when
+ * set will result in an SSL v2 Hello being sent with SSL (version 3.0)
+ * or TLS (version 3.1, 3.2, etc.) version info.
*/
private ProtocolList enabledProtocols;
@@ -342,6 +348,7 @@
sslContext = ctx;
sess = SSLSessionImpl.nullSession;
+ handshakeSession = null;
/*
* State is cs_START until we initialize the handshaker.
@@ -368,7 +375,7 @@
serverVerifyData = new byte[0];
enabledCipherSuites = CipherSuiteList.getDefault();
- enabledProtocols = ProtocolList.getDefault();
+ enabledProtocols = ProtocolList.getDefault(roleIsServer);
wrapLock = new Object();
unwrapLock = new Object();
@@ -405,8 +412,8 @@
* . if the engine is already closed, throw an Exception (internal error)
*
* . otherwise (cs_START or cs_DATA), create the appropriate handshaker
- * object, initialize it, and advance the connection state (to
- * cs_HANDSHAKE or cs_RENEGOTIATE, respectively).
+ * object and advance the connection state (to cs_HANDSHAKE or
+ * cs_RENEGOTIATE, respectively).
*
* This method is called right after a new engine is created, when
* starting renegotiation, or when changing client/server mode of the
@@ -454,12 +461,8 @@
protocolVersion, connectionState == cs_HANDSHAKE,
secureRenegotiation, clientVerifyData, serverVerifyData);
}
- handshaker.enabledCipherSuites = enabledCipherSuites;
+ handshaker.setEnabledCipherSuites(enabledCipherSuites);
handshaker.setEnableSessionCreation(enableSessionCreation);
- if (connectionState == cs_RENEGOTIATE) {
- // don't use SSLv2Hello when renegotiating
- handshaker.output.r.setHelloVersion(protocolVersion);
- }
}
/*
@@ -686,7 +689,15 @@
// to its HandshakeOutStream, which calls back into
// SSLSocketImpl.writeRecord() to send it.
//
- if (!handshaker.started()) {
+ if (!handshaker.activated()) {
+ // prior to handshaking, activate the handshake
+ if (connectionState == cs_RENEGOTIATE) {
+ // don't use SSLv2Hello when renegotiating
+ handshaker.activate(protocolVersion);
+ } else {
+ handshaker.activate(null);
+ }
+
if (handshaker instanceof ClientHandshaker) {
// send client hello
handshaker.kickstart();
@@ -696,6 +707,7 @@
} else {
// we want to renegotiate, send hello request
handshaker.kickstart();
+
// hello request is not included in the handshake
// hashes, reset them
handshaker.handshakeHash.reset();
@@ -982,6 +994,15 @@
* in it.
*/
initHandshaker();
+ if (!handshaker.activated()) {
+ // prior to handshaking, activate the handshake
+ if (connectionState == cs_RENEGOTIATE) {
+ // don't use SSLv2Hello when renegotiating
+ handshaker.activate(protocolVersion);
+ } else {
+ handshaker.activate(null);
+ }
+ }
/*
* process the handshake record ... may contain just
@@ -1007,6 +1028,7 @@
serverVerifyData = handshaker.getServerVerifyData();
sess = handshaker.getSession();
+ handshakeSession = null;
if (!writer.hasOutboundData()) {
hsStatus = HandshakeStatus.FINISHED;
}
@@ -1081,6 +1103,26 @@
}
break;
} // switch
+
+ /*
+ * We only need to check the sequence number state for
+ * non-handshaking record.
+ *
+ * Note that in order to maintain the handshake status
+ * properly, we check the sequence number after the last
+ * record reading process. As we request renegotiation
+ * or close the connection for wrapped sequence number
+ * when there is enough sequence number space left to
+ * handle a few more records, so the sequence number
+ * of the last record cannot be wrapped.
+ */
+ if (connectionState < cs_ERROR && !isInboundDone() &&
+ (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
+ if (checkSequenceNumber(readMAC,
+ inputRecord.contentType())) {
+ hsStatus = getHSStatus(null);
+ }
+ }
} // synchronized (this)
}
@@ -1229,7 +1271,29 @@
EngineArgs ea) throws IOException {
// eventually compress as well.
- return writer.writeRecord(eor, ea, writeMAC, writeCipher);
+ HandshakeStatus hsStatus =
+ writer.writeRecord(eor, ea, writeMAC, writeCipher);
+
+ /*
+ * We only need to check the sequence number state for
+ * non-handshaking record.
+ *
+ * Note that in order to maintain the handshake status
+ * properly, we check the sequence number after the last
+ * record writing process. As we request renegotiation
+ * or close the connection for wrapped sequence number
+ * when there is enough sequence number space left to
+ * handle a few more records, so the sequence number
+ * of the last record cannot be wrapped.
+ */
+ if (connectionState < cs_ERROR && !isOutboundDone() &&
+ (hsStatus == HandshakeStatus.NOT_HANDSHAKING)) {
+ if (checkSequenceNumber(writeMAC, eor.contentType())) {
+ hsStatus = getHSStatus(null);
+ }
+ }
+
+ return hsStatus;
}
/*
@@ -1238,6 +1302,21 @@
void writeRecord(EngineOutputRecord eor) throws IOException {
// eventually compress as well.
writer.writeRecord(eor, writeMAC, writeCipher);
+
+ /*
+ * Check the sequence number state
+ *
+ * Note that in order to maintain the connection I/O
+ * properly, we check the sequence number after the last
+ * record writing process. As we request renegotiation
+ * or close the connection for wrapped sequence number
+ * when there is enough sequence number space left to
+ * handle a few more records, so the sequence number
+ * of the last record cannot be wrapped.
+ */
+ if ((connectionState < cs_ERROR) && !isOutboundDone()) {
+ checkSequenceNumber(writeMAC, eor.contentType());
+ }
}
//
@@ -1245,6 +1324,67 @@
//
/**
+ * Check the sequence number state
+ *
+ * RFC 4346 states that, "Sequence numbers are of type uint64 and
+ * may not exceed 2^64-1. Sequence numbers do not wrap. If a TLS
+ * implementation would need to wrap a sequence number, it must
+ * renegotiate instead."
+ *
+ * Return true if the handshake status may be changed.
+ */
+ private boolean checkSequenceNumber(MAC mac, byte type)
+ throws IOException {
+
+ /*
+ * Don't bother to check the sequence number for error or
+ * closed connections, or NULL MAC
+ */
+ if (connectionState >= cs_ERROR || mac == MAC.NULL) {
+ return false;
+ }
+
+ /*
+ * Conservatively, close the connection immediately when the
+ * sequence number is close to overflow
+ */
+ if (mac.seqNumOverflow()) {
+ /*
+ * TLS protocols do not define a error alert for sequence
+ * number overflow. We use handshake_failure error alert
+ * for handshaking and bad_record_mac for other records.
+ */
+ if (debug != null && Debug.isOn("ssl")) {
+ System.out.println(threadName() +
+ ", sequence number extremely close to overflow " +
+ "(2^64-1 packets). Closing connection.");
+ }
+
+ fatal(Alerts.alert_handshake_failure, "sequence number overflow");
+
+ return true; // make the compiler happy
+ }
+
+ /*
+ * Ask for renegotiation when need to renew sequence number.
+ *
+ * Don't bother to kickstart the renegotiation when the local is
+ * asking for it.
+ */
+ if ((type != Record.ct_handshake) && mac.seqNumIsHuge()) {
+ if (debug != null && Debug.isOn("ssl")) {
+ System.out.println(threadName() + ", request renegotiation " +
+ "to avoid sequence number overflow");
+ }
+
+ beginHandshake();
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
* Signals that no more outbound application data will be sent
* on this <code>SSLEngine</code>.
*/
@@ -1394,6 +1534,15 @@
return sess;
}
+ @Override
+ synchronized public SSLSession getHandshakeSession() {
+ return handshakeSession;
+ }
+
+ synchronized void setHandshakeSession(SSLSessionImpl session) {
+ handshakeSession = session;
+ }
+
/**
* Returns a delegated <code>Runnable</code> task for
* this <code>SSLEngine</code>.
@@ -1495,6 +1644,9 @@
inboundDone = true;
sess.invalidate();
+ if (handshakeSession != null) {
+ handshakeSession.invalidate();
+ }
/*
* If we haven't even started handshaking yet, no need
@@ -1594,10 +1746,18 @@
* Emit alerts. Caller must have synchronized with "this".
*/
private void sendAlert(byte level, byte description) {
+ // the connectionState cannot be cs_START
if (connectionState >= cs_CLOSED) {
return;
}
+ // For initial handshaking, don't send alert message to peer if
+ // handshaker has not started.
+ if (connectionState == cs_HANDSHAKE &&
+ (handshaker == null || !handshaker.started())) {
+ return;
+ }
+
EngineOutputRecord r = new EngineOutputRecord(Record.ct_alert, this);
r.setVersion(protocolVersion);
@@ -1647,7 +1807,7 @@
synchronized public void setEnableSessionCreation(boolean flag) {
enableSessionCreation = flag;
- if ((handshaker != null) && !handshaker.started()) {
+ if ((handshaker != null) && !handshaker.activated()) {
handshaker.setEnableSessionCreation(enableSessionCreation);
}
}
@@ -1675,7 +1835,7 @@
if ((handshaker != null) &&
(handshaker instanceof ServerHandshaker) &&
- !handshaker.started()) {
+ !handshaker.activated()) {
((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
}
}
@@ -1698,7 +1858,7 @@
if ((handshaker != null) &&
(handshaker instanceof ServerHandshaker) &&
- !handshaker.started()) {
+ !handshaker.activated()) {
((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
}
}
@@ -1717,6 +1877,16 @@
switch (connectionState) {
case cs_START:
+ /*
+ * If we need to change the engine mode and the enabled
+ * protocols haven't specifically been set by the user,
+ * change them to the corresponding default ones.
+ */
+ if (roleIsServer != (!flag) &&
+ ProtocolList.isDefaultProtocolList(enabledProtocols)) {
+ enabledProtocols = ProtocolList.getDefault(!flag);
+ }
+
roleIsServer = !flag;
serverModeSet = true;
break;
@@ -1730,7 +1900,17 @@
* have the streams.
*/
assert(handshaker != null);
- if (!handshaker.started()) {
+ if (!handshaker.activated()) {
+ /*
+ * If we need to change the engine mode and the enabled
+ * protocols haven't specifically been set by the user,
+ * change them to the corresponding default ones.
+ */
+ if (roleIsServer != (!flag) &&
+ ProtocolList.isDefaultProtocolList(enabledProtocols)) {
+ enabledProtocols = ProtocolList.getDefault(!flag);
+ }
+
roleIsServer = !flag;
connectionState = cs_START;
initHandshaker();
@@ -1786,8 +1966,8 @@
*/
synchronized public void setEnabledCipherSuites(String[] suites) {
enabledCipherSuites = new CipherSuiteList(suites);
- if ((handshaker != null) && !handshaker.started()) {
- handshaker.enabledCipherSuites = enabledCipherSuites;
+ if ((handshaker != null) && !handshaker.activated()) {
+ handshaker.setEnabledCipherSuites(enabledCipherSuites);
}
}
@@ -1809,7 +1989,7 @@
/**
* Returns the protocols that are supported by this implementation.
* A subset of the supported protocols may be enabled for this connection
- * @ returns an array of protocol names.
+ * @return an array of protocol names.
*/
public String[] getSupportedProtocols() {
return ProtocolList.getSupported().toStringArray();
@@ -1826,7 +2006,7 @@
*/
synchronized public void setEnabledProtocols(String[] protocols) {
enabledProtocols = new ProtocolList(protocols);
- if ((handshaker != null) && !handshaker.started()) {
+ if ((handshaker != null) && !handshaker.activated()) {
handshaker.setEnabledProtocols(enabledProtocols);
}
}
@@ -1836,28 +2016,31 @@
}
/**
- * Try to configure the endpoint identification algorithm of the engine.
- *
- * @param identificationAlgorithm the algorithm used to check the
- * endpoint identity.
- * @return true if the identification algorithm configuration success.
+ * Returns the SSLParameters in effect for this SSLEngine.
*/
- synchronized public boolean trySetHostnameVerification(
- String identificationAlgorithm) {
- if (sslContext.getX509TrustManager() instanceof
- X509ExtendedTrustManager) {
- this.identificationAlg = identificationAlgorithm;
- return true;
- } else {
- return false;
- }
+ synchronized public SSLParameters getSSLParameters() {
+ SSLParameters params = super.getSSLParameters();
+
+ // the super implementation does not handle the following parameters
+ params.setEndpointIdentificationAlgorithm(identificationProtocol);
+ params.setAlgorithmConstraints(algorithmConstraints);
+
+ return params;
}
/**
- * Returns the endpoint identification algorithm of the engine.
+ * Applies SSLParameters to this engine.
*/
- synchronized public String getHostnameVerification() {
- return identificationAlg;
+ synchronized public void setSSLParameters(SSLParameters params) {
+ super.setSSLParameters(params);
+
+ // the super implementation does not handle the following parameters
+ identificationProtocol = params.getEndpointIdentificationAlgorithm();
+ algorithmConstraints = params.getAlgorithmConstraints();
+ if ((handshaker != null) && !handshaker.started()) {
+ handshaker.setIdentificationProtocol(identificationProtocol);
+ handshaker.setAlgorithmConstraints(algorithmConstraints);
+ }
}
/**
--- a/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -31,11 +31,14 @@
import java.net.Socket;
import java.net.ServerSocket;
+import java.security.AlgorithmConstraints;
+
import java.util.*;
import javax.net.ServerSocketFactory;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLParameters;
/**
@@ -83,6 +86,12 @@
/* could enabledCipherSuites ever complete handshaking? */
private boolean checkedEnabled = false;
+ // the endpoint identification protocol to use by default
+ private String identificationProtocol = null;
+
+ // The cryptographic algorithm constraints
+ private AlgorithmConstraints algorithmConstraints = null;
+
/**
* Create an SSL server socket on a port, using a non-default
* authentication context and a specified connection backlog.
@@ -145,7 +154,7 @@
}
sslContext = context;
enabledCipherSuites = CipherSuiteList.getDefault();
- enabledProtocols = ProtocolList.getDefault();
+ enabledProtocols = ProtocolList.getDefault(true);
}
/**
@@ -238,6 +247,16 @@
* rejoining the already-negotiated SSL connection.
*/
public void setUseClientMode(boolean flag) {
+ /*
+ * If we need to change the socket mode and the enabled
+ * protocols haven't specifically been set by the user,
+ * change them to the corresponding default ones.
+ */
+ if (useServerMode != (!flag) &&
+ ProtocolList.isDefaultProtocolList(enabledProtocols)) {
+ enabledProtocols = ProtocolList.getDefault(!flag);
+ }
+
useServerMode = !flag;
}
@@ -262,6 +281,29 @@
return enableSessionCreation;
}
+ /**
+ * Returns the SSLParameters in effect for newly accepted connections.
+ */
+ synchronized public SSLParameters getSSLParameters() {
+ SSLParameters params = super.getSSLParameters();
+
+ // the super implementation does not handle the following parameters
+ params.setEndpointIdentificationAlgorithm(identificationProtocol);
+ params.setAlgorithmConstraints(algorithmConstraints);
+
+ return params;
+ }
+
+ /**
+ * Applies SSLParameters to newly accepted connections.
+ */
+ synchronized public void setSSLParameters(SSLParameters params) {
+ super.setSSLParameters(params);
+
+ // the super implementation does not handle the following parameters
+ identificationProtocol = params.getEndpointIdentificationAlgorithm();
+ algorithmConstraints = params.getAlgorithmConstraints();
+ }
/**
* Accept a new SSL connection. This server identifies itself with
@@ -269,67 +311,15 @@
* presented during construction.
*/
public Socket accept() throws IOException {
- checkEnabledSuites();
-
SSLSocketImpl s = new SSLSocketImpl(sslContext, useServerMode,
enabledCipherSuites, doClientAuth, enableSessionCreation,
- enabledProtocols);
+ enabledProtocols, identificationProtocol, algorithmConstraints);
implAccept(s);
s.doneConnect();
return s;
}
-
- /*
- * This is a sometimes helpful diagnostic check that is performed
- * once for each ServerSocket to verify that the initial set of
- * enabled suites are capable of supporting a successful handshake.
- */
- private void checkEnabledSuites() throws IOException {
- //
- // We want to report an error if no cipher suites were actually
- // enabled, since this is an error users are known to make. Then
- // they get vastly confused by having clients report an error!
- //
- synchronized (this) {
- if (checkedEnabled) {
- return;
- }
- if (useServerMode == false) {
- return;
- }
-
- SSLSocketImpl tmp = new SSLSocketImpl(sslContext, useServerMode,
- enabledCipherSuites, doClientAuth,
- enableSessionCreation, enabledProtocols);
-
- try {
- ServerHandshaker handshaker = tmp.getServerHandshaker();
-
- for (Iterator<CipherSuite> t = enabledCipherSuites.iterator();
- t.hasNext();) {
- CipherSuite suite = t.next();
- if (handshaker.trySetCipherSuite(suite)) {
- checkedEnabled = true;
- return;
- }
- }
- } finally {
- tmp.closeSocket();
- }
-
- //
- // diagnostic text here is currently appropriate
- // since it's only certificate unavailability that can
- // cause such problems ... but that might change someday.
- //
- throw new SSLException("No available certificate or key corresponds"
- + " to the SSL cipher suites which are enabled.");
- }
- }
-
-
/**
* Provides a brief description of this SSL socket.
*/
--- a/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSessionImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2010, 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
@@ -31,6 +31,8 @@
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
+import java.util.Arrays;
+import java.util.Collection;
import java.security.Principal;
import java.security.PrivateKey;
@@ -47,6 +49,8 @@
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLPermission;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.ExtendedSSLSession;
import javax.security.auth.x500.X500Principal;
@@ -71,7 +75,7 @@
*
* @author David Brownell
*/
-final class SSLSessionImpl implements SSLSession {
+final class SSLSessionImpl extends ExtendedSSLSession {
/*
* we only really need a single null session
@@ -89,7 +93,7 @@
private final SessionId sessionId;
private X509Certificate[] peerCerts;
private byte compressionMethod;
- private final CipherSuite cipherSuite;
+ private CipherSuite cipherSuite;
private SecretKey masterSecret;
/*
@@ -105,6 +109,8 @@
private boolean invalidated;
private X509Certificate[] localCerts;
private PrivateKey localPrivateKey;
+ private String[] localSupportedSignAlgs;
+ private String[] peerSupportedSignAlgs;
// Principals for non-certificate based cipher suites
private Principal peerPrincipal;
@@ -132,8 +138,8 @@
* first opened and before handshaking begins.
*/
private SSLSessionImpl() {
- this(ProtocolVersion.NONE, CipherSuite.C_NULL,
- new SessionId(false, null), null, -1);
+ this(ProtocolVersion.NONE, CipherSuite.C_NULL, null,
+ new SessionId(false, null), null, -1);
}
/*
@@ -142,8 +148,9 @@
* is intended mostly for use by serves.
*/
SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
+ Collection<SignatureAndHashAlgorithm> algorithms,
SecureRandom generator, String host, int port) {
- this(protocolVersion, cipherSuite,
+ this(protocolVersion, cipherSuite, algorithms,
new SessionId(defaultRejoinable, generator), host, port);
}
@@ -151,6 +158,7 @@
* Record a new session, using a given cipher spec and session ID.
*/
SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
+ Collection<SignatureAndHashAlgorithm> algorithms,
SessionId id, String host, int port) {
this.protocolVersion = protocolVersion;
sessionId = id;
@@ -161,9 +169,11 @@
this.host = host;
this.port = port;
sessionCount = ++counter;
+ localSupportedSignAlgs =
+ SignatureAndHashAlgorithm.getAlgorithmNames(algorithms);
if (debug != null && Debug.isOn("session")) {
- System.out.println("%% Created: " + this);
+ System.out.println("%% Initialized: " + this);
}
}
@@ -196,6 +206,12 @@
localPrivateKey = privateKey;
}
+ void setPeerSupportedSignatureAlgorithms(
+ Collection<SignatureAndHashAlgorithm> algorithms) {
+ peerSupportedSignAlgs =
+ SignatureAndHashAlgorithm.getAlgorithmNames(algorithms);
+ }
+
/**
* Set the peer principal.
*/
@@ -293,6 +309,17 @@
}
/**
+ * Resets the cipher spec in use on this session
+ */
+ void setSuite(CipherSuite suite) {
+ cipherSuite = suite;
+
+ if (debug != null && Debug.isOn("session")) {
+ System.out.println("%% Negotiating: " + this);
+ }
+ }
+
+ /**
* Returns the name of the cipher suite in use on this session
*/
public String getCipherSuite() {
@@ -718,6 +745,30 @@
return getPacketBufferSize() - Record.headerSize;
}
+ /**
+ * Gets an array of supported signature algorithms that the local side is
+ * willing to verify.
+ */
+ public String[] getLocalSupportedSignatureAlgorithms() {
+ if (localSupportedSignAlgs != null) {
+ return localSupportedSignAlgs.clone();
+ }
+
+ return new String[0];
+ }
+
+ /**
+ * Gets an array of supported signature algorithms that the peer is
+ * able to verify.
+ */
+ public String[] getPeerSupportedSignatureAlgorithms() {
+ if (peerSupportedSignAlgs != null) {
+ return peerSupportedSignAlgs.clone();
+ }
+
+ return new String[0];
+ }
+
/** Returns a string representation of this SSL session */
public String toString() {
return "[Session-" + sessionCount
--- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -32,6 +32,7 @@
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
+import java.security.AlgorithmConstraints;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
@@ -194,15 +195,27 @@
*/
private byte doClientAuth;
private boolean roleIsServer;
- private CipherSuiteList enabledCipherSuites;
private boolean enableSessionCreation = true;
private String host;
private boolean autoClose = true;
private AccessControlContext acc;
- // hostname identification algorithm, the hostname identification is
- // disabled by default.
- private String identificationAlg = null;
+ /*
+ * We cannot use the hostname resolved from name services. For
+ * virtual hosting, multiple hostnames may be bound to the same IP
+ * address, so the hostname resolved from name services is not
+ * reliable.
+ */
+ private String rawHostname;
+
+ // The cipher suites enabled for use on this connection.
+ private CipherSuiteList enabledCipherSuites;
+
+ // The endpoint identification protocol
+ private String identificationProtocol = null;
+
+ // The cryptographic algorithm constraints
+ private AlgorithmConstraints algorithmConstraints = null;
/*
* READ ME * READ ME * READ ME * READ ME * READ ME * READ ME *
@@ -312,8 +325,9 @@
* is associated with a session at the same time. (TLS/IETF may
* change that to add client authentication w/o new key exchg.)
*/
- private SSLSessionImpl sess;
- private Handshaker handshaker;
+ private Handshaker handshaker;
+ private SSLSessionImpl sess;
+ private volatile SSLSessionImpl handshakeSession;
/*
@@ -341,11 +355,11 @@
private AppOutputStream output;
/*
- * The protocols we support are SSL Version 3.0) and
- * TLS (version 3.1).
- * In addition we support a pseudo protocol called
- * SSLv2Hello which when set will result in an SSL v2 Hello
- * being sent with SSLv3 or TLSv1 version info.
+ * The protocol versions enabled for use on this connection.
+ *
+ * Note: we support a pseudo protocol called SSLv2Hello which when
+ * set will result in an SSL v2 Hello being sent with SSL (version 3.0)
+ * or TLS (version 3.1, 3.2, etc.) version info.
*/
private ProtocolList enabledProtocols;
@@ -374,6 +388,7 @@
throws IOException, UnknownHostException {
super();
this.host = host;
+ this.rawHostname = host;
init(context, false);
SocketAddress socketAddress =
host != null ? new InetSocketAddress(host, port) :
@@ -416,6 +431,7 @@
throws IOException, UnknownHostException {
super();
this.host = host;
+ this.rawHostname = host;
init(context, false);
bind(new InetSocketAddress(localAddr, localPort));
SocketAddress socketAddress =
@@ -455,11 +471,15 @@
*/
SSLSocketImpl(SSLContextImpl context, boolean serverMode,
CipherSuiteList suites, byte clientAuth,
- boolean sessionCreation, ProtocolList protocols)
- throws IOException {
+ boolean sessionCreation, ProtocolList protocols,
+ String identificationProtocol,
+ AlgorithmConstraints algorithmConstraints) throws IOException {
+
super();
doClientAuth = clientAuth;
enableSessionCreation = sessionCreation;
+ this.identificationProtocol = identificationProtocol;
+ this.algorithmConstraints = algorithmConstraints;
init(context, serverMode);
/*
@@ -506,6 +526,7 @@
throw new SocketException("Underlying socket is not connected");
}
this.host = host;
+ this.rawHostname = host;
init(context, false);
this.autoClose = autoClose;
doneConnect();
@@ -517,6 +538,7 @@
private void init(SSLContextImpl context, boolean isServer) {
sslContext = context;
sess = SSLSessionImpl.nullSession;
+ handshakeSession = null;
/*
* role is as specified, state is START until after
@@ -541,7 +563,7 @@
serverVerifyData = new byte[0];
enabledCipherSuites = CipherSuiteList.getDefault();
- enabledProtocols = ProtocolList.getDefault();
+ enabledProtocols = ProtocolList.getDefault(roleIsServer);
inrec = null;
// save the acc
@@ -764,6 +786,21 @@
r.addMAC(writeMAC);
r.encrypt(writeCipher);
r.write(sockOutput);
+
+ /*
+ * Check the sequence number state
+ *
+ * Note that in order to maintain the connection I/O
+ * properly, we check the sequence number after the last
+ * record writing process. As we request renegotiation
+ * or close the connection for wrapped sequence number
+ * when there is enough sequence number space left to
+ * handle a few more records, so the sequence number
+ * of the last record cannot be wrapped.
+ */
+ if (connectionState < cs_ERROR) {
+ checkSequenceNumber(writeMAC, r.contentType());
+ }
}
@@ -883,6 +920,7 @@
}
}
+
// if (!r.decompress(c))
// fatal(Alerts.alert_decompression_failure,
// "decompression failure");
@@ -905,6 +943,15 @@
* in it.
*/
initHandshaker();
+ if (!handshaker.activated()) {
+ // prior to handshaking, activate the handshake
+ if (connectionState == cs_RENEGOTIATE) {
+ // don't use SSLv2Hello when renegotiating
+ handshaker.activate(protocolVersion);
+ } else {
+ handshaker.activate(null);
+ }
+ }
/*
* process the handshake record ... may contain just
@@ -930,6 +977,7 @@
serverVerifyData = handshaker.getServerVerifyData();
sess = handshaker.getSession();
+ handshakeSession = null;
handshaker = null;
connectionState = cs_DATA;
@@ -949,9 +997,8 @@
if (needAppData || connectionState != cs_DATA) {
continue;
- } else {
- return;
}
+ break;
case Record.ct_application_data:
// Pass this right back up to the application.
@@ -971,7 +1018,7 @@
}
r.setAppDataValid(true);
- return;
+ break;
case Record.ct_alert:
recvAlert(r);
@@ -1010,6 +1057,23 @@
}
continue;
} // switch
+
+ /*
+ * Check the sequence number state
+ *
+ * Note that in order to maintain the connection I/O
+ * properly, we check the sequence number after the last
+ * record reading process. As we request renegotiation
+ * or close the connection for wrapped sequence number
+ * when there is enough sequence number space left to
+ * handle a few more records, so the sequence number
+ * of the last record cannot be wrapped.
+ */
+ if (connectionState < cs_ERROR) {
+ checkSequenceNumber(readMAC, r.contentType());
+ }
+
+ return;
} // synchronized (this)
}
@@ -1021,6 +1085,61 @@
} // synchronized (readLock)
}
+ /**
+ * Check the sequence number state
+ *
+ * RFC 4346 states that, "Sequence numbers are of type uint64 and
+ * may not exceed 2^64-1. Sequence numbers do not wrap. If a TLS
+ * implementation would need to wrap a sequence number, it must
+ * renegotiate instead."
+ */
+ private void checkSequenceNumber(MAC mac, byte type)
+ throws IOException {
+
+ /*
+ * Don't bother to check the sequence number for error or
+ * closed connections, or NULL MAC.
+ */
+ if (connectionState >= cs_ERROR || mac == MAC.NULL) {
+ return;
+ }
+
+ /*
+ * Conservatively, close the connection immediately when the
+ * sequence number is close to overflow
+ */
+ if (mac.seqNumOverflow()) {
+ /*
+ * TLS protocols do not define a error alert for sequence
+ * number overflow. We use handshake_failure error alert
+ * for handshaking and bad_record_mac for other records.
+ */
+ if (debug != null && Debug.isOn("ssl")) {
+ System.out.println(threadName() +
+ ", sequence number extremely close to overflow " +
+ "(2^64-1 packets). Closing connection.");
+
+ }
+
+ fatal(Alerts.alert_handshake_failure, "sequence number overflow");
+ }
+
+ /*
+ * Ask for renegotiation when need to renew sequence number.
+ *
+ * Don't bother to kickstart the renegotiation when the local is
+ * asking for it.
+ */
+ if ((type != Record.ct_handshake) && mac.seqNumIsHuge()) {
+ if (debug != null && Debug.isOn("ssl")) {
+ System.out.println(threadName() + ", request renegotiation " +
+ "to avoid sequence number overflow");
+ }
+
+ startHandshake();
+ }
+ }
+
//
// HANDSHAKE RELATED CODE
//
@@ -1033,28 +1152,10 @@
}
/**
- * Initialize and get the server handshaker. Used by SSLServerSocketImpl
- * for the ciphersuite availability test *only*.
+ * Return the AppOutputStream. For use by Handshaker only.
*/
- ServerHandshaker getServerHandshaker() throws SSLException {
- initHandshaker();
-
- // The connection state would have been set to cs_HANDSHAKE during the
- // handshaking initializing, however the caller may not have the
- // the low level connection's established, which is not consistent with
- // the HANDSHAKE state. As if it is unconnected, we need to reset the
- // connection state to cs_START.
- if (!isConnected()) {
- connectionState = cs_START;
- }
-
- // Make sure that we get a ServerHandshaker.
- // This should never happen.
- if (!(handshaker instanceof ServerHandshaker)) {
- throw new SSLProtocolException("unexpected handshaker instance");
- }
-
- return (ServerHandshaker)handshaker;
+ AppOutputStream getAppOutputStream() {
+ return output;
}
/**
@@ -1066,8 +1167,8 @@
* . if the socket is already closed, throw an Exception (internal error)
*
* . otherwise (cs_START or cs_DATA), create the appropriate handshaker
- * object, initialize it, and advance the connection state (to
- * cs_HANDSHAKE or cs_RENEGOTIATE, respectively).
+ * object, and advance the connection state (to cs_HANDSHAKE or
+ * cs_RENEGOTIATE, respectively).
*
* This method is called right after a new socket is created, when
* starting renegotiation, or when changing client/ server mode of the
@@ -1115,12 +1216,8 @@
protocolVersion, connectionState == cs_HANDSHAKE,
secureRenegotiation, clientVerifyData, serverVerifyData);
}
- handshaker.enabledCipherSuites = enabledCipherSuites;
+ handshaker.setEnabledCipherSuites(enabledCipherSuites);
handshaker.setEnableSessionCreation(enableSessionCreation);
- if (connectionState == cs_RENEGOTIATE) {
- // don't use SSLv2Hello when renegotiating
- handshaker.output.r.setHelloVersion(protocolVersion);
- }
}
/**
@@ -1135,6 +1232,8 @@
// one thread performs the handshake
synchronized (handshakeLock) {
if (getConnectionState() == cs_HANDSHAKE) {
+ kickstartHandshake();
+
/*
* All initial handshaking goes through this
* InputRecord until we have a valid SSL connection.
@@ -1157,7 +1256,6 @@
inrec.enableFormatChecks();
}
- kickstartHandshake();
readRecord(inrec, false);
inrec = null;
}
@@ -1211,6 +1309,7 @@
* on servers when renegotiating).
*/
private synchronized void kickstartHandshake() throws IOException {
+
switch (connectionState) {
case cs_HANDSHAKE:
@@ -1257,7 +1356,15 @@
// to its HandshakeOutStream, which calls back into
// SSLSocketImpl.writeRecord() to send it.
//
- if (!handshaker.started()) {
+ if (!handshaker.activated()) {
+ // prior to handshaking, activate the handshake
+ if (connectionState == cs_RENEGOTIATE) {
+ // don't use SSLv2Hello when renegotiating
+ handshaker.activate(protocolVersion);
+ } else {
+ handshaker.activate(null);
+ }
+
if (handshaker instanceof ClientHandshaker) {
// send client hello
handshaker.kickstart();
@@ -1646,6 +1753,9 @@
input.r.close();
}
sess.invalidate();
+ if (handshakeSession != null) {
+ handshakeSession.invalidate();
+ }
int oldState = connectionState;
connectionState = cs_ERROR;
@@ -1752,10 +1862,18 @@
* Emit alerts. Caller must have synchronized with "this".
*/
private void sendAlert(byte level, byte description) {
+ // the connectionState cannot be cs_START
if (connectionState >= cs_SENT_CLOSE) {
return;
}
+ // For initial handshaking, don't send alert message to peer if
+ // handshaker has not started.
+ if (connectionState == cs_HANDSHAKE &&
+ (handshaker == null || !handshaker.started())) {
+ return;
+ }
+
OutputRecord r = new OutputRecord(Record.ct_alert);
r.setVersion(protocolVersion);
@@ -1878,9 +1996,14 @@
return host;
}
+ synchronized String getRawHostname() {
+ return rawHostname;
+ }
+
// ONLY used by HttpsClient to setup the URI specified hostname
synchronized public void setHost(String host) {
this.host = host;
+ this.rawHostname = host;
}
/**
@@ -1951,6 +2074,15 @@
}
}
+ @Override
+ synchronized public SSLSession getHandshakeSession() {
+ return handshakeSession;
+ }
+
+ synchronized void setHandshakeSession(SSLSessionImpl session) {
+ handshakeSession = session;
+ }
+
/**
* Controls whether new connections may cause creation of new SSL
* sessions.
@@ -1962,7 +2094,7 @@
synchronized public void setEnableSessionCreation(boolean flag) {
enableSessionCreation = flag;
- if ((handshaker != null) && !handshaker.started()) {
+ if ((handshaker != null) && !handshaker.activated()) {
handshaker.setEnableSessionCreation(enableSessionCreation);
}
}
@@ -1990,7 +2122,7 @@
if ((handshaker != null) &&
(handshaker instanceof ServerHandshaker) &&
- !handshaker.started()) {
+ !handshaker.activated()) {
((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
}
}
@@ -2013,7 +2145,7 @@
if ((handshaker != null) &&
(handshaker instanceof ServerHandshaker) &&
- !handshaker.started()) {
+ !handshaker.activated()) {
((ServerHandshaker) handshaker).setClientAuth(doClientAuth);
}
}
@@ -2032,6 +2164,15 @@
switch (connectionState) {
case cs_START:
+ /*
+ * If we need to change the socket mode and the enabled
+ * protocols haven't specifically been set by the user,
+ * change them to the corresponding default ones.
+ */
+ if (roleIsServer != (!flag) &&
+ ProtocolList.isDefaultProtocolList(enabledProtocols)) {
+ enabledProtocols = ProtocolList.getDefault(!flag);
+ }
roleIsServer = !flag;
break;
@@ -2044,7 +2185,16 @@
* have the streams.
*/
assert(handshaker != null);
- if (!handshaker.started()) {
+ if (!handshaker.activated()) {
+ /*
+ * If we need to change the socket mode and the enabled
+ * protocols haven't specifically been set by the user,
+ * change them to the corresponding default ones.
+ */
+ if (roleIsServer != (!flag) &&
+ ProtocolList.isDefaultProtocolList(enabledProtocols)) {
+ enabledProtocols = ProtocolList.getDefault(!flag);
+ }
roleIsServer = !flag;
connectionState = cs_START;
initHandshaker();
@@ -2095,8 +2245,8 @@
*/
synchronized public void setEnabledCipherSuites(String[] suites) {
enabledCipherSuites = new CipherSuiteList(suites);
- if ((handshaker != null) && !handshaker.started()) {
- handshaker.enabledCipherSuites = enabledCipherSuites;
+ if ((handshaker != null) && !handshaker.activated()) {
+ handshaker.setEnabledCipherSuites(enabledCipherSuites);
}
}
@@ -2118,7 +2268,7 @@
/**
* Returns the protocols that are supported by this implementation.
* A subset of the supported protocols may be enabled for this connection
- * @ returns an array of protocol names.
+ * @return an array of protocol names.
*/
public String[] getSupportedProtocols() {
return ProtocolList.getSupported().toStringArray();
@@ -2135,7 +2285,7 @@
*/
synchronized public void setEnabledProtocols(String[] protocols) {
enabledProtocols = new ProtocolList(protocols);
- if ((handshaker != null) && !handshaker.started()) {
+ if ((handshaker != null) && !handshaker.activated()) {
handshaker.setEnabledProtocols(enabledProtocols);
}
}
@@ -2194,28 +2344,31 @@
}
/**
- * Try to configure the endpoint identification algorithm of the socket.
- *
- * @param identificationAlgorithm the algorithm used to check the
- * endpoint identity.
- * @return true if the identification algorithm configuration success.
+ * Returns the SSLParameters in effect for this SSLSocket.
*/
- synchronized public boolean trySetHostnameVerification(
- String identificationAlgorithm) {
- if (sslContext.getX509TrustManager() instanceof
- X509ExtendedTrustManager) {
- this.identificationAlg = identificationAlgorithm;
- return true;
- } else {
- return false;
- }
+ synchronized public SSLParameters getSSLParameters() {
+ SSLParameters params = super.getSSLParameters();
+
+ // the super implementation does not handle the following parameters
+ params.setEndpointIdentificationAlgorithm(identificationProtocol);
+ params.setAlgorithmConstraints(algorithmConstraints);
+
+ return params;
}
/**
- * Returns the endpoint identification algorithm of the socket.
+ * Applies SSLParameters to this socket.
*/
- synchronized public String getHostnameVerification() {
- return identificationAlg;
+ synchronized public void setSSLParameters(SSLParameters params) {
+ super.setSSLParameters(params);
+
+ // the super implementation does not handle the following parameters
+ identificationProtocol = params.getEndpointIdentificationAlgorithm();
+ algorithmConstraints = params.getAlgorithmConstraints();
+ if ((handshaker != null) && !handshaker.started()) {
+ handshaker.setIdentificationProtocol(identificationProtocol);
+ handshaker.setAlgorithmConstraints(algorithmConstraints);
+ }
}
//
--- a/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java Tue Nov 02 19:40:45 2010 -0700
@@ -40,10 +40,9 @@
import javax.security.auth.Subject;
-import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;
-
import sun.security.ssl.HandshakeMessage.*;
import sun.security.ssl.CipherSuite.*;
+import sun.security.ssl.SignatureAndHashAlgorithm.*;
import static sun.security.ssl.CipherSuite.*;
import static sun.security.ssl.CipherSuite.KeyExchange.*;
@@ -92,6 +91,9 @@
private SupportedEllipticCurvesExtension supportedCurves;
+ // the preferable signature algorithm used by ServerKeyExchange message
+ SignatureAndHashAlgorithm preferableSignatureAlgorithm;
+
/*
* Constructor ... use the keys found in the auth context.
*/
@@ -185,8 +187,10 @@
* temporary one used for non-export or signing-only
* certificates/keys.
*/
- RSAClientKeyExchange pms = new RSAClientKeyExchange
- (protocolVersion, input, message_len, privateKey);
+ RSAClientKeyExchange pms = new RSAClientKeyExchange(
+ protocolVersion, clientRequestedVersion,
+ sslContext.getSecureRandom(), input,
+ message_len, privateKey);
preMasterSecret = this.clientKeyExchange(pms);
break;
case K_KRB5:
@@ -231,11 +235,13 @@
break;
case HandshakeMessage.ht_certificate_verify:
- this.clientCertificateVerify(new CertificateVerify(input));
+ this.clientCertificateVerify(new CertificateVerify(input,
+ localSupportedSignAlgs, protocolVersion));
break;
case HandshakeMessage.ht_finished:
- this.clientFinished(new Finished(protocolVersion, input));
+ this.clientFinished(
+ new Finished(protocolVersion, input, cipherSuite));
break;
default:
@@ -408,21 +414,18 @@
clientRequestedVersion = mesg.protocolVersion;
- // check if clientVersion is recent enough for us
- if (clientRequestedVersion.v < enabledProtocols.min.v) {
+ // select a proper protocol version.
+ ProtocolVersion selectedVersion =
+ selectProtocolVersion(clientRequestedVersion);
+ if (selectedVersion == null ||
+ selectedVersion.v == ProtocolVersion.SSL20Hello.v) {
fatalSE(Alerts.alert_handshake_failure,
"Client requested protocol " + clientRequestedVersion +
- " not enabled or not supported");
+ " not enabled or not supported");
}
- // now we know we have an acceptable version
- // use the lower of our max and the client requested version
- ProtocolVersion selectedVersion;
- if (clientRequestedVersion.v <= enabledProtocols.max.v) {
- selectedVersion = clientRequestedVersion;
- } else {
- selectedVersion = enabledProtocols.max;
- }
+ handshakeHash.protocolDetermined(
+ selectedVersion.v >= ProtocolVersion.TLS12.v);
setVersion(selectedVersion);
m1.protocolVersion = protocolVersion;
@@ -566,14 +569,71 @@
if (!enableNewSession) {
throw new SSLException("Client did not resume a session");
}
+
supportedCurves = (SupportedEllipticCurvesExtension)
mesg.extensions.get(ExtensionType.EXT_ELLIPTIC_CURVES);
+
+ // We only need to handle the "signature_algorithm" extension
+ // for full handshakes and TLS 1.2 or later.
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ SignatureAlgorithmsExtension signAlgs =
+ (SignatureAlgorithmsExtension)mesg.extensions.get(
+ ExtensionType.EXT_SIGNATURE_ALGORITHMS);
+ if (signAlgs != null) {
+ Collection<SignatureAndHashAlgorithm> peerSignAlgs =
+ signAlgs.getSignAlgorithms();
+ if (peerSignAlgs == null || peerSignAlgs.isEmpty()) {
+ throw new SSLHandshakeException(
+ "No peer supported signature algorithms");
+ }
+
+ Collection<SignatureAndHashAlgorithm>
+ supportedPeerSignAlgs =
+ SignatureAndHashAlgorithm.getSupportedAlgorithms(
+ peerSignAlgs);
+ if (supportedPeerSignAlgs.isEmpty()) {
+ throw new SSLHandshakeException(
+ "No supported signature and hash algorithm " +
+ "in common");
+ }
+
+ setPeerSupportedSignAlgs(supportedPeerSignAlgs);
+ } // else, need to use peer implicit supported signature algs
+ }
+
+ session = new SSLSessionImpl(protocolVersion, CipherSuite.C_NULL,
+ getLocalSupportedSignAlgs(),
+ sslContext.getSecureRandom(),
+ getHostAddressSE(), getPortSE());
+
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ if (peerSupportedSignAlgs != null) {
+ session.setPeerSupportedSignatureAlgorithms(
+ peerSupportedSignAlgs);
+ } // else, we will set the implicit peer supported signature
+ // algorithms in chooseCipherSuite()
+ }
+
+ // set the handshake session
+ setHandshakeSessionSE(session);
+
+ // choose cipher suite and corresponding private key
chooseCipherSuite(mesg);
- session = new SSLSessionImpl(protocolVersion, cipherSuite,
- sslContext.getSecureRandom(),
- getHostAddressSE(), getPortSE());
+
+ session.setSuite(cipherSuite);
session.setLocalPrivateKey(privateKey);
+
// chooseCompression(mesg);
+ } else {
+ // set the handshake session
+ setHandshakeSessionSE(session);
+ }
+
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ if (resumingSession) {
+ handshakeHash.setCertificateVerifyAlg(null);
+ }
+ handshakeHash.setFinishedAlg(cipherSuite.prfAlg.getPRFHashAlg());
}
m1.cipherSuite = cipherSuite;
@@ -693,14 +753,16 @@
privateKey,
clnt_random.random_bytes,
svr_random.random_bytes,
- sslContext.getSecureRandom());
+ sslContext.getSecureRandom(),
+ preferableSignatureAlgorithm,
+ protocolVersion);
} catch (GeneralSecurityException e) {
throwSSLException("Error generating DH server key exchange", e);
m3 = null; // make compiler happy
}
break;
case K_DH_ANON:
- m3 = new DH_ServerKeyExchange(dh);
+ m3 = new DH_ServerKeyExchange(dh, protocolVersion);
break;
case K_ECDHE_RSA:
case K_ECDHE_ECDSA:
@@ -710,9 +772,12 @@
privateKey,
clnt_random.random_bytes,
svr_random.random_bytes,
- sslContext.getSecureRandom());
+ sslContext.getSecureRandom(),
+ preferableSignatureAlgorithm,
+ protocolVersion);
} catch (GeneralSecurityException e) {
- throwSSLException("Error generating ECDH server key exchange", e);
+ throwSSLException(
+ "Error generating ECDH server key exchange", e);
m3 = null; // make compiler happy
}
break;
@@ -741,21 +806,48 @@
// Needed only if server requires client to authenticate self.
// Illegal for anonymous flavors, so we need to check that.
//
- if (keyExchange == K_KRB5 || keyExchange == K_KRB5_EXPORT) {
- // CertificateRequest is omitted for Kerberos ciphers
+ // CertificateRequest is omitted for Kerberos ciphers
+ if (doClientAuth != SSLEngineImpl.clauth_none &&
+ keyExchange != K_DH_ANON && keyExchange != K_ECDH_ANON &&
+ keyExchange != K_KRB5 && keyExchange != K_KRB5_EXPORT) {
- } else if (doClientAuth != SSLEngineImpl.clauth_none &&
- keyExchange != K_DH_ANON && keyExchange != K_ECDH_ANON) {
CertificateRequest m4;
X509Certificate caCerts[];
+ Collection<SignatureAndHashAlgorithm> localSignAlgs = null;
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ // We currently use all local upported signature and hash
+ // algorithms. However, to minimize the computation cost
+ // of requested hash algorithms, we may use a restricted
+ // set of signature algorithms in the future.
+ localSignAlgs = getLocalSupportedSignAlgs();
+ if (localSignAlgs.isEmpty()) {
+ throw new SSLHandshakeException(
+ "No supported signature algorithm");
+ }
+
+ Set<String> localHashAlgs =
+ SignatureAndHashAlgorithm.getHashAlgorithmNames(
+ localSignAlgs);
+ if (localHashAlgs.isEmpty()) {
+ throw new SSLHandshakeException(
+ "No supported signature algorithm");
+ }
+ handshakeHash.restrictCertificateVerifyAlgs(localHashAlgs);
+ }
+
caCerts = sslContext.getX509TrustManager().getAcceptedIssuers();
- m4 = new CertificateRequest(caCerts, keyExchange);
+ m4 = new CertificateRequest(caCerts, keyExchange,
+ localSignAlgs, protocolVersion);
if (debug != null && Debug.isOn("handshake")) {
m4.print(System.out);
}
m4.write(output);
+ } else {
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ handshakeHash.setCertificateVerifyAlg(null);
+ }
}
/*
@@ -813,8 +905,7 @@
* method should only be called if you really want to use the
* CipherSuite.
*
- * This method is called from chooseCipherSuite() in this class
- * and SSLServerSocketImpl.checkEnabledSuites() (as a sanity check).
+ * This method is called from chooseCipherSuite() in this class.
*/
boolean trySetCipherSuite(CipherSuite suite) {
/*
@@ -831,6 +922,16 @@
return false;
}
+ // must not negotiate the obsoleted weak cipher suites.
+ if (protocolVersion.v >= suite.obsoleted) {
+ return false;
+ }
+
+ // must not negotiate unsupported cipher suites.
+ if (protocolVersion.v < suite.supported) {
+ return false;
+ }
+
KeyExchange keyExchange = suite.keyExchange;
// null out any existing references
@@ -840,36 +941,136 @@
tempPrivateKey = null;
tempPublicKey = null;
+ Collection<SignatureAndHashAlgorithm> supportedSignAlgs = null;
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ if (peerSupportedSignAlgs != null) {
+ supportedSignAlgs = peerSupportedSignAlgs;
+ } else {
+ SignatureAndHashAlgorithm algorithm = null;
+
+ // we may optimize the performance
+ switch (keyExchange) {
+ // If the negotiated key exchange algorithm is one of
+ // (RSA, DHE_RSA, DH_RSA, RSA_PSK, ECDH_RSA, ECDHE_RSA),
+ // behave as if client had sent the value {sha1,rsa}.
+ case K_RSA:
+ case K_DHE_RSA:
+ case K_DH_RSA:
+ // case K_RSA_PSK:
+ case K_ECDH_RSA:
+ case K_ECDHE_RSA:
+ algorithm = SignatureAndHashAlgorithm.valueOf(
+ HashAlgorithm.SHA1.value,
+ SignatureAlgorithm.RSA.value, 0);
+ break;
+ // If the negotiated key exchange algorithm is one of
+ // (DHE_DSS, DH_DSS), behave as if the client had
+ // sent the value {sha1,dsa}.
+ case K_DHE_DSS:
+ case K_DH_DSS:
+ algorithm = SignatureAndHashAlgorithm.valueOf(
+ HashAlgorithm.SHA1.value,
+ SignatureAlgorithm.DSA.value, 0);
+ break;
+ // If the negotiated key exchange algorithm is one of
+ // (ECDH_ECDSA, ECDHE_ECDSA), behave as if the client
+ // had sent value {sha1,ecdsa}.
+ case K_ECDH_ECDSA:
+ case K_ECDHE_ECDSA:
+ algorithm = SignatureAndHashAlgorithm.valueOf(
+ HashAlgorithm.SHA1.value,
+ SignatureAlgorithm.ECDSA.value, 0);
+ break;
+ default:
+ // no peer supported signature algorithms
+ }
+
+ if (algorithm == null) {
+ supportedSignAlgs =
+ Collections.<SignatureAndHashAlgorithm>emptySet();
+ } else {
+ supportedSignAlgs =
+ new ArrayList<SignatureAndHashAlgorithm>(1);
+ supportedSignAlgs.add(algorithm);
+ }
+
+ // Sets the peer supported signature algorithm to use in KM
+ // temporarily.
+ session.setPeerSupportedSignatureAlgorithms(supportedSignAlgs);
+ }
+ }
+
switch (keyExchange) {
case K_RSA:
+ // need RSA certs for authentication
+ if (setupPrivateKeyAndChain("RSA") == false) {
+ return false;
+ }
+ break;
case K_RSA_EXPORT:
- case K_DHE_RSA:
- case K_ECDHE_RSA:
// need RSA certs for authentication
if (setupPrivateKeyAndChain("RSA") == false) {
return false;
}
- if (keyExchange == K_RSA_EXPORT) {
- try {
- if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) {
- if (!setupEphemeralRSAKeys(suite.exportable)) {
- return false;
- }
- }
- } catch (RuntimeException e) {
- // could not determine keylength, ignore key
+ try {
+ if (JsseJce.getRSAKeyLength(certs[0].getPublicKey()) > 512) {
+ if (!setupEphemeralRSAKeys(suite.exportable)) {
+ return false;
+ }
+ }
+ } catch (RuntimeException e) {
+ // could not determine keylength, ignore key
+ return false;
+ }
+ break;
+ case K_DHE_RSA:
+ // get preferable peer signature algorithm for server key exchange
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ preferableSignatureAlgorithm =
+ SignatureAndHashAlgorithm.getPreferableAlgorithm(
+ supportedSignAlgs, "RSA");
+ if (preferableSignatureAlgorithm == null) {
return false;
}
- } else if (keyExchange == K_DHE_RSA) {
- setupEphemeralDHKeys(suite.exportable);
- } else if (keyExchange == K_ECDHE_RSA) {
- if (setupEphemeralECDHKeys() == false) {
+ }
+
+ // 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");
+ if (preferableSignatureAlgorithm == null) {
return false;
}
- } // else nothing more to do for K_RSA
+ }
+
+ // need RSA certs for authentication
+ if (setupPrivateKeyAndChain("RSA") == false) {
+ return false;
+ }
+ if (setupEphemeralECDHKeys() == false) {
+ return false;
+ }
break;
case K_DHE_DSS:
+ // get preferable peer signature algorithm for server key exchange
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ preferableSignatureAlgorithm =
+ SignatureAndHashAlgorithm.getPreferableAlgorithm(
+ supportedSignAlgs, "DSA");
+ if (preferableSignatureAlgorithm == null) {
+ return false;
+ }
+ }
+
// need DSS certs for authentication
if (setupPrivateKeyAndChain("DSA") == false) {
return false;
@@ -877,6 +1078,16 @@
setupEphemeralDHKeys(suite.exportable);
break;
case K_ECDHE_ECDSA:
+ // get preferable peer signature algorithm for server key exchange
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ preferableSignatureAlgorithm =
+ SignatureAndHashAlgorithm.getPreferableAlgorithm(
+ supportedSignAlgs, "ECDSA");
+ if (preferableSignatureAlgorithm == null) {
+ return false;
+ }
+ }
+
// need EC cert signed using EC
if (setupPrivateKeyAndChain("EC_EC") == false) {
return false;
@@ -921,6 +1132,14 @@
throw new RuntimeException("Unrecognized cipherSuite: " + suite);
}
setCipherSuite(suite);
+
+ // set the peer implicit supported signature algorithms
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ if (peerSupportedSignAlgs == null) {
+ setPeerSupportedSignAlgs(supportedSignAlgs);
+ // we had alreay update the session
+ }
+ }
return true;
}
@@ -1170,6 +1389,24 @@
mesg.print(System.out);
}
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ SignatureAndHashAlgorithm signAlg =
+ mesg.getPreferableSignatureAlgorithm();
+ if (signAlg == null) {
+ throw new SSLHandshakeException(
+ "Illegal CertificateVerify message");
+ }
+
+ String hashAlg =
+ SignatureAndHashAlgorithm.getHashAlgorithmName(signAlg);
+ if (hashAlg == null || hashAlg.length() == 0) {
+ throw new SSLHandshakeException(
+ "No supported hash algorithm");
+ }
+
+ handshakeHash.setCertificateVerifyAlg(hashAlg);
+ }
+
try {
PublicKey publicKey =
session.getPeerCertificates()[0].getPublicKey();
@@ -1225,8 +1462,8 @@
* Verify the client's message with the "before" digest of messages,
* and forget about continuing to use that digest.
*/
- boolean verified = mesg.verify(protocolVersion, handshakeHash,
- Finished.CLIENT, session.getMasterSecret());
+ boolean verified = mesg.verify(handshakeHash, Finished.CLIENT,
+ session.getMasterSecret());
if (!verified) {
fatalSE(Alerts.alert_handshake_failure,
@@ -1281,7 +1518,7 @@
output.flush();
Finished mesg = new Finished(protocolVersion, handshakeHash,
- Finished.SERVER, session.getMasterSecret());
+ Finished.SERVER, session.getMasterSecret(), cipherSuite);
/*
* Send the change_cipher_spec record; then our Finished handshake
@@ -1351,7 +1588,8 @@
* ServerKeyExchange) message that was sent to it by the server. That's
* decrypted using the private key before we get here.
*/
- private SecretKey clientKeyExchange(RSAClientKeyExchange mesg) throws IOException {
+ private SecretKey clientKeyExchange(RSAClientKeyExchange mesg)
+ throws IOException {
if (debug != null && Debug.isOn("handshake")) {
mesg.print(System.out);
@@ -1379,6 +1617,11 @@
* not *REQUIRED*, this is an acceptable condition.)
*/
if (doClientAuth == SSLEngineImpl.clauth_requested) {
+ // Smart (aka stupid) to forecast that no CertificateVerify
+ // message will be received.
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ handshakeHash.setCertificateVerifyAlg(null);
+ }
return;
} else {
fatalSE(Alerts.alert_bad_certificate,
@@ -1405,26 +1648,23 @@
authType = "UNKNOWN";
}
- String identificator = getHostnameVerificationSE();
if (tm instanceof X509ExtendedTrustManager) {
- ((X509ExtendedTrustManager)tm).checkClientTrusted(
- (peerCerts != null ?
- peerCerts.clone() :
- null),
+ if (conn != null) {
+ ((X509ExtendedTrustManager)tm).checkClientTrusted(
+ peerCerts.clone(),
authType,
- getHostSE(),
- identificator);
+ conn);
+ } else {
+ ((X509ExtendedTrustManager)tm).checkClientTrusted(
+ peerCerts.clone(),
+ authType,
+ engine);
+ }
} else {
- if (identificator != null) {
- throw new RuntimeException(
- "trust manager does not support peer identification");
- }
-
- tm.checkClientTrusted(
- (peerCerts != null ?
- peerCerts.clone() :
- peerCerts),
- authType);
+ // Unlikely to happen, because we have wrapped the old
+ // X509TrustManager with the new X509ExtendedTrustManager.
+ throw new CertificateException(
+ "Improper X509TrustManager implementation");
}
} catch (CertificateException e) {
// This will throw an exception, so include the original error.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/ssl/SignatureAndHashAlgorithm.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2010, 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.ssl;
+
+import java.security.AlgorithmConstraints;
+import java.security.CryptoPrimitive;
+
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.EnumSet;
+import java.util.TreeMap;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.ArrayList;
+
+/**
+ * Signature and hash algorithm.
+ *
+ * [RFC5246] The client uses the "signature_algorithms" extension to
+ * indicate to the server which signature/hash algorithm pairs may be
+ * used in digital signatures. The "extension_data" field of this
+ * extension contains a "supported_signature_algorithms" value.
+ *
+ * enum {
+ * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
+ * sha512(6), (255)
+ * } HashAlgorithm;
+ *
+ * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
+ * SignatureAlgorithm;
+ *
+ * struct {
+ * HashAlgorithm hash;
+ * SignatureAlgorithm signature;
+ * } SignatureAndHashAlgorithm;
+ */
+final class SignatureAndHashAlgorithm {
+
+ // minimum priority for default enabled algorithms
+ final static int SUPPORTED_ALG_PRIORITY_MAX_NUM = 0x00F0;
+
+ // performance optimization
+ private final static Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
+ EnumSet.of(CryptoPrimitive.SIGNATURE);
+
+ // supported pairs of signature and hash algorithm
+ private final static Map<Integer, SignatureAndHashAlgorithm> supportedMap;
+ private final static Map<Integer, SignatureAndHashAlgorithm> priorityMap;
+
+ // the hash algorithm
+ private HashAlgorithm hash;
+
+ // the signature algorithm
+ private SignatureAlgorithm signature;
+
+ // id in 16 bit MSB format, i.e. 0x0603 for SHA512withECDSA
+ private int id;
+
+ // the standard algorithm name, for example "SHA512withECDSA"
+ private String algorithm;
+
+ // Priority for the preference order. The lower the better.
+ //
+ // If the algorithm is unsupported, its priority should be bigger
+ // than SUPPORTED_ALG_PRIORITY_MAX_NUM.
+ private int priority;
+
+ // constructor for supported algorithm
+ private SignatureAndHashAlgorithm(HashAlgorithm hash,
+ SignatureAlgorithm signature, String algorithm, int priority) {
+ this.hash = hash;
+ this.signature = signature;
+ this.algorithm = algorithm;
+ this.id = ((hash.value & 0xFF) << 8) | (signature.value & 0xFF);
+ this.priority = priority;
+ }
+
+ // constructor for unsupported algorithm
+ private SignatureAndHashAlgorithm(String algorithm, int id, int sequence) {
+ this.hash = HashAlgorithm.valueOf((id >> 8) & 0xFF);
+ this.signature = SignatureAlgorithm.valueOf(id & 0xFF);
+ this.algorithm = algorithm;
+ this.id = id;
+
+ // add one more to the sequece number, in case that the number is zero
+ this.priority = SUPPORTED_ALG_PRIORITY_MAX_NUM + sequence + 1;
+ }
+
+ // Note that we do not use the sequence argument for supported algorithms,
+ // so please don't sort by comparing the objects read from handshake
+ // messages.
+ static SignatureAndHashAlgorithm valueOf(int hash,
+ int signature, int sequence) {
+ hash &= 0xFF;
+ signature &= 0xFF;
+
+ int id = (hash << 8) | signature;
+ SignatureAndHashAlgorithm signAlg = supportedMap.get(id);
+ if (signAlg == null) {
+ // unsupported algorithm
+ signAlg = new SignatureAndHashAlgorithm(
+ "Unknown (hash:0x" + Integer.toString(hash, 16) +
+ ", signature:0x" + Integer.toString(signature, 16) + ")",
+ id, sequence);
+ }
+
+ return signAlg;
+ }
+
+ int getHashValue() {
+ return (id >> 8) & 0xFF;
+ }
+
+ int getSignatureValue() {
+ return id & 0xFF;
+ }
+
+ String getAlgorithmName() {
+ return algorithm;
+ }
+
+ // return the size of a SignatureAndHashAlgorithm structure in TLS record
+ static int sizeInRecord() {
+ return 2;
+ }
+
+ // Get local supported algorithm collection complying to
+ // algorithm constraints
+ static Collection<SignatureAndHashAlgorithm>
+ getSupportedAlgorithms(AlgorithmConstraints constraints) {
+
+ Collection<SignatureAndHashAlgorithm> supported =
+ new ArrayList<SignatureAndHashAlgorithm>();
+ synchronized (priorityMap) {
+ for (SignatureAndHashAlgorithm sigAlg : priorityMap.values()) {
+ if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM &&
+ constraints.permits(SIGNATURE_PRIMITIVE_SET,
+ sigAlg.algorithm, null)) {
+ supported.add(sigAlg);
+ }
+ }
+ }
+
+ return supported;
+ }
+
+ // Get supported algorithm collection from an untrusted collection
+ static Collection<SignatureAndHashAlgorithm> getSupportedAlgorithms(
+ Collection<SignatureAndHashAlgorithm> algorithms ) {
+ Collection<SignatureAndHashAlgorithm> supported =
+ new ArrayList<SignatureAndHashAlgorithm>();
+ for (SignatureAndHashAlgorithm sigAlg : algorithms) {
+ if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM) {
+ supported.add(sigAlg);
+ }
+ }
+
+ return supported;
+ }
+
+ static String[] getAlgorithmNames(
+ Collection<SignatureAndHashAlgorithm> algorithms) {
+ ArrayList<String> algorithmNames = new ArrayList<String>();
+ if (algorithms != null) {
+ for (SignatureAndHashAlgorithm sigAlg : algorithms) {
+ algorithmNames.add(sigAlg.algorithm);
+ }
+ }
+
+ String[] array = new String[algorithmNames.size()];
+ return algorithmNames.toArray(array);
+ }
+
+ static Set<String> getHashAlgorithmNames(
+ Collection<SignatureAndHashAlgorithm> algorithms) {
+ Set<String> algorithmNames = new HashSet<String>();
+ if (algorithms != null) {
+ for (SignatureAndHashAlgorithm sigAlg : algorithms) {
+ if (sigAlg.hash.value > 0) {
+ algorithmNames.add(sigAlg.hash.standardName);
+ }
+ }
+ }
+
+ return algorithmNames;
+ }
+
+ static String getHashAlgorithmName(SignatureAndHashAlgorithm algorithm) {
+ return algorithm.hash.standardName;
+ }
+
+ private static void supports(HashAlgorithm hash,
+ SignatureAlgorithm signature, String algorithm, int priority) {
+
+ SignatureAndHashAlgorithm pair =
+ new SignatureAndHashAlgorithm(hash, signature, algorithm, priority);
+ if (supportedMap.put(pair.id, pair) != null) {
+ throw new RuntimeException(
+ "Duplicate SignatureAndHashAlgorithm definition, id: " +
+ pair.id);
+ }
+ if (priorityMap.put(pair.priority, pair) != null) {
+ throw new RuntimeException(
+ "Duplicate SignatureAndHashAlgorithm definition, priority: " +
+ pair.priority);
+ }
+ }
+
+ static SignatureAndHashAlgorithm getPreferableAlgorithm(
+ Collection<SignatureAndHashAlgorithm> algorithms, String expected) {
+
+ if (expected == null && !algorithms.isEmpty()) {
+ for (SignatureAndHashAlgorithm sigAlg : algorithms) {
+ if (sigAlg.priority <= SUPPORTED_ALG_PRIORITY_MAX_NUM) {
+ return sigAlg;
+ }
+ }
+
+ return null; // no supported 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)) {
+ return algorithm;
+ }
+ }
+
+ return null;
+ }
+
+ 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);
+
+ 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;
+
+ private HashAlgorithm(String name, String standardName, int value) {
+ this.name = name;
+ this.standardName = standardName;
+ this.value = value;
+ }
+
+ static HashAlgorithm valueOf(int value) {
+ HashAlgorithm algorithm = UNDEFINED;
+ switch (value) {
+ case 0:
+ algorithm = NONE;
+ break;
+ case 1:
+ algorithm = MD5;
+ break;
+ case 2:
+ algorithm = SHA1;
+ break;
+ case 3:
+ algorithm = SHA224;
+ break;
+ case 4:
+ algorithm = SHA256;
+ break;
+ case 5:
+ algorithm = SHA384;
+ break;
+ case 6:
+ algorithm = SHA512;
+ break;
+ }
+
+ return algorithm;
+ }
+ }
+
+ static enum SignatureAlgorithm {
+ UNDEFINED("undefined", -1),
+ ANONYMOUS("anonymous", 0),
+ RSA( "rsa", 1),
+ DSA( "dsa", 2),
+ ECDSA( "ecdsa", 3);
+
+ final String name; // not the standard signature algorithm name
+ // except the UNDEFINED, other names are defined
+ // by TLS 1.2 protocol
+ final int value;
+
+ private SignatureAlgorithm(String name, int value) {
+ this.name = name;
+ this.value = value;
+ }
+
+ static SignatureAlgorithm valueOf(int value) {
+ SignatureAlgorithm algorithm = UNDEFINED;
+ switch (value) {
+ case 0:
+ algorithm = ANONYMOUS;
+ break;
+ case 1:
+ algorithm = RSA;
+ break;
+ case 2:
+ algorithm = DSA;
+ break;
+ case 3:
+ algorithm = ECDSA;
+ break;
+ }
+
+ return algorithm;
+ }
+ }
+
+ static {
+ supportedMap = Collections.synchronizedSortedMap(
+ new TreeMap<Integer, SignatureAndHashAlgorithm>());
+ priorityMap = Collections.synchronizedSortedMap(
+ new TreeMap<Integer, SignatureAndHashAlgorithm>());
+
+ synchronized (supportedMap) {
+ int p = SUPPORTED_ALG_PRIORITY_MAX_NUM;
+ supports(HashAlgorithm.MD5, SignatureAlgorithm.RSA,
+ "MD5withRSA", --p);
+ supports(HashAlgorithm.SHA1, SignatureAlgorithm.DSA,
+ "SHA1withDSA", --p);
+ supports(HashAlgorithm.SHA1, SignatureAlgorithm.RSA,
+ "SHA1withRSA", --p);
+ supports(HashAlgorithm.SHA1, SignatureAlgorithm.ECDSA,
+ "SHA1withECDSA", --p);
+ supports(HashAlgorithm.SHA224, SignatureAlgorithm.RSA,
+ "SHA224withRSA", --p);
+ supports(HashAlgorithm.SHA224, SignatureAlgorithm.ECDSA,
+ "SHA224withECDSA", --p);
+ supports(HashAlgorithm.SHA256, SignatureAlgorithm.RSA,
+ "SHA256withRSA", --p);
+ supports(HashAlgorithm.SHA256, SignatureAlgorithm.ECDSA,
+ "SHA256withECDSA", --p);
+ supports(HashAlgorithm.SHA384, SignatureAlgorithm.RSA,
+ "SHA384withRSA", --p);
+ supports(HashAlgorithm.SHA384, SignatureAlgorithm.ECDSA,
+ "SHA384withECDSA", --p);
+ supports(HashAlgorithm.SHA512, SignatureAlgorithm.RSA,
+ "SHA512withRSA", --p);
+ supports(HashAlgorithm.SHA512, SignatureAlgorithm.ECDSA,
+ "SHA512withECDSA", --p);
+ }
+ }
+}
+
--- a/jdk/src/share/classes/sun/security/ssl/SunJSSE.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/SunJSSE.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, 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
@@ -38,7 +38,7 @@
*
* SunJSSE now supports an experimental FIPS compliant mode when used with an
* appropriate FIPS certified crypto provider. In FIPS mode, we:
- * . allow only TLS 1.0
+ * . allow only TLS 1.0 or later
* . allow only FIPS approved ciphersuites
* . perform all crypto in the FIPS crypto provider
*
@@ -129,7 +129,8 @@
return t;
}
- private SunJSSE(java.security.Provider cryptoProvider, String providerName) {
+ private SunJSSE(java.security.Provider cryptoProvider,
+ String providerName) {
super("SunJSSE", 1.6d, fipsInfo + providerName + ")");
subclassCheck();
if (cryptoProvider == null) {
@@ -211,6 +212,10 @@
"sun.security.ssl.SSLContextImpl");
put("SSLContext.TLSv1",
"sun.security.ssl.SSLContextImpl");
+ put("SSLContext.TLSv1.1",
+ "sun.security.ssl.SSLContextImpl");
+ put("SSLContext.TLSv1.2",
+ "sun.security.ssl.SSLContextImpl");
put("SSLContext.Default",
"sun.security.ssl.DefaultSSLContextImpl");
--- a/jdk/src/share/classes/sun/security/ssl/TrustManagerFactoryImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/TrustManagerFactoryImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2010, 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
--- a/jdk/src/share/classes/sun/security/ssl/X509KeyManagerImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/X509KeyManagerImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2010, 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
@@ -38,6 +38,8 @@
import javax.net.ssl.*;
+import sun.security.provider.certpath.AlgorithmChecker;
+
/**
* The new X509 key manager implementation. The main differences to the
* old SunX509 key manager are:
@@ -111,36 +113,98 @@
public String chooseClientAlias(String[] keyTypes, Principal[] issuers,
Socket socket) {
- return chooseAlias(getKeyTypes(keyTypes), issuers, CheckType.CLIENT);
+ return chooseAlias(getKeyTypes(keyTypes), issuers, CheckType.CLIENT,
+ getAlgorithmConstraints(socket));
}
public String chooseEngineClientAlias(String[] keyTypes,
Principal[] issuers, SSLEngine engine) {
- return chooseAlias(getKeyTypes(keyTypes), issuers, CheckType.CLIENT);
+ return chooseAlias(getKeyTypes(keyTypes), issuers, CheckType.CLIENT,
+ getAlgorithmConstraints(engine));
}
public String chooseServerAlias(String keyType,
Principal[] issuers, Socket socket) {
- return chooseAlias(getKeyTypes(keyType), issuers, CheckType.SERVER);
+ return chooseAlias(getKeyTypes(keyType), issuers, CheckType.SERVER,
+ getAlgorithmConstraints(socket));
}
public String chooseEngineServerAlias(String keyType,
Principal[] issuers, SSLEngine engine) {
- return chooseAlias(getKeyTypes(keyType), issuers, CheckType.SERVER);
+ return chooseAlias(getKeyTypes(keyType), issuers, CheckType.SERVER,
+ getAlgorithmConstraints(engine));
}
public String[] getClientAliases(String keyType, Principal[] issuers) {
- return getAliases(keyType, issuers, CheckType.CLIENT);
+ return getAliases(keyType, issuers, CheckType.CLIENT, null);
}
public String[] getServerAliases(String keyType, Principal[] issuers) {
- return getAliases(keyType, issuers, CheckType.SERVER);
+ return getAliases(keyType, issuers, CheckType.SERVER, null);
}
//
// implementation private methods
//
+ // Gets algorithm constraints of the socket.
+ private AlgorithmConstraints getAlgorithmConstraints(Socket socket) {
+ if (socket != null && socket.isConnected() &&
+ socket instanceof SSLSocket) {
+
+ SSLSocket sslSocket = (SSLSocket)socket;
+ SSLSession session = sslSocket.getHandshakeSession();
+
+ if (session != null) {
+ ProtocolVersion protocolVersion =
+ ProtocolVersion.valueOf(session.getProtocol());
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ String[] peerSupportedSignAlgs = null;
+
+ if (session instanceof ExtendedSSLSession) {
+ ExtendedSSLSession extSession =
+ (ExtendedSSLSession)session;
+ peerSupportedSignAlgs =
+ extSession.getPeerSupportedSignatureAlgorithms();
+ }
+
+ return new SSLAlgorithmConstraints(
+ sslSocket, peerSupportedSignAlgs, true);
+ }
+ }
+
+ return new SSLAlgorithmConstraints(sslSocket, true);
+ }
+
+ return new SSLAlgorithmConstraints((SSLSocket)null, true);
+ }
+
+ // Gets algorithm constraints of the engine.
+ private AlgorithmConstraints getAlgorithmConstraints(SSLEngine engine) {
+ if (engine != null) {
+ SSLSession session = engine.getHandshakeSession();
+ if (session != null) {
+ ProtocolVersion protocolVersion =
+ ProtocolVersion.valueOf(session.getProtocol());
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ String[] peerSupportedSignAlgs = null;
+
+ if (session instanceof ExtendedSSLSession) {
+ ExtendedSSLSession extSession =
+ (ExtendedSSLSession)session;
+ peerSupportedSignAlgs =
+ extSession.getPeerSupportedSignatureAlgorithms();
+ }
+
+ return new SSLAlgorithmConstraints(
+ engine, peerSupportedSignAlgs, true);
+ }
+ }
+ }
+
+ return new SSLAlgorithmConstraints(engine, true);
+ }
+
// we construct the alias we return to JSSE as seen in the code below
// a unique id is included to allow us to reliably cache entries
// between the calls to getCertificateChain() and getPrivateKey()
@@ -196,6 +260,13 @@
private static class KeyType {
final String keyAlgorithm;
+
+ // In TLS 1.2, the signature algorithm has been obsoleted by the
+ // supported_signature_algorithms, and the certificate type no longer
+ // restricts the algorithm used to sign the certificate.
+ // However, because we don't support certificate type checking other
+ // than rsa_sign, dss_sign and ecdsa_sign, we don't have to check the
+ // protocol version here.
final String sigKeyAlgorithm;
KeyType(String algorithm) {
@@ -218,7 +289,8 @@
}
if (chain.length > 1) {
// if possible, check the public key in the issuer cert
- return sigKeyAlgorithm.equals(chain[1].getPublicKey().getAlgorithm());
+ return sigKeyAlgorithm.equals(
+ chain[1].getPublicKey().getAlgorithm());
} else {
// Check the signature algorithm of the certificate itself.
// Look for the "withRSA" in "SHA1withRSA", etc.
@@ -231,7 +303,8 @@
}
private static List<KeyType> getKeyTypes(String ... keyTypes) {
- if ((keyTypes == null) || (keyTypes.length == 0) || (keyTypes[0] == null)) {
+ if ((keyTypes == null) ||
+ (keyTypes.length == 0) || (keyTypes[0] == null)) {
return null;
}
List<KeyType> list = new ArrayList<KeyType>(keyTypes.length);
@@ -254,8 +327,8 @@
* with appropriate key usage to certs with the wrong key usage.
* return the first one of them.
*/
- private String chooseAlias(List<KeyType> keyTypeList,
- Principal[] issuers, CheckType checkType) {
+ private String chooseAlias(List<KeyType> keyTypeList, Principal[] issuers,
+ CheckType checkType, AlgorithmConstraints constraints) {
if (keyTypeList == null || keyTypeList.size() == 0) {
return null;
}
@@ -264,8 +337,8 @@
List<EntryStatus> allResults = null;
for (int i = 0, n = builders.size(); i < n; i++) {
try {
- List<EntryStatus> results =
- getAliases(i, keyTypeList, issuerSet, false, checkType);
+ List<EntryStatus> results = getAliases(i, keyTypeList,
+ issuerSet, false, checkType, constraints);
if (results != null) {
// the results will either be a single perfect match
// or 1 or more imperfect matches
@@ -308,7 +381,7 @@
* The perfect matches will be first in the array.
*/
public String[] getAliases(String keyType, Principal[] issuers,
- CheckType checkType) {
+ CheckType checkType, AlgorithmConstraints constraints) {
if (keyType == null) {
return null;
}
@@ -318,8 +391,8 @@
List<EntryStatus> allResults = null;
for (int i = 0, n = builders.size(); i < n; i++) {
try {
- List<EntryStatus> results =
- getAliases(i, keyTypeList, issuerSet, true, checkType);
+ List<EntryStatus> results = getAliases(i, keyTypeList,
+ issuerSet, true, checkType, constraints);
if (results != null) {
if (allResults == null) {
allResults = new ArrayList<EntryStatus>();
@@ -438,7 +511,8 @@
try {
// check extended key usage
List<String> certEku = cert.getExtendedKeyUsage();
- if ((certEku != null) && Collections.disjoint(validEku, certEku)) {
+ if ((certEku != null) &&
+ Collections.disjoint(validEku, certEku)) {
// if extension present and it does not contain any of
// the valid EKU OIDs, return extension_mismatch
return CheckResult.EXTENSION_MISMATCH;
@@ -534,7 +608,8 @@
*/
private List<EntryStatus> getAliases(int builderIndex,
List<KeyType> keyTypes, Set<Principal> issuerSet,
- boolean findAll, CheckType checkType) throws Exception {
+ boolean findAll, CheckType checkType,
+ AlgorithmConstraints constraints) throws Exception {
Builder builder = builders.get(builderIndex);
KeyStore ks = builder.getKeyStore();
List<EntryStatus> results = null;
@@ -552,6 +627,19 @@
// must be secret key entry, ignore
continue;
}
+
+ boolean incompatible = false;
+ for (Certificate cert : chain) {
+ if (cert instanceof X509Certificate == false) {
+ // not an X509Certificate, ignore this alias
+ incompatible = true;
+ break;
+ }
+ }
+ if (incompatible) {
+ continue;
+ }
+
// check keytype
int keyIndex = -1;
int j = 0;
@@ -573,10 +661,6 @@
if (issuerSet != null) {
boolean found = false;
for (Certificate cert : chain) {
- if (cert instanceof X509Certificate == false) {
- // not an X509Certificate, ignore this entry
- break;
- }
X509Certificate xcert = (X509Certificate)cert;
if (issuerSet.contains(xcert.getIssuerX500Principal())) {
found = true;
@@ -591,6 +675,19 @@
continue;
}
}
+
+ // check the algorithm constraints
+ if (constraints != null &&
+ !conformsToAlgorithmConstraints(constraints, chain)) {
+
+ if (useDebug) {
+ debug.println("Ignoring alias " + alias +
+ ": certificate list does not conform to " +
+ "algorithm constraints");
+ }
+ continue;
+ }
+
if (date == null) {
date = new Date();
}
@@ -616,4 +713,29 @@
return results;
}
+ private static boolean conformsToAlgorithmConstraints(
+ AlgorithmConstraints constraints, Certificate[] chain) {
+
+ AlgorithmChecker checker = new AlgorithmChecker(constraints);
+ try {
+ checker.init(false);
+ } catch (CertPathValidatorException cpve) {
+ // unlikely to happen
+ return false;
+ }
+
+ // It is a forward checker, so we need to check from trust to target.
+ for (int i = chain.length - 1; i >= 0; i--) {
+ Certificate cert = chain[i];
+ try {
+ // We don't care about the unresolved critical extensions.
+ checker.check(cert, Collections.<String>emptySet());
+ } catch (CertPathValidatorException cpve) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
}
--- a/jdk/src/share/classes/sun/security/ssl/X509TrustManagerImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/X509TrustManagerImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, 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
@@ -26,14 +26,15 @@
package sun.security.ssl;
+import java.net.Socket;
+import javax.net.ssl.SSLSession;
+
import java.util.*;
import java.security.*;
import java.security.cert.*;
import javax.net.ssl.*;
-import com.sun.net.ssl.internal.ssl.X509ExtendedTrustManager;
-
import sun.security.validator.*;
import sun.security.util.HostnameChecker;
@@ -41,7 +42,7 @@
/**
* This class implements the SunJSSE X.509 trust manager using the internal
* validator API in J2SE core. The logic in this class is minimal.<p>
- *
+ * <p>
* This class supports both the Simple validation algorithm from previous
* JSSE versions and PKIX validation. Currently, it is not possible for the
* application to specify PKIX parameters other than trust anchors. This will
@@ -50,19 +51,10 @@
* classes.
*
* @author Andreas Sterbenz
- * @author Xuelei Fan
*/
final class X509TrustManagerImpl extends X509ExtendedTrustManager
implements X509TrustManager {
- /**
- * Flag indicating whether to enable revocation check for the PKIX trust
- * manager. Typically, this will only work if the PKIX implementation
- * supports CRL distribution points as we do not manually setup CertStores.
- */
- private final static boolean checkRevocation =
- Debug.getBooleanProperty("com.sun.net.ssl.checkRevocation", false);
-
private final String validatorType;
/**
@@ -103,6 +95,199 @@
showTrustedCerts();
}
+ @Override
+ public void checkClientTrusted(X509Certificate chain[], String authType)
+ throws CertificateException {
+ checkTrusted(chain, authType, (Socket)null, true);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate chain[], String authType)
+ throws CertificateException {
+ checkTrusted(chain, authType, (Socket)null, false);
+ }
+
+ @Override
+ public X509Certificate[] getAcceptedIssuers() {
+ X509Certificate[] certsArray = new X509Certificate[trustedCerts.size()];
+ trustedCerts.toArray(certsArray);
+ return certsArray;
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType,
+ Socket socket) throws CertificateException {
+ checkTrusted(chain, authType, socket, true);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType,
+ Socket socket) throws CertificateException {
+ checkTrusted(chain, authType, socket, false);
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] chain, String authType,
+ SSLEngine engine) throws CertificateException {
+ checkTrusted(chain, authType, engine, true);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] chain, String authType,
+ SSLEngine engine) throws CertificateException {
+ checkTrusted(chain, authType, engine, false);
+ }
+
+ private Validator checkTrustedInit(X509Certificate[] chain,
+ String authType, boolean isClient) {
+ if (chain == null || chain.length == 0) {
+ throw new IllegalArgumentException(
+ "null or zero-length certificate chain");
+ }
+
+ if (authType == null || authType.length() == 0) {
+ throw new IllegalArgumentException(
+ "null or zero-length authentication type");
+ }
+
+ Validator v = null;
+ if (isClient) {
+ v = clientValidator;
+ if (v == null) {
+ synchronized (this) {
+ v = clientValidator;
+ if (v == null) {
+ v = getValidator(Validator.VAR_TLS_CLIENT);
+ clientValidator = v;
+ }
+ }
+ }
+ } else {
+ // assume double checked locking with a volatile flag works
+ // (guaranteed under the new Tiger memory model)
+ v = serverValidator;
+ if (v == null) {
+ synchronized (this) {
+ v = serverValidator;
+ if (v == null) {
+ v = getValidator(Validator.VAR_TLS_SERVER);
+ serverValidator = v;
+ }
+ }
+ }
+ }
+
+ return v;
+ }
+
+
+ private void checkTrusted(X509Certificate[] chain, String authType,
+ Socket socket, boolean isClient) throws CertificateException {
+ Validator v = checkTrustedInit(chain, authType, isClient);
+
+ AlgorithmConstraints constraints = null;
+ if ((socket != null) && socket.isConnected() &&
+ (socket instanceof SSLSocket)) {
+
+ SSLSocket sslSocket = (SSLSocket)socket;
+ SSLSession session = sslSocket.getHandshakeSession();
+ if (session == null) {
+ throw new CertificateException("No handshake session");
+ }
+
+ // check endpoint identity
+ String identityAlg = sslSocket.getSSLParameters().
+ getEndpointIdentificationAlgorithm();
+ if (identityAlg != null && identityAlg.length() != 0) {
+ String hostname = session.getPeerHost();
+ checkIdentity(hostname, chain[0], identityAlg);
+ }
+
+ // create the algorithm constraints
+ ProtocolVersion protocolVersion =
+ ProtocolVersion.valueOf(session.getProtocol());
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ if (session instanceof ExtendedSSLSession) {
+ ExtendedSSLSession extSession =
+ (ExtendedSSLSession)session;
+ String[] localSupportedSignAlgs =
+ extSession.getLocalSupportedSignatureAlgorithms();
+
+ constraints = new SSLAlgorithmConstraints(
+ sslSocket, localSupportedSignAlgs, false);
+ } else {
+ constraints =
+ new SSLAlgorithmConstraints(sslSocket, false);
+ }
+ } else {
+ constraints = new SSLAlgorithmConstraints(sslSocket, false);
+ }
+ }
+
+ X509Certificate[] trustedChain = null;
+ if (isClient) {
+ trustedChain = validate(v, chain, constraints, null);
+ } else {
+ trustedChain = validate(v, chain, constraints, authType);
+ }
+ if (debug != null && Debug.isOn("trustmanager")) {
+ System.out.println("Found trusted certificate:");
+ System.out.println(trustedChain[trustedChain.length - 1]);
+ }
+ }
+
+ private void checkTrusted(X509Certificate[] chain, String authType,
+ SSLEngine engine, boolean isClient) throws CertificateException {
+ Validator v = checkTrustedInit(chain, authType, isClient);
+
+ AlgorithmConstraints constraints = null;
+ if (engine != null) {
+ SSLSession session = engine.getHandshakeSession();
+ if (session == null) {
+ throw new CertificateException("No handshake session");
+ }
+
+ // check endpoint identity
+ String identityAlg = engine.getSSLParameters().
+ getEndpointIdentificationAlgorithm();
+ if (identityAlg != null && identityAlg.length() != 0) {
+ String hostname = session.getPeerHost();
+ checkIdentity(hostname, chain[0], identityAlg);
+ }
+
+ // create the algorithm constraints
+ ProtocolVersion protocolVersion =
+ ProtocolVersion.valueOf(session.getProtocol());
+ if (protocolVersion.v >= ProtocolVersion.TLS12.v) {
+ if (session instanceof ExtendedSSLSession) {
+ ExtendedSSLSession extSession =
+ (ExtendedSSLSession)session;
+ String[] localSupportedSignAlgs =
+ extSession.getLocalSupportedSignatureAlgorithms();
+
+ constraints = new SSLAlgorithmConstraints(
+ engine, localSupportedSignAlgs, false);
+ } else {
+ constraints =
+ new SSLAlgorithmConstraints(engine, false);
+ }
+ } else {
+ constraints = new SSLAlgorithmConstraints(engine, false);
+ }
+ }
+
+ X509Certificate[] trustedChain = null;
+ if (isClient) {
+ trustedChain = validate(v, chain, constraints, null);
+ } else {
+ trustedChain = validate(v, chain, constraints, authType);
+ }
+ if (debug != null && Debug.isOn("trustmanager")) {
+ System.out.println("Found trusted certificate:");
+ System.out.println(trustedChain[trustedChain.length - 1]);
+ }
+ }
+
private void showTrustedCerts() {
if (debug != null && Debug.isOn("trustmanager")) {
for (X509Certificate cert : trustedCerts) {
@@ -127,13 +312,6 @@
Validator v;
if (pkixParams == null) {
v = Validator.getInstance(validatorType, variant, trustedCerts);
- // if the PKIX validator is created from a KeyStore,
- // disable revocation checking
- if (v instanceof PKIXValidator) {
- PKIXValidator pkixValidator = (PKIXValidator)v;
- pkixValidator.getParameters().setRevocationEnabled
- (checkRevocation);
- }
} else {
v = Validator.getInstance(validatorType, variant, pkixParams);
}
@@ -141,150 +319,35 @@
}
private static X509Certificate[] validate(Validator v,
- X509Certificate[] chain, String authType) throws CertificateException {
+ X509Certificate[] chain, AlgorithmConstraints constraints,
+ String authType) throws CertificateException {
Object o = JsseJce.beginFipsProvider();
try {
- return v.validate(chain, null, authType);
+ return v.validate(chain, null, constraints, authType);
} finally {
JsseJce.endFipsProvider(o);
}
}
- /**
- * Returns true if the client certificate can be trusted.
+ /*
+ * Identify the peer by its certificate and hostname.
*
- * @param chain certificates which establish an identity for the client.
- * Chains of arbitrary length are supported, and certificates
- * marked internally as trusted will short-circuit signature checks.
- * @throws IllegalArgumentException if null or zero-length chain
- * is passed in for the chain parameter or if null or zero-length
- * string is passed in for the authType parameter.
- * @throws CertificateException if the certificate chain is not trusted
- * by this TrustManager.
- */
- public void checkClientTrusted(X509Certificate chain[], String authType)
- throws CertificateException {
- if (chain == null || chain.length == 0) {
- throw new IllegalArgumentException(
- "null or zero-length certificate chain");
- }
- if (authType == null || authType.length() == 0) {
- throw new IllegalArgumentException(
- "null or zero-length authentication type");
- }
-
- // assume double checked locking with a volatile flag works
- // (guaranteed under the new Tiger memory model)
- Validator v = clientValidator;
- if (v == null) {
- synchronized (this) {
- v = clientValidator;
- if (v == null) {
- v = getValidator(Validator.VAR_TLS_CLIENT);
- clientValidator = v;
- }
- }
- }
- X509Certificate[] trustedChain = validate(v, chain, null);
- if (debug != null && Debug.isOn("trustmanager")) {
- System.out.println("Found trusted certificate:");
- System.out.println(trustedChain[trustedChain.length - 1]);
- }
- }
-
- /**
- * Returns true if the server certifcate can be trusted.
- *
- * @param chain certificates which establish an identity for the server.
- * Chains of arbitrary length are supported, and certificates
- * marked internally as trusted will short-circuit signature checks.
- * @throws IllegalArgumentException if null or zero-length chain
- * is passed in for the chain parameter or if null or zero-length
- * string is passed in for the authType parameter.
- * @throws CertificateException if the certificate chain is not trusted
- * by this TrustManager.
+ * Lifted from sun.net.www.protocol.https.HttpsClient.
*/
- public void checkServerTrusted(X509Certificate chain[], String authType)
- throws CertificateException {
- if (chain == null || chain.length == 0) {
- throw new IllegalArgumentException(
- "null or zero-length certificate chain");
- }
- if (authType == null || authType.length() == 0) {
- throw new IllegalArgumentException(
- "null or zero-length authentication type");
- }
-
- // assume double checked locking with a volatile flag works
- // (guaranteed under the new Tiger memory model)
- Validator v = serverValidator;
- if (v == null) {
- synchronized (this) {
- v = serverValidator;
- if (v == null) {
- v = getValidator(Validator.VAR_TLS_SERVER);
- serverValidator = v;
- }
- }
- }
- X509Certificate[] trustedChain = validate(v, chain, authType);
- if (debug != null && Debug.isOn("trustmanager")) {
- System.out.println("Found trusted certificate:");
- System.out.println(trustedChain[trustedChain.length - 1]);
- }
- }
-
- /**
- * Returns a list of CAs accepted to authenticate entities for the
- * specified purpose.
- *
- * @param purpose activity for which CAs should be trusted
- * @return list of CAs accepted for authenticating such tasks
- */
- public X509Certificate[] getAcceptedIssuers() {
- X509Certificate[] certsArray = new X509Certificate[trustedCerts.size()];
- trustedCerts.toArray(certsArray);
- return certsArray;
- }
-
- /**
- * Given the partial or complete certificate chain provided by the
- * peer, check its identity and build a certificate path to a trusted
- * root, return if it can be validated and is trusted for client SSL
- * authentication based on the authentication type.
- */
- public void checkClientTrusted(X509Certificate[] chain, String authType,
- String hostname, String algorithm) throws CertificateException {
- checkClientTrusted(chain, authType);
- checkIdentity(hostname, chain[0], algorithm);
- }
-
- /**
- * Given the partial or complete certificate chain provided by the
- * peer, check its identity and build a certificate path to a trusted
- * root, return if it can be validated and is trusted for server SSL
- * authentication based on the authentication type.
- */
- public void checkServerTrusted(X509Certificate[] chain, String authType,
- String hostname, String algorithm) throws CertificateException {
- checkServerTrusted(chain, authType);
- checkIdentity(hostname, chain[0], algorithm);
- }
-
- // Identify the peer by its certificate and hostname.
- private void checkIdentity(String hostname, X509Certificate cert,
- String algorithm) throws CertificateException {
+ static void checkIdentity(String hostname, X509Certificate cert,
+ String algorithm) throws CertificateException {
if (algorithm != null && algorithm.length() != 0) {
// if IPv6 strip off the "[]"
- if (hostname != null && hostname.startsWith("[") &&
- hostname.endsWith("]")) {
- hostname = hostname.substring(1, hostname.length()-1);
+ if ((hostname != null) && hostname.startsWith("[") &&
+ hostname.endsWith("]")) {
+ hostname = hostname.substring(1, hostname.length() - 1);
}
if (algorithm.equalsIgnoreCase("HTTPS")) {
HostnameChecker.getInstance(HostnameChecker.TYPE_TLS).match(
hostname, cert);
- } else if (algorithm.equalsIgnoreCase("LDAP")) {
+ } else if (algorithm.equalsIgnoreCase("LDAP") ||
+ algorithm.equalsIgnoreCase("LDAPS")) {
HostnameChecker.getInstance(HostnameChecker.TYPE_LDAP).match(
hostname, cert);
} else {
--- a/jdk/src/share/classes/sun/security/ssl/krb5/KerberosClientKeyExchangeImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/krb5/KerberosClientKeyExchangeImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -244,7 +244,7 @@
clientVersion, rand, input, sessionKey);
} else {
// Generate bogus premaster secret
- preMaster = new KerberosPreMasterSecret(protocolVersion, rand);
+ preMaster = new KerberosPreMasterSecret(clientVersion, rand);
}
}
--- a/jdk/src/share/classes/sun/security/ssl/krb5/KerberosPreMasterSecret.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/ssl/krb5/KerberosPreMasterSecret.java Tue Nov 02 19:40:45 2010 -0700
@@ -176,13 +176,21 @@
// check if the premaster secret version is ok
// the specification says that it must be the maximum version supported
// by the client from its ClientHello message. However, many
- // implementations send the negotiated version, so accept both
+ // old implementations send the negotiated version, so accept both
+ // for SSL v3.0 and TLS v1.0.
// NOTE that we may be comparing two unsupported version numbers in
// the second case, which is why we cannot use object references
// equality in this special case
- boolean versionMismatch = (protocolVersion != currentVersion) &&
- (protocolVersion.v != clientVersion.v);
+ boolean versionMismatch = (protocolVersion.v != clientVersion.v);
+ /*
+ * we never checked the client_version in server side
+ * for TLS v1.0 and SSL v3.0. For compatibility, we
+ * maintain this behavior.
+ */
+ if (versionMismatch && (clientVersion.v <= 0x0301)) {
+ versionMismatch = (protocolVersion.v != currentVersion.v);
+ }
/*
* Bogus decrypted ClientKeyExchange? If so, conjure a
@@ -203,8 +211,14 @@
Debug.println(System.out, "Invalid secret", preMaster);
}
}
- preMaster = generatePreMaster(generator, currentVersion);
- protocolVersion = currentVersion;
+
+ /*
+ * Randomize the preMaster secret with the
+ * ClientHello.client_version, as will produce invalid master
+ * secret to prevent the attacks.
+ */
+ preMaster = generatePreMaster(generator, clientVersion);
+ protocolVersion = clientVersion;
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 2010, 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.AlgorithmConstraints;
+import java.security.CryptoPrimitive;
+import java.security.AlgorithmParameters;
+
+import java.security.Key;
+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;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * Algorithm constraints for disabled algorithms property
+ *
+ * See the "jdk.certpath.disabledAlgorithms" specification in java.security
+ * for the syntax of the disabled algorithm string.
+ */
+public class DisabledAlgorithmConstraints implements AlgorithmConstraints {
+
+ // the known security property, jdk.certpath.disabledAlgorithms
+ public final static String PROPERTY_CERTPATH_DISABLED_ALGS =
+ "jdk.certpath.disabledAlgorithms";
+
+ // the known security property, jdk.tls.disabledAlgorithms
+ public final static String PROPERTY_TLS_DISABLED_ALGS =
+ "jdk.tls.disabledAlgorithms";
+
+ private static Map<String, String[]> disabledAlgorithmsMap =
+ Collections.synchronizedMap(new HashMap<String, String[]>());
+ private static Map<String, KeySizeConstraints> keySizeConstraintsMap =
+ Collections.synchronizedMap(new HashMap<String, KeySizeConstraints>());
+
+ private String[] disabledAlgorithms;
+ private KeySizeConstraints keySizeConstraints;
+
+ /**
+ * Initialize algorithm constraints with the specified security property.
+ *
+ * @param propertyName the security property name that define the disabled
+ * algorithm constraints
+ */
+ public DisabledAlgorithmConstraints(String propertyName) {
+ synchronized (disabledAlgorithmsMap) {
+ if(!disabledAlgorithmsMap.containsKey(propertyName)) {
+ loadDisabledAlgorithmsMap(propertyName);
+ }
+
+ disabledAlgorithms = disabledAlgorithmsMap.get(propertyName);
+ keySizeConstraints = keySizeConstraintsMap.get(propertyName);
+ }
+ }
+
+ @Override
+ final public boolean permits(Set<CryptoPrimitive> primitives,
+ String algorithm, AlgorithmParameters parameters) {
+
+ if (algorithm == null || algorithm.length() == 0) {
+ throw new IllegalArgumentException("No algorithm name specified");
+ }
+
+ if (primitives == null || primitives.isEmpty()) {
+ throw new IllegalArgumentException(
+ "No cryptographic primitive specified");
+ }
+
+ Set<String> elements = null;
+ for (String disabled : disabledAlgorithms) {
+ if (disabled == null || disabled.isEmpty()) {
+ continue;
+ }
+
+ // check the full name
+ if (disabled.equalsIgnoreCase(algorithm)) {
+ return false;
+ }
+
+ // decompose the algorithm into sub-elements
+ if (elements == null) {
+ elements = decomposes(algorithm);
+ }
+
+ // check the items of the algorithm
+ for (String element : elements) {
+ if (disabled.equalsIgnoreCase(element)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ final public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
+ return checkConstraints(primitives, "", key, null);
+ }
+
+ @Override
+ final public boolean permits(Set<CryptoPrimitive> primitives,
+ String algorithm, Key key, AlgorithmParameters parameters) {
+
+ if (algorithm == null || algorithm.length() == 0) {
+ throw new IllegalArgumentException("No algorithm name specified");
+ }
+
+ return checkConstraints(primitives, algorithm, key, parameters);
+ }
+
+ /**
+ * Decompose the standard algorithm name into sub-elements.
+ * <p>
+ * For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
+ * so that we can check the "SHA1" and "RSA" algorithm constraints
+ * separately.
+ * <p>
+ * Please override the method if need to support more name pattern.
+ */
+ protected Set<String> decomposes(String algorithm) {
+ if (algorithm == null || algorithm.length() == 0) {
+ return new HashSet<String>();
+ }
+
+ // algorithm/mode/padding
+ Pattern transPattern = Pattern.compile("/");
+ String[] transTockens = transPattern.split(algorithm);
+
+ Set<String> elements = new HashSet<String>();
+ for (String transTocken : transTockens) {
+ if (transTocken == null || transTocken.length() == 0) {
+ continue;
+ }
+
+ // PBEWith<digest>And<encryption>
+ // PBEWith<prf>And<encryption>
+ // OAEPWith<digest>And<mgf>Padding
+ // <digest>with<encryption>
+ // <digest>with<encryption>and<mgf>
+ Pattern pattern =
+ Pattern.compile("with|and", Pattern.CASE_INSENSITIVE);
+ String[] tokens = pattern.split(transTocken);
+
+ for (String token : tokens) {
+ if (token == null || token.length() == 0) {
+ continue;
+ }
+
+ elements.add(token);
+ }
+ }
+
+ // In Java standard algorithm name specification, for different
+ // purpose, the SHA-1 and SHA-2 algorithm names are different. For
+ // example, for MessageDigest, the standard name is "SHA-256", while
+ // for Signature, the digest algorithm component is "SHA256" for
+ // signature algorithm "SHA256withRSA". So we need to check both
+ // "SHA-256" and "SHA256" to make the right constraint checking.
+
+ // handle special name: SHA-1 and SHA1
+ if (elements.contains("SHA1") && !elements.contains("SHA-1")) {
+ elements.add("SHA-1");
+ }
+ if (elements.contains("SHA-1") && !elements.contains("SHA1")) {
+ elements.add("SHA1");
+ }
+
+ // handle special name: SHA-224 and SHA224
+ if (elements.contains("SHA224") && !elements.contains("SHA-224")) {
+ elements.add("SHA-224");
+ }
+ if (elements.contains("SHA-224") && !elements.contains("SHA224")) {
+ elements.add("SHA224");
+ }
+
+ // handle special name: SHA-256 and SHA256
+ if (elements.contains("SHA256") && !elements.contains("SHA-256")) {
+ elements.add("SHA-256");
+ }
+ if (elements.contains("SHA-256") && !elements.contains("SHA256")) {
+ elements.add("SHA256");
+ }
+
+ // handle special name: SHA-384 and SHA384
+ if (elements.contains("SHA384") && !elements.contains("SHA-384")) {
+ elements.add("SHA-384");
+ }
+ if (elements.contains("SHA-384") && !elements.contains("SHA384")) {
+ elements.add("SHA384");
+ }
+
+ // handle special name: SHA-512 and SHA512
+ if (elements.contains("SHA512") && !elements.contains("SHA-512")) {
+ elements.add("SHA-512");
+ }
+ if (elements.contains("SHA-512") && !elements.contains("SHA512")) {
+ elements.add("SHA512");
+ }
+
+ return elements;
+ }
+
+ // Check algorithm constraints
+ private boolean checkConstraints(Set<CryptoPrimitive> primitives,
+ String algorithm, Key key, AlgorithmParameters parameters) {
+
+ // check the key parameter, it cannot be null.
+ if (key == null) {
+ throw new IllegalArgumentException("The key cannot be null");
+ }
+
+ // check the target algorithm
+ if (algorithm != null && algorithm.length() != 0) {
+ if (!permits(primitives, algorithm, parameters)) {
+ return false;
+ }
+ }
+
+ // check the key algorithm
+ if (!permits(primitives, key.getAlgorithm(), null)) {
+ return false;
+ }
+
+ // check the key constraints
+ if (keySizeConstraints.disables(key)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ // Get disabled algorithm constraints from the specified security property.
+ private static void loadDisabledAlgorithmsMap(
+ final String propertyName) {
+
+ String property = AccessController.doPrivileged(
+ new PrivilegedAction<String>() {
+ public String run() {
+ return Security.getProperty(propertyName);
+ }
+ });
+
+ String[] algorithmsInProperty = null;
+
+ if (property != null && !property.isEmpty()) {
+
+ // remove double quote marks from beginning/end of the property
+ if (property.charAt(0) == '"' &&
+ property.charAt(property.length() - 1) == '"') {
+ property = property.substring(1, property.length() - 1);
+ }
+
+ algorithmsInProperty = property.split(",");
+ for (int i = 0; i < algorithmsInProperty.length; i++) {
+ algorithmsInProperty[i] = algorithmsInProperty[i].trim();
+ }
+ }
+
+ // map the disabled algorithms
+ if (algorithmsInProperty == null) {
+ algorithmsInProperty = new String[0];
+ }
+ disabledAlgorithmsMap.put(propertyName, algorithmsInProperty);
+
+ // map the key constraints
+ KeySizeConstraints keySizeConstraints =
+ new KeySizeConstraints(algorithmsInProperty);
+ keySizeConstraintsMap.put(propertyName, keySizeConstraints);
+ }
+
+ /**
+ * key constraints
+ */
+ private static class KeySizeConstraints {
+ private static final Pattern pattern = Pattern.compile(
+ "(\\S+)\\s+keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
+
+ private Map<String, Set<KeySizeConstraint>> constraintsMap =
+ Collections.synchronizedMap(
+ new HashMap<String, Set<KeySizeConstraint>>());
+
+ public KeySizeConstraints(String[] restrictions) {
+ for (String restriction : restrictions) {
+ if (restriction == null || restriction.isEmpty()) {
+ continue;
+ }
+
+ Matcher matcher = pattern.matcher(restriction);
+ if (matcher.matches()) {
+ String algorithm = matcher.group(1);
+
+ KeySizeConstraint.Operator operator =
+ KeySizeConstraint.Operator.of(matcher.group(2));
+ int length = Integer.parseInt(matcher.group(3));
+
+ algorithm = algorithm.toLowerCase(Locale.ENGLISH);
+
+ synchronized (constraintsMap) {
+ if (!constraintsMap.containsKey(algorithm)) {
+ constraintsMap.put(algorithm,
+ new HashSet<KeySizeConstraint>());
+ }
+
+ Set<KeySizeConstraint> constraintSet =
+ constraintsMap.get(algorithm);
+ KeySizeConstraint constraint =
+ new KeySizeConstraint(operator, length);
+ constraintSet.add(constraint);
+ }
+ }
+ }
+ }
+
+ // Does this KeySizeConstraints disable the specified key?
+ public boolean disables(Key key) {
+ String algorithm = key.getAlgorithm().toLowerCase(Locale.ENGLISH);
+ synchronized (constraintsMap) {
+ if (constraintsMap.containsKey(algorithm)) {
+ Set<KeySizeConstraint> constraintSet =
+ constraintsMap.get(algorithm);
+ for (KeySizeConstraint constraint : constraintSet) {
+ if (constraint.disables(key)) {
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+ }
+
+ /**
+ * Key size constraint.
+ *
+ * e.g. "keysize <= 1024"
+ */
+ private static class KeySizeConstraint {
+ // operator
+ static enum Operator {
+ EQ, // "=="
+ NE, // "!="
+ LT, // "<"
+ LE, // "<="
+ GT, // ">"
+ GE; // ">="
+
+ static Operator of(String s) {
+ switch (s) {
+ case "==":
+ return EQ;
+ case "!=":
+ return NE;
+ case "<":
+ return LT;
+ case "<=":
+ return LE;
+ case ">":
+ return GT;
+ case ">=":
+ return GE;
+ }
+
+ throw new IllegalArgumentException(
+ s + " is not a legal Operator");
+ }
+ }
+
+ private int minSize; // the minimal available key size
+ private int maxSize; // the maximal available key size
+ private int prohibitedSize = -1; // unavailable key sizes
+
+ public KeySizeConstraint(Operator operator, int length) {
+ switch (operator) {
+ case EQ: // an unavailable key size
+ this.minSize = 0;
+ this.maxSize = Integer.MAX_VALUE;
+ prohibitedSize = length;
+ break;
+ case NE:
+ this.minSize = length;
+ this.maxSize = length;
+ break;
+ case LT:
+ this.minSize = length;
+ this.maxSize = Integer.MAX_VALUE;
+ break;
+ case LE:
+ this.minSize = length + 1;
+ this.maxSize = Integer.MAX_VALUE;
+ break;
+ case GT:
+ this.minSize = 0;
+ this.maxSize = length;
+ break;
+ case GE:
+ this.minSize = 0;
+ this.maxSize = length > 1 ? (length - 1) : 0;
+ break;
+ default:
+ // unlikely to happen
+ this.minSize = Integer.MAX_VALUE;
+ this.maxSize = -1;
+ }
+ }
+
+ // 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.
+
+ if (size == 0) {
+ return true; // we don't allow any key of size 0.
+ }
+
+ if (size >= 0) {
+ return ((size < minSize) || (size > maxSize) ||
+ (prohibitedSize == size));
+ }
+
+ return false;
+ }
+ }
+
+}
+
--- a/jdk/src/share/classes/sun/security/validator/PKIXValidator.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/validator/PKIXValidator.java Tue Nov 02 19:40:45 2010 -0700
@@ -31,20 +31,35 @@
import java.security.cert.*;
import javax.security.auth.x500.X500Principal;
+import sun.security.action.GetBooleanAction;
+import sun.security.provider.certpath.AlgorithmChecker;
/**
* Validator implementation built on the PKIX CertPath API. This
* implementation will be emphasized going forward.<p>
- *
+ * <p>
* Note that the validate() implementation tries to use a PKIX validator
* if that appears possible and a PKIX builder otherwise. This increases
* performance and currently also leads to better exception messages
* in case of failures.
+ * <p>
+ * {@code PKIXValidator} objects are immutable once they have been created.
+ * Please DO NOT add methods that can change the state of an instance once
+ * it has been created.
*
* @author Andreas Sterbenz
*/
public final class PKIXValidator extends Validator {
+ /**
+ * Flag indicating whether to enable revocation check for the PKIX trust
+ * manager. Typically, this will only work if the PKIX implementation
+ * supports CRL distribution points as we do not manually setup CertStores.
+ */
+ private final static boolean checkTLSRevocation =
+ AccessController.doPrivileged
+ (new GetBooleanAction("com.sun.net.ssl.checkRevocation"));
+
// enable use of the validator if possible
private final static boolean TRY_VALIDATOR = true;
@@ -53,10 +68,10 @@
private int certPathLength = -1;
// needed only for the validator
- private Map<X500Principal, List<PublicKey>> trustedSubjects;
- private CertificateFactory factory;
+ private final Map<X500Principal, List<PublicKey>> trustedSubjects;
+ private final CertificateFactory factory;
- private boolean plugin = false;
+ private final boolean plugin;
PKIXValidator(String variant, Collection<X509Certificate> trustedCerts) {
super(TYPE_PKIX, variant);
@@ -75,7 +90,33 @@
throw new RuntimeException("Unexpected error: " + e.toString(), e);
}
setDefaultParameters(variant);
- initCommon();
+
+ // initCommon();
+ if (TRY_VALIDATOR) {
+ if (TRY_VALIDATOR == false) {
+ return;
+ }
+ trustedSubjects = new HashMap<X500Principal, List<PublicKey>>();
+ for (X509Certificate cert : trustedCerts) {
+ X500Principal dn = cert.getSubjectX500Principal();
+ List<PublicKey> keys;
+ if (trustedSubjects.containsKey(dn)) {
+ keys = trustedSubjects.get(dn);
+ } else {
+ keys = new ArrayList<PublicKey>();
+ trustedSubjects.put(dn, keys);
+ }
+ keys.add(cert.getPublicKey());
+ }
+ try {
+ factory = CertificateFactory.getInstance("X.509");
+ } catch (CertificateException e) {
+ throw new RuntimeException("Internal error", e);
+ }
+ plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING);
+ } else {
+ plugin = false;
+ }
}
PKIXValidator(String variant, PKIXBuilderParameters params) {
@@ -88,31 +129,33 @@
}
}
parameterTemplate = params;
- initCommon();
- }
- private void initCommon() {
- if (TRY_VALIDATOR == false) {
- return;
+ // initCommon();
+ if (TRY_VALIDATOR) {
+ if (TRY_VALIDATOR == false) {
+ return;
+ }
+ trustedSubjects = new HashMap<X500Principal, List<PublicKey>>();
+ for (X509Certificate cert : trustedCerts) {
+ X500Principal dn = cert.getSubjectX500Principal();
+ List<PublicKey> keys;
+ if (trustedSubjects.containsKey(dn)) {
+ keys = trustedSubjects.get(dn);
+ } else {
+ keys = new ArrayList<PublicKey>();
+ trustedSubjects.put(dn, keys);
+ }
+ keys.add(cert.getPublicKey());
+ }
+ try {
+ factory = CertificateFactory.getInstance("X.509");
+ } catch (CertificateException e) {
+ throw new RuntimeException("Internal error", e);
+ }
+ plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING);
+ } else {
+ plugin = false;
}
- trustedSubjects = new HashMap<X500Principal, List<PublicKey>>();
- for (X509Certificate cert : trustedCerts) {
- X500Principal dn = cert.getSubjectX500Principal();
- List<PublicKey> keys;
- if (trustedSubjects.containsKey(dn)) {
- keys = trustedSubjects.get(dn);
- } else {
- keys = new ArrayList<PublicKey>();
- trustedSubjects.put(dn, keys);
- }
- keys.add(cert.getPublicKey());
- }
- try {
- factory = CertificateFactory.getInstance("X.509");
- } catch (CertificateException e) {
- throw new RuntimeException("Internal error", e);
- }
- plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING);
}
public Collection<X509Certificate> getTrustedCertificates() {
@@ -129,7 +172,7 @@
* @return the length of the last certification path passed to
* CertPathValidator.validate, or -1 if it has not been invoked yet
*/
- public int getCertPathLength() {
+ public int getCertPathLength() { // mutable, should be private
return certPathLength;
}
@@ -138,7 +181,12 @@
* revocation checking. In the future, this should be configurable.
*/
private void setDefaultParameters(String variant) {
- parameterTemplate.setRevocationEnabled(false);
+ if ((variant == Validator.VAR_TLS_SERVER) ||
+ (variant == Validator.VAR_TLS_CLIENT)) {
+ parameterTemplate.setRevocationEnabled(checkTLSRevocation);
+ } else {
+ parameterTemplate.setRevocationEnabled(false);
+ }
}
/**
@@ -146,17 +194,29 @@
* modify the parameters but must make sure not to perform any concurrent
* validations.
*/
- public PKIXBuilderParameters getParameters() {
+ public PKIXBuilderParameters getParameters() { // mutable, should be private
return parameterTemplate;
}
+ @Override
X509Certificate[] engineValidate(X509Certificate[] chain,
- Collection<X509Certificate> otherCerts, Object parameter)
- throws CertificateException {
+ Collection<X509Certificate> otherCerts,
+ AlgorithmConstraints constraints,
+ Object parameter) throws CertificateException {
if ((chain == null) || (chain.length == 0)) {
throw new CertificateException
("null or zero-length certificate chain");
}
+
+ // add new algorithm constraints checker
+ PKIXBuilderParameters pkixParameters =
+ (PKIXBuilderParameters) parameterTemplate.clone();
+ AlgorithmChecker algorithmChecker = null;
+ if (constraints != null) {
+ algorithmChecker = new AlgorithmChecker(constraints);
+ pkixParameters.addCertPathChecker(algorithmChecker);
+ }
+
if (TRY_VALIDATOR) {
// check that chain is in correct order and check if chain contains
// trust anchor
@@ -167,7 +227,7 @@
if (i != 0 &&
!dn.equals(prevIssuer)) {
// chain is not ordered correctly, call builder instead
- return doBuild(chain, otherCerts);
+ return doBuild(chain, otherCerts, pkixParameters);
}
// Check if chain[i] is already trusted. It may be inside
@@ -186,7 +246,7 @@
// Remove and call validator on partial chain [0 .. i-1]
X509Certificate[] newChain = new X509Certificate[i];
System.arraycopy(chain, 0, newChain, 0, i);
- return doValidate(newChain);
+ return doValidate(newChain, pkixParameters);
}
prevIssuer = cert.getIssuerX500Principal();
}
@@ -197,7 +257,7 @@
X500Principal subject = last.getSubjectX500Principal();
if (trustedSubjects.containsKey(issuer) &&
isSignatureValid(trustedSubjects.get(issuer), last)) {
- return doValidate(chain);
+ return doValidate(chain, pkixParameters);
}
// don't fallback to builder if called from plugin/webstart
@@ -209,18 +269,17 @@
X509Certificate[] newChain =
new X509Certificate[chain.length-1];
System.arraycopy(chain, 0, newChain, 0, newChain.length);
+
// temporarily set last cert as sole trust anchor
- PKIXBuilderParameters params =
- (PKIXBuilderParameters) parameterTemplate.clone();
try {
- params.setTrustAnchors
+ pkixParameters.setTrustAnchors
(Collections.singleton(new TrustAnchor
(chain[chain.length-1], null)));
} catch (InvalidAlgorithmParameterException iape) {
// should never occur, but ...
throw new CertificateException(iape);
}
- doValidate(newChain, params);
+ doValidate(newChain, pkixParameters);
}
// if the rest of the chain is valid, throw exception
// indicating no trust anchor was found
@@ -230,10 +289,11 @@
// otherwise, fall back to builder
}
- return doBuild(chain, otherCerts);
+ return doBuild(chain, otherCerts, pkixParameters);
}
- private boolean isSignatureValid(List<PublicKey> keys, X509Certificate sub) {
+ private boolean isSignatureValid(List<PublicKey> keys,
+ X509Certificate sub) {
if (plugin) {
for (PublicKey key: keys) {
try {
@@ -273,13 +333,6 @@
}
}
- private X509Certificate[] doValidate(X509Certificate[] chain)
- throws CertificateException {
- PKIXBuilderParameters params =
- (PKIXBuilderParameters)parameterTemplate.clone();
- return doValidate(chain, params);
- }
-
private X509Certificate[] doValidate(X509Certificate[] chain,
PKIXBuilderParameters params) throws CertificateException {
try {
@@ -300,11 +353,10 @@
}
private X509Certificate[] doBuild(X509Certificate[] chain,
- Collection<X509Certificate> otherCerts) throws CertificateException {
+ Collection<X509Certificate> otherCerts,
+ PKIXBuilderParameters params) throws CertificateException {
try {
- PKIXBuilderParameters params =
- (PKIXBuilderParameters)parameterTemplate.clone();
setDate(params);
// setup target constraints
--- a/jdk/src/share/classes/sun/security/validator/SimpleValidator.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/validator/SimpleValidator.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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
@@ -48,6 +48,10 @@
* deployed certificates and previous J2SE versions. It will never support
* more advanced features and will be deemphasized in favor of the PKIX
* validator going forward.
+ * <p>
+ * {@code SimpleValidator} objects are immutable once they have been created.
+ * Please DO NOT add methods that can change the state of an instance once
+ * it has been created.
*
* @author Andreas Sterbenz
*/
@@ -80,13 +84,14 @@
* The list is used because there may be multiple certificates
* with an identical subject DN.
*/
- private Map<X500Principal, List<X509Certificate>> trustedX500Principals;
+ private final Map<X500Principal, List<X509Certificate>>
+ trustedX500Principals;
/**
* Set of the trusted certificates. Present only for
* getTrustedCertificates().
*/
- private Collection<X509Certificate> trustedCerts;
+ private final Collection<X509Certificate> trustedCerts;
SimpleValidator(String variant, Collection<X509Certificate> trustedCerts) {
super(TYPE_SIMPLE, variant);
@@ -114,9 +119,11 @@
* Perform simple validation of chain. The arguments otherCerts and
* parameter are ignored.
*/
+ @Override
X509Certificate[] engineValidate(X509Certificate[] chain,
- Collection<X509Certificate> otherCerts, Object parameter)
- throws CertificateException {
+ Collection<X509Certificate> otherCerts,
+ AlgorithmConstraints constraints,
+ Object parameter) throws CertificateException {
if ((chain == null) || (chain.length == 0)) {
throw new CertificateException
("null or zero-length certificate chain");
@@ -129,6 +136,17 @@
if (date == null) {
date = new Date();
}
+
+ // create default algorithm constraints checker
+ TrustAnchor anchor = new TrustAnchor(chain[chain.length - 1], null);
+ AlgorithmChecker defaultAlgChecker = new AlgorithmChecker(anchor);
+
+ // create application level algorithm constraints checker
+ AlgorithmChecker appAlgChecker = null;
+ if (constraints != null) {
+ appAlgChecker = new AlgorithmChecker(anchor, constraints);
+ }
+
// verify top down, starting at the certificate issued by
// the trust anchor
int maxPathLength = chain.length - 1;
@@ -138,7 +156,12 @@
// check certificate algorithm
try {
- AlgorithmChecker.check(cert);
+ // Algorithm checker don't care about the unresolved critical
+ // extensions.
+ defaultAlgChecker.check(cert, Collections.<String>emptySet());
+ if (appAlgChecker != null) {
+ appAlgChecker.check(cert, Collections.<String>emptySet());
+ }
} catch (CertPathValidatorException cpve) {
throw new ValidatorException
(ValidatorException.T_ALGORITHM_DISABLED, cert, cpve);
--- a/jdk/src/share/classes/sun/security/validator/Validator.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/validator/Validator.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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.util.*;
+import java.security.AlgorithmConstraints;
import java.security.KeyStore;
import java.security.cert.*;
@@ -232,16 +233,44 @@
public final X509Certificate[] validate(X509Certificate[] chain,
Collection<X509Certificate> otherCerts, Object parameter)
throws CertificateException {
- chain = engineValidate(chain, otherCerts, parameter);
+ return validate(chain, otherCerts, null, parameter);
+ }
+
+ /**
+ * Validate the given certificate chain.
+ *
+ * @param chain the target certificate chain
+ * @param otherCerts a Collection of additional X509Certificates that
+ * could be helpful for path building (or null)
+ * @param constraints algorithm constraints for certification path
+ * processing
+ * @param parameter an additional parameter with variant specific meaning.
+ * Currently, it is only defined for TLS_SERVER variant validators,
+ * where it must be non null and the name of the TLS key exchange
+ * algorithm being used (see JSSE X509TrustManager specification).
+ * In the future, it could be used to pass in a PKCS#7 object for
+ * code signing to check time stamps.
+ * @return a non-empty chain that was used to validate the path. The
+ * end entity cert is at index 0, the trust anchor at index n-1.
+ */
+ public final X509Certificate[] validate(X509Certificate[] chain,
+ Collection<X509Certificate> otherCerts,
+ AlgorithmConstraints constraints,
+ Object parameter) throws CertificateException {
+ chain = engineValidate(chain, otherCerts, constraints, parameter);
+
// omit EE extension check if EE cert is also trust anchor
if (chain.length > 1) {
endEntityChecker.check(chain[0], parameter);
}
+
return chain;
}
abstract X509Certificate[] engineValidate(X509Certificate[] chain,
- Collection<X509Certificate> otherCerts, Object parameter) throws CertificateException;
+ Collection<X509Certificate> otherCerts,
+ AlgorithmConstraints constraints,
+ Object parameter) throws CertificateException;
/**
* Returns an immutable Collection of the X509Certificates this instance
--- a/jdk/src/share/classes/sun/security/x509/X509CRLImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/security/x509/X509CRLImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -764,6 +764,15 @@
}
/**
+ * Gets the signature AlgorithmId from the CRL.
+ *
+ * @return the signature AlgorithmId
+ */
+ public AlgorithmId getSigAlgId() {
+ return sigAlgId;
+ }
+
+ /**
* return the AuthorityKeyIdentifier, if any.
*
* @returns AuthorityKeyIdentifier or null
--- a/jdk/src/share/classes/sun/util/logging/PlatformLogger.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/classes/sun/util/logging/PlatformLogger.java Tue Nov 02 19:40:45 2010 -0700
@@ -535,10 +535,6 @@
}
void doLog(int level, String msg, Object... params) {
- int paramsNumber = (params != null) ? params.length : 0;
- for (int i = 0; i < paramsNumber; i++) {
- params[i] = String.valueOf(params[i]);
- }
LoggingSupport.log(javaLogger, levelObjects.get(level), msg, params);
}
--- a/jdk/src/share/lib/security/java.security Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/lib/security/java.security Tue Nov 02 19:40:45 2010 -0700
@@ -282,3 +282,95 @@
# krb5.kdc.bad.policy = tryLess:2,2000
krb5.kdc.bad.policy = tryLast
+# Algorithm restrictions for certification path (CertPath) processing
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# for certification path building and validation. For example, "MD2" is
+# generally no longer considered to be a secure hash algorithm. This section
+# describes the mechanism for disabling algorithms based on algorithm name
+# and/or key length. This includes algorithms used in certificates, as well
+# as revocation information such as CRLs and signed OCSP Responses.
+#
+# The syntax of the disabled algorithm string is described as this Java
+# BNF-style:
+# DisabledAlgorithms:
+# " DisabledAlgorithm { , DisabledAlgorithm } "
+#
+# DisabledAlgorithm:
+# AlgorithmName [Constraint]
+#
+# AlgorithmName:
+# (see below)
+#
+# Constraint:
+# KeySizeConstraint
+#
+# KeySizeConstraint:
+# keySize Operator DecimalInteger
+#
+# Operator:
+# <= | < | == | != | >= | >
+#
+# DecimalInteger:
+# DecimalDigits
+#
+# DecimalDigits:
+# DecimalDigit {DecimalDigit}
+#
+# DecimalDigit: one of
+# 1 2 3 4 5 6 7 8 9 0
+#
+# The "AlgorithmName" is the standard algorithm name of the disabled
+# algorithm. See "Java Cryptography Architecture Standard Algorithm Name
+# Documentation" for information about Standard Algorithm Names. Matching
+# is performed using a case-insensitive sub-element matching rule. (For
+# example, in "SHA1withECDSA" the sub-elements are "SHA1" for hashing and
+# "ECDSA" for signatures.) If the assertion "AlgorithmName" is a
+# sub-element of the certificate algorithm name, the algorithm will be
+# rejected during certification path building and validation. For example,
+# the assertion algorithm name "DSA" will disable all certificate algorithms
+# that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion
+# will not disable algorithms related to "ECDSA".
+#
+# A "Constraint" provides further guidance for the algorithm being specified.
+# The "KeySizeConstraint" requires a key of a valid size range if the
+# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the
+# key size specified in number of bits. For example, "RSA keySize <= 1024"
+# indicates that any RSA key with key size less than or equal to 1024 bits
+# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
+# that any RSA key with key size less than 1024 or greater than 2048 should
+# be disabled. Note that the "KeySizeConstraint" only makes sense to key
+# algorithms.
+#
+# Note: This property is currently used by Oracle's PKIX implementation. It
+# is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
+#
+#
+jdk.certpath.disabledAlgorithms=MD2
+
+# Algorithm restrictions for Secure Socket Layer/Transport Layer Security
+# (SSL/TLS) processing
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# when using SSL/TLS. This section describes the mechanism for disabling
+# algorithms during SSL/TLS security parameters negotiation, including cipher
+# suites selection, peer authentication and key exchange mechanisms.
+#
+# For PKI-based peer authentication and key exchange mechanisms, this list
+# of disabled algorithms will also be checked during certification path
+# building and validation, including algorithms used in certificates, as
+# well as revocation information such as CRLs and signed OCSP Responses.
+# This is in addition to the jdk.certpath.disabledAlgorithms property above.
+#
+# See the specification of "jdk.certpath.disabledAlgorithms" for the
+# syntax of the disabled algorithm string.
+#
+# Note: This property is currently used by Oracle's JSSE implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
+
--- a/jdk/src/share/lib/security/java.security-solaris Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/lib/security/java.security-solaris Tue Nov 02 19:40:45 2010 -0700
@@ -56,10 +56,10 @@
#
# Select the source of seed data for SecureRandom. By default an
-# attempt is made to use the entropy gathering device specified by
+# attempt is made to use the entropy gathering device specified by
# the securerandom.source property. If an exception occurs when
-# accessing the URL then the traditional system/thread activity
-# algorithm is used.
+# accessing the URL then the traditional system/thread activity
+# algorithm is used.
#
# On Solaris and Linux systems, if file:/dev/urandom is specified and it
# exists, a special SecureRandom implementation is activated by default.
@@ -73,7 +73,7 @@
# The entropy gathering device is described as a URL and can also
# be specified with the system property "java.security.egd". For example,
# -Djava.security.egd=file:/dev/urandom
-# Specifying this system property will override the securerandom.source
+# Specifying this system property will override the securerandom.source
# setting.
#
@@ -119,11 +119,6 @@
keystore.type=jks
#
-# Class to instantiate as the system scope:
-#
-system.scope=sun.security.provider.IdentityDatabase
-
-#
# List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when
# passed to checkPackageAccess unless the
@@ -150,7 +145,7 @@
security.overridePropertiesFile=true
#
-# Determines the default key and trust manager factory algorithms for
+# Determines the default key and trust manager factory algorithms for
# the javax.net.ssl package.
#
ssl.KeyManagerFactory.algorithm=SunX509
@@ -165,13 +160,14 @@
#
# default value is forever (FOREVER). For security reasons, this
# caching is made forever when a security manager is set. When a security
-# manager is not set, the default behavior is to cache for 30 seconds.
+# manager is not set, the default behavior in this implementation
+# is to cache for 30 seconds.
#
# NOTE: setting this to anything other than the default value can have
-# serious security implications. Do not set it unless
+# serious security implications. Do not set it unless
# you are sure you are not exposed to DNS spoofing attack.
#
-#networkaddress.cache.ttl=-1
+#networkaddress.cache.ttl=-1
# The Java-level namelookup cache policy for failed lookups:
#
@@ -183,7 +179,7 @@
# the WINS name service in addition to DNS, name service lookups
# that fail may take a noticeably long time to return (approx. 5 seconds).
# For this reason the default caching policy is to maintain these
-# results for 10 seconds.
+# results for 10 seconds.
#
#
networkaddress.cache.negative.ttl=10
@@ -192,7 +188,7 @@
# Properties to configure OCSP for certificate revocation checking
#
-# Enable OCSP
+# Enable OCSP
#
# By default, OCSP is not used for certificate revocation checking.
# This property enables the use of OCSP when set to the value "true".
@@ -201,7 +197,7 @@
#
# Example,
# ocsp.enable=true
-
+
#
# Location of the OCSP responder
#
@@ -213,15 +209,15 @@
#
# Example,
# ocsp.responderURL=http://ocsp.example.net:80
-
+
#
# Subject name of the OCSP responder's certificate
#
# By default, the certificate of the OCSP responder is that of the issuer
# of the certificate being validated. This property identifies the certificate
-# of the OCSP responder when the default does not apply. Its value is a string
-# distinguished name (defined in RFC 2253) which identifies a certificate in
-# the set of certificates supplied during cert path validation. In cases where
+# of the OCSP responder when the default does not apply. Its value is a string
+# distinguished name (defined in RFC 2253) which identifies a certificate in
+# the set of certificates supplied during cert path validation. In cases where
# the subject name alone is not sufficient to uniquely identify the certificate
# then both the "ocsp.responderCertIssuerName" and
# "ocsp.responderCertSerialNumber" properties must be used instead. When this
@@ -237,14 +233,14 @@
# of the certificate being validated. This property identifies the certificate
# of the OCSP responder when the default does not apply. Its value is a string
# distinguished name (defined in RFC 2253) which identifies a certificate in
-# the set of certificates supplied during cert path validation. When this
-# property is set then the "ocsp.responderCertSerialNumber" property must also
-# be set. When the "ocsp.responderCertSubjectName" property is set then this
+# the set of certificates supplied during cert path validation. When this
+# property is set then the "ocsp.responderCertSerialNumber" property must also
+# be set. When the "ocsp.responderCertSubjectName" property is set then this
# property is ignored.
#
# Example,
# ocsp.responderCertIssuerName="CN=Enterprise CA, O=XYZ Corp"
-
+
#
# Serial number of the OCSP responder's certificate
#
@@ -259,7 +255,7 @@
#
# Example,
# ocsp.responderCertSerialNumber=2A:FF:00
-
+
#
# Policy for failed Kerberos KDC lookups:
#
@@ -287,3 +283,95 @@
# krb5.kdc.bad.policy = tryLess:2,2000
krb5.kdc.bad.policy = tryLast
+# Algorithm restrictions for certification path (CertPath) processing
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# for certification path building and validation. For example, "MD2" is
+# generally no longer considered to be a secure hash algorithm. This section
+# describes the mechanism for disabling algorithms based on algorithm name
+# and/or key length. This includes algorithms used in certificates, as well
+# as revocation information such as CRLs and signed OCSP Responses.
+#
+# The syntax of the disabled algorithm string is described as this Java
+# BNF-style:
+# DisabledAlgorithms:
+# " DisabledAlgorithm { , DisabledAlgorithm } "
+#
+# DisabledAlgorithm:
+# AlgorithmName [Constraint]
+#
+# AlgorithmName:
+# (see below)
+#
+# Constraint:
+# KeySizeConstraint
+#
+# KeySizeConstraint:
+# keySize Operator DecimalInteger
+#
+# Operator:
+# <= | < | == | != | >= | >
+#
+# DecimalInteger:
+# DecimalDigits
+#
+# DecimalDigits:
+# DecimalDigit {DecimalDigit}
+#
+# DecimalDigit: one of
+# 1 2 3 4 5 6 7 8 9 0
+#
+# The "AlgorithmName" is the standard algorithm name of the disabled
+# algorithm. See "Java Cryptography Architecture Standard Algorithm Name
+# Documentation" for information about Standard Algorithm Names. Matching
+# is performed using a case-insensitive sub-element matching rule. (For
+# example, in "SHA1withECDSA" the sub-elements are "SHA1" for hashing and
+# "ECDSA" for signatures.) If the assertion "AlgorithmName" is a
+# sub-element of the certificate algorithm name, the algorithm will be
+# rejected during certification path building and validation. For example,
+# the assertion algorithm name "DSA" will disable all certificate algorithms
+# that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion
+# will not disable algorithms related to "ECDSA".
+#
+# A "Constraint" provides further guidance for the algorithm being specified.
+# The "KeySizeConstraint" requires a key of a valid size range if the
+# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the
+# key size specified in number of bits. For example, "RSA keySize <= 1024"
+# indicates that any RSA key with key size less than or equal to 1024 bits
+# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
+# that any RSA key with key size less than 1024 or greater than 2048 should
+# be disabled. Note that the "KeySizeConstraint" only makes sense to key
+# algorithms.
+#
+# Note: This property is currently used by Oracle's PKIX implementation. It
+# is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
+#
+#
+jdk.certpath.disabledAlgorithms=MD2
+
+# Algorithm restrictions for Secure Socket Layer/Transport Layer Security
+# (SSL/TLS) processing
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# when using SSL/TLS. This section describes the mechanism for disabling
+# algorithms during SSL/TLS security parameters negotiation, including cipher
+# suites selection, peer authentication and key exchange mechanisms.
+#
+# For PKI-based peer authentication and key exchange mechanisms, this list
+# of disabled algorithms will also be checked during certification path
+# building and validation, including algorithms used in certificates, as
+# well as revocation information such as CRLs and signed OCSP Responses.
+# This is in addition to the jdk.certpath.disabledAlgorithms property above.
+#
+# See the specification of "jdk.certpath.disabledAlgorithms" for the
+# syntax of the disabled algorithm string.
+#
+# Note: This property is currently used by Oracle's JSSE implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
+i
--- a/jdk/src/share/lib/security/java.security-windows Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/lib/security/java.security-windows Tue Nov 02 19:40:45 2010 -0700
@@ -56,10 +56,10 @@
#
# Select the source of seed data for SecureRandom. By default an
-# attempt is made to use the entropy gathering device specified by
+# attempt is made to use the entropy gathering device specified by
# the securerandom.source property. If an exception occurs when
-# accessing the URL then the traditional system/thread activity
-# algorithm is used.
+# accessing the URL then the traditional system/thread activity
+# algorithm is used.
#
# On Solaris and Linux systems, if file:/dev/urandom is specified and it
# exists, a special SecureRandom implementation is activated by default.
@@ -73,7 +73,7 @@
# The entropy gathering device is described as a URL and can also
# be specified with the system property "java.security.egd". For example,
# -Djava.security.egd=file:/dev/urandom
-# Specifying this system property will override the securerandom.source
+# Specifying this system property will override the securerandom.source
# setting.
#
@@ -119,11 +119,6 @@
keystore.type=jks
#
-# Class to instantiate as the system scope:
-#
-system.scope=sun.security.provider.IdentityDatabase
-
-#
# List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when
# passed to checkPackageAccess unless the
@@ -150,7 +145,7 @@
security.overridePropertiesFile=true
#
-# Determines the default key and trust manager factory algorithms for
+# Determines the default key and trust manager factory algorithms for
# the javax.net.ssl package.
#
ssl.KeyManagerFactory.algorithm=SunX509
@@ -165,13 +160,14 @@
#
# default value is forever (FOREVER). For security reasons, this
# caching is made forever when a security manager is set. When a security
-# manager is not set, the default behavior is to cache for 30 seconds.
+# manager is not set, the default behavior in this implementation
+# is to cache for 30 seconds.
#
# NOTE: setting this to anything other than the default value can have
-# serious security implications. Do not set it unless
+# serious security implications. Do not set it unless
# you are sure you are not exposed to DNS spoofing attack.
#
-#networkaddress.cache.ttl=-1
+#networkaddress.cache.ttl=-1
# The Java-level namelookup cache policy for failed lookups:
#
@@ -183,7 +179,7 @@
# the WINS name service in addition to DNS, name service lookups
# that fail may take a noticeably long time to return (approx. 5 seconds).
# For this reason the default caching policy is to maintain these
-# results for 10 seconds.
+# results for 10 seconds.
#
#
networkaddress.cache.negative.ttl=10
@@ -192,7 +188,7 @@
# Properties to configure OCSP for certificate revocation checking
#
-# Enable OCSP
+# Enable OCSP
#
# By default, OCSP is not used for certificate revocation checking.
# This property enables the use of OCSP when set to the value "true".
@@ -201,7 +197,7 @@
#
# Example,
# ocsp.enable=true
-
+
#
# Location of the OCSP responder
#
@@ -213,15 +209,15 @@
#
# Example,
# ocsp.responderURL=http://ocsp.example.net:80
-
+
#
# Subject name of the OCSP responder's certificate
#
# By default, the certificate of the OCSP responder is that of the issuer
# of the certificate being validated. This property identifies the certificate
-# of the OCSP responder when the default does not apply. Its value is a string
-# distinguished name (defined in RFC 2253) which identifies a certificate in
-# the set of certificates supplied during cert path validation. In cases where
+# of the OCSP responder when the default does not apply. Its value is a string
+# distinguished name (defined in RFC 2253) which identifies a certificate in
+# the set of certificates supplied during cert path validation. In cases where
# the subject name alone is not sufficient to uniquely identify the certificate
# then both the "ocsp.responderCertIssuerName" and
# "ocsp.responderCertSerialNumber" properties must be used instead. When this
@@ -237,14 +233,14 @@
# of the certificate being validated. This property identifies the certificate
# of the OCSP responder when the default does not apply. Its value is a string
# distinguished name (defined in RFC 2253) which identifies a certificate in
-# the set of certificates supplied during cert path validation. When this
-# property is set then the "ocsp.responderCertSerialNumber" property must also
-# be set. When the "ocsp.responderCertSubjectName" property is set then this
+# the set of certificates supplied during cert path validation. When this
+# property is set then the "ocsp.responderCertSerialNumber" property must also
+# be set. When the "ocsp.responderCertSubjectName" property is set then this
# property is ignored.
#
# Example,
# ocsp.responderCertIssuerName="CN=Enterprise CA, O=XYZ Corp"
-
+
#
# Serial number of the OCSP responder's certificate
#
@@ -259,7 +255,7 @@
#
# Example,
# ocsp.responderCertSerialNumber=2A:FF:00
-
+
#
# Policy for failed Kerberos KDC lookups:
#
@@ -287,3 +283,95 @@
# krb5.kdc.bad.policy = tryLess:2,2000
krb5.kdc.bad.policy = tryLast
+# Algorithm restrictions for certification path (CertPath) processing
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# for certification path building and validation. For example, "MD2" is
+# generally no longer considered to be a secure hash algorithm. This section
+# describes the mechanism for disabling algorithms based on algorithm name
+# and/or key length. This includes algorithms used in certificates, as well
+# as revocation information such as CRLs and signed OCSP Responses.
+#
+# The syntax of the disabled algorithm string is described as this Java
+# BNF-style:
+# DisabledAlgorithms:
+# " DisabledAlgorithm { , DisabledAlgorithm } "
+#
+# DisabledAlgorithm:
+# AlgorithmName [Constraint]
+#
+# AlgorithmName:
+# (see below)
+#
+# Constraint:
+# KeySizeConstraint
+#
+# KeySizeConstraint:
+# keySize Operator DecimalInteger
+#
+# Operator:
+# <= | < | == | != | >= | >
+#
+# DecimalInteger:
+# DecimalDigits
+#
+# DecimalDigits:
+# DecimalDigit {DecimalDigit}
+#
+# DecimalDigit: one of
+# 1 2 3 4 5 6 7 8 9 0
+#
+# The "AlgorithmName" is the standard algorithm name of the disabled
+# algorithm. See "Java Cryptography Architecture Standard Algorithm Name
+# Documentation" for information about Standard Algorithm Names. Matching
+# is performed using a case-insensitive sub-element matching rule. (For
+# example, in "SHA1withECDSA" the sub-elements are "SHA1" for hashing and
+# "ECDSA" for signatures.) If the assertion "AlgorithmName" is a
+# sub-element of the certificate algorithm name, the algorithm will be
+# rejected during certification path building and validation. For example,
+# the assertion algorithm name "DSA" will disable all certificate algorithms
+# that rely on DSA, such as NONEwithDSA, SHA1withDSA. However, the assertion
+# will not disable algorithms related to "ECDSA".
+#
+# A "Constraint" provides further guidance for the algorithm being specified.
+# The "KeySizeConstraint" requires a key of a valid size range if the
+# "AlgorithmName" is of a key algorithm. The "DecimalInteger" indicates the
+# key size specified in number of bits. For example, "RSA keySize <= 1024"
+# indicates that any RSA key with key size less than or equal to 1024 bits
+# should be disabled, and "RSA keySize < 1024, RSA keySize > 2048" indicates
+# that any RSA key with key size less than 1024 or greater than 2048 should
+# be disabled. Note that the "KeySizeConstraint" only makes sense to key
+# algorithms.
+#
+# Note: This property is currently used by Oracle's PKIX implementation. It
+# is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
+#
+#
+jdk.certpath.disabledAlgorithms=MD2
+
+# Algorithm restrictions for Secure Socket Layer/Transport Layer Security
+# (SSL/TLS) processing
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# when using SSL/TLS. This section describes the mechanism for disabling
+# algorithms during SSL/TLS security parameters negotiation, including cipher
+# suites selection, peer authentication and key exchange mechanisms.
+#
+# For PKI-based peer authentication and key exchange mechanisms, this list
+# of disabled algorithms will also be checked during certification path
+# building and validation, including algorithms used in certificates, as
+# well as revocation information such as CRLs and signed OCSP Responses.
+# This is in addition to the jdk.certpath.disabledAlgorithms property above.
+#
+# See the specification of "jdk.certpath.disabledAlgorithms" for the
+# syntax of the disabled algorithm string.
+#
+# Note: This property is currently used by Oracle's JSSE implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+# Example:
+# jdk.tls.disabledAlgorithms=MD5, SHA1, DSA, RSA keySize < 2048
+
--- a/jdk/src/share/native/common/jdk_util.c Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/native/common/jdk_util.c Tue Nov 02 19:40:45 2010 -0700
@@ -25,6 +25,8 @@
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
+#include <assert.h>
#include "jvm.h"
#include "jdk_util.h"
@@ -45,6 +47,7 @@
(unsigned int) atoi(JDK_MICRO_VERSION);
const char* jdk_build_string = JDK_BUILD_NUMBER;
+ char build_number[4];
unsigned int jdk_build_number = 0;
const char* jdk_update_string = JDK_UPDATE_VERSION;
@@ -55,16 +58,28 @@
/* If the JDK_BUILD_NUMBER is of format bXX and XX is an integer
* XX is the jdk_build_number.
*/
- if (strlen(jdk_build_string) == 3) {
- if (jdk_build_string[0] == 'b' &&
- jdk_build_string[1] >= '0' && jdk_build_string[1] <= '9' &&
- jdk_build_string[2] >= '0' && jdk_build_string[2] <= '9') {
- jdk_build_number = (unsigned int) atoi(&jdk_build_string[1]);
+ int len = strlen(jdk_build_string);
+ if (jdk_build_string[0] == 'b' && len >= 2) {
+ int i = 0;
+ for (i = 1; i < len; i++) {
+ if (isdigit(jdk_build_string[i])) {
+ build_number[i-1] = jdk_build_string[i];
+ } else {
+ // invalid build number
+ i = -1;
+ break;
+ }
+ }
+ if (i == len) {
+ build_number[len-1] = '\0';
+ jdk_build_number = (unsigned int) atoi(build_number) ;
}
}
+
+ assert(jdk_build_number >= 0 && jdk_build_number <= 255);
+
if (strlen(jdk_update_string) == 2 || strlen(jdk_update_string) == 3) {
- if (jdk_update_string[0] >= '0' && jdk_update_string[0] <= '9' &&
- jdk_update_string[1] >= '0' && jdk_update_string[1] <= '9') {
+ if (isdigit(jdk_update_string[0]) && isdigit(jdk_update_string[1])) {
update_ver[0] = jdk_update_string[0];
update_ver[1] = jdk_update_string[1];
update_ver[2] = '\0';
@@ -75,7 +90,6 @@
}
}
-
memset(info, 0, info_size);
info->jdk_version = ((jdk_major_version & 0xFF) << 24) |
((jdk_minor_version & 0xFF) << 16) |
--- a/jdk/src/share/native/java/util/zip/zlib-1.2.3/zcrc32.c Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/share/native/java/util/zip/zlib-1.2.3/zcrc32.c Tue Nov 02 19:40:45 2010 -0700
@@ -406,7 +406,7 @@
return crc1;
/* put operator for one zero bit in odd */
- odd[0] = 0xedb88320L; /* CRC-32 polynomial */
+ odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
row = 1;
for (n = 1; n < GF2_DIM; n++) {
odd[n] = row;
--- a/jdk/src/solaris/bin/java_md.c Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/solaris/bin/java_md.c Tue Nov 02 19:40:45 2010 -0700
@@ -868,7 +868,7 @@
while (dp != NULL) {
cp = JLI_StrChr(dp, (int)':');
if (cp != NULL)
- *cp = (char)NULL;
+ *cp = '\0';
if ((target = ProcessDir(info, dp)) != NULL)
break;
dp = cp;
--- a/jdk/src/solaris/bin/jexec.c Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/solaris/bin/jexec.c Tue Nov 02 19:40:45 2010 -0700
@@ -221,6 +221,7 @@
* implies an error in the exec. */
free(nargv);
errorExit(errno, BAD_EXEC_MSG);
+ return 0; // keep the compiler happy
}
--- a/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/FileDispatcherImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -94,6 +94,12 @@
preClose0(fd);
}
+ FileDescriptor duplicateForMapping(FileDescriptor fd) {
+ // file descriptor not required for mapping operations; okay
+ // to return invalid file descriptor.
+ return new FileDescriptor();
+ }
+
// -- Native methods --
static native int read0(FileDescriptor fd, long address, int len)
--- a/jdk/src/solaris/classes/sun/nio/ch/LinuxAsynchronousChannelProvider.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/LinuxAsynchronousChannelProvider.java Tue Nov 02 19:40:45 2010 -0700
@@ -29,7 +29,6 @@
import java.nio.channels.spi.AsynchronousChannelProvider;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
-import java.net.ProtocolFamily;
import java.io.IOException;
public class LinuxAsynchronousChannelProvider
@@ -88,12 +87,4 @@
{
return new UnixAsynchronousSocketChannelImpl(toPort(group));
}
-
- @Override
- public AsynchronousDatagramChannel openAsynchronousDatagramChannel(ProtocolFamily family,
- AsynchronousChannelGroup group)
- throws IOException
- {
- return new SimpleAsynchronousDatagramChannelImpl(family, toPort(group));
- }
}
--- a/jdk/src/solaris/classes/sun/nio/ch/SolarisAsynchronousChannelProvider.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/solaris/classes/sun/nio/ch/SolarisAsynchronousChannelProvider.java Tue Nov 02 19:40:45 2010 -0700
@@ -29,7 +29,6 @@
import java.nio.channels.spi.AsynchronousChannelProvider;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
-import java.net.ProtocolFamily;
import java.io.IOException;
public class SolarisAsynchronousChannelProvider
@@ -91,12 +90,4 @@
{
return new UnixAsynchronousSocketChannelImpl(toEventPort(group));
}
-
- @Override
- public AsynchronousDatagramChannel openAsynchronousDatagramChannel(ProtocolFamily family,
- AsynchronousChannelGroup group)
- throws IOException
- {
- return new SimpleAsynchronousDatagramChannelImpl(family, toEventPort(group));
- }
}
--- a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c Tue Nov 02 19:40:45 2010 -0700
@@ -381,7 +381,15 @@
n = sendto(fd, sendbuf, plen, 0, (struct sockaddr *)him,
sizeof(struct sockaddr));
if (n < 0 && errno != EINPROGRESS ) {
- NET_ThrowNew(env, errno, "Can't send ICMP packet");
+#ifdef __linux__
+ if (errno != EINVAL)
+ /*
+ * On some Linuxes, when bound to the loopback interface, sendto
+ * will fail and errno will be set to EINVAL. When that happens,
+ * don't throw an exception, just return false.
+ */
+#endif /*__linux__ */
+ NET_ThrowNew(env, errno, "Can't send ICMP packet");
close(fd);
return JNI_FALSE;
}
--- a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c Tue Nov 02 19:40:45 2010 -0700
@@ -506,7 +506,16 @@
plen = sizeof(struct icmp6_hdr) + sizeof(tv);
n = sendto(fd, sendbuf, plen, 0, (struct sockaddr*) him, sizeof(struct sockaddr_in6));
if (n < 0 && errno != EINPROGRESS) {
+#ifdef __linux__
+ if (errno != EINVAL)
+ /*
+ * On some Linuxes, when bound to the loopback interface, sendto
+ * will fail and errno will be set to EINVAL. When that happens,
+ * don't throw an exception, just return false.
+ */
+#endif /*__linux__ */
NET_ThrowNew(env, errno, "Can't send ICMP packet");
+ close(fd);
return JNI_FALSE;
}
--- a/jdk/src/solaris/native/java/nio/MappedByteBuffer.c Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/solaris/native/java/nio/MappedByteBuffer.c Tue Nov 02 19:40:45 2010 -0700
@@ -82,8 +82,8 @@
JNIEXPORT void JNICALL
-Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jlong address,
- jlong len)
+Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jobject fdo,
+ jlong address, jlong len)
{
void* a = (void *)jlong_to_ptr(address);
int result = msync(a, (size_t)len, MS_SYNC);
--- a/jdk/src/windows/bin/java_md.c Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/windows/bin/java_md.c Tue Nov 02 19:40:45 2010 -0700
@@ -318,7 +318,7 @@
struct stat s;
/* Make sure the jrepath contains something */
- if (jrepath[0] == NULL) {
+ if ((void*)jrepath[0] == NULL) {
return;
}
/* 32 bit windows only please */
@@ -650,7 +650,7 @@
/* get the length of the string we need */
int len = mlen = _vscprintf(fmt, vl) + 1;
if (freeit) {
- mlen += JLI_StrLen(errtext);
+ mlen += (int)JLI_StrLen(errtext);
}
message = (char *)JLI_MemAlloc(mlen);
@@ -1107,7 +1107,6 @@
exit(exitCode);
}
-
}
/*
--- a/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/windows/classes/sun/nio/ch/FileDispatcherImpl.java Tue Nov 02 19:40:45 2010 -0700
@@ -26,10 +26,11 @@
package sun.nio.ch;
import java.io.*;
+import sun.misc.SharedSecrets;
+import sun.misc.JavaIOFileDescriptorAccess;
class FileDispatcherImpl extends FileDispatcher
{
-
static {
Util.load();
}
@@ -94,6 +95,16 @@
close0(fd);
}
+ FileDescriptor duplicateForMapping(FileDescriptor fd) throws IOException {
+ // on Windows we need to keep a handle to the file
+ JavaIOFileDescriptorAccess fdAccess =
+ SharedSecrets.getJavaIOFileDescriptorAccess();
+ FileDescriptor result = new FileDescriptor();
+ long handle = duplicateHandle(fdAccess.getHandle(fd));
+ fdAccess.setHandle(result, handle);
+ return result;
+ }
+
//-- Native methods
static native int read0(FileDescriptor fd, long address, int len)
@@ -132,4 +143,5 @@
static native void closeByHandle(long fd) throws IOException;
+ static native long duplicateHandle(long fd) throws IOException;
}
--- a/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousChannelProvider.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/windows/classes/sun/nio/ch/WindowsAsynchronousChannelProvider.java Tue Nov 02 19:40:45 2010 -0700
@@ -29,7 +29,6 @@
import java.nio.channels.spi.AsynchronousChannelProvider;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
-import java.net.ProtocolFamily;
import java.io.IOException;
public class WindowsAsynchronousChannelProvider
@@ -90,12 +89,4 @@
{
return new WindowsAsynchronousSocketChannelImpl(toIocp(group));
}
-
- @Override
- public AsynchronousDatagramChannel openAsynchronousDatagramChannel(ProtocolFamily family,
- AsynchronousChannelGroup group)
- throws IOException
- {
- return new SimpleAsynchronousDatagramChannelImpl(family, toIocp(group));
- }
}
--- a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Ktab.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Ktab.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -39,10 +39,11 @@
import java.text.DateFormat;
import java.util.Arrays;
import java.util.Date;
+import java.util.Locale;
import sun.security.krb5.internal.crypto.EType;
/**
* This class can execute as a command-line tool to help the user manage
- * entires in the key table.
+ * entries in the key table.
* Available functions include list/add/update/delete service key(s).
*
* @author Yanni Zhang
@@ -60,30 +61,20 @@
int etype = -1;
char[] password = null;
+ boolean forced = false; // true if delete without prompt. Default false
+ boolean append = false; // true if new keys are appended. Default false
+ int vDel = -1; // kvno to delete, -1 all, -2 old. Default -1
+ int vAdd = -1; // kvno to add. Default -1, means auto incremented
+
/**
* The main program that can be invoked at command line.
- * <br>Usage: ktab <options>
- * <br>available options to Ktab:
- * <ul>
- * <li><b>-l [-e] [-t]</b> list the keytab name and entries, -e show
- * encryption etypes, -t show timestamps.
- * <li><b>-a</b> <<i>principal name</i>>
- * (<<i>password</i>>) add an entry to the keytab.
- * The entry is added only to the keytab. No changes are made to the
- * Kerberos database.
- * <li><b>-d</b> <<i>principal name</i>> [<<i>etype</i>>]
- * delete an entry from the keytab.
- * The entry is deleted only from the keytab. No changes are made to the
- * Kerberos database.
- * <li><b>-k</b> <<i>keytab name</i> >
- * specify keytab name and path with prefix FILE:
- * <li><b>-help</b> display instructions.
+ * See {@link #printHelp} for usages.
*/
public static void main(String[] args) {
Ktab ktab = new Ktab();
if ((args.length == 1) && (args[0].equalsIgnoreCase("-help"))) {
ktab.printHelp();
- System.exit(0);
+ return;
} else if ((args == null) || (args.length == 0)) {
ktab.action = 'l';
} else {
@@ -139,7 +130,6 @@
break;
default:
ktab.printHelp();
- System.exit(-1);
}
}
@@ -147,84 +137,129 @@
* Parses the command line arguments.
*/
void processArgs(String[] args) {
- Character arg = null;
+
+ // Commands (should appear before options):
+ // -l
+ // -a <princ>
+ // -d <princ>
+ // Options:
+ // -e <etype> (for -d)
+ // -e (for -l)
+ // -n <kvno>
+ // -k <keytab>
+ // -t
+ // -f
+ // -append
+ // Optional extra arguments:
+ // password for -a
+ // [kvno|all|old] for -d
+
+ boolean argAlreadyAppeared = false;
for (int i = 0; i < args.length; i++) {
- if ((args[i].length() == 2) && (args[i].startsWith("-"))) {
- arg = new Character(args[i].charAt(1));
- } else {
- printHelp();
- System.exit(-1);
- }
- switch (arg.charValue()) {
- case 'l':
- case 'L':
- action = 'l'; // list keytab location, name and entries
- break;
- case 'a':
- case 'A':
- action = 'a'; // add a new entry to keytab.
- i++;
- if ((i < args.length) && (!args[i].startsWith("-"))) {
- principal = args[i];
- } else {
- System.out.println("Please specify the principal name"+
- " after -a option.");
- printHelp();
- System.exit(-1);
+ if (args[i].startsWith("-")) {
+ switch (args[i].toLowerCase(Locale.US)) {
+
+ // Commands
+ case "-l": // list
+ action = 'l';
+ break;
+ case "-a": // add a new entry to keytab.
+ action = 'a';
+ if (++i >= args.length || args[i].startsWith("-")) {
+ error("A principal name must be specified after -a");
+ }
+ principal = args[i];
+ break;
+ case "-d": // delete entries
+ action = 'd';
+ if (++i >= args.length || args[i].startsWith("-")) {
+ error("A principal name must be specified after -d");
+ }
+ principal = args[i];
+ break;
+
+ // Options
+ case "-e":
+ if (action == 'l') { // list etypes
+ showEType = true;
+ } else if (action == 'd') { // delete etypes
+ if (++i >= args.length || args[i].startsWith("-")) {
+ error("An etype must be specified after -e");
+ }
+ try {
+ etype = Integer.parseInt(args[i]);
+ if (etype <= 0) {
+ throw new NumberFormatException();
+ }
+ } catch (NumberFormatException nfe) {
+ error(args[i] + " is not a valid etype");
+ }
+ } else {
+ error(args[i] + " is not valid after -" + action);
+ }
+ break;
+ case "-n": // kvno for -a
+ if (++i >= args.length || args[i].startsWith("-")) {
+ error("A KVNO must be specified after -n");
+ }
+ try {
+ vAdd = Integer.parseInt(args[i]);
+ if (vAdd < 0) {
+ throw new NumberFormatException();
+ }
+ } catch (NumberFormatException nfe) {
+ error(args[i] + " is not a valid KVNO");
+ }
+ break;
+ case "-k": // specify keytab to use
+ if (++i >= args.length || args[i].startsWith("-")) {
+ error("A keytab name must be specified after -k");
+ }
+ if (args[i].length() >= 5 &&
+ args[i].substring(0, 5).equalsIgnoreCase("FILE:")) {
+ name = args[i].substring(5);
+ } else {
+ name = args[i];
+ }
+ break;
+ case "-t": // list timestamps
+ showTime = true;
+ break;
+ case "-f": // force delete, no prompt
+ forced = true;
+ break;
+ case "-append": // -a, new keys append to file
+ append = true;
+ break;
+ default:
+ printHelp();
+ break;
}
- if ((i + 1 < args.length) &&
- (!args[i + 1].startsWith("-"))) {
- password = args[i + 1].toCharArray();
- i++;
- } else {
- password = null; // prompt user for password later.
+ } else { // optional standalone arguments
+ if (argAlreadyAppeared) {
+ error("Useless extra argument " + args[i]);
}
- break;
- case 'd':
- case 'D':
- action = 'd'; // delete an entry.
- i++;
- if ((i < args.length) && (!args[i].startsWith("-"))) {
- principal = args[i];
- int j = i + 1;
- if ((j < args.length) && (!args[j].startsWith("-"))) {
- etype = Integer.parseInt(args[j]);
- i = j;
+ if (action == 'a') {
+ password = args[i].toCharArray();
+ } else if (action == 'd') {
+ switch (args[i]) {
+ case "all": vDel = -1; break;
+ case "old": vDel = -2; break;
+ default: {
+ try {
+ vDel = Integer.parseInt(args[i]);
+ if (vDel < 0) {
+ throw new NumberFormatException();
+ }
+ } catch (NumberFormatException nfe) {
+ error(args[i] + " is not a valid KVNO");
+ }
+ }
}
} else {
- System.out.println("Please specify the principal" +
- "name of the entry you want to " +
- " delete after -d option.");
- printHelp();
- System.exit(-1);
+ error("Useless extra argument " + args[i]);
}
- break;
- case 'k':
- case 'K':
- i++;
- if ((i < args.length) && (!args[i].startsWith("-"))) {
- if (args[i].length() >= 5 &&
- args[i].substring(0, 5).equalsIgnoreCase("FILE:")) {
- name = args[i].substring(5);
- } else
- name = args[i];
- } else {
- System.out.println("Please specify the keytab "+
- "file name and location " +
- "after -k option");
- printHelp();
- System.exit(-1);
- }
- break;
- case 'e':
- showEType = true;
- break;
- case 't':
- showTime = true;
- break;
- default:
- printHelp();
- System.exit(-1);
+ argAlreadyAppeared = true;
}
}
}
@@ -263,7 +298,7 @@
}
try {
// admin.addEntry(pname, password);
- table.addEntry(pname, password);
+ table.addEntry(pname, password, vAdd, append);
Arrays.fill(password, '0'); // clear password
// admin.save();
table.save();
@@ -350,23 +385,25 @@
if (pname.getRealm() == null) {
pname.setRealm(Config.getInstance().getDefaultRealm());
}
- String answer;
- BufferedReader cis =
- new BufferedReader(new InputStreamReader(System.in));
- System.out.print("Are you sure you want to"+
- " delete service key for " + pname.toString() +
- " (" + (etype==-1?"all etypes":("etype = "+etype)) +
- ") in " + table.tabName() + "?(Y/N): ");
+ if (!forced) {
+ String answer;
+ BufferedReader cis =
+ new BufferedReader(new InputStreamReader(System.in));
+ System.out.print("Are you sure you want to delete "+
+ "service key(s) for " + pname.toString() +
+ " (" + (etype==-1?"all etypes":("etype="+etype)) + ", " +
+ (vDel==-1?"all kvno":(vDel==-2?"old kvno":("kvno=" + vDel))) +
+ ") in " + table.tabName() + "? (Y/[N]): ");
- System.out.flush();
- answer = cis.readLine();
- if (answer.equalsIgnoreCase("Y") ||
- answer.equalsIgnoreCase("Yes"));
- else {
- // no error, the user did not want to delete the entry
- System.exit(0);
+ System.out.flush();
+ answer = cis.readLine();
+ if (answer.equalsIgnoreCase("Y") ||
+ answer.equalsIgnoreCase("Yes"));
+ else {
+ // no error, the user did not want to delete the entry
+ System.exit(0);
+ }
}
-
} catch (KrbException e) {
System.err.println("Error occured while deleting the entry. "+
"Deletion failed.");
@@ -379,9 +416,7 @@
System.exit(-1);
}
- int count;
- if (etype == -1) count = table.deleteEntry(pname);
- else count = table.deleteEntry(pname, etype);
+ int count = table.deleteEntries(pname, etype, vDel);
if (count == 0) {
System.err.println("No matched entry in the keytab. " +
@@ -396,23 +431,47 @@
e.printStackTrace();
System.exit(-1);
}
- System.out.println("Done!");
+ System.out.println("Done! " + count + " entries removed.");
}
}
+ void error(String... errors) {
+ for (String error: errors) {
+ System.out.println("Error: " + error + ".");
+ }
+ printHelp();
+ System.exit(-1);
+ }
/**
* Prints out the help information.
*/
void printHelp() {
- System.out.println("\nUsage: ktab " +
- "<options>");
- System.out.println("available options to Ktab:");
- System.out.println("-l [-e] [-t]\t\t\tlist the keytab name and entries,\n\t\t\t\t-e with etype, -t with timestamp");
- System.out.println("-a <principal name> (<password>)add an entry " +
- "to the keytab");
- System.out.println("-d <principal name> [<etype>]\tdelete an "+
- "entry from the keytab");
- System.out.println("-k <keytab name>\t\tspecify keytab name and "+
- "path with prefix FILE:");
+ System.out.println("\nUsage: ktab <commands> <options>");
+ System.out.println();
+ System.out.println("Available commands:");
+ System.out.println();
+ System.out.println("-l [-e] [-t]\n"
+ + " list the keytab name and entries. -e with etype, -t with timestamp.");
+ System.out.println("-a <principal name> [<password>] [-n <kvno>] [-append]\n"
+ + " add new key entries to the keytab for the given principal name with\n"
+ + " optional <password>. If a <kvno> is specified, new keys' Key Version\n"
+ + " Numbers equal to the value, otherwise, automatically incrementing\n"
+ + " the Key Version Numbers. If -append is specified, new keys are\n"
+ + " appended to the keytab, otherwise, old keys for the\n"
+ + " same principal are removed.");
+ System.out.println("-d <principal name> [-f] [-e <etype>] [<kvno> | all | old]\n"
+ + " delete key entries from the keytab for the specified principal. If\n"
+ + " <kvno> is specified, delete keys whose Key Version Numbers match\n"
+ + " kvno. If \"all\" is specified, delete all keys. If \"old\" is specified,\n"
+ + " delete all keys except those with the highest kvno. Default action\n"
+ + " is \"all\". If <etype> is specified, only keys of this encryption type\n"
+ + " are deleted. <etype> should be specified as the numberic value etype\n"
+ + " defined in RFC 3961, section 8. A prompt to confirm the deletion is\n"
+ + " displayed unless -f is specified.");
+ System.out.println();
+ System.out.println("Common option(s):");
+ System.out.println();
+ System.out.println("-k <keytab name>\n"
+ + " specify keytab name and path with prefix FILE:");
}
}
--- a/jdk/src/windows/native/java/nio/MappedByteBuffer.c Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/windows/native/java/nio/MappedByteBuffer.c Tue Nov 02 19:40:45 2010 -0700
@@ -51,11 +51,11 @@
}
JNIEXPORT void JNICALL
-Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jlong address,
- jlong len)
+Java_java_nio_MappedByteBuffer_force0(JNIEnv *env, jobject obj, jobject fdo,
+ jlong address, jlong len)
{
void *a = (void *) jlong_to_ptr(address);
- int result;
+ BOOL result;
int retry;
/*
@@ -71,6 +71,30 @@
retry++;
} while (retry < 3);
+ /**
+ * FlushViewOfFile only initiates the writing of dirty pages to disk
+ * so we have to call FlushFileBuffers to and ensure they are written.
+ */
+ if (result != 0) {
+ // by right, the jfieldID initialization should be in a static
+ // initializer but we do it here instead to avoiding needing to
+ // load nio.dll during startup.
+ static jfieldID handle_fdID;
+ HANDLE h;
+ if (handle_fdID == NULL) {
+ jclass clazz = (*env)->FindClass(env, "java/io/FileDescriptor");
+ if (clazz == NULL)
+ return; // exception thrown
+ handle_fdID = (*env)->GetFieldID(env, clazz, "handle", "J");
+ }
+ h = jlong_to_ptr((*env)->GetLongField(env, fdo, handle_fdID));
+ result = FlushFileBuffers(h);
+ if (result == 0 && GetLastError() == ERROR_ACCESS_DENIED) {
+ // read-only mapping
+ result = 1;
+ }
+ }
+
if (result == 0) {
JNU_ThrowIOExceptionWithLastError(env, "Flush failed");
}
--- a/jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/src/windows/native/sun/nio/ch/FileDispatcherImpl.c Tue Nov 02 19:40:45 2010 -0700
@@ -32,6 +32,7 @@
#include <io.h>
#include "nio.h"
#include "nio_util.h"
+#include "jlong.h"
/**************************************************************
@@ -441,3 +442,15 @@
{
closeFile(env, fd);
}
+
+JNIEXPORT jlong JNICALL
+Java_sun_nio_ch_FileDispatcherImpl_duplicateHandle(JNIEnv *env, jclass this, jlong hFile)
+{
+ HANDLE hProcess = GetCurrentProcess();
+ HANDLE hResult;
+ BOOL res = DuplicateHandle(hProcess, hFile, hProcess, &hResult, 0, FALSE,
+ DUPLICATE_SAME_ACCESS);
+ if (res == 0)
+ JNU_ThrowIOExceptionWithLastError(env, "DuplicateHandle failed");
+ return ptr_to_jlong(hResult);
+}
--- a/jdk/test/com/sun/crypto/provider/TLS/TestKeyMaterial.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/com/sun/crypto/provider/TLS/TestKeyMaterial.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -117,16 +117,23 @@
System.out.print(".");
n++;
- KeyGenerator kg = KeyGenerator.getInstance("SunTlsKeyMaterial", provider);
- SecretKey masterKey = new SecretKeySpec(master, "TlsMasterSecret");
- TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec
- (masterKey, major, minor, clientRandom, serverRandom, cipherAlgorithm,
- keyLength, expandedKeyLength, ivLength, macLength);
+ KeyGenerator kg =
+ KeyGenerator.getInstance("SunTlsKeyMaterial", provider);
+ SecretKey masterKey =
+ new SecretKeySpec(master, "TlsMasterSecret");
+ TlsKeyMaterialParameterSpec spec =
+ new TlsKeyMaterialParameterSpec(masterKey, major, minor,
+ clientRandom, serverRandom, cipherAlgorithm,
+ keyLength, expandedKeyLength, ivLength, macLength,
+ null, -1, -1);
kg.init(spec);
- TlsKeyMaterialSpec result = (TlsKeyMaterialSpec)kg.generateKey();
- match(lineNumber, clientCipherBytes, result.getClientCipherKey());
- match(lineNumber, serverCipherBytes, result.getServerCipherKey());
+ TlsKeyMaterialSpec result =
+ (TlsKeyMaterialSpec)kg.generateKey();
+ match(lineNumber, clientCipherBytes,
+ result.getClientCipherKey());
+ match(lineNumber, serverCipherBytes,
+ result.getServerCipherKey());
match(lineNumber, clientIv, result.getClientIv());
match(lineNumber, serverIv, result.getServerIv());
match(lineNumber, clientMacBytes, result.getClientMacKey());
@@ -144,7 +151,8 @@
System.out.println("OK: " + n + " tests");
}
- private static void match(int lineNumber, byte[] out, Object res) throws Exception {
+ private static void match(int lineNumber, byte[] out, Object res)
+ throws Exception {
if ((out == null) || (res == null)) {
if (out != res) {
throw new Exception("null mismatch line " + lineNumber);
--- a/jdk/test/com/sun/crypto/provider/TLS/TestMasterSecret.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/com/sun/crypto/provider/TLS/TestMasterSecret.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -97,17 +97,22 @@
System.out.print(".");
n++;
- KeyGenerator kg = KeyGenerator.getInstance("SunTlsMasterSecret", provider);
- SecretKey premasterKey = new SecretKeySpec(premaster, algorithm);
- TlsMasterSecretParameterSpec spec = new TlsMasterSecretParameterSpec
- (premasterKey, protoMajor, protoMinor, clientRandom, serverRandom);
+ KeyGenerator kg =
+ KeyGenerator.getInstance("SunTlsMasterSecret", provider);
+ SecretKey premasterKey =
+ new SecretKeySpec(premaster, algorithm);
+ TlsMasterSecretParameterSpec spec =
+ new TlsMasterSecretParameterSpec(premasterKey, protoMajor,
+ protoMinor, clientRandom, serverRandom,
+ null, -1, -1);
kg.init(spec);
TlsMasterSecret key = (TlsMasterSecret)kg.generateKey();
byte[] enc = key.getEncoded();
if (Arrays.equals(master, enc) == false) {
throw new Exception("mismatch line: " + lineNumber);
}
- if ((preMajor != key.getMajorVersion()) || (preMinor != key.getMinorVersion())) {
+ if ((preMajor != key.getMajorVersion()) ||
+ (preMinor != key.getMinorVersion())) {
throw new Exception("version mismatch line: " + lineNumber);
}
} else {
--- a/jdk/test/com/sun/crypto/provider/TLS/TestPRF.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/com/sun/crypto/provider/TLS/TestPRF.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -85,14 +85,17 @@
System.out.print(".");
n++;
- KeyGenerator kg = KeyGenerator.getInstance("SunTlsPrf", provider);
+ KeyGenerator kg =
+ KeyGenerator.getInstance("SunTlsPrf", provider);
SecretKey inKey;
if (secret == null) {
inKey = null;
} else {
inKey = new SecretKeySpec(secret, "Generic");
}
- TlsPrfParameterSpec spec = new TlsPrfParameterSpec(inKey, label, seed, length);
+ TlsPrfParameterSpec spec =
+ new TlsPrfParameterSpec(inKey, label, seed, length,
+ null, -1, -1);
kg.init(spec);
SecretKey key = kg.generateKey();
byte[] enc = key.getEncoded();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/TLS/TestPRF12.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2010, 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 6313661
+ * @summary Basic known-answer-test for TlsPrf 12
+ *
+ * Vector obtained from the IETF TLS working group mailing list:
+ *
+ * http://www.ietf.org/mail-archive/web/tls/current/msg03416.html
+ */
+
+import java.io.*;
+import java.util.*;
+
+import java.security.Security;
+import java.security.Provider;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+
+import javax.crypto.spec.*;
+
+import sun.security.internal.spec.*;
+
+public class TestPRF12 extends Utils {
+
+ private static int PREFIX_LENGTH = "prf-output: ".length();
+
+ public static void main(String[] args) throws Exception {
+ Provider provider = Security.getProvider("SunJCE");
+
+ InputStream in = new FileInputStream(new File(BASE, "prf12data.txt"));
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+
+ int n = 0;
+ int lineNumber = 0;
+
+ byte[] secret = null;
+ String label = null;
+ byte[] seed = null;
+ int length = 0;
+ String prfAlg = null;
+ int prfHashLength = 0;
+ int prfBlockSize = 0;
+ byte[] output = null;
+
+ while (true) {
+ String line = reader.readLine();
+ lineNumber++;
+ if (line == null) {
+ break;
+ }
+ if (line.startsWith("prf-") == false) {
+ continue;
+ }
+
+ String data = line.substring(PREFIX_LENGTH);
+ if (line.startsWith("prf-secret:")) {
+ secret = parse(data);
+ } else if (line.startsWith("prf-label:")) {
+ label = data;
+ } else if (line.startsWith("prf-seed:")) {
+ seed = parse(data);
+ } else if (line.startsWith("prf-length:")) {
+ length = Integer.parseInt(data);
+ } else if (line.startsWith("prf-alg:")) {
+ prfAlg = data;
+ switch (prfAlg) {
+ case "SHA-224":
+ prfHashLength = 28;
+ prfBlockSize = 64;
+ break;
+ case "SHA-256":
+ prfHashLength = 32;
+ prfBlockSize = 64;
+ break;
+ case "SHA-384":
+ prfHashLength = 48;
+ prfBlockSize = 128;
+ break;
+ case "SHA-512":
+ prfHashLength = 64;
+ prfBlockSize = 128;
+ break;
+ default:
+ throw new Exception("Unknown Alg in the data.");
+ }
+ } else if (line.startsWith("prf-output:")) {
+ output = parse(data);
+
+ System.out.print(".");
+ n++;
+
+ KeyGenerator kg =
+ KeyGenerator.getInstance("SunTls12Prf", provider);
+ SecretKey inKey;
+ if (secret == null) {
+ inKey = null;
+ } else {
+ inKey = new SecretKeySpec(secret, "Generic");
+ }
+ TlsPrfParameterSpec spec =
+ new TlsPrfParameterSpec(inKey, label, seed, length,
+ prfAlg, prfHashLength, prfBlockSize);
+ kg.init(spec);
+ SecretKey key = kg.generateKey();
+ byte[] enc = key.getEncoded();
+ if (Arrays.equals(output, enc) == false) {
+ throw new Exception("mismatch line: " + lineNumber);
+ }
+ } else {
+ throw new Exception("Unknown line: " + line);
+ }
+ }
+ if (n == 0) {
+ throw new Exception("no tests");
+ }
+ in.close();
+ System.out.println();
+ System.out.println("OK: " + n + " tests");
+ }
+
+}
--- a/jdk/test/com/sun/crypto/provider/TLS/TestPremaster.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/com/sun/crypto/provider/TLS/TestPremaster.java Tue Nov 02 19:40:45 2010 -0700
@@ -60,7 +60,8 @@
System.out.println("Done.");
}
- private static void test(KeyGenerator kg, int major, int minor) throws Exception {
+ private static void test(KeyGenerator kg, int major, int minor)
+ throws Exception {
kg.init(new TlsRsaPremasterSecretParameterSpec(major, minor));
SecretKey key = kg.generateKey();
@@ -69,7 +70,8 @@
throw new Exception("length: " + encoded.length);
}
if ((encoded[0] != major) || (encoded[1] != minor)) {
- throw new Exception("version mismatch: " + encoded[0] + "." + encoded[1]);
+ throw new Exception("version mismatch: " + encoded[0] +
+ "." + encoded[1]);
}
System.out.println("OK: " + major + "." + minor);
}
--- a/jdk/test/com/sun/crypto/provider/TLS/Utils.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/com/sun/crypto/provider/TLS/Utils.java Tue Nov 02 19:40:45 2010 -0700
@@ -22,7 +22,6 @@
*/
import java.io.*;
-import java.util.*;
class Utils {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/crypto/provider/TLS/prf12data.txt Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,19 @@
+prf-secret: 9b:be:43:6b:a9:40:f0:17:b1:76:52:84:9a:71:db:35
+prf-seed: a0:ba:9f:93:6c:da:31:18:27:a6:f7:96:ff:d5:19:8c
+prf-label: test label
+prf-length: 100
+prf-alg: SHA-256
+prf-output: e3:f2:29:ba:72:7b:e1:7b:8d:12:26:20:55:7c:d4:53:c2:aa:b2:1d:07:c3:d4:95:32:9b:52:d4:e6:1e:db:5a:6b:30:17:91:e9:0d:35:c9:c9:a4:6b:4e:14:ba:f9:af:0f:a0:22:f7:07:7d:ef:17:ab:fd:37:97:c0:56:4b:ab:4f:bc:91:66:6e:9d:ef:9b:97:fc:e3:4f:79:67:89:ba:a4:80:82:d1:22:ee:42:c5:a7:2e:5a:51:10:ff:f7:01:87:34:7b:66
+prf-secret: b8:0b:73:3d:6c:ee:fc:dc:71:56:6e:a4:8e:55:67:df
+prf-seed: cd:66:5c:f6:a8:44:7d:d6:ff:8b:27:55:5e:db:74:65
+prf-label: test label
+prf-length: 148
+prf-alg: SHA-384
+prf-output: 7b:0c:18:e9:ce:d4:10:ed:18:04:f2:cf:a3:4a:33:6a:1c:14:df:fb:49:00:bb:5f:d7:94:21:07:e8:1c:83:cd:e9:ca:0f:aa:60:be:9f:e3:4f:82:b1:23:3c:91:46:a0:e5:34:cb:40:0f:ed:27:00:88:4f:9d:c2:36:f8:0e:dd:8b:fa:96:11:44:c9:e8:d7:92:ec:a7:22:a7:b3:2f:c3:d4:16:d4:73:eb:c2:c5:fd:4a:bf:da:d0:5d:91:84:25:9b:5b:f8:cd:4d:90:fa:0d:31:e2:de:c4:79:e4:f1:a2:60:66:f2:ee:a9:a6:92:36:a3:e5:26:55:c9:e9:ae:e6:91:c8:f3:a2:68:54:30:8d:5e:aa:3b:e8:5e:09:90:70:3d:73:e5:6f
+prf-secret: b0:32:35:23:c1:85:35:99:58:4d:88:56:8b:bb:05:eb
+prf-seed: d4:64:0e:12:e4:bc:db:fb:43:7f:03:e6:ae:41:8e:e5
+prf-label: test label
+prf-length: 196
+prf-alg: SHA-512
+prf-output: 12:61:f5:88:c7:98:c5:c2:01:ff:03:6e:7a:9c:b5:ed:cd:7f:e3:f9:4c:66:9a:12:2a:46:38:d7:d5:08:b2:83:04:2d:f6:78:98:75:c7:14:7e:90:6d:86:8b:c7:5c:45:e2:0e:b4:0c:1c:f4:a1:71:3b:27:37:1f:68:43:25:92:f7:dc:8e:a8:ef:22:3e:12:ea:85:07:84:13:11:bf:68:65:3d:0c:fc:40:56:d8:11:f0:25:c4:5d:df:a6:e6:fe:c7:02:f0:54:b4:09:d6:f2:8d:d0:a3:23:3e:49:8d:a4:1a:3e:75:c5:63:0e:ed:be:22:fe:25:4e:33:a1:b0:e9:f6:b9:82:66:75:be:c7:d0:1a:84:56:58:dc:9c:39:75:45:40:1d:40:b9:f4:6c:7a:40:0e:e1:b8:f8:1c:a0:a6:0d:1a:39:7a:10:28:bf:f5:d2:ef:50:66:12:68:42:fb:8d:a4:19:76:32:bd:b5:4f:f6:63:3f:86:bb:c8:36:e6:40:d4:d8:98
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StringBuilder/EnsureCapacity.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2010, 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 6955504 6992121
+ * @summary Test the StringBuilder.ensureCapacity() with negative minimumCapacity
+ * and append() method with negative length input argument.
+ * Also, test the StringBuffer class.
+ */
+
+import java.util.ArrayList;
+import java.util.Vector;
+
+public class EnsureCapacity {
+ public static void main(String[] args) {
+ testStringBuilder();
+ testStringBuffer();
+ }
+
+ private static void checkCapacity(int before, int after) {
+ if (before != after) {
+ throw new RuntimeException("capacity is expected to be unchanged: " +
+ "before=" + before + " after=" + after);
+ }
+ }
+
+ private static void testStringBuilder() {
+ StringBuilder sb = new StringBuilder("abc");
+ int cap = sb.capacity();
+
+ // test if negative minimumCapacity
+ sb.ensureCapacity(Integer.MIN_VALUE);
+ checkCapacity(cap, sb.capacity());
+
+ try {
+ char[] str = {'a', 'b', 'c', 'd'};
+ // test if negative length
+ sb.append(str, 0, Integer.MIN_VALUE + 10);
+ throw new RuntimeException("IndexOutOfBoundsException not thrown");
+ } catch (IndexOutOfBoundsException ex) {
+ }
+ }
+
+ private static void testStringBuffer() {
+ StringBuffer sb = new StringBuffer("abc");
+ int cap = sb.capacity();
+
+ // test if negative minimumCapacity
+ sb.ensureCapacity(Integer.MIN_VALUE);
+ checkCapacity(cap, sb.capacity());
+
+ try {
+ char[] str = {'a', 'b', 'c', 'd'};
+ // test if negative length
+ sb.append(str, 0, Integer.MIN_VALUE + 10);
+ throw new RuntimeException("IndexOutOfBoundsException not thrown");
+ } catch (IndexOutOfBoundsException ex) {
+ }
+ }
+}
--- a/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java Tue Nov 02 19:40:45 2010 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4959889
+ * @bug 4959889 6992968
* @summary Basic unit test of memory management testing:
* 1) setCollectionUsageThreshold() and getCollectionUsageThreshold()
* 2) test notification emitted for two different memory pools.
@@ -34,8 +34,10 @@
* @run main/timeout=300 CollectionUsageThreshold
*/
+import java.lang.Thread.*;
import java.lang.management.*;
import java.util.*;
+import java.util.concurrent.*;
import javax.management.*;
import javax.management.openmbean.CompositeData;
@@ -52,6 +54,12 @@
private static Checker checker;
private static int numGCs = 0;
+ // semaphore to signal the arrival of a low memory notification
+ private static Semaphore signals = new Semaphore(0);
+ // barrier for the main thread to wait until the checker thread
+ // finishes checking the low memory notification result
+ private static CyclicBarrier barrier = new CyclicBarrier(2);
+
static class PoolRecord {
private MemoryPoolMXBean pool;
private int listenerInvoked = 0;
@@ -98,10 +106,9 @@
}
pr.addNotification(minfo);
synchronized (this) {
+ System.out.println("notifying the checker thread to check result");
numNotifs++;
- if (numNotifs > 0 && (numNotifs % EXPECTED_NUM_POOLS) == 0) {
- checker.goCheckResult();
- }
+ signals.release();
}
}
}
@@ -134,6 +141,9 @@
}
try {
+ // This test creates a checker thread responsible for checking
+ // the low memory notifications. It blocks until a permit
+ // from the signals semaphore is available.
checker = new Checker("Checker thread");
checker.setDaemon(true);
checker.start();
@@ -148,9 +158,18 @@
NotificationEmitter emitter = (NotificationEmitter) mm;
emitter.addNotificationListener(listener, null, null);
+ // The main thread invokes GC to trigger the VM to perform
+ // low memory detection and then waits until the checker thread
+ // finishes its work to check for a low-memory notification.
+ //
+ // At GC time, VM will issue low-memory notification and invoke
+ // the listener which will release a permit to the signals semaphore.
+ // When the checker thread acquires the permit and finishes
+ // checking the low-memory notification, it will also call
+ // barrier.await() to signal the main thread to resume its work.
for (int i = 0; i < NUM_GCS; i++) {
invokeGC();
- checker.waitForCheckResult();
+ barrier.await();
}
} finally {
// restore the default
@@ -166,6 +185,7 @@
}
+
private static void invokeGC() {
System.out.println("Calling System.gc()");
numGCs++;
@@ -180,8 +200,6 @@
}
static class Checker extends Thread {
- private Object lock = new Object();
- private Object go = new Object();
private boolean checkerReady = false;
private int waiters = 0;
private boolean readyToCheck = false;
@@ -190,83 +208,48 @@
};
public void run() {
while (true) {
- synchronized (lock) {
- checkerReady = true;
- try {
- lock.wait();
- } catch (InterruptedException e) {
- // ignore
- }
+ try {
+ signals.acquire(EXPECTED_NUM_POOLS);
checkResult();
- checkerReady = false;
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ } catch (BrokenBarrierException e) {
+ throw new RuntimeException(e);
}
}
}
- private void checkResult() {
+ private void checkResult() throws InterruptedException, BrokenBarrierException {
for (PoolRecord pr : result.values()) {
if (pr.getListenerInvokedCount() != numGCs) {
- throw new RuntimeException("Listeners invoked count = " +
+ fail("Listeners invoked count = " +
pr.getListenerInvokedCount() + " expected to be " +
numGCs);
}
if (pr.getNotifCount() != numGCs) {
- throw new RuntimeException("Notif Count = " +
+ fail("Notif Count = " +
pr.getNotifCount() + " expected to be " +
numGCs);
}
long count = pr.getPool().getCollectionUsageThresholdCount();
if (count != numGCs) {
- throw new RuntimeException("CollectionUsageThresholdCount = " +
+ fail("CollectionUsageThresholdCount = " +
count + " expected to be " + numGCs);
}
if (!pr.getPool().isCollectionUsageThresholdExceeded()) {
- throw new RuntimeException("isCollectionUsageThresholdExceeded" +
+ fail("isCollectionUsageThresholdExceeded" +
" expected to be true");
}
}
- synchronized (go) {
- // wait until the main thread is waiting for notification
- while (waiters == 0) {
- try {
- go.wait(50);
- } catch (InterruptedException e) {
- // ignore
- }
- }
-
- System.out.println(Thread.currentThread().getName() +
- " notifying main thread to continue - result checking finished");
- go.notify();
- }
- }
- public void goCheckResult() {
- System.out.println(Thread.currentThread().getName() +
- " notifying to check result");
- synchronized (lock) {
- while (!checkerReady) {
- try {
- lock.wait(50);
- } catch (InterruptedException e) {
- // ignore
- }
- }
- lock.notify();
- }
+ // wait until the main thread is waiting for notification
+ barrier.await();
+ System.out.println("notifying main thread to continue - result checking finished");
}
- public void waitForCheckResult() {
- System.out.println(Thread.currentThread().getName() +
- " waiting for result checking finishes");
- synchronized (go) {
- waiters++;
- try {
- go.wait();
- } catch (InterruptedException e) {
- // ignore
- }
- waiters--;
- }
+ private void fail(String msg) {
+ // reset the barrier to cause BrokenBarrierException to avoid hanging
+ barrier.reset();
+ throw new RuntimeException(msg);
}
}
}
--- a/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThresholdConcMarkSweepGC.sh Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/java/lang/management/MemoryMXBean/CollectionUsageThresholdConcMarkSweepGC.sh Tue Nov 02 19:40:45 2010 -0700
@@ -27,6 +27,7 @@
# @summary Test CollectionUsageThreshold with concurrent marksweep collector
# @author Mandy Chung
#
+# @ignore 6982965
# @run build CollectionUsageThreshold
# @run shell/timeout=300 CollectionUsageThresholdConcMarkSweepGC.sh
#
--- a/jdk/test/java/nio/MappedByteBuffer/Basic.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/java/nio/MappedByteBuffer/Basic.java Tue Nov 02 19:40:45 2010 -0700
@@ -24,7 +24,6 @@
/* @test
* @bug 4462336 6799037
* @summary Simple MappedByteBuffer tests
- * @run main/othervm Basic
*/
import java.io.*;
@@ -76,5 +75,10 @@
throw new RuntimeException("Incorrect isReadOnly");
fc.close();
raf.close();
+
+ // clean-up
+ mbb = null;
+ System.gc();
+ Thread.sleep(500);
}
}
--- a/jdk/test/java/nio/channels/AsynchronousChannelGroup/Basic.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/java/nio/channels/AsynchronousChannelGroup/Basic.java Tue Nov 02 19:40:45 2010 -0700
@@ -89,10 +89,9 @@
}
// create channel that is bound to group
AsynchronousChannel ch;
- switch (rand.nextInt(3)) {
+ switch (rand.nextInt(2)) {
case 0 : ch = AsynchronousSocketChannel.open(group); break;
case 1 : ch = AsynchronousServerSocketChannel.open(group); break;
- case 2 : ch = AsynchronousDatagramChannel.open(null, group); break;
default : throw new AssertionError();
}
group.shutdown();
@@ -128,18 +127,9 @@
}
// I/O in progress
- AsynchronousChannel ch;
- if (rand.nextBoolean()) {
- AsynchronousServerSocketChannel listener = AsynchronousServerSocketChannel
- .open(group).bind(new InetSocketAddress(0));
- listener.accept();
- ch = listener;
- } else {
- AsynchronousDatagramChannel adc =
- AsynchronousDatagramChannel.open(null, group);
- adc.receive(ByteBuffer.allocate(100));
- ch = adc;
- }
+ AsynchronousServerSocketChannel ch = AsynchronousServerSocketChannel
+ .open(group).bind(new InetSocketAddress(0));
+ ch.accept();
// forceful shutdown
group.shutdownNow();
--- a/jdk/test/java/nio/channels/AsynchronousDatagramChannel/Basic.java Tue Nov 02 12:45:49 2010 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,410 +0,0 @@
-/*
- * Copyright (c) 2008, 2009, 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 4527345 6842687
- * @summary Unit test for AsynchronousDatagramChannel
- */
-
-import java.nio.ByteBuffer;
-import java.nio.channels.*;
-import java.net.*;
-import java.util.concurrent.*;
-import java.util.concurrent.atomic.*;
-
-public class Basic {
-
- public static void main(String[] args) throws Exception {
- doReceiveTests();
- doReadTests();
- doSendTests();
- doWriteTests();
- doCancelTests();
- doMulticastTests();
- }
-
- // basic receive tests
- static void doReceiveTests() throws Exception {
- final byte[] msg = "hello".getBytes();
-
- AsynchronousDatagramChannel ch = AsynchronousDatagramChannel.open()
- .bind(new InetSocketAddress(0));
- int port = ((InetSocketAddress)(ch.getLocalAddress())).getPort();
- InetAddress rh = InetAddress.getLocalHost();
- final SocketAddress sa = new InetSocketAddress(rh, port);
-
- DatagramChannel sender = DatagramChannel.open();
- ByteBuffer dst = ByteBuffer.allocateDirect(100);
-
- // Test: datagram packet received immediately
- sender.send(ByteBuffer.wrap(msg), sa);
- dst.clear();
- ch.receive(dst).get(1, TimeUnit.SECONDS);
- if (dst.flip().remaining() != msg.length)
- throw new RuntimeException("Unexpected number of bytes read");
-
- // Test: datagram packet not received immediately
- dst.clear();
- final CountDownLatch latch = new CountDownLatch(1);
- ch.receive(dst, (Void)null, new CompletionHandler<SocketAddress,Void>() {
- public void completed(SocketAddress source, Void att) {
- latch.countDown();
- }
- public void failed (Throwable exc, Void att) {
- }
- });
- Thread.sleep(2000);
- sender.send(ByteBuffer.wrap(msg), sa);
- latch.await(2, TimeUnit.SECONDS); // wait for completion handler
-
- // Test: timeout
- dst.clear();
- final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
- ch.receive(dst, 2, TimeUnit.SECONDS, (Void)null, new CompletionHandler<SocketAddress,Void>() {
- public void completed(SocketAddress source, Void att) {
- }
- public void failed (Throwable exc, Void att) {
- exception.set(exc);
- }
- });
- Throwable result;
- while ((result = exception.get()) == null) {
- Thread.sleep(100);
- }
- if (!(result instanceof InterruptedByTimeoutException))
- throw new RuntimeException("InterruptedByTimeoutException expected");
-
- // AsynchronousCloseException
- dst = ByteBuffer.allocateDirect(100);
- exception.set(null);
- ch.receive(dst, (Void)null, new CompletionHandler<SocketAddress,Void>() {
- public void completed(SocketAddress source, Void att) {
- }
- public void failed (Throwable exc, Void att) {
- exception.set(exc);
- }
- });
- ch.close();
- while ((result = exception.get()) == null) {
- Thread.sleep(100);
- }
- if (!(result instanceof AsynchronousCloseException))
- throw new RuntimeException("AsynchronousCloseException expected");
-
- // done
- sender.close();
- }
-
- // basic read tests
- static void doReadTests() throws Exception {
- final byte[] msg = "hello".getBytes();
-
- AsynchronousDatagramChannel ch = AsynchronousDatagramChannel.open()
- .bind(new InetSocketAddress(0));
- int port = ((InetSocketAddress)(ch.getLocalAddress())).getPort();
- InetAddress lh = InetAddress.getLocalHost();
- final SocketAddress sa = new InetSocketAddress(lh, port);
-
- DatagramChannel sender = DatagramChannel.open();
- ByteBuffer dst = ByteBuffer.allocateDirect(100);
-
- // Test: not connected
- try {
- ch.read(dst);
- throw new RuntimeException("NotYetConnectedException expected");
- } catch (NotYetConnectedException e) {
- }
-
- // connect the channel
- sender.bind(new InetSocketAddress(0));
- ch.connect(new InetSocketAddress(lh,
- ((InetSocketAddress)(sender.getLocalAddress())).getPort()));
-
- // Test: datagram packet received immediately
- sender.send(ByteBuffer.wrap(msg), sa);
- dst.clear();
- ch.read(dst).get(1, TimeUnit.SECONDS);
- if (dst.flip().remaining() != msg.length)
- throw new RuntimeException("Unexpected number of bytes read");
-
- // Test: datagram packet not received immediately
- dst.clear();
- final CountDownLatch l1 = new CountDownLatch(1);
- ch.read(dst, (Void)null, new CompletionHandler<Integer,Void>() {
- public void completed(Integer bytesRead, Void att) {
- l1.countDown();
- }
- public void failed (Throwable exc, Void att) {
- }
- });
- Thread.sleep(2000);
- sender.send(ByteBuffer.wrap(msg), sa);
- l1.await(2, TimeUnit.SECONDS);
-
- // Test: timeout
- dst.clear();
- final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
- ch.read(dst, 2, TimeUnit.SECONDS, (Void)null, new CompletionHandler<Integer,Void>() {
- public void completed(Integer bytesRead, Void att) {
- }
- public void failed (Throwable exc, Void att) {
- exception.set(exc);
- }
- });
- Throwable result;
- while ((result = exception.get()) == null) {
- Thread.sleep(100);
- }
- if (!(result instanceof InterruptedByTimeoutException))
- throw new RuntimeException("InterruptedByTimeoutException expected");
-
- // AsynchronousCloseException
- dst.clear();
- exception.set(null);
- ch.read(dst, (Void)null, new CompletionHandler<Integer,Void>() {
- public void completed(Integer bytesRead, Void att) {
- }
- public void failed (Throwable exc, Void att) {
- exception.set(exc);
- }
- });
- ch.close();
- while ((result = exception.get()) == null) {
- Thread.sleep(100);
- }
- if (!(result instanceof AsynchronousCloseException))
- throw new RuntimeException("AsynchronousCloseException expected");
-
- // done
- sender.close();
- }
-
- // basic send tests
- static void doSendTests() throws Exception {
- final byte[] msg = "hello".getBytes();
-
- DatagramChannel reader = DatagramChannel.open()
- .bind(new InetSocketAddress(0));
- int port = ((InetSocketAddress)(reader.getLocalAddress())).getPort();
- InetAddress rh = InetAddress.getLocalHost();
- SocketAddress sa = new InetSocketAddress(rh, port);
-
- AsynchronousDatagramChannel ch = AsynchronousDatagramChannel.open();
-
- // Test: send datagram packet to reader
- int bytesSent = ch.send(ByteBuffer.wrap(msg), sa).get();
- if (bytesSent != msg.length)
- throw new RuntimeException("Unexpected number of bytes sent");
-
- // check received
- ByteBuffer dst = ByteBuffer.allocateDirect(100);
- reader.receive(dst);
- dst.flip();
- if (dst.remaining() != msg.length)
- throw new RuntimeException("Unexpected number of bytes received");
-
- // Test: send datagram packet to reader and check completion handler
- // is invoked
- final CountDownLatch l2 = new CountDownLatch(1);
- ch.send(ByteBuffer.wrap(msg), sa, (Void)null, new CompletionHandler<Integer,Void>() {
- public void completed(Integer bytesSent, Void att) {
- if (bytesSent != msg.length)
- throw new RuntimeException("Unexpected number of bytes received");
- l2.countDown();
- }
- public void failed (Throwable exc, Void att) {
- }
- });
- l2.await(5, TimeUnit.SECONDS);
-
- // check received
- dst.clear();
- reader.receive(dst);
- dst.flip();
- if (dst.remaining() != msg.length)
- throw new RuntimeException("Unexpected number of bytes received");
-
- // Test: check that failed method is invoked
- ch.close();
- final CountDownLatch l3 = new CountDownLatch(1);
- ch.send(ByteBuffer.wrap(msg), sa, (Void)null, new CompletionHandler<Integer,Void>() {
- public void completed(Integer bytesSent, Void att) {
- throw new RuntimeException("completed method invoked");
- }
- public void failed (Throwable exc, Void att) {
- if (exc instanceof ClosedChannelException) {
- l3.countDown();
- } else {
- throw new RuntimeException(exc);
- }
- }
- });
- l3.await(5, TimeUnit.SECONDS);
-
- // done
- reader.close();
- }
-
- // basic write tests
- static void doWriteTests() throws Exception {
- final byte[] msg = "hello".getBytes();
-
- DatagramChannel reader = DatagramChannel.open()
- .bind(new InetSocketAddress(0));
- int port = ((InetSocketAddress)(reader.getLocalAddress())).getPort();
- InetAddress rh = InetAddress.getLocalHost();
- SocketAddress sa = new InetSocketAddress(rh, port);
-
- AsynchronousDatagramChannel ch = AsynchronousDatagramChannel.open();
-
- // Test: unconnected
- try {
- ch.write(ByteBuffer.wrap(msg)).get();
- throw new RuntimeException("NotYetConnectedException expected");
- } catch (NotYetConnectedException e) {
- }
-
- // Test: connect, and write datagram
- ch.connect(sa);
- int bytesSent = ch.write(ByteBuffer.wrap(msg)).get();
- if (bytesSent != msg.length)
- throw new RuntimeException("Unexpected number of bytes sent");
-
- // check received
- ByteBuffer dst = ByteBuffer.allocateDirect(100);
- reader.receive(dst);
- dst.flip();
- if (dst.remaining() != msg.length)
- throw new RuntimeException("Unexpected number of bytes received");
-
- // Test: write datagram and check completion handler is invoked
- final CountDownLatch l2 = new CountDownLatch(1);
- ch.write(ByteBuffer.wrap(msg), (Void)null, new CompletionHandler<Integer,Void>() {
- public void completed(Integer bytesSent, Void att) {
- if (bytesSent != msg.length)
- throw new RuntimeException("Unexpected number of bytes received");
- l2.countDown();
- }
- public void failed (Throwable exc, Void att) {
- }
- });
- l2.await(5, TimeUnit.SECONDS);
-
- // check received
- dst.clear();
- reader.receive(dst);
- dst.flip();
- if (dst.remaining() != msg.length)
- throw new RuntimeException("Unexpected number of bytes received");
-
- // done
- ch.close();
- reader.close();
- }
-
- static void cancelAndCheck(Future<?> result)
- throws InterruptedException
- {
- boolean cancelled = result.cancel(false);
- if (!cancelled)
- throw new RuntimeException("Not cancelled");
- if (!result.isDone())
- throw new RuntimeException("Should be done");
- try {
- result.get();
- throw new RuntimeException("Result not expected");
- } catch (CancellationException e) {
- // expected
- } catch (ExecutionException e) {
- throw new RuntimeException("Should not fail");
- }
- }
-
- // basic cancel tests
- static void doCancelTests() throws Exception {
- InetAddress lh = InetAddress.getLocalHost();
-
- // receive
- for (int i=0; i<2; i++) {
- AsynchronousDatagramChannel ch =
- AsynchronousDatagramChannel.open().bind(new InetSocketAddress(0));
- Future<SocketAddress> remote = ch.receive(ByteBuffer.allocate(100));
- cancelAndCheck(remote);
- ch.close();
- }
-
- // read
- for (int i=0; i<2; i++) {
- AsynchronousDatagramChannel ch =
- AsynchronousDatagramChannel.open().bind(new InetSocketAddress(0));
- ch.connect(new InetSocketAddress(lh,
- ((InetSocketAddress)(ch.getLocalAddress())).getPort()));
- final CountDownLatch latch = new CountDownLatch(1);
- long timeout = (i == 0) ? 0L : 60L;
- Future<Integer> result = ch.read(ByteBuffer.allocate(100));
- cancelAndCheck(result);
- ch.close();
- }
- }
-
- // basic multicast test
- static void doMulticastTests() throws Exception {
- final byte[] msg = "hello".getBytes();
-
- InetAddress lh = InetAddress.getLocalHost();
- NetworkInterface interf = NetworkInterface.getByInetAddress(lh);
- if (interf.isLoopback() || !interf.supportsMulticast()) {
- System.out.println("Multicasting not tested");
- return;
- }
-
- AsynchronousDatagramChannel ch = AsynchronousDatagramChannel
- .open(StandardProtocolFamily.INET, null)
- .setOption(StandardSocketOption.SO_REUSEADDR, true)
- .bind(new InetSocketAddress(0));
-
- int port = ((InetSocketAddress)(ch.getLocalAddress())).getPort();
-
- // join group
- InetAddress group = InetAddress.getByName("225.4.5.6");
- MembershipKey key = ch.join(group, interf);
-
- // check key
- if (key.channel() != ch)
- throw new RuntimeException("Not the expected channel");
-
- // send message to group
- DatagramChannel sender = DatagramChannel.open();
- sender.send(ByteBuffer.wrap(msg), new InetSocketAddress(group, port));
- sender.close();
-
- // check message received
- ByteBuffer dst = ByteBuffer.allocate(200);
- SocketAddress source = ch.receive(dst).get(2, TimeUnit.SECONDS);
- if (!((InetSocketAddress)source).getAddress().equals(lh))
- throw new RuntimeException("Unexpected source");
-
- // done
- ch.close();
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/channels/DatagramChannel/ChangingAddress.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2010, 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 6431343
+ * @summary Test that DatagramChannel.getLocalAddress returns the right local
+ * address after connect/disconnect.
+ */
+import java.net.*;
+import java.nio.channels.DatagramChannel;
+
+public class ChangingAddress {
+
+ // Checks that the given DatagramSocket and DatagramChannel are bound to the
+ // same local address.
+ static void check(DatagramSocket ds, DatagramChannel dc) {
+ InetAddress expected = ds.getLocalAddress();
+ InetAddress actual = dc.socket().getLocalAddress();
+ // okay if one bound to 0.0.0.0 and the other to ::0
+ if ((expected.isAnyLocalAddress() != actual.isAnyLocalAddress()) &&
+ !expected.equals(actual))
+ {
+ throw new RuntimeException("Expected: " + expected + ", actual: " + actual);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ InetAddress lh = InetAddress.getLocalHost();
+ SocketAddress remote = new InetSocketAddress(lh, 1234);
+
+ DatagramSocket ds = null;
+ DatagramChannel dc = null;
+ try {
+
+ ds = new DatagramSocket();
+ dc = DatagramChannel.open().bind(new InetSocketAddress(0));
+ check(ds, dc);
+
+ ds.connect(remote);
+ dc.connect(remote);
+ check(ds, dc);
+
+ ds.disconnect();
+ dc.disconnect();
+ check(ds, dc);
+
+ // repeat tests using socket adapter
+ ds.connect(remote);
+ dc.socket().connect(remote);
+ check(ds, dc);
+
+ ds.disconnect();
+ dc.socket().disconnect();
+ check(ds, dc);
+
+ } finally {
+ if (ds != null) ds.close();
+ if (dc != null) dc.close();
+ }
+ }
+}
--- a/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/Provider1.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/Provider1.java Tue Nov 02 19:40:45 2010 -0700
@@ -23,7 +23,6 @@
import java.nio.channels.spi.AsynchronousChannelProvider;
import java.nio.channels.*;
-import java.net.ProtocolFamily;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
import java.io.IOException;
@@ -59,11 +58,4 @@
{
throw new RuntimeException();
}
-
- @Override
- public AsynchronousDatagramChannel openAsynchronousDatagramChannel
- (ProtocolFamily family, AsynchronousChannelGroup group) throws IOException
- {
- throw new RuntimeException();
- }
}
--- a/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/Provider2.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/java/nio/channels/spi/AsynchronousChannelProvider/Provider2.java Tue Nov 02 19:40:45 2010 -0700
@@ -23,7 +23,6 @@
import java.nio.channels.spi.AsynchronousChannelProvider;
import java.nio.channels.*;
-import java.net.ProtocolFamily;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;
import java.io.IOException;
@@ -59,11 +58,4 @@
{
throw new RuntimeException();
}
-
- @Override
- public AsynchronousDatagramChannel openAsynchronousDatagramChannel
- (ProtocolFamily family, AsynchronousChannelGroup group) throws IOException
- {
- throw new RuntimeException();
- }
}
--- a/jdk/test/java/nio/file/Path/InterruptCopy.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/java/nio/file/Path/InterruptCopy.java Tue Nov 02 19:40:45 2010 -0700
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4313887
+ * @bug 4313887 6993267
* @summary Unit test for Sun-specific ExtendedCopyOption.INTERRUPTIBLE option
* @library ..
* @run main/othervm -XX:-UseVMInterruptibleIO InterruptCopy
@@ -36,8 +36,9 @@
public class InterruptCopy {
- private static final long FILE_SIZE_TO_COPY = 512 * 1024 * 1024;
+ private static final long FILE_SIZE_TO_COPY = 512L * 1024L * 1024L;
private static final int DELAY_IN_MS = 500;
+ private static final int DURATION_MAX_IN_MS = 5000;
public static void main(String[] args) throws Exception {
Path dir = TestUtil.createTemporaryDirectory();
@@ -81,20 +82,27 @@
try {
// copy source to target in main thread, interrupting it after a delay
final Thread me = Thread.currentThread();
- pool.schedule(new Runnable() {
+ Future<?> wakeup = pool.schedule(new Runnable() {
public void run() {
me.interrupt();
}}, DELAY_IN_MS, TimeUnit.MILLISECONDS);
System.out.println("Copying file...");
try {
+ long start = System.currentTimeMillis();
source.copyTo(target, ExtendedCopyOption.INTERRUPTIBLE);
- throw new RuntimeException("Copy completed (this is not expected)");
+ long duration = System.currentTimeMillis() - start;
+ if (duration > DURATION_MAX_IN_MS)
+ throw new RuntimeException("Copy was not interrupted");
} catch (IOException e) {
boolean interrupted = Thread.interrupted();
if (!interrupted)
throw new RuntimeException("Interrupt status was not set");
System.out.println("Copy failed (this is expected)");
}
+ try {
+ wakeup.get();
+ } catch (InterruptedException ignore) { }
+ Thread.interrupted();
// copy source to target via task in thread pool, interrupting it after
// a delay using cancel(true)
@@ -113,7 +121,6 @@
System.out.println("Copy cancelled.");
} finally {
pool.shutdown();
- pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
}
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/ArrayList/EnsureCapacity.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2010, 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 6992121
+ * @summary Test the ArrayList.ensureCapacity() and Vector.ensureCapacity
+ * method with negative minimumCapacity input argument.
+ */
+
+import java.util.ArrayList;
+import java.util.Vector;
+
+public class EnsureCapacity {
+ public static void main(String[] args) {
+ testArrayList();
+ testVector();
+ }
+
+ private static void checkCapacity(int before, int after) {
+ if (before != after) {
+ throw new RuntimeException("capacity is expected to be unchanged: " +
+ "before=" + before + " after=" + after);
+ }
+ }
+
+ private static void testArrayList() {
+ ArrayList<String> al = new ArrayList<String>();
+ al.add("abc");
+ al.ensureCapacity(Integer.MIN_VALUE);
+
+ // there is no method to query the capacity of ArrayList
+ // so before and after capacity are not checked
+ }
+
+ private static void testVector() {
+ Vector<String> vector = new Vector<String>();
+ vector.add("abc");
+
+ int cap = vector.capacity();
+ vector.ensureCapacity(Integer.MIN_VALUE);
+ checkCapacity(cap, vector.capacity());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/misc/Version/Version.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2010, 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 6994413
+ * @summary Check the JDK and JVM version returned by sun.misc.Version
+ * matches the versions defined in the system properties
+ * @compile -XDignore.symbol.file Version.java
+ * @run main Version
+ */
+
+import static sun.misc.Version.*;
+public class Version {
+
+ public static void main(String[] args) throws Exception {
+ VersionInfo jdk = newVersionInfo(System.getProperty("java.runtime.version"));
+ VersionInfo v1 = new VersionInfo(jdkMajorVersion(),
+ jdkMinorVersion(),
+ jdkMicroVersion(),
+ jdkUpdateVersion(),
+ jdkSpecialVersion(),
+ jdkBuildNumber());
+ System.out.println("JDK version = " + jdk + " " + v1);
+ if (!jdk.equals(v1)) {
+ throw new RuntimeException("Unmatched version: " + jdk + " vs " + v1);
+ }
+ VersionInfo jvm = newVersionInfo(System.getProperty("java.vm.version"));
+ VersionInfo v2 = new VersionInfo(jvmMajorVersion(),
+ jvmMinorVersion(),
+ jvmMicroVersion(),
+ jvmUpdateVersion(),
+ jvmSpecialVersion(),
+ jvmBuildNumber());
+ System.out.println("JVM version = " + jvm + " " + v2);
+ if (!jvm.equals(v2)) {
+ throw new RuntimeException("Unmatched version: " + jvm + " vs " + v2);
+ }
+ }
+
+ static class VersionInfo {
+ final int major;
+ final int minor;
+ final int micro;
+ final int update;
+ final String special;
+ final int build;
+ VersionInfo(int major, int minor, int micro,
+ int update, String special, int build) {
+ this.major = major;
+ this.minor = minor;
+ this.micro = micro;
+ this.update = update;
+ this.special = special;
+ this.build = build;
+ }
+
+ public boolean equals(VersionInfo v) {
+ return (this.major == v.major && this.minor == v.minor &&
+ this.micro == v.micro && this.update == v.update &&
+ this.special.equals(v.special) && this.build == v.build);
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(major + "." + minor + "." + micro);
+ if (update > 0) {
+ sb.append("_" + update);
+ }
+
+ if (!special.isEmpty()) {
+ sb.append(special);
+ }
+ sb.append("-b" + build);
+ return sb.toString();
+ }
+ }
+
+ private static VersionInfo newVersionInfo(String version) throws Exception {
+ // valid format of the version string is:
+ // n.n.n[_uu[c]][-<identifer>]-bxx
+ int major = 0;
+ int minor = 0;
+ int micro = 0;
+ int update = 0;
+ String special = "";
+ int build = 0;
+ CharSequence cs = version;
+ if (cs.length() >= 5) {
+ if (Character.isDigit(cs.charAt(0)) && cs.charAt(1) == '.' &&
+ Character.isDigit(cs.charAt(2)) && cs.charAt(3) == '.' &&
+ Character.isDigit(cs.charAt(4))) {
+ major = Character.digit(cs.charAt(0), 10);
+ minor = Character.digit(cs.charAt(2), 10);
+ micro = Character.digit(cs.charAt(4), 10);
+ cs = cs.subSequence(5, cs.length());
+ } else if (Character.isDigit(cs.charAt(0)) &&
+ Character.isDigit(cs.charAt(1)) && cs.charAt(2) == '.' &&
+ Character.isDigit(cs.charAt(3))) {
+ // HSX has nn.n (major.minor) version
+ major = Integer.valueOf(version.substring(0, 2)).intValue();
+ minor = Character.digit(cs.charAt(3), 10);
+ cs = cs.subSequence(4, cs.length());
+ }
+ if (cs.charAt(0) == '_' && cs.length() >= 3 &&
+ Character.isDigit(cs.charAt(1)) &&
+ Character.isDigit(cs.charAt(2))) {
+ int nextChar = 3;
+ String uu = cs.subSequence(1, 3).toString();
+ update = Integer.valueOf(uu).intValue();
+ if (cs.length() >= 4) {
+ char c = cs.charAt(3);
+ if (c >= 'a' && c <= 'z') {
+ special = Character.toString(c);
+ nextChar++;
+ }
+ }
+ cs = cs.subSequence(nextChar, cs.length());
+ }
+ if (cs.charAt(0) == '-') {
+ // skip the first character
+ // valid format: <identifier>-bxx or bxx
+ // non-product VM will have -debug|-release appended
+ cs = cs.subSequence(1, cs.length());
+ String[] res = cs.toString().split("-");
+ for (String s : res) {
+ if (s.charAt(0) == 'b') {
+ build =
+ Integer.valueOf(s.substring(1, s.length())).intValue();
+ break;
+ }
+ }
+ }
+ }
+ return new VersionInfo(major, minor, micro, update, special, build);
+ }
+}
--- a/jdk/test/sun/net/www/http/HttpClient/B6726695.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/net/www/http/HttpClient/B6726695.java Tue Nov 02 19:40:45 2010 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6726695
+ * @bug 6726695 6993490
* @summary HttpURLConnection shoul support 'Expect: 100-contimue' headers for PUT
*/
@@ -184,7 +184,15 @@
out.flush();
// Then read the body
char[] cbuf = new char[512];
- int l = in.read(cbuf);
+ in.read(cbuf);
+
+ /* Force the server to not respond for more that the expect 100-Continue
+ * timeout set by the HTTP handler (5000 millis). This ensures the
+ * timeout is correctly resets the default read timeout, infinity.
+ * See 6993490. */
+ System.out.println("server sleeping...");
+ try {Thread.sleep(6000); } catch (InterruptedException e) {}
+
// finally send the 200 OK
out.print("HTTP/1.1 200 OK");
out.print("Server: Sun-Java-System-Web-Server/7.0\r\n");
--- a/jdk/test/sun/net/www/http/KeepAliveCache/B5045306.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/net/www/http/KeepAliveCache/B5045306.java Tue Nov 02 19:40:45 2010 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 5045306 6356004
+ * @bug 5045306 6356004 6993490
* @library ../../httptest/
* @build HttpCallback HttpServer HttpTransaction
* @run main/othervm B5045306
@@ -32,7 +32,6 @@
import java.net.*;
import java.io.*;
-import java.nio.channels.*;
import java.lang.management.*;
/* Part 1:
@@ -164,6 +163,14 @@
failed = true;
trans.setResponseHeader ("Content-length", Integer.toString(0));
+
+ /* Force the server to not respond for more that the timeout
+ * set by the keepalive cleaner (5000 millis). This ensures the
+ * timeout is correctly resets the default read timeout,
+ * infinity. See 6993490. */
+ System.out.println("server sleeping...");
+ try {Thread.sleep(6000); } catch (InterruptedException e) {}
+
trans.sendResponse(200, "OK");
} else if(path.equals("/part2")) {
System.out.println("Call to /part2");
--- a/jdk/test/sun/net/www/protocol/http/ChunkedErrorStream.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/net/www/protocol/http/ChunkedErrorStream.java Tue Nov 02 19:40:45 2010 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6488669 6595324
+ * @bug 6488669 6595324 6993490
* @run main/othervm ChunkedErrorStream
* @summary Chunked ErrorStream tests
*/
@@ -48,6 +48,18 @@
* 2) Client sends request to server and tries to
* getErrorStream(). 4K + 10 bytes must be read from
* the errorStream.
+ *
+ * Part 3: 6993490
+ * Reuse persistent connection from part 2, the error stream
+ * buffering will have set a reduced timeout on the socket and
+ * tried to reset it to the default, infinity. Client must not
+ * throw a timeout exception. If it does, it indicates that the
+ * default timeout was not reset correctly.
+ * If no timeout exception is thrown, it does not guarantee that
+ * the timeout was reset correctly, as there is a potential race
+ * between the sleeping server and the client thread. Typically,
+ * 1000 millis has been enought to reliable reproduce this problem
+ * since the error stream buffering sets the timeout to 60 millis.
*/
public class ChunkedErrorStream
@@ -75,19 +87,18 @@
} finally {
httpServer.stop(1);
}
-
}
void doClient() {
- for (int times=0; times<2; times++) {
+ for (int times=0; times<3; times++) {
HttpURLConnection uc = null;
try {
InetSocketAddress address = httpServer.getAddress();
String URLStr = "http://localhost:" + address.getPort() + "/test/";
if (times == 0) {
- URLStr += 6488669;
+ URLStr += "first";
} else {
- URLStr += 6595324;
+ URLStr += "second";
}
System.out.println("Trying " + URLStr);
@@ -97,6 +108,11 @@
throw new RuntimeException("Failed: getInputStream should throw and IOException");
} catch (IOException e) {
+ if (e instanceof SocketTimeoutException) {
+ e.printStackTrace();
+ throw new RuntimeException("Failed: SocketTimeoutException should not happen");
+ }
+
// This is what we expect to happen.
InputStream es = uc.getErrorStream();
byte[] ba = new byte[1024];
@@ -112,7 +128,7 @@
if (count == 0)
throw new RuntimeException("Failed: ErrorStream returning 0 bytes");
- if (times == 1 && count != (4096+10))
+ if (times >= 1 && count != (4096+10))
throw new RuntimeException("Failed: ErrorStream returning " + count +
" bytes. Expecting " + (4096+10));
@@ -128,13 +144,13 @@
httpServer = com.sun.net.httpserver.HttpServer.create(new InetSocketAddress(0), 0);
// create HttpServer context
- HttpContext ctx1 = httpServer.createContext("/test/6488669", new Handler6488669());
- HttpContext ctx2 = httpServer.createContext("/test/6595324", new Handler6595324());
+ httpServer.createContext("/test/first", new FirstHandler());
+ httpServer.createContext("/test/second", new SecondHandler());
httpServer.start();
}
- class Handler6488669 implements HttpHandler {
+ class FirstHandler implements HttpHandler {
public void handle(HttpExchange t) throws IOException {
InputStream is = t.getRequestBody();
byte[] ba = new byte[1024];
@@ -156,13 +172,22 @@
}
}
- class Handler6595324 implements HttpHandler {
+ static class SecondHandler implements HttpHandler {
+ /* count greater than 0, slow response */
+ static int count = 0;
+
public void handle(HttpExchange t) throws IOException {
InputStream is = t.getRequestBody();
byte[] ba = new byte[1024];
while (is.read(ba) != -1);
is.close();
+ if (count > 0) {
+ System.out.println("server sleeping...");
+ try { Thread.sleep(1000); } catch(InterruptedException e) {}
+ }
+ count++;
+
t.sendResponseHeaders(404, 0);
OutputStream os = t.getResponseBody();
--- a/jdk/test/sun/security/ec/TestEC.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/ec/TestEC.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2010, 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 @@
* @test
* @bug 6840752
* @summary Provide out-of-the-box support for ECC algorithms
+ * @ignore JSSE supported cipher suites are changed with CR 6916074,
+ * need to update this test case in JDK 7 soon
* @library ../pkcs11
* @library ../pkcs11/ec
* @library ../pkcs11/sslecc
--- a/jdk/test/sun/security/krb5/auto/KDC.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/krb5/auto/KDC.java Tue Nov 02 19:40:45 2010 -0700
@@ -245,7 +245,7 @@
name.indexOf('/') < 0 ?
PrincipalName.KRB_NT_UNKNOWN :
PrincipalName.KRB_NT_SRV_HST),
- kdc.passwords.get(name));
+ kdc.passwords.get(name), -1, true);
}
}
ktab.save();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/tools/KtabCheck.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010, 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.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import sun.security.krb5.internal.ktab.KeyTab;
+import sun.security.krb5.internal.ktab.KeyTabEntry;
+
+/**
+ * This class is called by the test ktcheck.sh and is not meant to run
+ * by itself.
+ */
+public class KtabCheck {
+ /**
+ * Checks if a keytab contains exactly the keys (kvno and etype)
+ * @param args keytabname kvno etype...
+ */
+ public static void main(String[] args) throws Exception {
+ System.out.println("Checking " + Arrays.toString(args));
+ KeyTab ktab = KeyTab.getInstance(args[0]);
+ Set<String> expected = new HashSet<String>();
+ for (int i=1; i<args.length; i += 2) {
+ expected.add(args[i]+":"+args[i+1]);
+ }
+ for (KeyTabEntry e: ktab.getEntries()) {
+ // KVNO and etype
+ String vne = e.getKey().getKeyVersionNumber() + ":" +
+ e.getKey().getEType();
+ if (!expected.contains(vne)) {
+ throw new Exception("No " + vne + " in expected");
+ }
+ expected.remove(vne);
+ }
+ if (!expected.isEmpty()) {
+ throw new Exception("Extra elements in expected");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/tools/ktcheck.sh Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,94 @@
+#
+# Copyright (c) 2010, 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 6950546
+# @summary "ktab -d name etype" to "ktab -d name [-e etype] [kvno | all | old]"
+# @run shell ktcheck.sh
+#
+
+if [ "${TESTJAVA}" = "" ] ; then
+ JAVAC_CMD=`which javac`
+ TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+if [ "${TESTSRC}" = "" ] ; then
+ TESTSRC="."
+fi
+
+OS=`uname -s`
+case "$OS" in
+ CYGWIN* )
+ FS="/"
+ ;;
+ Windows_* )
+ FS="\\"
+ ;;
+ * )
+ FS="/"
+ echo "Unsupported system!"
+ exit 0;
+ ;;
+esac
+
+KEYTAB=ktab.tmp
+
+rm $KEYTAB
+${TESTJAVA}${FS}bin${FS}javac -d . ${TESTSRC}${FS}KtabCheck.java
+
+EXTRA_OPTIONS="-Djava.security.krb5.conf=${TESTSRC}${FS}onlythree.conf"
+KTAB="${TESTJAVA}${FS}bin${FS}ktab -J${EXTRA_OPTIONS} -k $KEYTAB -f"
+CHECK="${TESTJAVA}${FS}bin${FS}java ${EXTRA_OPTIONS} KtabCheck $KEYTAB"
+
+echo ${EXTRA_OPTIONS}
+
+$KTAB -a me mine
+$CHECK 1 16 1 23 1 17 || exit 1
+$KTAB -a me mine -n 0
+$CHECK 0 16 0 23 0 17 || exit 1
+$KTAB -a me mine -n 1 -append
+$CHECK 0 16 0 23 0 17 1 16 1 23 1 17 || exit 1
+$KTAB -a me mine -append
+$CHECK 0 16 0 23 0 17 1 16 1 23 1 17 2 16 2 23 2 17 || exit 1
+$KTAB -a me mine
+$CHECK 3 16 3 23 3 17 || exit 1
+$KTAB -a me mine -n 4 -append
+$CHECK 3 16 3 23 3 17 4 16 4 23 4 17 || exit 1
+$KTAB -a me mine -n 5 -append
+$CHECK 3 16 3 23 3 17 4 16 4 23 4 17 5 16 5 23 5 17 || exit 1
+$KTAB -a me mine -n 6 -append
+$CHECK 3 16 3 23 3 17 4 16 4 23 4 17 5 16 5 23 5 17 6 16 6 23 6 17 || exit 1
+$KTAB -d me 3
+$CHECK 4 16 4 23 4 17 5 16 5 23 5 17 6 16 6 23 6 17 || exit 1
+$KTAB -d me -e 16 6
+$CHECK 4 16 4 23 4 17 5 16 5 23 5 17 6 23 6 17 || exit 1
+$KTAB -d me -e 17 6
+$CHECK 4 16 4 23 4 17 5 16 5 23 5 17 6 23 || exit 1
+$KTAB -d me -e 16 5
+$CHECK 4 16 4 23 4 17 5 23 5 17 6 23 || exit 1
+$KTAB -d me old
+$CHECK 4 16 5 17 6 23 || exit 1
+$KTAB -d me old
+$CHECK 4 16 5 17 6 23 || exit 1
+$KTAB -d me
+$CHECK || exit 1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/tools/onlythree.conf Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,9 @@
+[libdefaults]
+default_realm = LOCAL.COM
+default_tkt_enctypes = des3-cbc-sha1 rc4-hmac aes128-cts
+
+[realms]
+LOCAL.COM = {
+ kdc = localhost
+}
+
--- a/jdk/test/sun/security/pkcs11/fips/CipherTest.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/pkcs11/fips/CipherTest.java Tue Nov 02 19:40:45 2010 -0700
@@ -119,6 +119,13 @@
return false;
}
+ // ignore exportable cipher suite for TLSv1.1
+ if (protocol.equals("TLSv1.1")) {
+ if(cipherSuite.indexOf("_EXPORT_") != -1) {
+ return false;
+ }
+ }
+
return true;
}
@@ -149,18 +156,14 @@
cipherSuites.length * protocols.length * clientAuths.length);
for (int i = 0; i < cipherSuites.length; i++) {
String cipherSuite = cipherSuites[i];
- if (peerFactory.isSupported(cipherSuite) == false) {
- continue;
- }
- // skip kerberos cipher suites
- if (cipherSuite.startsWith("TLS_KRB5")) {
- continue;
- }
+
for (int j = 0; j < protocols.length; j++) {
String protocol = protocols[j];
- if (protocol.equals("SSLv2Hello")) {
+
+ if (!peerFactory.isSupported(cipherSuite, protocol)) {
continue;
}
+
for (int k = 0; k < clientAuths.length; k++) {
String clientAuth = clientAuths[k];
if ((clientAuth != null) &&
@@ -293,11 +296,12 @@
return ks;
}
- public static void main(PeerFactory peerFactory, KeyStore keyStore, String[] args)
- throws Exception {
+ public static void main(PeerFactory peerFactory, KeyStore keyStore,
+ String[] args) throws Exception {
+
long time = System.currentTimeMillis();
String relPath;
- if ((args.length > 0) && args[0].equals("sh")) {
+ if ((args != null) && (args.length > 0) && args[0].equals("sh")) {
relPath = pathToStoresSH;
} else {
relPath = pathToStores;
@@ -345,7 +349,30 @@
abstract Server newServer(CipherTest cipherTest) throws Exception;
- boolean isSupported(String cipherSuite) {
+ boolean isSupported(String cipherSuite, String protocol) {
+ // skip kerberos cipher suites
+ if (cipherSuite.startsWith("TLS_KRB5")) {
+ System.out.println("Skipping unsupported test for " +
+ cipherSuite + " of " + protocol);
+ return false;
+ }
+
+ // skip SSLv2Hello protocol
+ if (protocol.equals("SSLv2Hello")) {
+ System.out.println("Skipping unsupported test for " +
+ cipherSuite + " of " + protocol);
+ return false;
+ }
+
+ // ignore exportable cipher suite for TLSv1.1
+ if (protocol.equals("TLSv1.1")) {
+ if (cipherSuite.indexOf("_EXPORT_WITH") != -1) {
+ System.out.println("Skipping obsoleted test for " +
+ cipherSuite + " of " + protocol);
+ return false;
+ }
+ }
+
return true;
}
}
--- a/jdk/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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 @@
* @test
* @bug 6313675 6323647
* @summary Verify that all ciphersuites work in FIPS mode
+ * @ignore JSSE supported cipher suites are changed with CR 6916074,
+ * need to update this test case in JDK 7 soon
* @author Andreas Sterbenz
* @library ..
*/
--- a/jdk/test/sun/security/pkcs11/sslecc/CipherTest.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/pkcs11/sslecc/CipherTest.java Tue Nov 02 19:40:45 2010 -0700
@@ -119,6 +119,13 @@
return false;
}
+ // ignore exportable cipher suite for TLSv1.1
+ if (protocol.equals("TLSv1.1")) {
+ if(cipherSuite.indexOf("_EXPORT_") != -1) {
+ return false;
+ }
+ }
+
return true;
}
@@ -148,18 +155,14 @@
cipherSuites.length * protocols.length * clientAuths.length);
for (int i = 0; i < cipherSuites.length; i++) {
String cipherSuite = cipherSuites[i];
- if (peerFactory.isSupported(cipherSuite) == false) {
- continue;
- }
- // skip kerberos cipher suites
- if (cipherSuite.startsWith("TLS_KRB5")) {
- continue;
- }
+
for (int j = 0; j < protocols.length; j++) {
String protocol = protocols[j];
- if (protocol.equals("SSLv2Hello")) {
+
+ if (!peerFactory.isSupported(cipherSuite, protocol)) {
continue;
}
+
for (int k = 0; k < clientAuths.length; k++) {
String clientAuth = clientAuths[k];
if ((clientAuth != null) &&
@@ -275,7 +278,6 @@
// for some reason, ${test.src} has a different value when the
// test is called from the script and when it is called directly...
-// static String pathToStores = "../../etc";
static String pathToStores = ".";
static String pathToStoresSH = ".";
static String keyStoreFile = "keystore";
@@ -336,7 +338,30 @@
abstract Server newServer(CipherTest cipherTest) throws Exception;
- boolean isSupported(String cipherSuite) {
+ boolean isSupported(String cipherSuite, String protocol) {
+ // skip kerberos cipher suites
+ if (cipherSuite.startsWith("TLS_KRB5")) {
+ System.out.println("Skipping unsupported test for " +
+ cipherSuite + " of " + protocol);
+ return false;
+ }
+
+ // skip SSLv2Hello protocol
+ if (protocol.equals("SSLv2Hello")) {
+ System.out.println("Skipping unsupported test for " +
+ cipherSuite + " of " + protocol);
+ return false;
+ }
+
+ // ignore exportable cipher suite for TLSv1.1
+ if (protocol.equals("TLSv1.1")) {
+ if (cipherSuite.indexOf("_EXPORT_WITH") != -1) {
+ System.out.println("Skipping obsoleted test for " +
+ cipherSuite + " of " + protocol);
+ return false;
+ }
+ }
+
return true;
}
}
--- a/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/pkcs11/tls/TestKeyMaterial.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -125,16 +125,23 @@
System.out.print(".");
n++;
- KeyGenerator kg = KeyGenerator.getInstance("SunTlsKeyMaterial", provider);
- SecretKey masterKey = new SecretKeySpec(master, "TlsMasterSecret");
- TlsKeyMaterialParameterSpec spec = new TlsKeyMaterialParameterSpec
- (masterKey, major, minor, clientRandom, serverRandom, cipherAlgorithm,
- keyLength, expandedKeyLength, ivLength, macLength);
+ KeyGenerator kg =
+ KeyGenerator.getInstance("SunTlsKeyMaterial", provider);
+ SecretKey masterKey =
+ new SecretKeySpec(master, "TlsMasterSecret");
+ TlsKeyMaterialParameterSpec spec =
+ new TlsKeyMaterialParameterSpec(masterKey, major, minor,
+ clientRandom, serverRandom, cipherAlgorithm,
+ keyLength, expandedKeyLength, ivLength, macLength,
+ null, -1, -1);
kg.init(spec);
- TlsKeyMaterialSpec result = (TlsKeyMaterialSpec)kg.generateKey();
- match(lineNumber, clientCipherBytes, result.getClientCipherKey(), cipherAlgorithm);
- match(lineNumber, serverCipherBytes, result.getServerCipherKey(), cipherAlgorithm);
+ TlsKeyMaterialSpec result =
+ (TlsKeyMaterialSpec)kg.generateKey();
+ match(lineNumber, clientCipherBytes,
+ result.getClientCipherKey(), cipherAlgorithm);
+ match(lineNumber, serverCipherBytes,
+ result.getServerCipherKey(), cipherAlgorithm);
match(lineNumber, clientIv, result.getClientIv(), "");
match(lineNumber, serverIv, result.getServerIv(), "");
match(lineNumber, clientMacBytes, result.getClientMacKey(), "");
@@ -158,7 +165,8 @@
}
}
- private static void match(int lineNumber, byte[] out, Object res, String cipherAlgorithm) throws Exception {
+ private static void match(int lineNumber, byte[] out, Object res,
+ String cipherAlgorithm) throws Exception {
if ((out == null) || (res == null)) {
if (out != res) {
throw new Exception("null mismatch line " + lineNumber);
@@ -169,7 +177,8 @@
byte[] b;
if (res instanceof SecretKey) {
b = ((SecretKey)res).getEncoded();
- if (cipherAlgorithm.equalsIgnoreCase("DES") || cipherAlgorithm.equalsIgnoreCase("DESede")) {
+ if (cipherAlgorithm.equalsIgnoreCase("DES") ||
+ cipherAlgorithm.equalsIgnoreCase("DESede")) {
// strip DES parity bits before comparision
stripParity(out);
stripParity(b);
--- a/jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/pkcs11/tls/TestMasterSecret.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -104,17 +104,22 @@
System.out.print(".");
n++;
- KeyGenerator kg = KeyGenerator.getInstance("SunTlsMasterSecret", provider);
- SecretKey premasterKey = new SecretKeySpec(premaster, algorithm);
- TlsMasterSecretParameterSpec spec = new TlsMasterSecretParameterSpec
- (premasterKey, protoMajor, protoMinor, clientRandom, serverRandom);
+ KeyGenerator kg =
+ KeyGenerator.getInstance("SunTlsMasterSecret", provider);
+ SecretKey premasterKey =
+ new SecretKeySpec(premaster, algorithm);
+ TlsMasterSecretParameterSpec spec =
+ new TlsMasterSecretParameterSpec(premasterKey,
+ protoMajor, protoMinor, clientRandom, serverRandom,
+ null, -1, -1);
kg.init(spec);
TlsMasterSecret key = (TlsMasterSecret)kg.generateKey();
byte[] enc = key.getEncoded();
if (Arrays.equals(master, enc) == false) {
throw new Exception("mismatch line: " + lineNumber);
}
- if ((preMajor != key.getMajorVersion()) || (preMinor != key.getMinorVersion())) {
+ if ((preMajor != key.getMajorVersion()) ||
+ (preMinor != key.getMinorVersion())) {
throw new Exception("version mismatch line: " + lineNumber);
}
} else {
--- a/jdk/test/sun/security/pkcs11/tls/TestPRF.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/pkcs11/tls/TestPRF.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2010, 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
@@ -93,14 +93,17 @@
System.out.print(".");
n++;
- KeyGenerator kg = KeyGenerator.getInstance("SunTlsPrf", provider);
+ KeyGenerator kg =
+ KeyGenerator.getInstance("SunTlsPrf", provider);
SecretKey inKey;
if (secret == null) {
inKey = null;
} else {
inKey = new SecretKeySpec(secret, "Generic");
}
- TlsPrfParameterSpec spec = new TlsPrfParameterSpec(inKey, label, seed, length);
+ TlsPrfParameterSpec spec =
+ new TlsPrfParameterSpec(inKey, label, seed, length,
+ null, -1, -1);
SecretKey key;
try {
kg.init(spec);
@@ -109,7 +112,8 @@
if (secret == null) {
// This fails on Solaris, but since we never call this
// API for this case in JSSE, ignore the failure.
- // (SunJSSE uses the CKM_TLS_KEY_AND_MAC_DERIVE mechanism)
+ // (SunJSSE uses the CKM_TLS_KEY_AND_MAC_DERIVE
+ // mechanism)
System.out.print("X");
continue;
}
--- a/jdk/test/sun/security/pkcs11/tls/TestPremaster.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/pkcs11/tls/TestPremaster.java Tue Nov 02 19:40:45 2010 -0700
@@ -44,7 +44,8 @@
}
public void main(Provider provider) throws Exception {
- if (provider.getService("KeyGenerator", "SunTlsRsaPremasterSecret") == null) {
+ if (provider.getService(
+ "KeyGenerator", "SunTlsRsaPremasterSecret") == null) {
System.out.println("Not supported by provider, skipping");
return;
}
@@ -66,7 +67,8 @@
System.out.println("Done.");
}
- private static void test(KeyGenerator kg, int major, int minor) throws Exception {
+ private static void test(KeyGenerator kg, int major, int minor)
+ throws Exception {
kg.init(new TlsRsaPremasterSecretParameterSpec(major, minor));
SecretKey key = kg.generateKey();
@@ -75,7 +77,8 @@
throw new Exception("length: " + encoded.length);
}
if ((encoded[0] != major) || (encoded[1] != minor)) {
- throw new Exception("version mismatch: " + encoded[0] + "." + encoded[1]);
+ throw new Exception("version mismatch: " + encoded[0] +
+ "." + encoded[1]);
}
System.out.println("OK: " + major + "." + minor);
}
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ClientModeClientAuth.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ClientModeClientAuth.java Tue Nov 02 19:40:45 2010 -0700
@@ -24,6 +24,7 @@
/*
* @test
* @bug 4390659
+ * @run main/othervm -Djavax.net.debug=all ClientModeClientAuth
* @summary setNeedClientAuth() isn't working after a handshaker is established
* @author Brad Wetmore
*/
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/ClientServer.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/ClientServer.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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 @@
* @test
* @bug 4717766
* @summary 1.0.3 JsseX509TrustManager erroneously calls isClientTrusted()
+ * @ignore JSSE supports algorithm constraints with CR 6916074,
+ * need to update this test case in JDK 7 soon
* @author Brad Wetmore
*
* This problem didn't exist in JSSE 1.4, only JSSE 1.0.3. However,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/PKIXExtendedTM.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,882 @@
+/*
+ * Copyright (c) 2010, 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 6916074
+ * @summary Add support for TLS 1.2
+ */
+
+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 java.math.BigInteger;
+
+
+/*
+ * Certificates and key used in the test.
+ *
+ * TLS server certificate:
+ * server private key:
+ * -----BEGIN RSA PRIVATE KEY-----
+ * Proc-Type: 4,ENCRYPTED
+ * DEK-Info: DES-EDE3-CBC,D9AE407F6D0E389A
+ *
+ * WPrA7TFol/cQCcp9oHnXWNpYlvRbbIcQj0m+RKT2Iuzfus+DHt3Zadf8nJpKfX2e
+ * h2rnhlzCN9M7djRDooZKDOPCsdBn51Au7HlZF3S3Opgo7D8XFM1a8t1Je4ke14oI
+ * nw6QKYsBblRziPnP2PZ0zvX24nOv7bbY8beynlJHGs00VWSFdoH2DS0aE1p6D+3n
+ * ptJuJ75dVfZFK4X7162APlNXevX8D6PEQpSiRw1rjjGGcnvQ4HdWk3BxDVDcCNJb
+ * Y1aGNRxsjTDvPi3R9Qx2M+W03QzEPx4SR3ZHVskeSJHaetM0TM/w/45Paq4GokXP
+ * ZeTnbEx1xmjkA7h+t4doLL4watx5F6yLsJzu8xB3lt/1EtmkYtLz1t7X4BetPAXz
+ * zS69X/VwhKfsOI3qXBWuL2oHPyhDmT1gcaUQwEPSV6ogHEEQEDXdiUS8heNK13KF
+ * TCQYFkETvV2BLxUhV1hypPzRQ6tUpJiAbD5KmoK2lD9slshG2QtvKQq0/bgkDY5J
+ * LhDHV2dtcZ3kDPkkZXpbcJQvoeH3d09C5sIsuTFo2zgNR6oETHUc5TzP6FY2YYRa
+ * QcK5HcmtsRRiXFm01ac+aMejJUIujjFt84SiKWT/73vC8AmY4tYcJBLjCg4XIxSH
+ * fdDFLL1YZENNO5ivlp8mdiHqcawx+36L7DrEZQ8RZt6cqST5t/+XTdM74s6k81GT
+ * pNsa82P2K2zmIUZ/DL2mKjW1vfRByw1NQFEBkN3vdyZxYfM/JyUzX4hbjXBEkh9Q
+ * QYrcwLKLjis2QzSvK04B3bvRzRb+4ocWiso8ZPAXAIxZFBWDpTMM2A==
+ * -----END RSA PRIVATE KEY-----
+ *
+ * -----BEGIN RSA PRIVATE KEY-----
+ * MIICXAIBAAKBgQClrFscN6LdmYktsnm4j9VIpecchBeNaZzGrG358h0fORna03Ie
+ * buxEzHCk3LoAMPagTz1UemFqzFfQCn+VKBg/mtmU8hvIJIh+/p0PPftXUwizIDPU
+ * PxdHFNHN6gjYDnVOr77M0uyvqXpJ38LZrLgkQJCmA1Yq0DAFQCxPq9l0iQIDAQAB
+ * AoGAbqcbg1E1mkR99uOJoNeQYKFOJyGiiXTMnXV1TseC4+PDfQBU7Dax35GcesBi
+ * CtapIpFKKS5D+ozY6b7ZT8ojxuQ/uHLPAvz0WDR3ds4iRF8tyu71Q1ZHcQsJa17y
+ * yO7UbkSSKn/Mp9Rb+/dKqftUGNXVFLqgHBOzN2s3We3bbbECQQDYBPKOg3hkaGHo
+ * OhpHKqtQ6EVkldihG/3i4WejRonelXN+HRh1KrB2HBx0M8D/qAzP1i3rNSlSHer4
+ * 59YRTJnHAkEAxFX/sVYSn07BHv9Zhn6XXct/Cj43z/tKNbzlNbcxqQwQerw3IH51
+ * 8UH2YOA+GD3lXbKp+MytoFLWv8zg4YT/LwJAfqan75Z1R6lLffRS49bIiq8jwE16
+ * rTrUJ+kv8jKxMqc9B3vXkxpsS1M/+4E8bqgAmvpgAb8xcsvHsBd9ErdukQJBAKs2
+ * j67W75BrPjBI34pQ1LEfp56IGWXOrq1kF8IbCjxv3+MYRT6Z6UJFkpRymNPNDjsC
+ * dgUYgITiGJHUGXuw3lMCQHEHqo9ZtXz92yFT+VhsNc29B8m/sqUJdtCcMd/jGpAF
+ * u6GHufjqIZBpQsk63wbwESAPZZ+kk1O1kS5GIRLX608=
+ * -----END RSA PRIVATE KEY-----
+ *
+ * Private-Key: (1024 bit)
+ * modulus:
+ * 00:a5:ac:5b:1c:37:a2:dd:99:89:2d:b2:79:b8:8f:
+ * d5:48:a5:e7:1c:84:17:8d:69:9c:c6:ac:6d:f9:f2:
+ * 1d:1f:39:19:da:d3:72:1e:6e:ec:44:cc:70:a4:dc:
+ * ba:00:30:f6:a0:4f:3d:54:7a:61:6a:cc:57:d0:0a:
+ * 7f:95:28:18:3f:9a:d9:94:f2:1b:c8:24:88:7e:fe:
+ * 9d:0f:3d:fb:57:53:08:b3:20:33:d4:3f:17:47:14:
+ * d1:cd:ea:08:d8:0e:75:4e:af:be:cc:d2:ec:af:a9:
+ * 7a:49:df:c2:d9:ac:b8:24:40:90:a6:03:56:2a:d0:
+ * 30:05:40:2c:4f:ab:d9:74:89
+ * publicExponent: 65537 (0x10001)
+ * privateExponent:
+ * 6e:a7:1b:83:51:35:9a:44:7d:f6:e3:89:a0:d7:90:
+ * 60:a1:4e:27:21:a2:89:74:cc:9d:75:75:4e:c7:82:
+ * e3:e3:c3:7d:00:54:ec:36:b1:df:91:9c:7a:c0:62:
+ * 0a:d6:a9:22:91:4a:29:2e:43:fa:8c:d8:e9:be:d9:
+ * 4f:ca:23:c6:e4:3f:b8:72:cf:02:fc:f4:58:34:77:
+ * 76:ce:22:44:5f:2d:ca:ee:f5:43:56:47:71:0b:09:
+ * 6b:5e:f2:c8:ee:d4:6e:44:92:2a:7f:cc:a7:d4:5b:
+ * fb:f7:4a:a9:fb:54:18:d5:d5:14:ba:a0:1c:13:b3:
+ * 37:6b:37:59:ed:db:6d:b1
+ * prime1:
+ * 00:d8:04:f2:8e:83:78:64:68:61:e8:3a:1a:47:2a:
+ * ab:50:e8:45:64:95:d8:a1:1b:fd:e2:e1:67:a3:46:
+ * 89:de:95:73:7e:1d:18:75:2a:b0:76:1c:1c:74:33:
+ * c0:ff:a8:0c:cf:d6:2d:eb:35:29:52:1d:ea:f8:e7:
+ * d6:11:4c:99:c7
+ * prime2:
+ * 00:c4:55:ff:b1:56:12:9f:4e:c1:1e:ff:59:86:7e:
+ * 97:5d:cb:7f:0a:3e:37:cf:fb:4a:35:bc:e5:35:b7:
+ * 31:a9:0c:10:7a:bc:37:20:7e:75:f1:41:f6:60:e0:
+ * 3e:18:3d:e5:5d:b2:a9:f8:cc:ad:a0:52:d6:bf:cc:
+ * e0:e1:84:ff:2f
+ * exponent1:
+ * 7e:a6:a7:ef:96:75:47:a9:4b:7d:f4:52:e3:d6:c8:
+ * 8a:af:23:c0:4d:7a:ad:3a:d4:27:e9:2f:f2:32:b1:
+ * 32:a7:3d:07:7b:d7:93:1a:6c:4b:53:3f:fb:81:3c:
+ * 6e:a8:00:9a:fa:60:01:bf:31:72:cb:c7:b0:17:7d:
+ * 12:b7:6e:91
+ * exponent2:
+ * 00:ab:36:8f:ae:d6:ef:90:6b:3e:30:48:df:8a:50:
+ * d4:b1:1f:a7:9e:88:19:65:ce:ae:ad:64:17:c2:1b:
+ * 0a:3c:6f:df:e3:18:45:3e:99:e9:42:45:92:94:72:
+ * 98:d3:cd:0e:3b:02:76:05:18:80:84:e2:18:91:d4:
+ * 19:7b:b0:de:53
+ * coefficient:
+ * 71:07:aa:8f:59:b5:7c:fd:db:21:53:f9:58:6c:35:
+ * cd:bd:07:c9:bf:b2:a5:09:76:d0:9c:31:df:e3:1a:
+ * 90:05:bb:a1:87:b9:f8:ea:21:90:69:42:c9:3a:df:
+ * 06:f0:11:20:0f:65:9f:a4:93:53:b5:91:2e:46:21:
+ * 12:d7:eb:4f
+ *
+ *
+ * server certificate:
+ * Data:
+ * Version: 3 (0x2)
+ * Serial Number: 8 (0x8)
+ * Signature Algorithm: md5WithRSAEncryption
+ * Issuer: C=US, ST=Some-State, L=Some-City, O=Some-Org
+ * Validity
+ * Not Before: Dec 8 03:43:04 2008 GMT
+ * Not After : Aug 25 03:43:04 2028 GMT
+ * Subject: C=US, ST=Some-State, L=Some-City, O=Some-Org, OU=SSL-Server, CN=localhost
+ * Subject Public Key Info:
+ * Public Key Algorithm: rsaEncryption
+ * RSA Public Key: (1024 bit)
+ * Modulus (1024 bit):
+ * 00:a5:ac:5b:1c:37:a2:dd:99:89:2d:b2:79:b8:8f:
+ * d5:48:a5:e7:1c:84:17:8d:69:9c:c6:ac:6d:f9:f2:
+ * 1d:1f:39:19:da:d3:72:1e:6e:ec:44:cc:70:a4:dc:
+ * ba:00:30:f6:a0:4f:3d:54:7a:61:6a:cc:57:d0:0a:
+ * 7f:95:28:18:3f:9a:d9:94:f2:1b:c8:24:88:7e:fe:
+ * 9d:0f:3d:fb:57:53:08:b3:20:33:d4:3f:17:47:14:
+ * d1:cd:ea:08:d8:0e:75:4e:af:be:cc:d2:ec:af:a9:
+ * 7a:49:df:c2:d9:ac:b8:24:40:90:a6:03:56:2a:d0:
+ * 30:05:40:2c:4f:ab:d9:74:89
+ * Exponent: 65537 (0x10001)
+ * X509v3 extensions:
+ * X509v3 Basic Constraints:
+ * CA:FALSE
+ * X509v3 Key Usage:
+ * Digital Signature, Non Repudiation, Key Encipherment
+ * X509v3 Subject Key Identifier:
+ * ED:6E:DB:F4:B5:56:C8:FB:1A:06:61:3F:0F:08:BB:A6:04:D8:16:54
+ * X509v3 Authority Key Identifier:
+ * keyid:FA:B9:51:BF:4C:E7:D9:86:98:33:F9:E7:CB:1E:F1:33:49:F7:A8:14
+ *
+ * X509v3 Subject Alternative Name: critical
+ * DNS:localhost
+ * Signature Algorithm: md5WithRSAEncryption0
+ *
+ * -----BEGIN CERTIFICATE-----
+ * MIICpDCCAg2gAwIBAgIBCDANBgkqhkiG9w0BAQQFADBJMQswCQYDVQQGEwJVUzET
+ * MBEGA1UECBMKU29tZS1TdGF0ZTESMBAGA1UEBxMJU29tZS1DaXR5MREwDwYDVQQK
+ * EwhTb21lLU9yZzAeFw0wODEyMDgwMzQzMDRaFw0yODA4MjUwMzQzMDRaMHIxCzAJ
+ * BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRIwEAYDVQQHEwlTb21lLUNp
+ * dHkxETAPBgNVBAoTCFNvbWUtT3JnMRMwEQYDVQQLEwpTU0wtU2VydmVyMRIwEAYD
+ * VQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKWsWxw3
+ * ot2ZiS2yebiP1Uil5xyEF41pnMasbfnyHR85GdrTch5u7ETMcKTcugAw9qBPPVR6
+ * YWrMV9AKf5UoGD+a2ZTyG8gkiH7+nQ89+1dTCLMgM9Q/F0cU0c3qCNgOdU6vvszS
+ * 7K+peknfwtmsuCRAkKYDVirQMAVALE+r2XSJAgMBAAGjczBxMAkGA1UdEwQCMAAw
+ * CwYDVR0PBAQDAgXgMB0GA1UdDgQWBBTtbtv0tVbI+xoGYT8PCLumBNgWVDAfBgNV
+ * HSMEGDAWgBT6uVG/TOfZhpgz+efLHvEzSfeoFDAXBgNVHREBAf8EDTALgglsb2Nh
+ * bGhvc3QwDQYJKoZIhvcNAQEEBQADgYEAoqVTciHtcvsUj+YaTct8tUh3aTCsKsac
+ * PHhfQ+ObjiXSgxsKYTX7ym/wk/wvlbUcbqLKxsu7qrcJitH+H9heV1hEHEu65Uoi
+ * nRugFruyOrwvAylV8Cm2af7ddilmYJ+sdJA6N2M3xJRxR0G2LFHEXDNEjYReyexn
+ * JqCpf5uZGOo=
+ * -----END CERTIFICATE-----
+ *
+ *
+ * TLS client certificate:
+ * client private key:
+ * ----BEGIN RSA PRIVATE KEY-----
+ * Proc-Type: 4,ENCRYPTED
+ * DEK-Info: DES-EDE3-CBC,FA2A435CD35A9390
+ *
+ * Z+Y2uaETbsUWIyJUyVu1UV2G4rgFYJyACZT6Tp1KjRtxflSh2kXkJ9MpuXMXA0V4
+ * Yy3fDzPqCL9NJmQAYRlAx/W/+j4F5EyMWDIx8fUxzONRZyoiwF7jLm+KscAfv6Pf
+ * q7ItWOdj3z7IYrwlB8YIGd3F2cDKT3S+lYRk7rKb/qT7itbuHnY4Ardh3yl+MZak
+ * jBp+ELUlRsUqSr1V0LoM+0rCCykarpyfhpxEcqsrl0v9Cyi5uhU50/oKv5zql3SH
+ * l2ImgDjp3batAs8+Bd4NF2aqi0a7Hy44JUHxRm4caZryU/i/D9N1MbuM6882HLat
+ * 5N0G+NaIUfywa8mjwq2D5aiit18HqKA6XeRRYeJ5Dvu9DCO4GeFSwcUFIBMI0L46
+ * 7s114+oDodg57pMgITi+04vmUxvqlN9aiyd7f5Fgd7PeHGeOdbMz1NaJLJaPI9++
+ * NakK8eK9iwT/Gdq0Uap5/CHW7vCT5PO+h3HY0STH0lWStXhdWnFO04zTdywsbSp+
+ * DLpHeFT66shfeUlxR0PsCbG9vPRt/QmGLeYQZITppWo/ylSq4j+pRIuXvuWHdBRN
+ * rTZ8QF4Y7AxQUXVz1j1++s6ZMHTzaK2i9HrhmDs1MbJl+QwWre3Xpv3LvTVz3k5U
+ * wX8kuY1m3STt71QCaRWENq5sRaMImLxZbxc/ivFl9RAzUqo4NCxLod/QgA4iLqtO
+ * ztnlpzwlC/F8HbQ1oqYWwnZAPhzU/cULtstl+Yrws2c2atO323LbPXZqbASySgig
+ * sNpFXQMObdfP6LN23bY+1SvtK7V4NUTNhpdIc6INQAQ=
+ * -----END RSA PRIVATE KEY-----
+ *
+ * -----BEGIN RSA PRIVATE KEY-----
+ * MIICWwIBAAKBgQC78EA2rCZUTvSjWgAvaSFvuXo6k+yi9uGOx2PYLxIwmS6w8o/4
+ * Jy0keCiE9wG/jUR53TvSVfPOPLJbIX3v/TNKsaP/xsibuQ98QTWX+ds6BWAFFa9Z
+ * F5KjEK0WHOQHU6+odqJWKpLT+SjgeM9eH0irXBnd4WdDunWN9YKsQ5JEGwIDAQAB
+ * AoGAEbdqNj0wN85hnWyEi/ObJU8UyKTdL9eaF72QGfcF/fLSxfd3vurihIeXOkGW
+ * tpn4lIxYcVGM9CognhqgJpl11jFTQzn1KqZ+NEJRKkCHA4hDabKJbSC9fXHvRwrf
+ * BsFpZqgiNxp3HseUTiwnaUVeyPgMt/jAj5nB5Sib+UyUxrECQQDnNQBiF2aifEg6
+ * zbJOOC7he5CHAdkFxSxWVFVHL6EfXfqdLVkUohMbgZv+XxyIeU2biOExSg49Kds3
+ * FOKgTau1AkEA0Bd1haj6QuCo8I0AXm2WO+MMTZMTvtHD/bGjKNM+fT4I8rKYnQRX
+ * 1acHdqS9Xx2rNJqZgkMmpESIdPR2fc4yjwJALFeM6EMmqvj8/VIf5UJ/Mz14fXwM
+ * PEARfckUxd9LnnFutCBTWlKvKXJVEZb6KO5ixPaegc57Jp3Vbh3yTN44lQJADD/1
+ * SSMDaIB1MYP7a5Oj7m6VQNPRq8AJe5vDcRnOae0G9dKRrVyeFxO4GsHj6/+BHp2j
+ * P8nYMn9eURQ7DXjf/QJAAQzMlWnKGSO8pyTDtnQx3hRMoUkOEhmNq4bQhLkYqtnY
+ * FcqpUQ2qMjW+NiNWk5HnTrMS3L9EdJobMUzaNZLy4w==
+ * -----END RSA PRIVATE KEY-----
+ *
+ * Private-Key: (1024 bit)
+ * modulus:
+ * 00:bb:f0:40:36:ac:26:54:4e:f4:a3:5a:00:2f:69:
+ * 21:6f:b9:7a:3a:93:ec:a2:f6:e1:8e:c7:63:d8:2f:
+ * 12:30:99:2e:b0:f2:8f:f8:27:2d:24:78:28:84:f7:
+ * 01:bf:8d:44:79:dd:3b:d2:55:f3:ce:3c:b2:5b:21:
+ * 7d:ef:fd:33:4a:b1:a3:ff:c6:c8:9b:b9:0f:7c:41:
+ * 35:97:f9:db:3a:05:60:05:15:af:59:17:92:a3:10:
+ * ad:16:1c:e4:07:53:af:a8:76:a2:56:2a:92:d3:f9:
+ * 28:e0:78:cf:5e:1f:48:ab:5c:19:dd:e1:67:43:ba:
+ * 75:8d:f5:82:ac:43:92:44:1b
+ * publicExponent: 65537 (0x10001)
+ * privateExponent:
+ * 11:b7:6a:36:3d:30:37:ce:61:9d:6c:84:8b:f3:9b:
+ * 25:4f:14:c8:a4:dd:2f:d7:9a:17:bd:90:19:f7:05:
+ * fd:f2:d2:c5:f7:77:be:ea:e2:84:87:97:3a:41:96:
+ * b6:99:f8:94:8c:58:71:51:8c:f4:2a:20:9e:1a:a0:
+ * 26:99:75:d6:31:53:43:39:f5:2a:a6:7e:34:42:51:
+ * 2a:40:87:03:88:43:69:b2:89:6d:20:bd:7d:71:ef:
+ * 47:0a:df:06:c1:69:66:a8:22:37:1a:77:1e:c7:94:
+ * 4e:2c:27:69:45:5e:c8:f8:0c:b7:f8:c0:8f:99:c1:
+ * e5:28:9b:f9:4c:94:c6:b1
+ * prime1:
+ * 00:e7:35:00:62:17:66:a2:7c:48:3a:cd:b2:4e:38:
+ * 2e:e1:7b:90:87:01:d9:05:c5:2c:56:54:55:47:2f:
+ * a1:1f:5d:fa:9d:2d:59:14:a2:13:1b:81:9b:fe:5f:
+ * 1c:88:79:4d:9b:88:e1:31:4a:0e:3d:29:db:37:14:
+ * e2:a0:4d:ab:b5
+ * prime2:
+ * 00:d0:17:75:85:a8:fa:42:e0:a8:f0:8d:00:5e:6d:
+ * 96:3b:e3:0c:4d:93:13:be:d1:c3:fd:b1:a3:28:d3:
+ * 3e:7d:3e:08:f2:b2:98:9d:04:57:d5:a7:07:76:a4:
+ * bd:5f:1d:ab:34:9a:99:82:43:26:a4:44:88:74:f4:
+ * 76:7d:ce:32:8f
+ * exponent1:
+ * 2c:57:8c:e8:43:26:aa:f8:fc:fd:52:1f:e5:42:7f:
+ * 33:3d:78:7d:7c:0c:3c:40:11:7d:c9:14:c5:df:4b:
+ * 9e:71:6e:b4:20:53:5a:52:af:29:72:55:11:96:fa:
+ * 28:ee:62:c4:f6:9e:81:ce:7b:26:9d:d5:6e:1d:f2:
+ * 4c:de:38:95
+ * exponent2:
+ * 0c:3f:f5:49:23:03:68:80:75:31:83:fb:6b:93:a3:
+ * ee:6e:95:40:d3:d1:ab:c0:09:7b:9b:c3:71:19:ce:
+ * 69:ed:06:f5:d2:91:ad:5c:9e:17:13:b8:1a:c1:e3:
+ * eb:ff:81:1e:9d:a3:3f:c9:d8:32:7f:5e:51:14:3b:
+ * 0d:78:df:fd
+ * coefficient:
+ * 01:0c:cc:95:69:ca:19:23:bc:a7:24:c3:b6:74:31:
+ * de:14:4c:a1:49:0e:12:19:8d:ab:86:d0:84:b9:18:
+ * aa:d9:d8:15:ca:a9:51:0d:aa:32:35:be:36:23:56:
+ * 93:91:e7:4e:b3:12:dc:bf:44:74:9a:1b:31:4c:da:
+ * 35:92:f2:e3
+ *
+ * client certificate:
+ * Data:
+ * Version: 3 (0x2)
+ * Serial Number: 9 (0x9)
+ * Signature Algorithm: md5WithRSAEncryption
+ * Issuer: C=US, ST=Some-State, L=Some-City, O=Some-Org
+ * Validity
+ * Not Before: Dec 8 03:43:24 2008 GMT
+ * Not After : Aug 25 03:43:24 2028 GMT
+ * Subject: C=US, ST=Some-State, L=Some-City, O=Some-Org, OU=SSL-Client, CN=localhost
+ * Subject Public Key Info:
+ * Public Key Algorithm: rsaEncryption
+ * RSA Public Key: (1024 bit)
+ * Modulus (1024 bit):
+ * 00:bb:f0:40:36:ac:26:54:4e:f4:a3:5a:00:2f:69:
+ * 21:6f:b9:7a:3a:93:ec:a2:f6:e1:8e:c7:63:d8:2f:
+ * 12:30:99:2e:b0:f2:8f:f8:27:2d:24:78:28:84:f7:
+ * 01:bf:8d:44:79:dd:3b:d2:55:f3:ce:3c:b2:5b:21:
+ * 7d:ef:fd:33:4a:b1:a3:ff:c6:c8:9b:b9:0f:7c:41:
+ * 35:97:f9:db:3a:05:60:05:15:af:59:17:92:a3:10:
+ * ad:16:1c:e4:07:53:af:a8:76:a2:56:2a:92:d3:f9:
+ * 28:e0:78:cf:5e:1f:48:ab:5c:19:dd:e1:67:43:ba:
+ * 75:8d:f5:82:ac:43:92:44:1b
+ * Exponent: 65537 (0x10001)
+ * X509v3 extensions:
+ * X509v3 Basic Constraints:
+ * CA:FALSE
+ * X509v3 Key Usage:
+ * Digital Signature, Non Repudiation, Key Encipherment
+ * X509v3 Subject Key Identifier:
+ * CD:BB:C8:85:AA:91:BD:FD:1D:BE:CD:67:7C:FF:B3:E9:4C:A8:22:E6
+ * X509v3 Authority Key Identifier:
+ * keyid:FA:B9:51:BF:4C:E7:D9:86:98:33:F9:E7:CB:1E:F1:33:49:F7:A8:14
+ *
+ * X509v3 Subject Alternative Name: critical
+ * DNS:localhost
+ * Signature Algorithm: md5WithRSAEncryption
+ *
+ * -----BEGIN CERTIFICATE-----
+ * MIICpDCCAg2gAwIBAgIBCTANBgkqhkiG9w0BAQQFADBJMQswCQYDVQQGEwJVUzET
+ * MBEGA1UECBMKU29tZS1TdGF0ZTESMBAGA1UEBxMJU29tZS1DaXR5MREwDwYDVQQK
+ * EwhTb21lLU9yZzAeFw0wODEyMDgwMzQzMjRaFw0yODA4MjUwMzQzMjRaMHIxCzAJ
+ * BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRIwEAYDVQQHEwlTb21lLUNp
+ * dHkxETAPBgNVBAoTCFNvbWUtT3JnMRMwEQYDVQQLEwpTU0wtQ2xpZW50MRIwEAYD
+ * VQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALvwQDas
+ * JlRO9KNaAC9pIW+5ejqT7KL24Y7HY9gvEjCZLrDyj/gnLSR4KIT3Ab+NRHndO9JV
+ * 8848slshfe/9M0qxo//GyJu5D3xBNZf52zoFYAUVr1kXkqMQrRYc5AdTr6h2olYq
+ * ktP5KOB4z14fSKtcGd3hZ0O6dY31gqxDkkQbAgMBAAGjczBxMAkGA1UdEwQCMAAw
+ * CwYDVR0PBAQDAgXgMB0GA1UdDgQWBBTNu8iFqpG9/R2+zWd8/7PpTKgi5jAfBgNV
+ * HSMEGDAWgBT6uVG/TOfZhpgz+efLHvEzSfeoFDAXBgNVHREBAf8EDTALgglsb2Nh
+ * bGhvc3QwDQYJKoZIhvcNAQEEBQADgYEAm25gJyqW1JznQ1EyOtTGswBVwfgBOf+F
+ * HJuBTcflYQLbTD/AETPQJGvZU9tdhuLtbG3OPhR7vSY8zeAbfM3dbH7QFr3r47Gj
+ * XEH7qM/MX+Z3ifVaC4MeJmrYQkYFSuKeyyKpdRVX4w4nnFHF6OsNASsYrMW6LpxN
+ * cl/epUcHL7E=
+ * -----END CERTIFICATE-----
+ *
+ *
+ *
+ * Trusted CA certificate:
+ * Certificate:
+ * Data:
+ * Version: 3 (0x2)
+ * Serial Number: 0 (0x0)
+ * Signature Algorithm: md5WithRSAEncryption
+ * Issuer: C=US, ST=Some-State, L=Some-City, O=Some-Org
+ * Validity
+ * Not Before: Dec 8 02:43:36 2008 GMT
+ * Not After : Aug 25 02:43:36 2028 GMT
+ * Subject: C=US, ST=Some-State, L=Some-City, O=Some-Org
+ * Subject Public Key Info:
+ * Public Key Algorithm: rsaEncryption
+ * RSA Public Key: (1024 bit)
+ * Modulus (1024 bit):
+ * 00:cb:c4:38:20:07:be:88:a7:93:b0:a1:43:51:2d:
+ * d7:8e:85:af:54:dd:ad:a2:7b:23:5b:cf:99:13:53:
+ * 99:45:7d:ee:6d:ba:2d:bf:e3:ad:6e:3d:9f:1a:f9:
+ * 03:97:e0:17:55:ae:11:26:57:de:01:29:8e:05:3f:
+ * 21:f7:e7:36:e8:2e:37:d7:48:ac:53:d6:60:0e:c7:
+ * 50:6d:f6:c5:85:f7:8b:a6:c5:91:35:72:3c:94:ee:
+ * f1:17:f0:71:e3:ec:1b:ce:ca:4e:40:42:b0:6d:ee:
+ * 6a:0e:d6:e5:ad:3c:0f:c9:ba:82:4f:78:f8:89:97:
+ * 89:2a:95:12:4c:d8:09:2a:e9
+ * Exponent: 65537 (0x10001)
+ * X509v3 extensions:
+ * X509v3 Subject Key Identifier:
+ * FA:B9:51:BF:4C:E7:D9:86:98:33:F9:E7:CB:1E:F1:33:49:F7:A8:14
+ * X509v3 Authority Key Identifier:
+ * keyid:FA:B9:51:BF:4C:E7:D9:86:98:33:F9:E7:CB:1E:F1:33:49:F7:A8:14
+ * DirName:/C=US/ST=Some-State/L=Some-City/O=Some-Org
+ * serial:00
+ *
+ * X509v3 Basic Constraints:
+ * CA:TRUE
+ * Signature Algorithm: md5WithRSAEncryption
+ *
+ * -----BEGIN CERTIFICATE-----
+ * MIICrDCCAhWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBJMQswCQYDVQQGEwJVUzET
+ * MBEGA1UECBMKU29tZS1TdGF0ZTESMBAGA1UEBxMJU29tZS1DaXR5MREwDwYDVQQK
+ * EwhTb21lLU9yZzAeFw0wODEyMDgwMjQzMzZaFw0yODA4MjUwMjQzMzZaMEkxCzAJ
+ * BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRIwEAYDVQQHEwlTb21lLUNp
+ * dHkxETAPBgNVBAoTCFNvbWUtT3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+ * gQDLxDggB76Ip5OwoUNRLdeOha9U3a2ieyNbz5kTU5lFfe5tui2/461uPZ8a+QOX
+ * 4BdVrhEmV94BKY4FPyH35zboLjfXSKxT1mAOx1Bt9sWF94umxZE1cjyU7vEX8HHj
+ * 7BvOyk5AQrBt7moO1uWtPA/JuoJPePiJl4kqlRJM2Akq6QIDAQABo4GjMIGgMB0G
+ * A1UdDgQWBBT6uVG/TOfZhpgz+efLHvEzSfeoFDBxBgNVHSMEajBogBT6uVG/TOfZ
+ * hpgz+efLHvEzSfeoFKFNpEswSTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUt
+ * U3RhdGUxEjAQBgNVBAcTCVNvbWUtQ2l0eTERMA8GA1UEChMIU29tZS1PcmeCAQAw
+ * DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBcIm534U123Hz+rtyYO5uA
+ * ofd81G6FnTfEAV8Kw9fGyyEbQZclBv34A9JsFKeMvU4OFIaixD7nLZ/NZ+IWbhmZ
+ * LovmJXyCkOufea73pNiZ+f/4/ScZaIlM/PRycQSqbFNd4j9Wott+08qxHPLpsf3P
+ * 6Mvf0r1PNTY2hwTJLJmKtg==
+ * -----END CERTIFICATE---
+ */
+
+
+public class PKIXExtendedTM {
+
+ /*
+ * =============================================================
+ * 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 = true;
+
+ /*
+ * Where do we find the keystores?
+ */
+ static String trusedCertStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICrDCCAhWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBJMQswCQYDVQQGEwJVUzET\n" +
+ "MBEGA1UECBMKU29tZS1TdGF0ZTESMBAGA1UEBxMJU29tZS1DaXR5MREwDwYDVQQK\n" +
+ "EwhTb21lLU9yZzAeFw0wODEyMDgwMjQzMzZaFw0yODA4MjUwMjQzMzZaMEkxCzAJ\n" +
+ "BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRIwEAYDVQQHEwlTb21lLUNp\n" +
+ "dHkxETAPBgNVBAoTCFNvbWUtT3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n" +
+ "gQDLxDggB76Ip5OwoUNRLdeOha9U3a2ieyNbz5kTU5lFfe5tui2/461uPZ8a+QOX\n" +
+ "4BdVrhEmV94BKY4FPyH35zboLjfXSKxT1mAOx1Bt9sWF94umxZE1cjyU7vEX8HHj\n" +
+ "7BvOyk5AQrBt7moO1uWtPA/JuoJPePiJl4kqlRJM2Akq6QIDAQABo4GjMIGgMB0G\n" +
+ "A1UdDgQWBBT6uVG/TOfZhpgz+efLHvEzSfeoFDBxBgNVHSMEajBogBT6uVG/TOfZ\n" +
+ "hpgz+efLHvEzSfeoFKFNpEswSTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUt\n" +
+ "U3RhdGUxEjAQBgNVBAcTCVNvbWUtQ2l0eTERMA8GA1UEChMIU29tZS1PcmeCAQAw\n" +
+ "DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBcIm534U123Hz+rtyYO5uA\n" +
+ "ofd81G6FnTfEAV8Kw9fGyyEbQZclBv34A9JsFKeMvU4OFIaixD7nLZ/NZ+IWbhmZ\n" +
+ "LovmJXyCkOufea73pNiZ+f/4/ScZaIlM/PRycQSqbFNd4j9Wott+08qxHPLpsf3P\n" +
+ "6Mvf0r1PNTY2hwTJLJmKtg==\n" +
+ "-----END CERTIFICATE-----";
+
+ static String serverCertStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICpDCCAg2gAwIBAgIBCDANBgkqhkiG9w0BAQQFADBJMQswCQYDVQQGEwJVUzET\n" +
+ "MBEGA1UECBMKU29tZS1TdGF0ZTESMBAGA1UEBxMJU29tZS1DaXR5MREwDwYDVQQK\n" +
+ "EwhTb21lLU9yZzAeFw0wODEyMDgwMzQzMDRaFw0yODA4MjUwMzQzMDRaMHIxCzAJ\n" +
+ "BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRIwEAYDVQQHEwlTb21lLUNp\n" +
+ "dHkxETAPBgNVBAoTCFNvbWUtT3JnMRMwEQYDVQQLEwpTU0wtU2VydmVyMRIwEAYD\n" +
+ "VQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKWsWxw3\n" +
+ "ot2ZiS2yebiP1Uil5xyEF41pnMasbfnyHR85GdrTch5u7ETMcKTcugAw9qBPPVR6\n" +
+ "YWrMV9AKf5UoGD+a2ZTyG8gkiH7+nQ89+1dTCLMgM9Q/F0cU0c3qCNgOdU6vvszS\n" +
+ "7K+peknfwtmsuCRAkKYDVirQMAVALE+r2XSJAgMBAAGjczBxMAkGA1UdEwQCMAAw\n" +
+ "CwYDVR0PBAQDAgXgMB0GA1UdDgQWBBTtbtv0tVbI+xoGYT8PCLumBNgWVDAfBgNV\n" +
+ "HSMEGDAWgBT6uVG/TOfZhpgz+efLHvEzSfeoFDAXBgNVHREBAf8EDTALgglsb2Nh\n" +
+ "bGhvc3QwDQYJKoZIhvcNAQEEBQADgYEAoqVTciHtcvsUj+YaTct8tUh3aTCsKsac\n" +
+ "PHhfQ+ObjiXSgxsKYTX7ym/wk/wvlbUcbqLKxsu7qrcJitH+H9heV1hEHEu65Uoi\n" +
+ "nRugFruyOrwvAylV8Cm2af7ddilmYJ+sdJA6N2M3xJRxR0G2LFHEXDNEjYReyexn\n" +
+ "JqCpf5uZGOo=\n" +
+ "-----END CERTIFICATE-----";
+
+ static String clientCertStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICpDCCAg2gAwIBAgIBCTANBgkqhkiG9w0BAQQFADBJMQswCQYDVQQGEwJVUzET\n" +
+ "MBEGA1UECBMKU29tZS1TdGF0ZTESMBAGA1UEBxMJU29tZS1DaXR5MREwDwYDVQQK\n" +
+ "EwhTb21lLU9yZzAeFw0wODEyMDgwMzQzMjRaFw0yODA4MjUwMzQzMjRaMHIxCzAJ\n" +
+ "BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRIwEAYDVQQHEwlTb21lLUNp\n" +
+ "dHkxETAPBgNVBAoTCFNvbWUtT3JnMRMwEQYDVQQLEwpTU0wtQ2xpZW50MRIwEAYD\n" +
+ "VQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALvwQDas\n" +
+ "JlRO9KNaAC9pIW+5ejqT7KL24Y7HY9gvEjCZLrDyj/gnLSR4KIT3Ab+NRHndO9JV\n" +
+ "8848slshfe/9M0qxo//GyJu5D3xBNZf52zoFYAUVr1kXkqMQrRYc5AdTr6h2olYq\n" +
+ "ktP5KOB4z14fSKtcGd3hZ0O6dY31gqxDkkQbAgMBAAGjczBxMAkGA1UdEwQCMAAw\n" +
+ "CwYDVR0PBAQDAgXgMB0GA1UdDgQWBBTNu8iFqpG9/R2+zWd8/7PpTKgi5jAfBgNV\n" +
+ "HSMEGDAWgBT6uVG/TOfZhpgz+efLHvEzSfeoFDAXBgNVHREBAf8EDTALgglsb2Nh\n" +
+ "bGhvc3QwDQYJKoZIhvcNAQEEBQADgYEAm25gJyqW1JznQ1EyOtTGswBVwfgBOf+F\n" +
+ "HJuBTcflYQLbTD/AETPQJGvZU9tdhuLtbG3OPhR7vSY8zeAbfM3dbH7QFr3r47Gj\n" +
+ "XEH7qM/MX+Z3ifVaC4MeJmrYQkYFSuKeyyKpdRVX4w4nnFHF6OsNASsYrMW6LpxN\n" +
+ "cl/epUcHL7E=\n" +
+ "-----END CERTIFICATE-----";
+
+ static byte serverPrivateExponent[] = {
+ (byte)0x6e, (byte)0xa7, (byte)0x1b, (byte)0x83,
+ (byte)0x51, (byte)0x35, (byte)0x9a, (byte)0x44,
+ (byte)0x7d, (byte)0xf6, (byte)0xe3, (byte)0x89,
+ (byte)0xa0, (byte)0xd7, (byte)0x90, (byte)0x60,
+ (byte)0xa1, (byte)0x4e, (byte)0x27, (byte)0x21,
+ (byte)0xa2, (byte)0x89, (byte)0x74, (byte)0xcc,
+ (byte)0x9d, (byte)0x75, (byte)0x75, (byte)0x4e,
+ (byte)0xc7, (byte)0x82, (byte)0xe3, (byte)0xe3,
+ (byte)0xc3, (byte)0x7d, (byte)0x00, (byte)0x54,
+ (byte)0xec, (byte)0x36, (byte)0xb1, (byte)0xdf,
+ (byte)0x91, (byte)0x9c, (byte)0x7a, (byte)0xc0,
+ (byte)0x62, (byte)0x0a, (byte)0xd6, (byte)0xa9,
+ (byte)0x22, (byte)0x91, (byte)0x4a, (byte)0x29,
+ (byte)0x2e, (byte)0x43, (byte)0xfa, (byte)0x8c,
+ (byte)0xd8, (byte)0xe9, (byte)0xbe, (byte)0xd9,
+ (byte)0x4f, (byte)0xca, (byte)0x23, (byte)0xc6,
+ (byte)0xe4, (byte)0x3f, (byte)0xb8, (byte)0x72,
+ (byte)0xcf, (byte)0x02, (byte)0xfc, (byte)0xf4,
+ (byte)0x58, (byte)0x34, (byte)0x77, (byte)0x76,
+ (byte)0xce, (byte)0x22, (byte)0x44, (byte)0x5f,
+ (byte)0x2d, (byte)0xca, (byte)0xee, (byte)0xf5,
+ (byte)0x43, (byte)0x56, (byte)0x47, (byte)0x71,
+ (byte)0x0b, (byte)0x09, (byte)0x6b, (byte)0x5e,
+ (byte)0xf2, (byte)0xc8, (byte)0xee, (byte)0xd4,
+ (byte)0x6e, (byte)0x44, (byte)0x92, (byte)0x2a,
+ (byte)0x7f, (byte)0xcc, (byte)0xa7, (byte)0xd4,
+ (byte)0x5b, (byte)0xfb, (byte)0xf7, (byte)0x4a,
+ (byte)0xa9, (byte)0xfb, (byte)0x54, (byte)0x18,
+ (byte)0xd5, (byte)0xd5, (byte)0x14, (byte)0xba,
+ (byte)0xa0, (byte)0x1c, (byte)0x13, (byte)0xb3,
+ (byte)0x37, (byte)0x6b, (byte)0x37, (byte)0x59,
+ (byte)0xed, (byte)0xdb, (byte)0x6d, (byte)0xb1
+ };
+
+ static byte serverModulus[] = {
+ (byte)0x00,
+ (byte)0xa5, (byte)0xac, (byte)0x5b, (byte)0x1c,
+ (byte)0x37, (byte)0xa2, (byte)0xdd, (byte)0x99,
+ (byte)0x89, (byte)0x2d, (byte)0xb2, (byte)0x79,
+ (byte)0xb8, (byte)0x8f, (byte)0xd5, (byte)0x48,
+ (byte)0xa5, (byte)0xe7, (byte)0x1c, (byte)0x84,
+ (byte)0x17, (byte)0x8d, (byte)0x69, (byte)0x9c,
+ (byte)0xc6, (byte)0xac, (byte)0x6d, (byte)0xf9,
+ (byte)0xf2, (byte)0x1d, (byte)0x1f, (byte)0x39,
+ (byte)0x19, (byte)0xda, (byte)0xd3, (byte)0x72,
+ (byte)0x1e, (byte)0x6e, (byte)0xec, (byte)0x44,
+ (byte)0xcc, (byte)0x70, (byte)0xa4, (byte)0xdc,
+ (byte)0xba, (byte)0x00, (byte)0x30, (byte)0xf6,
+ (byte)0xa0, (byte)0x4f, (byte)0x3d, (byte)0x54,
+ (byte)0x7a, (byte)0x61, (byte)0x6a, (byte)0xcc,
+ (byte)0x57, (byte)0xd0, (byte)0x0a, (byte)0x7f,
+ (byte)0x95, (byte)0x28, (byte)0x18, (byte)0x3f,
+ (byte)0x9a, (byte)0xd9, (byte)0x94, (byte)0xf2,
+ (byte)0x1b, (byte)0xc8, (byte)0x24, (byte)0x88,
+ (byte)0x7e, (byte)0xfe, (byte)0x9d, (byte)0x0f,
+ (byte)0x3d, (byte)0xfb, (byte)0x57, (byte)0x53,
+ (byte)0x08, (byte)0xb3, (byte)0x20, (byte)0x33,
+ (byte)0xd4, (byte)0x3f, (byte)0x17, (byte)0x47,
+ (byte)0x14, (byte)0xd1, (byte)0xcd, (byte)0xea,
+ (byte)0x08, (byte)0xd8, (byte)0x0e, (byte)0x75,
+ (byte)0x4e, (byte)0xaf, (byte)0xbe, (byte)0xcc,
+ (byte)0xd2, (byte)0xec, (byte)0xaf, (byte)0xa9,
+ (byte)0x7a, (byte)0x49, (byte)0xdf, (byte)0xc2,
+ (byte)0xd9, (byte)0xac, (byte)0xb8, (byte)0x24,
+ (byte)0x40, (byte)0x90, (byte)0xa6, (byte)0x03,
+ (byte)0x56, (byte)0x2a, (byte)0xd0, (byte)0x30,
+ (byte)0x05, (byte)0x40, (byte)0x2c, (byte)0x4f,
+ (byte)0xab, (byte)0xd9, (byte)0x74, (byte)0x89
+ };
+
+ static byte clientPrivateExponent[] = {
+ (byte)0x11, (byte)0xb7, (byte)0x6a, (byte)0x36,
+ (byte)0x3d, (byte)0x30, (byte)0x37, (byte)0xce,
+ (byte)0x61, (byte)0x9d, (byte)0x6c, (byte)0x84,
+ (byte)0x8b, (byte)0xf3, (byte)0x9b, (byte)0x25,
+ (byte)0x4f, (byte)0x14, (byte)0xc8, (byte)0xa4,
+ (byte)0xdd, (byte)0x2f, (byte)0xd7, (byte)0x9a,
+ (byte)0x17, (byte)0xbd, (byte)0x90, (byte)0x19,
+ (byte)0xf7, (byte)0x05, (byte)0xfd, (byte)0xf2,
+ (byte)0xd2, (byte)0xc5, (byte)0xf7, (byte)0x77,
+ (byte)0xbe, (byte)0xea, (byte)0xe2, (byte)0x84,
+ (byte)0x87, (byte)0x97, (byte)0x3a, (byte)0x41,
+ (byte)0x96, (byte)0xb6, (byte)0x99, (byte)0xf8,
+ (byte)0x94, (byte)0x8c, (byte)0x58, (byte)0x71,
+ (byte)0x51, (byte)0x8c, (byte)0xf4, (byte)0x2a,
+ (byte)0x20, (byte)0x9e, (byte)0x1a, (byte)0xa0,
+ (byte)0x26, (byte)0x99, (byte)0x75, (byte)0xd6,
+ (byte)0x31, (byte)0x53, (byte)0x43, (byte)0x39,
+ (byte)0xf5, (byte)0x2a, (byte)0xa6, (byte)0x7e,
+ (byte)0x34, (byte)0x42, (byte)0x51, (byte)0x2a,
+ (byte)0x40, (byte)0x87, (byte)0x03, (byte)0x88,
+ (byte)0x43, (byte)0x69, (byte)0xb2, (byte)0x89,
+ (byte)0x6d, (byte)0x20, (byte)0xbd, (byte)0x7d,
+ (byte)0x71, (byte)0xef, (byte)0x47, (byte)0x0a,
+ (byte)0xdf, (byte)0x06, (byte)0xc1, (byte)0x69,
+ (byte)0x66, (byte)0xa8, (byte)0x22, (byte)0x37,
+ (byte)0x1a, (byte)0x77, (byte)0x1e, (byte)0xc7,
+ (byte)0x94, (byte)0x4e, (byte)0x2c, (byte)0x27,
+ (byte)0x69, (byte)0x45, (byte)0x5e, (byte)0xc8,
+ (byte)0xf8, (byte)0x0c, (byte)0xb7, (byte)0xf8,
+ (byte)0xc0, (byte)0x8f, (byte)0x99, (byte)0xc1,
+ (byte)0xe5, (byte)0x28, (byte)0x9b, (byte)0xf9,
+ (byte)0x4c, (byte)0x94, (byte)0xc6, (byte)0xb1
+ };
+
+ static byte clientModulus[] = {
+ (byte)0x00,
+ (byte)0xbb, (byte)0xf0, (byte)0x40, (byte)0x36,
+ (byte)0xac, (byte)0x26, (byte)0x54, (byte)0x4e,
+ (byte)0xf4, (byte)0xa3, (byte)0x5a, (byte)0x00,
+ (byte)0x2f, (byte)0x69, (byte)0x21, (byte)0x6f,
+ (byte)0xb9, (byte)0x7a, (byte)0x3a, (byte)0x93,
+ (byte)0xec, (byte)0xa2, (byte)0xf6, (byte)0xe1,
+ (byte)0x8e, (byte)0xc7, (byte)0x63, (byte)0xd8,
+ (byte)0x2f, (byte)0x12, (byte)0x30, (byte)0x99,
+ (byte)0x2e, (byte)0xb0, (byte)0xf2, (byte)0x8f,
+ (byte)0xf8, (byte)0x27, (byte)0x2d, (byte)0x24,
+ (byte)0x78, (byte)0x28, (byte)0x84, (byte)0xf7,
+ (byte)0x01, (byte)0xbf, (byte)0x8d, (byte)0x44,
+ (byte)0x79, (byte)0xdd, (byte)0x3b, (byte)0xd2,
+ (byte)0x55, (byte)0xf3, (byte)0xce, (byte)0x3c,
+ (byte)0xb2, (byte)0x5b, (byte)0x21, (byte)0x7d,
+ (byte)0xef, (byte)0xfd, (byte)0x33, (byte)0x4a,
+ (byte)0xb1, (byte)0xa3, (byte)0xff, (byte)0xc6,
+ (byte)0xc8, (byte)0x9b, (byte)0xb9, (byte)0x0f,
+ (byte)0x7c, (byte)0x41, (byte)0x35, (byte)0x97,
+ (byte)0xf9, (byte)0xdb, (byte)0x3a, (byte)0x05,
+ (byte)0x60, (byte)0x05, (byte)0x15, (byte)0xaf,
+ (byte)0x59, (byte)0x17, (byte)0x92, (byte)0xa3,
+ (byte)0x10, (byte)0xad, (byte)0x16, (byte)0x1c,
+ (byte)0xe4, (byte)0x07, (byte)0x53, (byte)0xaf,
+ (byte)0xa8, (byte)0x76, (byte)0xa2, (byte)0x56,
+ (byte)0x2a, (byte)0x92, (byte)0xd3, (byte)0xf9,
+ (byte)0x28, (byte)0xe0, (byte)0x78, (byte)0xcf,
+ (byte)0x5e, (byte)0x1f, (byte)0x48, (byte)0xab,
+ (byte)0x5c, (byte)0x19, (byte)0xdd, (byte)0xe1,
+ (byte)0x67, (byte)0x43, (byte)0xba, (byte)0x75,
+ (byte)0x8d, (byte)0xf5, (byte)0x82, (byte)0xac,
+ (byte)0x43, (byte)0x92, (byte)0x44, (byte)0x1b
+ };
+
+ 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 = getSSLContext(trusedCertStr, serverCertStr,
+ serverModulus, serverPrivateExponent, passphrase);
+ SSLServerSocketFactory sslssf = context.getServerSocketFactory();
+
+ SSLServerSocket sslServerSocket =
+ (SSLServerSocket) sslssf.createServerSocket(serverPort);
+ serverPort = sslServerSocket.getLocalPort();
+
+ // enable endpoint identification
+ // ignore, we may test the feature when known how to parse client
+ // hostname
+ //SSLParameters params = sslServerSocket.getSSLParameters();
+ //params.setEndpointIdentificationAlgorithm("HTTPS");
+ //sslServerSocket.setSSLParameters(params);
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
+ sslSocket.setNeedClientAuth(true);
+
+ 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);
+ }
+
+ SSLContext context = getSSLContext(trusedCertStr, clientCertStr,
+ clientModulus, clientPrivateExponent, passphrase);
+
+ SSLSocketFactory sslsf = context.getSocketFactory();
+ SSLSocket sslSocket = (SSLSocket)
+ sslsf.createSocket("localhost", serverPort);
+
+ // enable endpoint identification
+ SSLParameters params = sslSocket.getSSLParameters();
+ params.setEndpointIdentificationAlgorithm("HTTPS");
+ sslSocket.setSSLParameters(params);
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write(280);
+ sslOS.flush();
+ sslIS.read();
+
+ sslSocket.close();
+
+ }
+
+ // get the ssl context
+ private static SSLContext getSSLContext(String trusedCertStr,
+ String keyCertStr, byte[] modulus,
+ byte[] privateExponent, char[] passphrase) throws Exception {
+
+ // generate certificate from cert string
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+
+ ByteArrayInputStream is =
+ new ByteArrayInputStream(trusedCertStr.getBytes());
+ Certificate trusedCert = cf.generateCertificate(is);
+ is.close();
+
+ // create a key store
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(null, null);
+
+ // import the trused cert
+ ks.setCertificateEntry("RSA Export Signer", trusedCert);
+
+ if (keyCertStr != null) {
+ // generate the private key.
+ RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(
+ new BigInteger(modulus),
+ new BigInteger(privateExponent));
+ 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 = new Certificate[2];
+ chain[0] = keyCert;
+ chain[1] = trusedCert;
+
+ // import the key entry.
+ ks.setKeyEntry("Whatever", priKey, passphrase, chain);
+ }
+
+ // create SSL context
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
+ tmf.init(ks);
+
+ TrustManager tms[] = tmf.getTrustManagers();
+ if (tms == null || tms.length == 0) {
+ throw new Exception("unexpected trust manager implementation");
+ } else {
+ if (!(tms[0] instanceof X509ExtendedTrustManager)) {
+ throw new Exception("unexpected trust manager implementation: "
+ + tms[0].getClass().getCanonicalName());
+ }
+ }
+
+
+ SSLContext ctx = SSLContext.getInstance("TLS");
+
+ if (keyCertStr != null) {
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, passphrase);
+
+ ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+ } else {
+ ctx.init(null, tmf.getTrustManagers(), null);
+ }
+
+ return ctx;
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+
+ // 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");
+
+ /*
+ * Start the tests.
+ */
+ new PKIXExtendedTM();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ PKIXExtendedTM() throws Exception {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ serverThread.join();
+ } else {
+ clientThread.join();
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ *
+ * If the main thread excepted, that propagates back
+ * immediately. If the other thread threw an exception, we
+ * should report back.
+ */
+ if (serverException != null)
+ throw serverException;
+ if (clientException != null)
+ throw clientException;
+ }
+
+ 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 {
+ doServerSide();
+ }
+ }
+
+ 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 {
+ doClientSide();
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/SunX509ExtendedTM.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,884 @@
+/*
+ * Copyright (c) 2010, 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 6916074
+ * @run main/othervm -Djavax.net.debug=all SunX509ExtendedTM
+ * @summary Add support for TLS 1.2
+ */
+
+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 java.math.BigInteger;
+
+
+/*
+ * Certificates and key used in the test.
+ *
+ * TLS server certificate:
+ * server private key:
+ * -----BEGIN RSA PRIVATE KEY-----
+ * Proc-Type: 4,ENCRYPTED
+ * DEK-Info: DES-EDE3-CBC,D9AE407F6D0E389A
+ *
+ * WPrA7TFol/cQCcp9oHnXWNpYlvRbbIcQj0m+RKT2Iuzfus+DHt3Zadf8nJpKfX2e
+ * h2rnhlzCN9M7djRDooZKDOPCsdBn51Au7HlZF3S3Opgo7D8XFM1a8t1Je4ke14oI
+ * nw6QKYsBblRziPnP2PZ0zvX24nOv7bbY8beynlJHGs00VWSFdoH2DS0aE1p6D+3n
+ * ptJuJ75dVfZFK4X7162APlNXevX8D6PEQpSiRw1rjjGGcnvQ4HdWk3BxDVDcCNJb
+ * Y1aGNRxsjTDvPi3R9Qx2M+W03QzEPx4SR3ZHVskeSJHaetM0TM/w/45Paq4GokXP
+ * ZeTnbEx1xmjkA7h+t4doLL4watx5F6yLsJzu8xB3lt/1EtmkYtLz1t7X4BetPAXz
+ * zS69X/VwhKfsOI3qXBWuL2oHPyhDmT1gcaUQwEPSV6ogHEEQEDXdiUS8heNK13KF
+ * TCQYFkETvV2BLxUhV1hypPzRQ6tUpJiAbD5KmoK2lD9slshG2QtvKQq0/bgkDY5J
+ * LhDHV2dtcZ3kDPkkZXpbcJQvoeH3d09C5sIsuTFo2zgNR6oETHUc5TzP6FY2YYRa
+ * QcK5HcmtsRRiXFm01ac+aMejJUIujjFt84SiKWT/73vC8AmY4tYcJBLjCg4XIxSH
+ * fdDFLL1YZENNO5ivlp8mdiHqcawx+36L7DrEZQ8RZt6cqST5t/+XTdM74s6k81GT
+ * pNsa82P2K2zmIUZ/DL2mKjW1vfRByw1NQFEBkN3vdyZxYfM/JyUzX4hbjXBEkh9Q
+ * QYrcwLKLjis2QzSvK04B3bvRzRb+4ocWiso8ZPAXAIxZFBWDpTMM2A==
+ * -----END RSA PRIVATE KEY-----
+ *
+ * -----BEGIN RSA PRIVATE KEY-----
+ * MIICXAIBAAKBgQClrFscN6LdmYktsnm4j9VIpecchBeNaZzGrG358h0fORna03Ie
+ * buxEzHCk3LoAMPagTz1UemFqzFfQCn+VKBg/mtmU8hvIJIh+/p0PPftXUwizIDPU
+ * PxdHFNHN6gjYDnVOr77M0uyvqXpJ38LZrLgkQJCmA1Yq0DAFQCxPq9l0iQIDAQAB
+ * AoGAbqcbg1E1mkR99uOJoNeQYKFOJyGiiXTMnXV1TseC4+PDfQBU7Dax35GcesBi
+ * CtapIpFKKS5D+ozY6b7ZT8ojxuQ/uHLPAvz0WDR3ds4iRF8tyu71Q1ZHcQsJa17y
+ * yO7UbkSSKn/Mp9Rb+/dKqftUGNXVFLqgHBOzN2s3We3bbbECQQDYBPKOg3hkaGHo
+ * OhpHKqtQ6EVkldihG/3i4WejRonelXN+HRh1KrB2HBx0M8D/qAzP1i3rNSlSHer4
+ * 59YRTJnHAkEAxFX/sVYSn07BHv9Zhn6XXct/Cj43z/tKNbzlNbcxqQwQerw3IH51
+ * 8UH2YOA+GD3lXbKp+MytoFLWv8zg4YT/LwJAfqan75Z1R6lLffRS49bIiq8jwE16
+ * rTrUJ+kv8jKxMqc9B3vXkxpsS1M/+4E8bqgAmvpgAb8xcsvHsBd9ErdukQJBAKs2
+ * j67W75BrPjBI34pQ1LEfp56IGWXOrq1kF8IbCjxv3+MYRT6Z6UJFkpRymNPNDjsC
+ * dgUYgITiGJHUGXuw3lMCQHEHqo9ZtXz92yFT+VhsNc29B8m/sqUJdtCcMd/jGpAF
+ * u6GHufjqIZBpQsk63wbwESAPZZ+kk1O1kS5GIRLX608=
+ * -----END RSA PRIVATE KEY-----
+ *
+ * Private-Key: (1024 bit)
+ * modulus:
+ * 00:a5:ac:5b:1c:37:a2:dd:99:89:2d:b2:79:b8:8f:
+ * d5:48:a5:e7:1c:84:17:8d:69:9c:c6:ac:6d:f9:f2:
+ * 1d:1f:39:19:da:d3:72:1e:6e:ec:44:cc:70:a4:dc:
+ * ba:00:30:f6:a0:4f:3d:54:7a:61:6a:cc:57:d0:0a:
+ * 7f:95:28:18:3f:9a:d9:94:f2:1b:c8:24:88:7e:fe:
+ * 9d:0f:3d:fb:57:53:08:b3:20:33:d4:3f:17:47:14:
+ * d1:cd:ea:08:d8:0e:75:4e:af:be:cc:d2:ec:af:a9:
+ * 7a:49:df:c2:d9:ac:b8:24:40:90:a6:03:56:2a:d0:
+ * 30:05:40:2c:4f:ab:d9:74:89
+ * publicExponent: 65537 (0x10001)
+ * privateExponent:
+ * 6e:a7:1b:83:51:35:9a:44:7d:f6:e3:89:a0:d7:90:
+ * 60:a1:4e:27:21:a2:89:74:cc:9d:75:75:4e:c7:82:
+ * e3:e3:c3:7d:00:54:ec:36:b1:df:91:9c:7a:c0:62:
+ * 0a:d6:a9:22:91:4a:29:2e:43:fa:8c:d8:e9:be:d9:
+ * 4f:ca:23:c6:e4:3f:b8:72:cf:02:fc:f4:58:34:77:
+ * 76:ce:22:44:5f:2d:ca:ee:f5:43:56:47:71:0b:09:
+ * 6b:5e:f2:c8:ee:d4:6e:44:92:2a:7f:cc:a7:d4:5b:
+ * fb:f7:4a:a9:fb:54:18:d5:d5:14:ba:a0:1c:13:b3:
+ * 37:6b:37:59:ed:db:6d:b1
+ * prime1:
+ * 00:d8:04:f2:8e:83:78:64:68:61:e8:3a:1a:47:2a:
+ * ab:50:e8:45:64:95:d8:a1:1b:fd:e2:e1:67:a3:46:
+ * 89:de:95:73:7e:1d:18:75:2a:b0:76:1c:1c:74:33:
+ * c0:ff:a8:0c:cf:d6:2d:eb:35:29:52:1d:ea:f8:e7:
+ * d6:11:4c:99:c7
+ * prime2:
+ * 00:c4:55:ff:b1:56:12:9f:4e:c1:1e:ff:59:86:7e:
+ * 97:5d:cb:7f:0a:3e:37:cf:fb:4a:35:bc:e5:35:b7:
+ * 31:a9:0c:10:7a:bc:37:20:7e:75:f1:41:f6:60:e0:
+ * 3e:18:3d:e5:5d:b2:a9:f8:cc:ad:a0:52:d6:bf:cc:
+ * e0:e1:84:ff:2f
+ * exponent1:
+ * 7e:a6:a7:ef:96:75:47:a9:4b:7d:f4:52:e3:d6:c8:
+ * 8a:af:23:c0:4d:7a:ad:3a:d4:27:e9:2f:f2:32:b1:
+ * 32:a7:3d:07:7b:d7:93:1a:6c:4b:53:3f:fb:81:3c:
+ * 6e:a8:00:9a:fa:60:01:bf:31:72:cb:c7:b0:17:7d:
+ * 12:b7:6e:91
+ * exponent2:
+ * 00:ab:36:8f:ae:d6:ef:90:6b:3e:30:48:df:8a:50:
+ * d4:b1:1f:a7:9e:88:19:65:ce:ae:ad:64:17:c2:1b:
+ * 0a:3c:6f:df:e3:18:45:3e:99:e9:42:45:92:94:72:
+ * 98:d3:cd:0e:3b:02:76:05:18:80:84:e2:18:91:d4:
+ * 19:7b:b0:de:53
+ * coefficient:
+ * 71:07:aa:8f:59:b5:7c:fd:db:21:53:f9:58:6c:35:
+ * cd:bd:07:c9:bf:b2:a5:09:76:d0:9c:31:df:e3:1a:
+ * 90:05:bb:a1:87:b9:f8:ea:21:90:69:42:c9:3a:df:
+ * 06:f0:11:20:0f:65:9f:a4:93:53:b5:91:2e:46:21:
+ * 12:d7:eb:4f
+ *
+ *
+ * server certificate:
+ * Data:
+ * Version: 3 (0x2)
+ * Serial Number: 8 (0x8)
+ * Signature Algorithm: md5WithRSAEncryption
+ * Issuer: C=US, ST=Some-State, L=Some-City, O=Some-Org
+ * Validity
+ * Not Before: Dec 8 03:43:04 2008 GMT
+ * Not After : Aug 25 03:43:04 2028 GMT
+ * Subject: C=US, ST=Some-State, L=Some-City, O=Some-Org, OU=SSL-Server, CN=localhost
+ * Subject Public Key Info:
+ * Public Key Algorithm: rsaEncryption
+ * RSA Public Key: (1024 bit)
+ * Modulus (1024 bit):
+ * 00:a5:ac:5b:1c:37:a2:dd:99:89:2d:b2:79:b8:8f:
+ * d5:48:a5:e7:1c:84:17:8d:69:9c:c6:ac:6d:f9:f2:
+ * 1d:1f:39:19:da:d3:72:1e:6e:ec:44:cc:70:a4:dc:
+ * ba:00:30:f6:a0:4f:3d:54:7a:61:6a:cc:57:d0:0a:
+ * 7f:95:28:18:3f:9a:d9:94:f2:1b:c8:24:88:7e:fe:
+ * 9d:0f:3d:fb:57:53:08:b3:20:33:d4:3f:17:47:14:
+ * d1:cd:ea:08:d8:0e:75:4e:af:be:cc:d2:ec:af:a9:
+ * 7a:49:df:c2:d9:ac:b8:24:40:90:a6:03:56:2a:d0:
+ * 30:05:40:2c:4f:ab:d9:74:89
+ * Exponent: 65537 (0x10001)
+ * X509v3 extensions:
+ * X509v3 Basic Constraints:
+ * CA:FALSE
+ * X509v3 Key Usage:
+ * Digital Signature, Non Repudiation, Key Encipherment
+ * X509v3 Subject Key Identifier:
+ * ED:6E:DB:F4:B5:56:C8:FB:1A:06:61:3F:0F:08:BB:A6:04:D8:16:54
+ * X509v3 Authority Key Identifier:
+ * keyid:FA:B9:51:BF:4C:E7:D9:86:98:33:F9:E7:CB:1E:F1:33:49:F7:A8:14
+ *
+ * X509v3 Subject Alternative Name: critical
+ * DNS:localhost
+ * Signature Algorithm: md5WithRSAEncryption0
+ *
+ * -----BEGIN CERTIFICATE-----
+ * MIICpDCCAg2gAwIBAgIBCDANBgkqhkiG9w0BAQQFADBJMQswCQYDVQQGEwJVUzET
+ * MBEGA1UECBMKU29tZS1TdGF0ZTESMBAGA1UEBxMJU29tZS1DaXR5MREwDwYDVQQK
+ * EwhTb21lLU9yZzAeFw0wODEyMDgwMzQzMDRaFw0yODA4MjUwMzQzMDRaMHIxCzAJ
+ * BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRIwEAYDVQQHEwlTb21lLUNp
+ * dHkxETAPBgNVBAoTCFNvbWUtT3JnMRMwEQYDVQQLEwpTU0wtU2VydmVyMRIwEAYD
+ * VQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKWsWxw3
+ * ot2ZiS2yebiP1Uil5xyEF41pnMasbfnyHR85GdrTch5u7ETMcKTcugAw9qBPPVR6
+ * YWrMV9AKf5UoGD+a2ZTyG8gkiH7+nQ89+1dTCLMgM9Q/F0cU0c3qCNgOdU6vvszS
+ * 7K+peknfwtmsuCRAkKYDVirQMAVALE+r2XSJAgMBAAGjczBxMAkGA1UdEwQCMAAw
+ * CwYDVR0PBAQDAgXgMB0GA1UdDgQWBBTtbtv0tVbI+xoGYT8PCLumBNgWVDAfBgNV
+ * HSMEGDAWgBT6uVG/TOfZhpgz+efLHvEzSfeoFDAXBgNVHREBAf8EDTALgglsb2Nh
+ * bGhvc3QwDQYJKoZIhvcNAQEEBQADgYEAoqVTciHtcvsUj+YaTct8tUh3aTCsKsac
+ * PHhfQ+ObjiXSgxsKYTX7ym/wk/wvlbUcbqLKxsu7qrcJitH+H9heV1hEHEu65Uoi
+ * nRugFruyOrwvAylV8Cm2af7ddilmYJ+sdJA6N2M3xJRxR0G2LFHEXDNEjYReyexn
+ * JqCpf5uZGOo=
+ * -----END CERTIFICATE-----
+ *
+ *
+ * TLS client certificate:
+ * client private key:
+ * ----BEGIN RSA PRIVATE KEY-----
+ * Proc-Type: 4,ENCRYPTED
+ * DEK-Info: DES-EDE3-CBC,FA2A435CD35A9390
+ *
+ * Z+Y2uaETbsUWIyJUyVu1UV2G4rgFYJyACZT6Tp1KjRtxflSh2kXkJ9MpuXMXA0V4
+ * Yy3fDzPqCL9NJmQAYRlAx/W/+j4F5EyMWDIx8fUxzONRZyoiwF7jLm+KscAfv6Pf
+ * q7ItWOdj3z7IYrwlB8YIGd3F2cDKT3S+lYRk7rKb/qT7itbuHnY4Ardh3yl+MZak
+ * jBp+ELUlRsUqSr1V0LoM+0rCCykarpyfhpxEcqsrl0v9Cyi5uhU50/oKv5zql3SH
+ * l2ImgDjp3batAs8+Bd4NF2aqi0a7Hy44JUHxRm4caZryU/i/D9N1MbuM6882HLat
+ * 5N0G+NaIUfywa8mjwq2D5aiit18HqKA6XeRRYeJ5Dvu9DCO4GeFSwcUFIBMI0L46
+ * 7s114+oDodg57pMgITi+04vmUxvqlN9aiyd7f5Fgd7PeHGeOdbMz1NaJLJaPI9++
+ * NakK8eK9iwT/Gdq0Uap5/CHW7vCT5PO+h3HY0STH0lWStXhdWnFO04zTdywsbSp+
+ * DLpHeFT66shfeUlxR0PsCbG9vPRt/QmGLeYQZITppWo/ylSq4j+pRIuXvuWHdBRN
+ * rTZ8QF4Y7AxQUXVz1j1++s6ZMHTzaK2i9HrhmDs1MbJl+QwWre3Xpv3LvTVz3k5U
+ * wX8kuY1m3STt71QCaRWENq5sRaMImLxZbxc/ivFl9RAzUqo4NCxLod/QgA4iLqtO
+ * ztnlpzwlC/F8HbQ1oqYWwnZAPhzU/cULtstl+Yrws2c2atO323LbPXZqbASySgig
+ * sNpFXQMObdfP6LN23bY+1SvtK7V4NUTNhpdIc6INQAQ=
+ * -----END RSA PRIVATE KEY-----
+ *
+ * -----BEGIN RSA PRIVATE KEY-----
+ * MIICWwIBAAKBgQC78EA2rCZUTvSjWgAvaSFvuXo6k+yi9uGOx2PYLxIwmS6w8o/4
+ * Jy0keCiE9wG/jUR53TvSVfPOPLJbIX3v/TNKsaP/xsibuQ98QTWX+ds6BWAFFa9Z
+ * F5KjEK0WHOQHU6+odqJWKpLT+SjgeM9eH0irXBnd4WdDunWN9YKsQ5JEGwIDAQAB
+ * AoGAEbdqNj0wN85hnWyEi/ObJU8UyKTdL9eaF72QGfcF/fLSxfd3vurihIeXOkGW
+ * tpn4lIxYcVGM9CognhqgJpl11jFTQzn1KqZ+NEJRKkCHA4hDabKJbSC9fXHvRwrf
+ * BsFpZqgiNxp3HseUTiwnaUVeyPgMt/jAj5nB5Sib+UyUxrECQQDnNQBiF2aifEg6
+ * zbJOOC7he5CHAdkFxSxWVFVHL6EfXfqdLVkUohMbgZv+XxyIeU2biOExSg49Kds3
+ * FOKgTau1AkEA0Bd1haj6QuCo8I0AXm2WO+MMTZMTvtHD/bGjKNM+fT4I8rKYnQRX
+ * 1acHdqS9Xx2rNJqZgkMmpESIdPR2fc4yjwJALFeM6EMmqvj8/VIf5UJ/Mz14fXwM
+ * PEARfckUxd9LnnFutCBTWlKvKXJVEZb6KO5ixPaegc57Jp3Vbh3yTN44lQJADD/1
+ * SSMDaIB1MYP7a5Oj7m6VQNPRq8AJe5vDcRnOae0G9dKRrVyeFxO4GsHj6/+BHp2j
+ * P8nYMn9eURQ7DXjf/QJAAQzMlWnKGSO8pyTDtnQx3hRMoUkOEhmNq4bQhLkYqtnY
+ * FcqpUQ2qMjW+NiNWk5HnTrMS3L9EdJobMUzaNZLy4w==
+ * -----END RSA PRIVATE KEY-----
+ *
+ * Private-Key: (1024 bit)
+ * modulus:
+ * 00:bb:f0:40:36:ac:26:54:4e:f4:a3:5a:00:2f:69:
+ * 21:6f:b9:7a:3a:93:ec:a2:f6:e1:8e:c7:63:d8:2f:
+ * 12:30:99:2e:b0:f2:8f:f8:27:2d:24:78:28:84:f7:
+ * 01:bf:8d:44:79:dd:3b:d2:55:f3:ce:3c:b2:5b:21:
+ * 7d:ef:fd:33:4a:b1:a3:ff:c6:c8:9b:b9:0f:7c:41:
+ * 35:97:f9:db:3a:05:60:05:15:af:59:17:92:a3:10:
+ * ad:16:1c:e4:07:53:af:a8:76:a2:56:2a:92:d3:f9:
+ * 28:e0:78:cf:5e:1f:48:ab:5c:19:dd:e1:67:43:ba:
+ * 75:8d:f5:82:ac:43:92:44:1b
+ * publicExponent: 65537 (0x10001)
+ * privateExponent:
+ * 11:b7:6a:36:3d:30:37:ce:61:9d:6c:84:8b:f3:9b:
+ * 25:4f:14:c8:a4:dd:2f:d7:9a:17:bd:90:19:f7:05:
+ * fd:f2:d2:c5:f7:77:be:ea:e2:84:87:97:3a:41:96:
+ * b6:99:f8:94:8c:58:71:51:8c:f4:2a:20:9e:1a:a0:
+ * 26:99:75:d6:31:53:43:39:f5:2a:a6:7e:34:42:51:
+ * 2a:40:87:03:88:43:69:b2:89:6d:20:bd:7d:71:ef:
+ * 47:0a:df:06:c1:69:66:a8:22:37:1a:77:1e:c7:94:
+ * 4e:2c:27:69:45:5e:c8:f8:0c:b7:f8:c0:8f:99:c1:
+ * e5:28:9b:f9:4c:94:c6:b1
+ * prime1:
+ * 00:e7:35:00:62:17:66:a2:7c:48:3a:cd:b2:4e:38:
+ * 2e:e1:7b:90:87:01:d9:05:c5:2c:56:54:55:47:2f:
+ * a1:1f:5d:fa:9d:2d:59:14:a2:13:1b:81:9b:fe:5f:
+ * 1c:88:79:4d:9b:88:e1:31:4a:0e:3d:29:db:37:14:
+ * e2:a0:4d:ab:b5
+ * prime2:
+ * 00:d0:17:75:85:a8:fa:42:e0:a8:f0:8d:00:5e:6d:
+ * 96:3b:e3:0c:4d:93:13:be:d1:c3:fd:b1:a3:28:d3:
+ * 3e:7d:3e:08:f2:b2:98:9d:04:57:d5:a7:07:76:a4:
+ * bd:5f:1d:ab:34:9a:99:82:43:26:a4:44:88:74:f4:
+ * 76:7d:ce:32:8f
+ * exponent1:
+ * 2c:57:8c:e8:43:26:aa:f8:fc:fd:52:1f:e5:42:7f:
+ * 33:3d:78:7d:7c:0c:3c:40:11:7d:c9:14:c5:df:4b:
+ * 9e:71:6e:b4:20:53:5a:52:af:29:72:55:11:96:fa:
+ * 28:ee:62:c4:f6:9e:81:ce:7b:26:9d:d5:6e:1d:f2:
+ * 4c:de:38:95
+ * exponent2:
+ * 0c:3f:f5:49:23:03:68:80:75:31:83:fb:6b:93:a3:
+ * ee:6e:95:40:d3:d1:ab:c0:09:7b:9b:c3:71:19:ce:
+ * 69:ed:06:f5:d2:91:ad:5c:9e:17:13:b8:1a:c1:e3:
+ * eb:ff:81:1e:9d:a3:3f:c9:d8:32:7f:5e:51:14:3b:
+ * 0d:78:df:fd
+ * coefficient:
+ * 01:0c:cc:95:69:ca:19:23:bc:a7:24:c3:b6:74:31:
+ * de:14:4c:a1:49:0e:12:19:8d:ab:86:d0:84:b9:18:
+ * aa:d9:d8:15:ca:a9:51:0d:aa:32:35:be:36:23:56:
+ * 93:91:e7:4e:b3:12:dc:bf:44:74:9a:1b:31:4c:da:
+ * 35:92:f2:e3
+ *
+ * client certificate:
+ * Data:
+ * Version: 3 (0x2)
+ * Serial Number: 9 (0x9)
+ * Signature Algorithm: md5WithRSAEncryption
+ * Issuer: C=US, ST=Some-State, L=Some-City, O=Some-Org
+ * Validity
+ * Not Before: Dec 8 03:43:24 2008 GMT
+ * Not After : Aug 25 03:43:24 2028 GMT
+ * Subject: C=US, ST=Some-State, L=Some-City, O=Some-Org, OU=SSL-Client, CN=localhost
+ * Subject Public Key Info:
+ * Public Key Algorithm: rsaEncryption
+ * RSA Public Key: (1024 bit)
+ * Modulus (1024 bit):
+ * 00:bb:f0:40:36:ac:26:54:4e:f4:a3:5a:00:2f:69:
+ * 21:6f:b9:7a:3a:93:ec:a2:f6:e1:8e:c7:63:d8:2f:
+ * 12:30:99:2e:b0:f2:8f:f8:27:2d:24:78:28:84:f7:
+ * 01:bf:8d:44:79:dd:3b:d2:55:f3:ce:3c:b2:5b:21:
+ * 7d:ef:fd:33:4a:b1:a3:ff:c6:c8:9b:b9:0f:7c:41:
+ * 35:97:f9:db:3a:05:60:05:15:af:59:17:92:a3:10:
+ * ad:16:1c:e4:07:53:af:a8:76:a2:56:2a:92:d3:f9:
+ * 28:e0:78:cf:5e:1f:48:ab:5c:19:dd:e1:67:43:ba:
+ * 75:8d:f5:82:ac:43:92:44:1b
+ * Exponent: 65537 (0x10001)
+ * X509v3 extensions:
+ * X509v3 Basic Constraints:
+ * CA:FALSE
+ * X509v3 Key Usage:
+ * Digital Signature, Non Repudiation, Key Encipherment
+ * X509v3 Subject Key Identifier:
+ * CD:BB:C8:85:AA:91:BD:FD:1D:BE:CD:67:7C:FF:B3:E9:4C:A8:22:E6
+ * X509v3 Authority Key Identifier:
+ * keyid:FA:B9:51:BF:4C:E7:D9:86:98:33:F9:E7:CB:1E:F1:33:49:F7:A8:14
+ *
+ * X509v3 Subject Alternative Name: critical
+ * DNS:localhost
+ * Signature Algorithm: md5WithRSAEncryption
+ *
+ * -----BEGIN CERTIFICATE-----
+ * MIICpDCCAg2gAwIBAgIBCTANBgkqhkiG9w0BAQQFADBJMQswCQYDVQQGEwJVUzET
+ * MBEGA1UECBMKU29tZS1TdGF0ZTESMBAGA1UEBxMJU29tZS1DaXR5MREwDwYDVQQK
+ * EwhTb21lLU9yZzAeFw0wODEyMDgwMzQzMjRaFw0yODA4MjUwMzQzMjRaMHIxCzAJ
+ * BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRIwEAYDVQQHEwlTb21lLUNp
+ * dHkxETAPBgNVBAoTCFNvbWUtT3JnMRMwEQYDVQQLEwpTU0wtQ2xpZW50MRIwEAYD
+ * VQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALvwQDas
+ * JlRO9KNaAC9pIW+5ejqT7KL24Y7HY9gvEjCZLrDyj/gnLSR4KIT3Ab+NRHndO9JV
+ * 8848slshfe/9M0qxo//GyJu5D3xBNZf52zoFYAUVr1kXkqMQrRYc5AdTr6h2olYq
+ * ktP5KOB4z14fSKtcGd3hZ0O6dY31gqxDkkQbAgMBAAGjczBxMAkGA1UdEwQCMAAw
+ * CwYDVR0PBAQDAgXgMB0GA1UdDgQWBBTNu8iFqpG9/R2+zWd8/7PpTKgi5jAfBgNV
+ * HSMEGDAWgBT6uVG/TOfZhpgz+efLHvEzSfeoFDAXBgNVHREBAf8EDTALgglsb2Nh
+ * bGhvc3QwDQYJKoZIhvcNAQEEBQADgYEAm25gJyqW1JznQ1EyOtTGswBVwfgBOf+F
+ * HJuBTcflYQLbTD/AETPQJGvZU9tdhuLtbG3OPhR7vSY8zeAbfM3dbH7QFr3r47Gj
+ * XEH7qM/MX+Z3ifVaC4MeJmrYQkYFSuKeyyKpdRVX4w4nnFHF6OsNASsYrMW6LpxN
+ * cl/epUcHL7E=
+ * -----END CERTIFICATE-----
+ *
+ *
+ *
+ * Trusted CA certificate:
+ * Certificate:
+ * Data:
+ * Version: 3 (0x2)
+ * Serial Number: 0 (0x0)
+ * Signature Algorithm: md5WithRSAEncryption
+ * Issuer: C=US, ST=Some-State, L=Some-City, O=Some-Org
+ * Validity
+ * Not Before: Dec 8 02:43:36 2008 GMT
+ * Not After : Aug 25 02:43:36 2028 GMT
+ * Subject: C=US, ST=Some-State, L=Some-City, O=Some-Org
+ * Subject Public Key Info:
+ * Public Key Algorithm: rsaEncryption
+ * RSA Public Key: (1024 bit)
+ * Modulus (1024 bit):
+ * 00:cb:c4:38:20:07:be:88:a7:93:b0:a1:43:51:2d:
+ * d7:8e:85:af:54:dd:ad:a2:7b:23:5b:cf:99:13:53:
+ * 99:45:7d:ee:6d:ba:2d:bf:e3:ad:6e:3d:9f:1a:f9:
+ * 03:97:e0:17:55:ae:11:26:57:de:01:29:8e:05:3f:
+ * 21:f7:e7:36:e8:2e:37:d7:48:ac:53:d6:60:0e:c7:
+ * 50:6d:f6:c5:85:f7:8b:a6:c5:91:35:72:3c:94:ee:
+ * f1:17:f0:71:e3:ec:1b:ce:ca:4e:40:42:b0:6d:ee:
+ * 6a:0e:d6:e5:ad:3c:0f:c9:ba:82:4f:78:f8:89:97:
+ * 89:2a:95:12:4c:d8:09:2a:e9
+ * Exponent: 65537 (0x10001)
+ * X509v3 extensions:
+ * X509v3 Subject Key Identifier:
+ * FA:B9:51:BF:4C:E7:D9:86:98:33:F9:E7:CB:1E:F1:33:49:F7:A8:14
+ * X509v3 Authority Key Identifier:
+ * keyid:FA:B9:51:BF:4C:E7:D9:86:98:33:F9:E7:CB:1E:F1:33:49:F7:A8:14
+ * DirName:/C=US/ST=Some-State/L=Some-City/O=Some-Org
+ * serial:00
+ *
+ * X509v3 Basic Constraints:
+ * CA:TRUE
+ * Signature Algorithm: md5WithRSAEncryption
+ *
+ * -----BEGIN CERTIFICATE-----
+ * MIICrDCCAhWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBJMQswCQYDVQQGEwJVUzET
+ * MBEGA1UECBMKU29tZS1TdGF0ZTESMBAGA1UEBxMJU29tZS1DaXR5MREwDwYDVQQK
+ * EwhTb21lLU9yZzAeFw0wODEyMDgwMjQzMzZaFw0yODA4MjUwMjQzMzZaMEkxCzAJ
+ * BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRIwEAYDVQQHEwlTb21lLUNp
+ * dHkxETAPBgNVBAoTCFNvbWUtT3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+ * gQDLxDggB76Ip5OwoUNRLdeOha9U3a2ieyNbz5kTU5lFfe5tui2/461uPZ8a+QOX
+ * 4BdVrhEmV94BKY4FPyH35zboLjfXSKxT1mAOx1Bt9sWF94umxZE1cjyU7vEX8HHj
+ * 7BvOyk5AQrBt7moO1uWtPA/JuoJPePiJl4kqlRJM2Akq6QIDAQABo4GjMIGgMB0G
+ * A1UdDgQWBBT6uVG/TOfZhpgz+efLHvEzSfeoFDBxBgNVHSMEajBogBT6uVG/TOfZ
+ * hpgz+efLHvEzSfeoFKFNpEswSTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUt
+ * U3RhdGUxEjAQBgNVBAcTCVNvbWUtQ2l0eTERMA8GA1UEChMIU29tZS1PcmeCAQAw
+ * DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBcIm534U123Hz+rtyYO5uA
+ * ofd81G6FnTfEAV8Kw9fGyyEbQZclBv34A9JsFKeMvU4OFIaixD7nLZ/NZ+IWbhmZ
+ * LovmJXyCkOufea73pNiZ+f/4/ScZaIlM/PRycQSqbFNd4j9Wott+08qxHPLpsf3P
+ * 6Mvf0r1PNTY2hwTJLJmKtg==
+ * -----END CERTIFICATE---
+ */
+
+
+public class SunX509ExtendedTM {
+
+ /*
+ * =============================================================
+ * 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?
+ */
+ static String trusedCertStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICrDCCAhWgAwIBAgIBADANBgkqhkiG9w0BAQQFADBJMQswCQYDVQQGEwJVUzET\n" +
+ "MBEGA1UECBMKU29tZS1TdGF0ZTESMBAGA1UEBxMJU29tZS1DaXR5MREwDwYDVQQK\n" +
+ "EwhTb21lLU9yZzAeFw0wODEyMDgwMjQzMzZaFw0yODA4MjUwMjQzMzZaMEkxCzAJ\n" +
+ "BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRIwEAYDVQQHEwlTb21lLUNp\n" +
+ "dHkxETAPBgNVBAoTCFNvbWUtT3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n" +
+ "gQDLxDggB76Ip5OwoUNRLdeOha9U3a2ieyNbz5kTU5lFfe5tui2/461uPZ8a+QOX\n" +
+ "4BdVrhEmV94BKY4FPyH35zboLjfXSKxT1mAOx1Bt9sWF94umxZE1cjyU7vEX8HHj\n" +
+ "7BvOyk5AQrBt7moO1uWtPA/JuoJPePiJl4kqlRJM2Akq6QIDAQABo4GjMIGgMB0G\n" +
+ "A1UdDgQWBBT6uVG/TOfZhpgz+efLHvEzSfeoFDBxBgNVHSMEajBogBT6uVG/TOfZ\n" +
+ "hpgz+efLHvEzSfeoFKFNpEswSTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUt\n" +
+ "U3RhdGUxEjAQBgNVBAcTCVNvbWUtQ2l0eTERMA8GA1UEChMIU29tZS1PcmeCAQAw\n" +
+ "DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQQFAAOBgQBcIm534U123Hz+rtyYO5uA\n" +
+ "ofd81G6FnTfEAV8Kw9fGyyEbQZclBv34A9JsFKeMvU4OFIaixD7nLZ/NZ+IWbhmZ\n" +
+ "LovmJXyCkOufea73pNiZ+f/4/ScZaIlM/PRycQSqbFNd4j9Wott+08qxHPLpsf3P\n" +
+ "6Mvf0r1PNTY2hwTJLJmKtg==\n" +
+ "-----END CERTIFICATE-----";
+
+ static String serverCertStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICpDCCAg2gAwIBAgIBCDANBgkqhkiG9w0BAQQFADBJMQswCQYDVQQGEwJVUzET\n" +
+ "MBEGA1UECBMKU29tZS1TdGF0ZTESMBAGA1UEBxMJU29tZS1DaXR5MREwDwYDVQQK\n" +
+ "EwhTb21lLU9yZzAeFw0wODEyMDgwMzQzMDRaFw0yODA4MjUwMzQzMDRaMHIxCzAJ\n" +
+ "BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRIwEAYDVQQHEwlTb21lLUNp\n" +
+ "dHkxETAPBgNVBAoTCFNvbWUtT3JnMRMwEQYDVQQLEwpTU0wtU2VydmVyMRIwEAYD\n" +
+ "VQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKWsWxw3\n" +
+ "ot2ZiS2yebiP1Uil5xyEF41pnMasbfnyHR85GdrTch5u7ETMcKTcugAw9qBPPVR6\n" +
+ "YWrMV9AKf5UoGD+a2ZTyG8gkiH7+nQ89+1dTCLMgM9Q/F0cU0c3qCNgOdU6vvszS\n" +
+ "7K+peknfwtmsuCRAkKYDVirQMAVALE+r2XSJAgMBAAGjczBxMAkGA1UdEwQCMAAw\n" +
+ "CwYDVR0PBAQDAgXgMB0GA1UdDgQWBBTtbtv0tVbI+xoGYT8PCLumBNgWVDAfBgNV\n" +
+ "HSMEGDAWgBT6uVG/TOfZhpgz+efLHvEzSfeoFDAXBgNVHREBAf8EDTALgglsb2Nh\n" +
+ "bGhvc3QwDQYJKoZIhvcNAQEEBQADgYEAoqVTciHtcvsUj+YaTct8tUh3aTCsKsac\n" +
+ "PHhfQ+ObjiXSgxsKYTX7ym/wk/wvlbUcbqLKxsu7qrcJitH+H9heV1hEHEu65Uoi\n" +
+ "nRugFruyOrwvAylV8Cm2af7ddilmYJ+sdJA6N2M3xJRxR0G2LFHEXDNEjYReyexn\n" +
+ "JqCpf5uZGOo=\n" +
+ "-----END CERTIFICATE-----";
+
+ static String clientCertStr =
+ "-----BEGIN CERTIFICATE-----\n" +
+ "MIICpDCCAg2gAwIBAgIBCTANBgkqhkiG9w0BAQQFADBJMQswCQYDVQQGEwJVUzET\n" +
+ "MBEGA1UECBMKU29tZS1TdGF0ZTESMBAGA1UEBxMJU29tZS1DaXR5MREwDwYDVQQK\n" +
+ "EwhTb21lLU9yZzAeFw0wODEyMDgwMzQzMjRaFw0yODA4MjUwMzQzMjRaMHIxCzAJ\n" +
+ "BgNVBAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMRIwEAYDVQQHEwlTb21lLUNp\n" +
+ "dHkxETAPBgNVBAoTCFNvbWUtT3JnMRMwEQYDVQQLEwpTU0wtQ2xpZW50MRIwEAYD\n" +
+ "VQQDEwlsb2NhbGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALvwQDas\n" +
+ "JlRO9KNaAC9pIW+5ejqT7KL24Y7HY9gvEjCZLrDyj/gnLSR4KIT3Ab+NRHndO9JV\n" +
+ "8848slshfe/9M0qxo//GyJu5D3xBNZf52zoFYAUVr1kXkqMQrRYc5AdTr6h2olYq\n" +
+ "ktP5KOB4z14fSKtcGd3hZ0O6dY31gqxDkkQbAgMBAAGjczBxMAkGA1UdEwQCMAAw\n" +
+ "CwYDVR0PBAQDAgXgMB0GA1UdDgQWBBTNu8iFqpG9/R2+zWd8/7PpTKgi5jAfBgNV\n" +
+ "HSMEGDAWgBT6uVG/TOfZhpgz+efLHvEzSfeoFDAXBgNVHREBAf8EDTALgglsb2Nh\n" +
+ "bGhvc3QwDQYJKoZIhvcNAQEEBQADgYEAm25gJyqW1JznQ1EyOtTGswBVwfgBOf+F\n" +
+ "HJuBTcflYQLbTD/AETPQJGvZU9tdhuLtbG3OPhR7vSY8zeAbfM3dbH7QFr3r47Gj\n" +
+ "XEH7qM/MX+Z3ifVaC4MeJmrYQkYFSuKeyyKpdRVX4w4nnFHF6OsNASsYrMW6LpxN\n" +
+ "cl/epUcHL7E=\n" +
+ "-----END CERTIFICATE-----";
+
+ static byte serverPrivateExponent[] = {
+ (byte)0x6e, (byte)0xa7, (byte)0x1b, (byte)0x83,
+ (byte)0x51, (byte)0x35, (byte)0x9a, (byte)0x44,
+ (byte)0x7d, (byte)0xf6, (byte)0xe3, (byte)0x89,
+ (byte)0xa0, (byte)0xd7, (byte)0x90, (byte)0x60,
+ (byte)0xa1, (byte)0x4e, (byte)0x27, (byte)0x21,
+ (byte)0xa2, (byte)0x89, (byte)0x74, (byte)0xcc,
+ (byte)0x9d, (byte)0x75, (byte)0x75, (byte)0x4e,
+ (byte)0xc7, (byte)0x82, (byte)0xe3, (byte)0xe3,
+ (byte)0xc3, (byte)0x7d, (byte)0x00, (byte)0x54,
+ (byte)0xec, (byte)0x36, (byte)0xb1, (byte)0xdf,
+ (byte)0x91, (byte)0x9c, (byte)0x7a, (byte)0xc0,
+ (byte)0x62, (byte)0x0a, (byte)0xd6, (byte)0xa9,
+ (byte)0x22, (byte)0x91, (byte)0x4a, (byte)0x29,
+ (byte)0x2e, (byte)0x43, (byte)0xfa, (byte)0x8c,
+ (byte)0xd8, (byte)0xe9, (byte)0xbe, (byte)0xd9,
+ (byte)0x4f, (byte)0xca, (byte)0x23, (byte)0xc6,
+ (byte)0xe4, (byte)0x3f, (byte)0xb8, (byte)0x72,
+ (byte)0xcf, (byte)0x02, (byte)0xfc, (byte)0xf4,
+ (byte)0x58, (byte)0x34, (byte)0x77, (byte)0x76,
+ (byte)0xce, (byte)0x22, (byte)0x44, (byte)0x5f,
+ (byte)0x2d, (byte)0xca, (byte)0xee, (byte)0xf5,
+ (byte)0x43, (byte)0x56, (byte)0x47, (byte)0x71,
+ (byte)0x0b, (byte)0x09, (byte)0x6b, (byte)0x5e,
+ (byte)0xf2, (byte)0xc8, (byte)0xee, (byte)0xd4,
+ (byte)0x6e, (byte)0x44, (byte)0x92, (byte)0x2a,
+ (byte)0x7f, (byte)0xcc, (byte)0xa7, (byte)0xd4,
+ (byte)0x5b, (byte)0xfb, (byte)0xf7, (byte)0x4a,
+ (byte)0xa9, (byte)0xfb, (byte)0x54, (byte)0x18,
+ (byte)0xd5, (byte)0xd5, (byte)0x14, (byte)0xba,
+ (byte)0xa0, (byte)0x1c, (byte)0x13, (byte)0xb3,
+ (byte)0x37, (byte)0x6b, (byte)0x37, (byte)0x59,
+ (byte)0xed, (byte)0xdb, (byte)0x6d, (byte)0xb1
+ };
+
+ static byte serverModulus[] = {
+ (byte)0x00,
+ (byte)0xa5, (byte)0xac, (byte)0x5b, (byte)0x1c,
+ (byte)0x37, (byte)0xa2, (byte)0xdd, (byte)0x99,
+ (byte)0x89, (byte)0x2d, (byte)0xb2, (byte)0x79,
+ (byte)0xb8, (byte)0x8f, (byte)0xd5, (byte)0x48,
+ (byte)0xa5, (byte)0xe7, (byte)0x1c, (byte)0x84,
+ (byte)0x17, (byte)0x8d, (byte)0x69, (byte)0x9c,
+ (byte)0xc6, (byte)0xac, (byte)0x6d, (byte)0xf9,
+ (byte)0xf2, (byte)0x1d, (byte)0x1f, (byte)0x39,
+ (byte)0x19, (byte)0xda, (byte)0xd3, (byte)0x72,
+ (byte)0x1e, (byte)0x6e, (byte)0xec, (byte)0x44,
+ (byte)0xcc, (byte)0x70, (byte)0xa4, (byte)0xdc,
+ (byte)0xba, (byte)0x00, (byte)0x30, (byte)0xf6,
+ (byte)0xa0, (byte)0x4f, (byte)0x3d, (byte)0x54,
+ (byte)0x7a, (byte)0x61, (byte)0x6a, (byte)0xcc,
+ (byte)0x57, (byte)0xd0, (byte)0x0a, (byte)0x7f,
+ (byte)0x95, (byte)0x28, (byte)0x18, (byte)0x3f,
+ (byte)0x9a, (byte)0xd9, (byte)0x94, (byte)0xf2,
+ (byte)0x1b, (byte)0xc8, (byte)0x24, (byte)0x88,
+ (byte)0x7e, (byte)0xfe, (byte)0x9d, (byte)0x0f,
+ (byte)0x3d, (byte)0xfb, (byte)0x57, (byte)0x53,
+ (byte)0x08, (byte)0xb3, (byte)0x20, (byte)0x33,
+ (byte)0xd4, (byte)0x3f, (byte)0x17, (byte)0x47,
+ (byte)0x14, (byte)0xd1, (byte)0xcd, (byte)0xea,
+ (byte)0x08, (byte)0xd8, (byte)0x0e, (byte)0x75,
+ (byte)0x4e, (byte)0xaf, (byte)0xbe, (byte)0xcc,
+ (byte)0xd2, (byte)0xec, (byte)0xaf, (byte)0xa9,
+ (byte)0x7a, (byte)0x49, (byte)0xdf, (byte)0xc2,
+ (byte)0xd9, (byte)0xac, (byte)0xb8, (byte)0x24,
+ (byte)0x40, (byte)0x90, (byte)0xa6, (byte)0x03,
+ (byte)0x56, (byte)0x2a, (byte)0xd0, (byte)0x30,
+ (byte)0x05, (byte)0x40, (byte)0x2c, (byte)0x4f,
+ (byte)0xab, (byte)0xd9, (byte)0x74, (byte)0x89
+ };
+
+ static byte clientPrivateExponent[] = {
+ (byte)0x11, (byte)0xb7, (byte)0x6a, (byte)0x36,
+ (byte)0x3d, (byte)0x30, (byte)0x37, (byte)0xce,
+ (byte)0x61, (byte)0x9d, (byte)0x6c, (byte)0x84,
+ (byte)0x8b, (byte)0xf3, (byte)0x9b, (byte)0x25,
+ (byte)0x4f, (byte)0x14, (byte)0xc8, (byte)0xa4,
+ (byte)0xdd, (byte)0x2f, (byte)0xd7, (byte)0x9a,
+ (byte)0x17, (byte)0xbd, (byte)0x90, (byte)0x19,
+ (byte)0xf7, (byte)0x05, (byte)0xfd, (byte)0xf2,
+ (byte)0xd2, (byte)0xc5, (byte)0xf7, (byte)0x77,
+ (byte)0xbe, (byte)0xea, (byte)0xe2, (byte)0x84,
+ (byte)0x87, (byte)0x97, (byte)0x3a, (byte)0x41,
+ (byte)0x96, (byte)0xb6, (byte)0x99, (byte)0xf8,
+ (byte)0x94, (byte)0x8c, (byte)0x58, (byte)0x71,
+ (byte)0x51, (byte)0x8c, (byte)0xf4, (byte)0x2a,
+ (byte)0x20, (byte)0x9e, (byte)0x1a, (byte)0xa0,
+ (byte)0x26, (byte)0x99, (byte)0x75, (byte)0xd6,
+ (byte)0x31, (byte)0x53, (byte)0x43, (byte)0x39,
+ (byte)0xf5, (byte)0x2a, (byte)0xa6, (byte)0x7e,
+ (byte)0x34, (byte)0x42, (byte)0x51, (byte)0x2a,
+ (byte)0x40, (byte)0x87, (byte)0x03, (byte)0x88,
+ (byte)0x43, (byte)0x69, (byte)0xb2, (byte)0x89,
+ (byte)0x6d, (byte)0x20, (byte)0xbd, (byte)0x7d,
+ (byte)0x71, (byte)0xef, (byte)0x47, (byte)0x0a,
+ (byte)0xdf, (byte)0x06, (byte)0xc1, (byte)0x69,
+ (byte)0x66, (byte)0xa8, (byte)0x22, (byte)0x37,
+ (byte)0x1a, (byte)0x77, (byte)0x1e, (byte)0xc7,
+ (byte)0x94, (byte)0x4e, (byte)0x2c, (byte)0x27,
+ (byte)0x69, (byte)0x45, (byte)0x5e, (byte)0xc8,
+ (byte)0xf8, (byte)0x0c, (byte)0xb7, (byte)0xf8,
+ (byte)0xc0, (byte)0x8f, (byte)0x99, (byte)0xc1,
+ (byte)0xe5, (byte)0x28, (byte)0x9b, (byte)0xf9,
+ (byte)0x4c, (byte)0x94, (byte)0xc6, (byte)0xb1
+ };
+
+ static byte clientModulus[] = {
+ (byte)0x00,
+ (byte)0xbb, (byte)0xf0, (byte)0x40, (byte)0x36,
+ (byte)0xac, (byte)0x26, (byte)0x54, (byte)0x4e,
+ (byte)0xf4, (byte)0xa3, (byte)0x5a, (byte)0x00,
+ (byte)0x2f, (byte)0x69, (byte)0x21, (byte)0x6f,
+ (byte)0xb9, (byte)0x7a, (byte)0x3a, (byte)0x93,
+ (byte)0xec, (byte)0xa2, (byte)0xf6, (byte)0xe1,
+ (byte)0x8e, (byte)0xc7, (byte)0x63, (byte)0xd8,
+ (byte)0x2f, (byte)0x12, (byte)0x30, (byte)0x99,
+ (byte)0x2e, (byte)0xb0, (byte)0xf2, (byte)0x8f,
+ (byte)0xf8, (byte)0x27, (byte)0x2d, (byte)0x24,
+ (byte)0x78, (byte)0x28, (byte)0x84, (byte)0xf7,
+ (byte)0x01, (byte)0xbf, (byte)0x8d, (byte)0x44,
+ (byte)0x79, (byte)0xdd, (byte)0x3b, (byte)0xd2,
+ (byte)0x55, (byte)0xf3, (byte)0xce, (byte)0x3c,
+ (byte)0xb2, (byte)0x5b, (byte)0x21, (byte)0x7d,
+ (byte)0xef, (byte)0xfd, (byte)0x33, (byte)0x4a,
+ (byte)0xb1, (byte)0xa3, (byte)0xff, (byte)0xc6,
+ (byte)0xc8, (byte)0x9b, (byte)0xb9, (byte)0x0f,
+ (byte)0x7c, (byte)0x41, (byte)0x35, (byte)0x97,
+ (byte)0xf9, (byte)0xdb, (byte)0x3a, (byte)0x05,
+ (byte)0x60, (byte)0x05, (byte)0x15, (byte)0xaf,
+ (byte)0x59, (byte)0x17, (byte)0x92, (byte)0xa3,
+ (byte)0x10, (byte)0xad, (byte)0x16, (byte)0x1c,
+ (byte)0xe4, (byte)0x07, (byte)0x53, (byte)0xaf,
+ (byte)0xa8, (byte)0x76, (byte)0xa2, (byte)0x56,
+ (byte)0x2a, (byte)0x92, (byte)0xd3, (byte)0xf9,
+ (byte)0x28, (byte)0xe0, (byte)0x78, (byte)0xcf,
+ (byte)0x5e, (byte)0x1f, (byte)0x48, (byte)0xab,
+ (byte)0x5c, (byte)0x19, (byte)0xdd, (byte)0xe1,
+ (byte)0x67, (byte)0x43, (byte)0xba, (byte)0x75,
+ (byte)0x8d, (byte)0xf5, (byte)0x82, (byte)0xac,
+ (byte)0x43, (byte)0x92, (byte)0x44, (byte)0x1b
+ };
+
+ 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 = getSSLContext(trusedCertStr, serverCertStr,
+ serverModulus, serverPrivateExponent, passphrase);
+ SSLServerSocketFactory sslssf = context.getServerSocketFactory();
+
+ SSLServerSocket sslServerSocket =
+ (SSLServerSocket) sslssf.createServerSocket(serverPort);
+ serverPort = sslServerSocket.getLocalPort();
+
+
+ // enable endpoint identification
+ // ignore, we may test the feature when known how to parse client
+ // hostname
+ //SSLParameters params = sslServerSocket.getSSLParameters();
+ //params.setEndpointIdentificationAlgorithm("HTTPS");
+ //sslServerSocket.setSSLParameters(params);
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
+ sslSocket.setNeedClientAuth(true);
+
+ 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);
+ }
+
+ SSLContext context = getSSLContext(trusedCertStr, clientCertStr,
+ clientModulus, clientPrivateExponent, passphrase);
+
+ SSLSocketFactory sslsf = context.getSocketFactory();
+ SSLSocket sslSocket = (SSLSocket)
+ sslsf.createSocket("localhost", serverPort);
+
+ // enable endpoint identification
+ SSLParameters params = sslSocket.getSSLParameters();
+ params.setEndpointIdentificationAlgorithm("HTTPS");
+ sslSocket.setSSLParameters(params);
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write(280);
+ sslOS.flush();
+ sslIS.read();
+
+ sslSocket.close();
+
+ }
+
+ // get the ssl context
+ private static SSLContext getSSLContext(String trusedCertStr,
+ String keyCertStr, byte[] modulus,
+ byte[] privateExponent, char[] passphrase) throws Exception {
+
+ // generate certificate from cert string
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+
+ ByteArrayInputStream is =
+ new ByteArrayInputStream(trusedCertStr.getBytes());
+ Certificate trusedCert = cf.generateCertificate(is);
+ is.close();
+
+ // create a key store
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(null, null);
+
+ // import the trused cert
+ ks.setCertificateEntry("RSA Export Signer", trusedCert);
+
+ if (keyCertStr != null) {
+ // generate the private key.
+ RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(
+ new BigInteger(modulus),
+ new BigInteger(privateExponent));
+ 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 = new Certificate[2];
+ chain[0] = keyCert;
+ chain[1] = trusedCert;
+
+ // import the key entry.
+ ks.setKeyEntry("Whatever", priKey, passphrase, chain);
+ }
+
+ // create SSL context
+ TrustManagerFactory tmf =
+ TrustManagerFactory.getInstance("SunX509");
+ tmf.init(ks);
+
+ TrustManager tms[] = tmf.getTrustManagers();
+ if (tms == null || tms.length == 0) {
+ throw new Exception("unexpected trust manager implementation");
+ } else {
+ if (!(tms[0] instanceof X509ExtendedTrustManager)) {
+ throw new Exception("unexpected trust manager implementation: "
+ + tms[0].getClass().getCanonicalName());
+ }
+ }
+
+
+ SSLContext ctx = SSLContext.getInstance("TLS");
+
+ if (keyCertStr != null) {
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, passphrase);
+
+ ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+ } else {
+ ctx.init(null, tmf.getTrustManagers(), null);
+ }
+
+ return ctx;
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+
+ // 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");
+
+ /*
+ * Start the tests.
+ */
+ new SunX509ExtendedTM();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ SunX509ExtendedTM() throws Exception {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ serverThread.join();
+ } else {
+ clientThread.join();
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ *
+ * If the main thread excepted, that propagates back
+ * immediately. If the other thread threw an exception, we
+ * should report back.
+ */
+ if (serverException != null)
+ throw serverException;
+ if (clientException != null)
+ throw clientException;
+ }
+
+ 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 {
+ doServerSide();
+ }
+ }
+
+ 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 {
+ doClientSide();
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/X509ExtendedTMEnabled.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,384 @@
+/*
+ * Copyright (c) 2010, 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 6916074
+ * @summary Add support for TLS 1.2
+ *
+ * Ensure that the SunJSSE provider enables the X509ExtendedTrustManager.
+ */
+
+import java.io.*;
+import java.net.*;
+import javax.net.ssl.*;
+import java.security.cert.*;
+import java.security.*;
+
+public class X509ExtendedTMEnabled {
+
+ /*
+ * =============================================================
+ * 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 = true;
+
+ /*
+ * Where do we find the keystores?
+ */
+ static String pathToStores = "../../../../../../../etc";
+ static String keyStoreFile = "keystore";
+ static String trustStoreFile = "truststore";
+ static String passwd = "passphrase";
+ private final static char[] cpasswd = "passphrase".toCharArray();
+
+ /*
+ * 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 {
+ SSLServerSocketFactory sslssf =
+ getContext(true).getServerSocketFactory();
+ SSLServerSocket sslServerSocket =
+ (SSLServerSocket) sslssf.createServerSocket(serverPort);
+ serverPort = sslServerSocket.getLocalPort();
+
+ // enable endpoint identification
+ // ignore, we may test the feature when known how to parse client
+ // hostname
+ //SSLParameters params = sslServerSocket.getSSLParameters();
+ //params.setEndpointIdentificationAlgorithm("HTTPS");
+ //sslServerSocket.setSSLParameters(params);
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
+ sslSocket.setNeedClientAuth(true);
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslIS.read();
+ sslOS.write(85);
+ sslOS.flush();
+
+ sslSocket.close();
+
+ if (!serverTM.wasServerChecked() && serverTM.wasClientChecked()) {
+ System.out.println("SERVER TEST PASSED!");
+ } else {
+ throw new Exception("SERVER TEST FAILED! " +
+ !serverTM.wasServerChecked() + " " +
+ serverTM.wasClientChecked());
+ }
+ }
+
+ /*
+ * 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);
+ }
+
+ SSLSocketFactory sslsf = getContext(false).getSocketFactory();
+ SSLSocket sslSocket = (SSLSocket)
+ sslsf.createSocket("localhost", serverPort);
+
+ // enable endpoint identification
+ SSLParameters params = sslSocket.getSSLParameters();
+ params.setEndpointIdentificationAlgorithm("HTTPS");
+ sslSocket.setSSLParameters(params);
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write(280);
+ sslOS.flush();
+ sslIS.read();
+
+ sslSocket.close();
+
+ if (clientTM.wasServerChecked() && !clientTM.wasClientChecked()) {
+ System.out.println("CLIENT TEST PASSED!");
+ } else {
+ throw new Exception("CLIENT TEST FAILED! " +
+ clientTM.wasServerChecked() + " " +
+ !clientTM.wasClientChecked());
+ }
+ }
+
+ MyExtendedX509TM serverTM;
+ MyExtendedX509TM clientTM;
+
+ private SSLContext getContext(boolean server) throws Exception {
+ String keyFilename =
+ System.getProperty("test.src", "./") + "/" + pathToStores +
+ "/" + keyStoreFile;
+ String trustFilename =
+ System.getProperty("test.src", "./") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(new FileInputStream(keyFilename), cpasswd);
+ kmf.init(ks, cpasswd);
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ KeyStore ts = KeyStore.getInstance("JKS");
+ ts.load(new FileInputStream(trustFilename), cpasswd);
+ tmf.init(ts);
+
+ TrustManager tms[] = tmf.getTrustManagers();
+ if (tms == null || tms.length == 0) {
+ throw new Exception("unexpected trust manager implementation");
+ } else {
+ if (!(tms[0] instanceof X509TrustManager)) {
+ throw new Exception("unexpected trust manager implementation: "
+ + tms[0].getClass().getCanonicalName());
+ }
+ }
+
+ if (server) {
+ serverTM = new MyExtendedX509TM((X509TrustManager)tms[0]);
+
+ tms = new TrustManager[] {serverTM};
+ } else {
+ clientTM = new MyExtendedX509TM((X509TrustManager)tms[0]);
+
+ tms = new TrustManager[] {clientTM};
+ }
+
+ SSLContext ctx = SSLContext.getInstance("TLS");
+ ctx.init(kmf.getKeyManagers(), tms, null);
+
+ return ctx;
+ }
+
+ static class MyExtendedX509TM extends X509ExtendedTrustManager
+ implements X509TrustManager {
+
+ X509TrustManager tm;
+
+ boolean clientChecked;
+ boolean serverChecked;
+
+ MyExtendedX509TM(X509TrustManager tm) {
+ clientChecked = false;
+ serverChecked = false;
+
+ this.tm = tm;
+ }
+
+ public boolean wasClientChecked() {
+ return clientChecked;
+ }
+
+ public boolean wasServerChecked() {
+ return serverChecked;
+ }
+
+
+ public void checkClientTrusted(X509Certificate chain[], String authType)
+ throws CertificateException {
+ tm.checkClientTrusted(chain, authType);
+ }
+
+ public void checkServerTrusted(X509Certificate chain[], String authType)
+ throws CertificateException {
+ tm.checkServerTrusted(chain, authType);
+ }
+
+ public X509Certificate[] getAcceptedIssuers() {
+ return tm.getAcceptedIssuers();
+ }
+
+ public void checkClientTrusted(X509Certificate[] chain, String authType,
+ Socket socket) throws CertificateException {
+ clientChecked = true;
+ tm.checkClientTrusted(chain, authType);
+ }
+
+ public void checkServerTrusted(X509Certificate[] chain, String authType,
+ Socket socket) throws CertificateException {
+ serverChecked = true;
+ tm.checkServerTrusted(chain, authType);
+ }
+
+ public void checkClientTrusted(X509Certificate[] chain, String authType,
+ SSLEngine engine) throws CertificateException {
+ clientChecked = true;
+ tm.checkClientTrusted(chain, authType);
+ }
+
+ public void checkServerTrusted(X509Certificate[] chain, String authType,
+ SSLEngine engine) throws CertificateException {
+ serverChecked = true;
+ tm.checkServerTrusted(chain, authType);
+ }
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+
+ // 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");
+
+ /*
+ * Start the tests.
+ */
+ new X509ExtendedTMEnabled();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ X509ExtendedTMEnabled() throws Exception {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ serverThread.join();
+ } else {
+ clientThread.join();
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ *
+ * If the main thread excepted, that propagates back
+ * immediately. If the other thread threw an exception, we
+ * should report back.
+ */
+ if (serverException != null)
+ throw serverException;
+ if (clientException != null)
+ throw clientException;
+ }
+
+ 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 {
+ doServerSide();
+ }
+ }
+
+ 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 {
+ doClientSide();
+ }
+ }
+}
+
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/CheckMyTrustedKeystore.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/CheckMyTrustedKeystore.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2010, 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
@@ -26,6 +26,8 @@
* @bug 4329114
* @summary Need better way of reflecting the reason when a chain is
* rejected as untrusted.
+ * @ignore JSSE supports algorithm constraints with CR 6916074,
+ * need to update this test case in JDK 7 soon
* This is a serious hack job!
* @author Brad Wetmore
*/
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/Basics.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/Basics.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, 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
@@ -26,6 +26,8 @@
* @bug 4495742
* @summary Add non-blocking SSL/TLS functionality, usable with any
* I/O abstraction
+ * @ignore JSSE supported cipher suites are changed with CR 6916074,
+ * need to update this test case in JDK 7 soon
*
* This is intended to test many of the basic API calls to the SSLEngine
* interface. This doesn't really exercise much of the SSL code.
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/TestAllSuites.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/TestAllSuites.java Tue Nov 02 19:40:45 2010 -0700
@@ -24,6 +24,8 @@
/*
* @test
* @bug 4495742
+ * @ignore JSSE supported cipher suites are changed with CR 6916074,
+ * need to update this test case in JDK 7 soon
* @run main/timeout=180 TestAllSuites
* @summary Add non-blocking SSL/TLS functionality, usable with any
* I/O abstraction
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/EmptyCertificateAuthorities.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2010, 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 4873188
+ * @summary Support TLS 1.1
+ * @run main/othervm -Djavax.net.debug=all EmptyCertificateAuthorities
+ *
+ * @author Xuelei Fan
+ */
+
+import java.io.*;
+import java.net.*;
+import java.security.*;
+import java.security.cert.*;
+import javax.net.ssl.*;
+
+public class EmptyCertificateAuthorities {
+
+ /*
+ * =============================================================
+ * 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?
+ */
+ static String pathToStores = "/../../../../etc";
+ static String keyStoreFile = "keystore";
+ static String trustStoreFile = "truststore";
+ static String passwd = "passphrase";
+
+ /*
+ * 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 {
+ SSLServerSocketFactory sslssf = getSSLServerSF();
+ SSLServerSocket sslServerSocket =
+ (SSLServerSocket) sslssf.createServerSocket(serverPort);
+
+ // require client authentication.
+ sslServerSocket.setNeedClientAuth(true);
+
+ 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);
+ }
+
+ SSLSocketFactory sslsf =
+ (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocket sslSocket = (SSLSocket)
+ sslsf.createSocket("localhost", serverPort);
+
+ // enable TLSv1.1 only
+ sslSocket.setEnabledProtocols(new String[] {"TLSv1.1"});
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write('B');
+ sslOS.flush();
+ sslIS.read();
+
+ sslSocket.close();
+ }
+
+ private SSLServerSocketFactory getSSLServerSF() throws Exception {
+
+ char [] password =
+ System.getProperty("javax.net.ssl.keyStorePassword").toCharArray();
+ String keyFilename = System.getProperty("javax.net.ssl.keyStore");
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(new FileInputStream(keyFilename), password);
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
+ kmf.init(ks, password);
+
+ KeyManager[] kms = kmf.getKeyManagers();
+ TrustManager[] tms = new MyX509TM[] {new MyX509TM()};
+
+ SSLContext ctx = SSLContext.getInstance("TLS");
+ ctx.init(kms, tms, null);
+
+ return ctx.getServerSocketFactory();
+ }
+
+
+ static class MyX509TM implements X509TrustManager {
+ X509TrustManager tm;
+
+ public void checkClientTrusted(X509Certificate[] chain,
+ String authType) throws CertificateException {
+ if (tm == null) {
+ initialize();
+ }
+ tm.checkClientTrusted(chain, authType);
+ }
+
+ public void checkServerTrusted(X509Certificate[] chain,
+ String authType) throws CertificateException {
+ if (tm == null) {
+ initialize();
+ }
+ tm.checkServerTrusted(chain, authType);
+ }
+
+ public X509Certificate[] getAcceptedIssuers() {
+ // always return empty array
+ return new X509Certificate[0];
+ }
+
+ private void initialize() throws CertificateException {
+ String passwd =
+ System.getProperty("javax.net.ssl.trustStorePassword");
+ char [] password = passwd.toCharArray();
+ String trustFilename =
+ System.getProperty("javax.net.ssl.trustStore");
+
+ try {
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(new FileInputStream(trustFilename), password);
+
+ TrustManagerFactory tmf =
+ TrustManagerFactory.getInstance("PKIX");
+ tmf.init(ks);
+ tm = (X509TrustManager)tmf.getTrustManagers()[0];
+ } catch (Exception e) {
+ throw new CertificateException("Unable to initialize TM");
+ }
+
+ }
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+
+ // 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 {
+ String keyFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + keyStoreFile;
+ String trustFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ System.setProperty("javax.net.ssl.keyStore", keyFilename);
+ System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+ System.setProperty("javax.net.ssl.trustStore", trustFilename);
+ System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+ if (debug)
+ System.setProperty("javax.net.debug", "all");
+
+ /*
+ * Start the tests.
+ */
+ new EmptyCertificateAuthorities();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ EmptyCertificateAuthorities() 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;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/ExportableBlockCipher.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2010, 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 4873188
+ * @summary Support TLS 1.1
+ * @run main/othervm -Djavax.net.debug=all ExportableBlockCipher
+ *
+ * @author Xuelei Fan
+ */
+
+import java.io.*;
+import java.net.*;
+import javax.net.ssl.*;
+
+public class ExportableBlockCipher {
+
+ /*
+ * =============================================================
+ * 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?
+ */
+ static String pathToStores = "/../../../../etc";
+ static String keyStoreFile = "keystore";
+ static String trustStoreFile = "truststore";
+ static String passwd = "passphrase";
+
+ /*
+ * 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 {
+ SSLServerSocketFactory sslssf =
+ (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+ 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();
+
+ boolean interrupted = false;
+ try {
+ sslIS.read();
+ sslOS.write('A');
+ sslOS.flush();
+ } catch (SSLException ssle) {
+ // get the expected exception
+ interrupted = true;
+ } finally {
+ sslSocket.close();
+ }
+
+ if (!interrupted) {
+ throw new SSLHandshakeException(
+ "A weak cipher suite is negotiated, " +
+ "TLSv1.1 must not negotiate the exportable cipher suites.");
+ }
+ }
+
+ /*
+ * 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);
+ }
+
+ SSLSocketFactory sslsf =
+ (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocket sslSocket = (SSLSocket)
+ sslsf.createSocket("localhost", serverPort);
+
+ // enable TLSv1.1 only
+ sslSocket.setEnabledProtocols(new String[] {"TLSv1.1"});
+
+ // enable a exportable block cipher
+ sslSocket.setEnabledCipherSuites(
+ new String[] {"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"});
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ boolean interrupted = false;
+ try {
+ sslOS.write('B');
+ sslOS.flush();
+ sslIS.read();
+ } catch (SSLException ssle) {
+ // get the expected exception
+ interrupted = true;
+ } finally {
+ sslSocket.close();
+ }
+
+ if (!interrupted) {
+ throw new SSLHandshakeException(
+ "A weak cipher suite is negotiated, " +
+ "TLSv1.1 must not negotiate the exportable cipher suites.");
+ }
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+
+ // 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 {
+ String keyFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + keyStoreFile;
+ String trustFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ System.setProperty("javax.net.ssl.keyStore", keyFilename);
+ System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+ System.setProperty("javax.net.ssl.trustStore", trustFilename);
+ System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+ if (debug)
+ System.setProperty("javax.net.debug", "all");
+
+ /*
+ * Start the tests.
+ */
+ new ExportableBlockCipher();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ ExportableBlockCipher() 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;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/ExportableStreamCipher.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2010, 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 4873188
+ * @summary Support TLS 1.1
+ * @run main/othervm -Djavax.net.debug=all ExportableStreamCipher
+ *
+ * @author Xuelei Fan
+ */
+
+import java.io.*;
+import java.net.*;
+import javax.net.ssl.*;
+
+public class ExportableStreamCipher {
+
+ /*
+ * =============================================================
+ * 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?
+ */
+ static String pathToStores = "/../../../../etc";
+ static String keyStoreFile = "keystore";
+ static String trustStoreFile = "truststore";
+ static String passwd = "passphrase";
+
+ /*
+ * 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 {
+ SSLServerSocketFactory sslssf =
+ (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+ 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();
+
+ boolean interrupted = false;
+ try {
+ sslIS.read();
+ sslOS.write('A');
+ sslOS.flush();
+ } catch (SSLException ssle) {
+ // get the expected exception
+ interrupted = true;
+ } finally {
+ sslSocket.close();
+ }
+
+ if (!interrupted) {
+ throw new SSLHandshakeException(
+ "A weak cipher suite is negotiated, " +
+ "TLSv1.1 must not negotiate the exportable cipher suites.");
+ }
+ }
+
+ /*
+ * 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);
+ }
+
+ SSLSocketFactory sslsf =
+ (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocket sslSocket = (SSLSocket)
+ sslsf.createSocket("localhost", serverPort);
+
+ // enable TLSv1.1 only
+ sslSocket.setEnabledProtocols(new String[] {"TLSv1.1"});
+
+ // enable a exportable stream cipher
+ sslSocket.setEnabledCipherSuites(
+ new String[] {"SSL_RSA_EXPORT_WITH_RC4_40_MD5"});
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ boolean interrupted = false;
+ try {
+ sslOS.write('B');
+ sslOS.flush();
+ sslIS.read();
+ } catch (SSLException ssle) {
+ // get the expected exception
+ interrupted = true;
+ } finally {
+ sslSocket.close();
+ }
+
+ if (!interrupted) {
+ throw new SSLHandshakeException(
+ "A weak cipher suite is negotiated, " +
+ "TLSv1.1 must not negotiate the exportable cipher suites.");
+ }
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+
+ // 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 {
+ String keyFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + keyStoreFile;
+ String trustFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ System.setProperty("javax.net.ssl.keyStore", keyFilename);
+ System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+ System.setProperty("javax.net.ssl.trustStore", trustFilename);
+ System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+ if (debug)
+ System.setProperty("javax.net.debug", "all");
+
+ /*
+ * Start the tests.
+ */
+ new ExportableStreamCipher();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ ExportableStreamCipher() 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;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/GenericBlockCipher.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2010, 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 4873188
+ * @summary Support TLS 1.1
+ * @run main/othervm -Djavax.net.debug=all GenericBlockCipher
+ *
+ * @author Xuelei Fan
+ */
+
+import java.io.*;
+import java.net.*;
+import javax.net.ssl.*;
+
+public class GenericBlockCipher {
+
+ /*
+ * =============================================================
+ * 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?
+ */
+ static String pathToStores = "/../../../../etc";
+ static String keyStoreFile = "keystore";
+ static String trustStoreFile = "truststore";
+ static String passwd = "passphrase";
+
+ /*
+ * 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 {
+ SSLServerSocketFactory sslssf =
+ (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+ 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);
+ }
+
+ SSLSocketFactory sslsf =
+ (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocket sslSocket = (SSLSocket)
+ sslsf.createSocket("localhost", serverPort);
+
+ // enable TLSv1.1 only
+ sslSocket.setEnabledProtocols(new String[] {"TLSv1.1"});
+
+ // enable a block cipher
+ sslSocket.setEnabledCipherSuites(
+ new String[] {"TLS_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
+ */
+
+ // 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 {
+ String keyFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + keyStoreFile;
+ String trustFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ System.setProperty("javax.net.ssl.keyStore", keyFilename);
+ System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+ System.setProperty("javax.net.ssl.trustStore", trustFilename);
+ System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+ if (debug)
+ System.setProperty("javax.net.debug", "all");
+
+ /*
+ * Start the tests.
+ */
+ new GenericBlockCipher();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ GenericBlockCipher() 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;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/GenericStreamCipher.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2010, 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 4873188
+ * @summary Support TLS 1.1
+ * @run main/othervm -Djavax.net.debug=all GenericStreamCipher
+ *
+ * @author Xuelei Fan
+ */
+
+import java.io.*;
+import java.net.*;
+import javax.net.ssl.*;
+
+public class GenericStreamCipher {
+
+ /*
+ * =============================================================
+ * 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?
+ */
+ static String pathToStores = "/../../../../etc";
+ static String keyStoreFile = "keystore";
+ static String trustStoreFile = "truststore";
+ static String passwd = "passphrase";
+
+ /*
+ * 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 {
+ SSLServerSocketFactory sslssf =
+ (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
+ 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);
+ }
+
+ SSLSocketFactory sslsf =
+ (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocket sslSocket = (SSLSocket)
+ sslsf.createSocket("localhost", serverPort);
+
+ // enable TLSv1.1 only
+ sslSocket.setEnabledProtocols(new String[] {"TLSv1.1"});
+
+ // enable a stream cipher
+ sslSocket.setEnabledCipherSuites(
+ new String[] {"SSL_RSA_WITH_RC4_128_MD5"});
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write('B');
+ sslOS.flush();
+ sslIS.read();
+
+ sslSocket.close();
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+
+ // 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 {
+ String keyFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + keyStoreFile;
+ String trustFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ System.setProperty("javax.net.ssl.keyStore", keyFilename);
+ System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+ System.setProperty("javax.net.ssl.trustStore", trustFilename);
+ System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+
+ if (debug)
+ System.setProperty("javax.net.debug", "all");
+
+ /*
+ * Start the tests.
+ */
+ new GenericStreamCipher();
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ GenericStreamCipher() 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;
+ }
+ }
+ }
+}
--- a/jdk/test/sun/security/ssl/sanity/ciphersuites/CheckCipherSuites.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/ssl/sanity/ciphersuites/CheckCipherSuites.java Tue Nov 02 19:40:45 2010 -0700
@@ -25,6 +25,8 @@
* @test
* @bug 4750141 4895631
* @summary Check enabled and supported ciphersuites are correct
+ * @ignore JSSE supported cipher suites are changed with CR 6916074,
+ * need to update this test case in JDK 7 soon
*/
import java.util.*;
--- a/jdk/test/sun/security/ssl/sanity/interop/CipherTest.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/ssl/sanity/interop/CipherTest.java Tue Nov 02 19:40:45 2010 -0700
@@ -120,6 +120,13 @@
return false;
}
+ // ignore exportable cipher suite for TLSv1.1
+ if (protocol.equals("TLSv1.1")) {
+ if(cipherSuite.indexOf("_EXPORT_") != -1) {
+ return false;
+ }
+ }
+
return true;
}
@@ -149,18 +156,14 @@
cipherSuites.length * protocols.length * clientAuths.length);
for (int i = 0; i < cipherSuites.length; i++) {
String cipherSuite = cipherSuites[i];
- if (peerFactory.isSupported(cipherSuite) == false) {
- continue;
- }
- // skip kerberos cipher suites
- if (cipherSuite.startsWith("TLS_KRB5")) {
- continue;
- }
+
for (int j = 0; j < protocols.length; j++) {
String protocol = protocols[j];
- if (protocol.equals("SSLv2Hello")) {
+
+ if (!peerFactory.isSupported(cipherSuite, protocol)) {
continue;
}
+
for (int k = 0; k < clientAuths.length; k++) {
String clientAuth = clientAuths[k];
if ((clientAuth != null) &&
@@ -297,7 +300,7 @@
throws Exception {
long time = System.currentTimeMillis();
String relPath;
- if ((args.length > 0) && args[0].equals("sh")) {
+ if ((args != null) && (args.length > 0) && args[0].equals("sh")) {
relPath = pathToStoresSH;
} else {
relPath = pathToStores;
@@ -336,7 +339,36 @@
abstract Server newServer(CipherTest cipherTest) throws Exception;
- boolean isSupported(String cipherSuite) {
+ boolean isSupported(String cipherSuite, String protocol) {
+ // skip kerberos cipher suites
+ if (cipherSuite.startsWith("TLS_KRB5")) {
+ System.out.println("Skipping unsupported test for " +
+ cipherSuite + " of " + protocol);
+ return false;
+ }
+
+ // skip SSLv2Hello protocol
+ if (protocol.equals("SSLv2Hello")) {
+ System.out.println("Skipping unsupported test for " +
+ cipherSuite + " of " + protocol);
+ return false;
+ }
+
+ // ignore exportable cipher suite for TLSv1.1
+ if (protocol.equals("TLSv1.1")) {
+ if (cipherSuite.indexOf("_EXPORT_WITH") != -1) {
+ System.out.println("Skipping obsoleted test for " +
+ cipherSuite + " of " + protocol);
+ return false;
+ }
+ }
+
+ // ignore obsoleted cipher suite for the specified protocol
+ // TODO
+
+ // ignore unsupported cipher suite for the specified protocol
+ // TODO
+
return true;
}
}
--- a/jdk/test/sun/security/ssl/sanity/interop/ClientJSSEServerJSSE.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/ssl/sanity/interop/ClientJSSEServerJSSE.java Tue Nov 02 19:40:45 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2010, 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 @@
* @test
* @bug 4496785
* @summary Verify that all ciphersuites work in all configurations
+ * @ignore JSSE supported cipher suites are changed with CR 6916074,
+ * need to update this test case in JDK 7 soon
* @author Andreas Sterbenz
* @run main/othervm/timeout=300 ClientJSSEServerJSSE
*/
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressDNSIdentities.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressDNSIdentities.java Tue Nov 02 19:40:45 2010 -0700
@@ -713,13 +713,16 @@
http = (HttpsURLConnection)url.openConnection();
int respCode = http.getResponseCode();
- System.out.println("respCode = "+respCode);
+ System.out.println("respCode = " + respCode);
throw new Exception("Unexpectly found subject alternative name " +
"matching IP address");
} catch (SSLHandshakeException sslhe) {
// no subject alternative names matching IP address 127.0.0.1 found
// that's the expected exception, ignore it.
+ } catch (IOException ioe) {
+ // HttpsClient may throw IOE during checking URL spoofing,
+ // that's the expected exception, ignore it.
} finally {
if (http != null) {
http.disconnect();
--- a/jdk/test/sun/util/logging/PlatformLoggerTest.java Tue Nov 02 12:45:49 2010 -0700
+++ b/jdk/test/sun/util/logging/PlatformLoggerTest.java Tue Nov 02 19:40:45 2010 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6882376
+ * @bug 6882376 6985460
* @summary Test if java.util.logging.Logger is created before and after
* logging is enabled. Also validate some basic PlatformLogger
* operations.
@@ -43,6 +43,8 @@
final String GOO_PLATFORM_LOGGER = "test.platformlogger.goo";
final String BAR_LOGGER = "test.logger.bar";
PlatformLogger goo = PlatformLogger.getLogger(GOO_PLATFORM_LOGGER);
+ // test the PlatformLogger methods
+ testLogMethods(goo);
// Create a platform logger using the default
PlatformLogger foo = PlatformLogger.getLogger(FOO_PLATFORM_LOGGER);
@@ -56,6 +58,10 @@
PlatformLogger bar = PlatformLogger.getLogger(BAR_PLATFORM_LOGGER);
checkPlatformLogger(bar, BAR_PLATFORM_LOGGER);
+ // test the PlatformLogger methods
+ testLogMethods(goo);
+ testLogMethods(bar);
+
checkLogger(FOO_PLATFORM_LOGGER, Level.FINER);
checkLogger(BAR_PLATFORM_LOGGER, Level.FINER);
@@ -64,6 +70,7 @@
foo.setLevel(PlatformLogger.SEVERE);
checkLogger(FOO_PLATFORM_LOGGER, Level.SEVERE);
+
}
private static void checkPlatformLogger(PlatformLogger logger, String name) {
@@ -108,4 +115,33 @@
logger.getName() + " " + logger.getLevel());
}
}
+
+ private static void testLogMethods(PlatformLogger logger) {
+ logger.severe("Test severe(String, Object...) {0} {1}", new Long(1), "string");
+ // test Object[]
+ logger.severe("Test severe(String, Object...) {0}", (Object[]) getPoints());
+ logger.warning("Test warning(String, Throwable)", new Throwable("Testing"));
+ logger.info("Test info(String)");
+ }
+
+ static Point[] getPoints() {
+ Point[] res = new Point[3];
+ res[0] = new Point(0,0);
+ res[1] = new Point(1,1);
+ res[2] = new Point(2,2);
+ return res;
+ }
+
+ static class Point {
+ final int x;
+ final int y;
+ public Point(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+ public String toString() {
+ return "{x="+x + ", y=" + y + "}";
+ }
+ }
+
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/util/logging/SourceClassName.java Tue Nov 02 19:40:45 2010 -0700
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2010, 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 6985460
+ * @summary Test the source class name and method output by the platform
+ * logger.
+ *
+ * @compile -XDignore.symbol.file SourceClassName.java
+ * @run main/othervm SourceClassName
+ */
+
+import java.util.logging.*;
+import java.io.*;
+import sun.util.logging.PlatformLogger;
+
+public class SourceClassName {
+ public static void main(String[] args) throws Exception {
+ File dir = new File(System.getProperty("user.dir", "."));
+ File log = new File(dir, "testlog.txt");
+ PrintStream logps = new PrintStream(log);
+ writeLogRecords(logps);
+ checkLogRecords(log);
+ }
+
+ private static void writeLogRecords(PrintStream logps) throws Exception {
+ PrintStream err = System.err;
+ try {
+ System.setErr(logps);
+
+ Object[] params = new Object[] { new Long(1), "string"};
+ PlatformLogger plog = PlatformLogger.getLogger("test.log.foo");
+ plog.severe("Log message {0} {1}", (Object[]) params);
+
+ // create a java.util.logging.Logger
+ // now java.util.logging.Logger should be created for each platform logger
+ Logger logger = Logger.getLogger("test.log.bar");
+ logger.log(Level.SEVERE, "Log message {0} {1}", params);
+
+ plog.severe("Log message {0} {1}", (Object[]) params);
+ } finally {
+ logps.flush();
+ logps.close();
+ System.setErr(err);
+ }
+ }
+
+ private static void checkLogRecords(File log) throws Exception {
+ System.out.println("Checking log records in file: " + log);
+ FileInputStream in = new FileInputStream(log);
+ String EXPECTED_LOG = "SEVERE: Log message 1 string";
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ String line;
+ String[] record = new String[2];
+ int count = 0;
+ int i = 0;
+ while ((line = reader.readLine()) != null) {
+ line = line.trim();
+ System.out.println(line);
+ record[i++] = line;
+ if (i == 2) {
+ i = 0;
+ count++;
+ // check source class name and method
+ String[] ss = record[0].split("\\s+");
+ int len = ss.length;
+ if (!ss[len-2].equals("SourceClassName") ||
+ !ss[len-1].equals("writeLogRecords")) {
+ throw new RuntimeException("Unexpected source: " +
+ ss[len-2] + " " + ss[len-1]);
+ }
+
+ // check log message
+ if (!record[1].equals(EXPECTED_LOG)) {
+ throw new RuntimeException("Unexpected log: " + record[1]);
+ }
+ }
+ }
+ if (count != 3) {
+ throw new RuntimeException("Unexpected number of records: " + count);
+ }
+ } finally {
+ in.close();
+ }
+ }
+}