--- a/jdk/make/tools/CharsetMapping/Big5.c2b Tue Apr 20 16:50:10 2010 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-#Add the following 5 characters which are duplicated
-#or have conflicts with other characters.
-0xA1C4 0xFF3F #REGWARN Fallback 0xA1C4 SPACING UNDERSCORE
-0xA2AC 0x2571 #REGWARN Fallback 0xA2AC LT DIAG UP RIGHT TO LOW LEFT
-0xA2AD 0x2572 #REGWARN Fallback 0xA2AD LT DIAG UP LEFT TO LOW RIGHT
-0xA451 0x5341 #REGWARN Fallback 0xA451 HANGZHOU NUMERAL TEN
-0xA4CA 0x5345 #REGWARN Fallback 0xA4CA HANGZHOU NUMERAL THIRTY
-#
--- a/jdk/make/tools/CharsetMapping/Big5.map Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/make/tools/CharsetMapping/Big5.map Tue Apr 20 16:51:13 2010 -0700
@@ -13830,8 +13830,21 @@
0xF9D4 0x9F49 # <CJK>
0xF9D5 0x9F98 # <CJK>
#
+# from Big5.b2c-irreversible
+#
0xA15A 0xFF3F #SPACING UNDERSCORE
0xA1FE 0x2571 #LT DIAG UP RIGHT TO LOW LEFT
0xA240 0x2572 #LT DIAG UP LEFT TO LOW RIGHTG
0xA2CC 0x5341 #HANGHZOU NUMERAL TEN
0xA2CE 0x5345 #HANGZHOU NUMERAL THIRTY
+#
+# Add the following 5 characters from Big5.c2b-irreversible
+# It appears these 5 should be here to be the round-trip
+# for these 5 characters. Above 5 are the b->c only nrt.
+#
+0xA1C4 0xFF3F
+0xA2AC 0x2571
+0xA2AD 0x2572
+0xA451 0x5341
+0xA4CA 0x5345
+#
--- a/jdk/src/share/classes/java/net/NetworkInterface.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/java/net/NetworkInterface.java Tue Apr 20 16:51:13 2010 -0700
@@ -221,11 +221,12 @@
* A display name is a human readable String describing the network
* device.
*
- * @return the display name of this network interface,
- * or null if no display name is available.
+ * @return a non-empty string representing the display name of this network
+ * interface, or null if no display name is available.
*/
public String getDisplayName() {
- return displayName;
+ /* strict TCK conformance */
+ return "".equals(displayName) ? null : displayName;
}
/**
--- a/jdk/src/share/classes/sun/misc/SharedSecrets.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/misc/SharedSecrets.java Tue Apr 20 16:51:13 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2002-2010 Sun Microsystems, Inc. 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
@@ -29,6 +29,7 @@
import java.io.Console;
import java.io.File;
import java.io.FileDescriptor;
+import java.security.ProtectionDomain;
/** A repository of "shared secrets", which are a mechanism for
calling implementation-private methods in another package without
@@ -121,6 +122,8 @@
public static JavaSecurityProtectionDomainAccess
getJavaSecurityProtectionDomainAccess() {
+ if (javaSecurityProtectionDomainAccess == null)
+ unsafe.ensureClassInitialized(ProtectionDomain.class);
return javaSecurityProtectionDomainAccess;
}
}
--- a/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java Tue Apr 20 16:51:13 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005-2010 Sun Microsystems, Inc. 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
@@ -77,26 +77,34 @@
if (DEBUG) err.printStackTrace();
return null;
}
- String gssLib = System.getProperty(LIB_PROP);
- if (gssLib == null || gssLib.trim().equals("")) {
+ String gssLibs[] = new String[0];
+ String defaultLib = System.getProperty(LIB_PROP);
+ if (defaultLib == null || defaultLib.trim().equals("")) {
String osname = System.getProperty("os.name");
if (osname.startsWith("SunOS")) {
- gssLib = "libgss.so";
+ gssLibs = new String[]{ "libgss.so" };
} else if (osname.startsWith("Linux")) {
- gssLib = "libgssapi.so";
+ gssLibs = new String[]{
+ "libgssapi.so",
+ "libgssapi_krb5.so",
+ };
}
+ } else {
+ gssLibs = new String[]{ defaultLib };
}
- if (GSSLibStub.init(gssLib)) {
- debug("Loaded GSS library: " + gssLib);
- Oid[] mechs = GSSLibStub.indicateMechs();
- HashMap<String, String> map =
- new HashMap<String, String>();
- for (int i = 0; i < mechs.length; i++) {
- debug("Native MF for " + mechs[i]);
- map.put("GssApiMechanism." + mechs[i],
- MF_CLASS);
+ for (String libName: gssLibs) {
+ if (GSSLibStub.init(libName)) {
+ debug("Loaded GSS library: " + libName);
+ Oid[] mechs = GSSLibStub.indicateMechs();
+ HashMap<String, String> map =
+ new HashMap<String, String>();
+ for (int i = 0; i < mechs.length; i++) {
+ debug("Native MF for " + mechs[i]);
+ map.put("GssApiMechanism." + mechs[i],
+ MF_CLASS);
+ }
+ return map;
}
- return map;
}
return null;
}
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Cipher.java Tue Apr 20 16:51:13 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc. 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
@@ -192,7 +192,6 @@
// should not happen
throw new ProviderException(nspe);
}
- session = token.getOpSession();
}
protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
@@ -847,18 +846,6 @@
return n;
}
- @Override
- protected void finalize() throws Throwable {
- try {
- if ((session != null) && token.isValid()) {
- cancelOperation();
- session = token.releaseSession(session);
- }
- } finally {
- super.finalize();
- }
- }
-
private final void bufferInputBytes(byte[] in, int inOfs, int len) {
System.arraycopy(in, inOfs, padBuffer, padBufferLen, len);
padBufferLen += len;
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Digest.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Digest.java Tue Apr 20 16:51:13 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc. 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
@@ -308,16 +308,4 @@
throw new ProviderException("update() failed", e);
}
}
-
- protected void finalize() throws Throwable {
- try {
- if ((session != null) && token.isValid()) {
- cancelOperation();
- session = token.releaseSession(session);
- }
- } finally {
- super.finalize();
- }
- }
-
}
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Key.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Key.java Tue Apr 20 16:51:13 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc. 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,7 +85,7 @@
// flags indicating whether the key is a token object, sensitive, extractable
final boolean tokenObject, sensitive, extractable;
- // weak reference notification clean up for session keys
+ // phantom reference notification clean up for session keys
private final SessionKeyRef sessionKeyRef;
P11Key(String type, Session session, long keyID, String algorithm,
@@ -1051,7 +1051,12 @@
}
}
-final class SessionKeyRef extends WeakReference<P11Key>
+/*
+ * NOTE: Must use PhantomReference here and not WeakReference
+ * otherwise the key maybe cleared before other objects which
+ * still use these keys during finalization such as SSLSocket.
+ */
+final class SessionKeyRef extends PhantomReference<P11Key>
implements Comparable<SessionKeyRef> {
private static ReferenceQueue<P11Key> refQueue =
new ReferenceQueue<P11Key>();
@@ -1062,14 +1067,11 @@
return refQueue;
}
- static final private int MAX_ITERATIONS = 2;
-
private static void drainRefQueueBounded() {
- int iterations = 0;
- while (iterations < MAX_ITERATIONS) {
+ while (true) {
SessionKeyRef next = (SessionKeyRef) refQueue.poll();
- if (next != null) next.dispose();
- ++iterations;
+ if (next == null) break;
+ next.dispose();
}
}
@@ -1087,7 +1089,7 @@
drainRefQueueBounded();
}
- void dispose() {
+ private void dispose() {
refList.remove(this);
if (session.token.isValid()) {
Session newSession = null;
@@ -1097,6 +1099,7 @@
} catch (PKCS11Exception e) {
// ignore
} finally {
+ this.clear();
session.token.releaseSession(newSession);
session.removeObject();
}
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Mac.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Mac.java Tue Apr 20 16:51:13 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc. 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
@@ -263,16 +263,4 @@
throw new ProviderException("update() failed", e);
}
}
-
- protected void finalize() throws Throwable {
- try {
- if ((session != null) && token.isValid()) {
- cancelOperation();
- session = token.releaseSession(session);
- }
- } finally {
- super.finalize();
- }
- }
-
}
--- a/jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11RSACipher.java Tue Apr 20 16:51:13 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc. 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
@@ -485,18 +485,6 @@
int n = P11KeyFactory.convertKey(token, key, algorithm).keyLength();
return n;
}
-
- protected void finalize() throws Throwable {
- try {
- if ((session != null) && token.isValid()) {
- cancelOperation();
- session = token.releaseSession(session);
- }
- } finally {
- super.finalize();
- }
- }
-
}
final class ConstructKeys {
--- a/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs11/P11Signature.java Tue Apr 20 16:51:13 2010 -0700
@@ -226,7 +226,6 @@
this.buffer = buffer;
this.digestOID = digestOID;
this.md = md;
- session = token.getOpSession();
}
private void ensureInitialized() {
@@ -732,16 +731,4 @@
throws InvalidParameterException {
throw new UnsupportedOperationException("getParameter() not supported");
}
-
- protected void finalize() throws Throwable {
- try {
- if ((session != null) && token.isValid()) {
- cancelOperation();
- session = token.releaseSession(session);
- }
- } finally {
- super.finalize();
- }
- }
-
}
--- a/jdk/src/share/classes/sun/security/pkcs11/Session.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs11/Session.java Tue Apr 20 16:51:13 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc. 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,7 @@
package sun.security.pkcs11;
+import java.lang.ref.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
@@ -59,11 +60,14 @@
// this could lead to idle sessions being closed early, but that is harmless
private long lastAccess;
+ private final SessionRef sessionRef;
+
Session(Token token, long id) {
this.token = token;
this.id = id;
createdObjects = new AtomicInteger();
id();
+ sessionRef = new SessionRef(this, id, token);
}
public int compareTo(Session other) {
@@ -108,4 +112,76 @@
return createdObjects.get() != 0;
}
+ void close() {
+ if (hasObjects()) {
+ throw new ProviderException(
+ "Internal error: close session with active objects");
+ }
+ sessionRef.dispose();
+ }
}
+
+/*
+ * NOTE: Use PhantomReference here and not WeakReference
+ * otherwise the sessions maybe closed before other objects
+ * which are still being finalized.
+ */
+final class SessionRef extends PhantomReference<Session>
+ implements Comparable<SessionRef> {
+
+ private static ReferenceQueue<Session> refQueue =
+ new ReferenceQueue<Session>();
+
+ private static Set<SessionRef> refList =
+ Collections.synchronizedSortedSet(new TreeSet<SessionRef>());
+
+ static ReferenceQueue<Session> referenceQueue() {
+ return refQueue;
+ }
+
+ static int totalCount() {
+ return refList.size();
+ }
+
+ private static void drainRefQueueBounded() {
+ while (true) {
+ SessionRef next = (SessionRef) refQueue.poll();
+ if (next == null) break;
+ next.dispose();
+ }
+ }
+
+ // handle to the native session
+ private long id;
+ private Token token;
+
+ SessionRef(Session session, long id, Token token) {
+ super(session, refQueue);
+ this.id = id;
+ this.token = token;
+ refList.add(this);
+ // TBD: run at some interval and not every time?
+ drainRefQueueBounded();
+ }
+
+ void dispose() {
+ refList.remove(this);
+ try {
+ token.p11.C_CloseSession(id);
+ } catch (PKCS11Exception e1) {
+ // ignore
+ } catch (ProviderException e2) {
+ // ignore
+ } finally {
+ this.clear();
+ }
+ }
+
+ public int compareTo(SessionRef other) {
+ if (this.id == other.id) {
+ return 0;
+ } else {
+ return (this.id < other.id) ? -1 : 1;
+ }
+ }
+}
--- a/jdk/src/share/classes/sun/security/pkcs11/SessionManager.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs11/SessionManager.java Tue Apr 20 16:51:13 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2010 Sun Microsystems, Inc. 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
@@ -51,10 +51,12 @@
* number of such sessions low. Note that we occasionally want to explicitly
* close a session, see P11Signature.
*
- * NOTE that all sessions obtained from this class MUST be returned using
- * either releaseSession() or closeSession() using a finally block or a
- * finalizer where appropriate. Otherwise, they will be "lost", i.e. there
- * will be a resource leak eventually leading to exhaustion.
+ * NOTE that sessions obtained from this class SHOULD be returned using
+ * either releaseSession() or closeSession() using a finally block when
+ * not needed anymore. Otherwise, they will be left for cleanup via the
+ * PhantomReference mechanism when GC kicks in, but it's best not to rely
+ * on that since GC may not run timely enough since the native PKCS11 library
+ * is also consuming memory.
*
* Note that sessions are automatically closed when they are not used for a
* period of time, see Session.
@@ -74,9 +76,6 @@
// maximum number of sessions to open with this token
private final int maxSessions;
- // total number of active sessions
- private int activeSessions;
-
// pool of available object sessions
private final Pool objSessions;
@@ -116,6 +115,11 @@
return (maxSessions <= DEFAULT_MAX_SESSIONS);
}
+ // returns the total number of active sessions
+ int totalSessionCount() {
+ return SessionRef.totalCount();
+ }
+
synchronized Session getObjSession() throws PKCS11Exception {
Session session = objSessions.poll();
if (session != null) {
@@ -136,7 +140,8 @@
}
// create a new session rather than re-using an obj session
// that avoids potential expensive cancels() for Signatures & RSACipher
- if (activeSessions < maxSessions) {
+ if (maxSessions == Integer.MAX_VALUE ||
+ totalSessionCount() < maxSessions) {
session = openSession();
return ensureValid(session);
}
@@ -159,14 +164,10 @@
if (debug != null) {
String location = new Exception().getStackTrace()[2].toString();
System.out.println("Killing session (" + location + ") active: "
- + activeSessions);
+ + totalSessionCount());
}
- try {
- closeSession(session);
- return null;
- } catch (PKCS11Exception e) {
- throw new ProviderException(e);
- }
+ closeSession(session);
+ return null;
}
synchronized Session releaseSession(Session session) {
@@ -187,7 +188,8 @@
return;
}
if (debug != null) {
- System.out.println("Demoting session, active: " + activeSessions);
+ System.out.println("Demoting session, active: " +
+ totalSessionCount());
}
boolean present = objSessions.remove(session);
if (present == false) {
@@ -199,16 +201,17 @@
}
private Session openSession() throws PKCS11Exception {
- if (activeSessions >= maxSessions) {
+ if ((maxSessions != Integer.MAX_VALUE) &&
+ (totalSessionCount() >= maxSessions)) {
throw new ProviderException("No more sessions available");
}
long id = token.p11.C_OpenSession
(token.provider.slotID, openSessionFlags, null, null);
Session session = new Session(token, id);
- activeSessions++;
if (debug != null) {
- if (activeSessions > maxActiveSessions) {
- maxActiveSessions = activeSessions;
+ int currTotal = totalSessionCount();
+ if (currTotal > maxActiveSessions) {
+ maxActiveSessions = currTotal;
if (maxActiveSessions % 10 == 0) {
System.out.println("Open sessions: " + maxActiveSessions);
}
@@ -217,13 +220,8 @@
return session;
}
- private void closeSession(Session session) throws PKCS11Exception {
- if (session.hasObjects()) {
- throw new ProviderException
- ("Internal error: close session with active objects");
- }
- token.p11.C_CloseSession(session.id());
- activeSessions--;
+ private void closeSession(Session session) {
+ session.close();
}
private static final class Pool {
@@ -267,28 +265,20 @@
}
Collections.sort(pool);
int i = 0;
- PKCS11Exception exc = null;
while (i < n - 1) { // always keep at least 1 session open
oldestSession = pool.get(i);
if (oldestSession.isLive(time)) {
break;
}
i++;
- try {
- mgr.closeSession(oldestSession);
- } catch (PKCS11Exception e) {
- exc = e;
- }
+ mgr.closeSession(oldestSession);
}
if (debug != null) {
System.out.println("Closing " + i + " idle sessions, active: "
- + mgr.activeSessions);
+ + mgr.totalSessionCount());
}
List<Session> subList = pool.subList(0, i);
subList.clear();
- if (exc != null) {
- throw new ProviderException(exc);
- }
}
}
--- a/jdk/src/share/classes/sun/security/pkcs11/wrapper/PKCS11Exception.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs11/wrapper/PKCS11Exception.java Tue Apr 20 16:51:13 2010 -0700
@@ -148,6 +148,7 @@
0x00000115,
0x00000120,
0x00000121,
+ 0x00000130,
0x00000150,
0x00000160,
0x00000170,
@@ -156,6 +157,7 @@
0x00000191,
0x000001A0,
0x000001A1,
+ 0x00000200,
0x80000000,
};
String[] errorMessages = new String[] {
@@ -234,6 +236,7 @@
"CKR_WRAPPING_KEY_TYPE_INCONSISTENT",
"CKR_RANDOM_SEED_NOT_SUPPORTED",
"CKR_RANDOM_NO_RNG",
+ "CKR_DOMAIN_PARAMS_INVALID",
"CKR_BUFFER_TOO_SMALL",
"CKR_SAVED_STATE_INVALID",
"CKR_INFORMATION_SENSITIVE",
@@ -242,6 +245,7 @@
"CKR_CRYPTOKI_ALREADY_INITIALIZED",
"CKR_MUTEX_BAD",
"CKR_MUTEX_NOT_LOCKED",
+ "CKR_FUNCTION_REJECTED",
"CKR_VENDOR_DEFINED",
};
errorMap = new HashMap<Long,String>();
--- a/jdk/src/share/classes/sun/security/smartcardio/CardImpl.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/security/smartcardio/CardImpl.java Tue Apr 20 16:51:13 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2005-2010 Sun Microsystems, Inc. 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
@@ -214,7 +214,7 @@
SCardEndTransaction(cardId, SCARD_LEAVE_CARD);
} catch (PCSCException e) {
handleError(e);
- throw new CardException("beginExclusive() failed", e);
+ throw new CardException("endExclusive() failed", e);
} finally {
exclusiveThread = null;
}
--- a/jdk/src/share/classes/sun/security/tools/KeyTool.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/security/tools/KeyTool.java Tue Apr 20 16:51:13 2010 -0700
@@ -1211,6 +1211,14 @@
X509CertImpl cert = new X509CertImpl(info);
cert.sign(privateKey, sigAlgName);
dumpCert(cert, out);
+ for (Certificate ca: keyStore.getCertificateChain(alias)) {
+ if (ca instanceof X509Certificate) {
+ X509Certificate xca = (X509Certificate)ca;
+ if (!isSelfSigned(xca)) {
+ dumpCert(xca, out);
+ }
+ }
+ }
}
/**
@@ -2640,19 +2648,33 @@
}
/**
- * Returns true if the given certificate is trusted, false otherwise.
+ * Locates a signer for a given certificate from a given keystore and
+ * returns the signer's certificate.
+ * @param cert the certificate whose signer is searched, not null
+ * @param ks the keystore to search with, not null
+ * @return <code>cert</code> itself if it's already inside <code>ks</code>,
+ * or a certificate inside <code>ks</code> who signs <code>cert</code>,
+ * or null otherwise.
*/
- private boolean isTrusted(Certificate cert)
- throws Exception
- {
- if (keyStore.getCertificateAlias(cert) != null) {
- return true; // found in own keystore
+ private static Certificate getTrustedSigner(Certificate cert, KeyStore ks)
+ throws Exception {
+ if (ks.getCertificateAlias(cert) != null) {
+ return cert;
}
- if (trustcacerts && (caks != null) &&
- (caks.getCertificateAlias(cert) != null)) {
- return true; // found in CA keystore
+ for (Enumeration<String> aliases = ks.aliases();
+ aliases.hasMoreElements(); ) {
+ String name = aliases.nextElement();
+ Certificate trustedCert = ks.getCertificate(name);
+ if (trustedCert != null) {
+ try {
+ cert.verify(trustedCert.getPublicKey());
+ return trustedCert;
+ } catch (Exception e) {
+ // Not verified, skip to the next one
+ }
+ }
}
- return false;
+ return null;
}
/**
@@ -2985,48 +3007,33 @@
return replyCerts;
}
- // do we trust the (root) cert at the top?
+ // do we trust the cert at the top?
Certificate topCert = replyCerts[replyCerts.length-1];
- if (!isTrusted(topCert)) {
- boolean verified = false;
- Certificate rootCert = null;
- if (trustcacerts && (caks!= null)) {
- for (Enumeration<String> aliases = caks.aliases();
- aliases.hasMoreElements(); ) {
- String name = aliases.nextElement();
- rootCert = caks.getCertificate(name);
- if (rootCert != null) {
- try {
- topCert.verify(rootCert.getPublicKey());
- verified = true;
- break;
- } catch (Exception e) {
- }
- }
- }
+ Certificate root = getTrustedSigner(topCert, keyStore);
+ if (root == null && trustcacerts && caks != null) {
+ root = getTrustedSigner(topCert, caks);
+ }
+ if (root == null) {
+ System.err.println();
+ System.err.println
+ (rb.getString("Top-level certificate in reply:\n"));
+ printX509Cert((X509Certificate)topCert, System.out);
+ System.err.println();
+ System.err.print(rb.getString("... is not trusted. "));
+ String reply = getYesNoReply
+ (rb.getString("Install reply anyway? [no]: "));
+ if ("NO".equals(reply)) {
+ return null;
}
- if (!verified) {
- System.err.println();
- System.err.println
- (rb.getString("Top-level certificate in reply:\n"));
- printX509Cert((X509Certificate)topCert, System.out);
- System.err.println();
- System.err.print(rb.getString("... is not trusted. "));
- String reply = getYesNoReply
- (rb.getString("Install reply anyway? [no]: "));
- if ("NO".equals(reply)) {
- return null;
- }
- } else {
- if (!isSelfSigned((X509Certificate)topCert)) {
- // append the (self-signed) root CA cert to the chain
- Certificate[] tmpCerts =
- new Certificate[replyCerts.length+1];
- System.arraycopy(replyCerts, 0, tmpCerts, 0,
- replyCerts.length);
- tmpCerts[tmpCerts.length-1] = rootCert;
- replyCerts = tmpCerts;
- }
+ } else {
+ if (root != topCert) {
+ // append the root CA cert to the chain
+ Certificate[] tmpCerts =
+ new Certificate[replyCerts.length+1];
+ System.arraycopy(replyCerts, 0, tmpCerts, 0,
+ replyCerts.length);
+ tmpCerts[tmpCerts.length-1] = root;
+ replyCerts = tmpCerts;
}
}
--- a/jdk/src/share/classes/sun/security/tools/TimestampedSigner.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/security/tools/TimestampedSigner.java Tue Apr 20 16:51:13 2010 -0700
@@ -82,6 +82,11 @@
private static final String KP_TIMESTAMPING_OID = "1.3.6.1.5.5.7.3.8";
/*
+ * Object identifier for extendedKeyUsage extension
+ */
+ private static final String EXTENDED_KEY_USAGE_OID = "2.5.29.37";
+
+ /*
* Object identifier for the timestamping access descriptors.
*/
private static final ObjectIdentifier AD_TIMESTAMPING_Id;
@@ -357,34 +362,26 @@
}
// Examine the TSA's certificate (if present)
- List<String> keyPurposes = null;
- X509Certificate[] certs = tsToken.getCertificates();
- if (certs != null && certs.length > 0) {
- // Use certficate from the TSP reply
- // Pick out the cert for the TS server, which is the end-entity
- // one inside the chain.
- for (X509Certificate cert: certs) {
- boolean isSigner = false;
- for (X509Certificate cert2: certs) {
- if (cert != cert2) {
- if (cert.getSubjectDN().equals(cert2.getIssuerDN())) {
- isSigner = true;
- break;
- }
- }
+ for (SignerInfo si: tsToken.getSignerInfos()) {
+ X509Certificate cert = si.getCertificate(tsToken);
+ if (cert == null) {
+ // Error, we've already set tsRequestCertificate = true
+ throw new CertificateException(
+ "Certificate not included in timestamp token");
+ } else {
+ if (!cert.getCriticalExtensionOIDs().contains(
+ EXTENDED_KEY_USAGE_OID)) {
+ throw new CertificateException(
+ "Certificate is not valid for timestamping");
}
- if (!isSigner) {
- keyPurposes = cert.getExtendedKeyUsage();
- if (keyPurposes == null ||
- ! keyPurposes.contains(KP_TIMESTAMPING_OID)) {
- throw new CertificateException(
- "Certificate is not valid for timestamping");
- }
- break;
+ List keyPurposes = cert.getExtendedKeyUsage();
+ if (keyPurposes == null ||
+ ! keyPurposes.contains(KP_TIMESTAMPING_OID)) {
+ throw new CertificateException(
+ "Certificate is not valid for timestamping");
}
}
}
-
return tsReply.getEncodedToken();
}
}
--- a/jdk/src/share/classes/sun/security/x509/X509Key.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/src/share/classes/sun/security/x509/X509Key.java Tue Apr 20 16:51:13 2010 -0700
@@ -171,7 +171,7 @@
in.data.getUnalignedBitString());
} catch (InvalidKeyException e) {
- throw new IOException("subject key, " + e.getMessage());
+ throw new IOException("subject key, " + e.getMessage(), e);
}
if (in.data.available() != 0)
@@ -224,7 +224,7 @@
} catch (NoSuchAlgorithmException e) {
// Return generic X509Key with opaque key data (see below)
} catch (InvalidKeySpecException e) {
- throw new InvalidKeyException(e.getMessage());
+ throw new InvalidKeyException(e.getMessage(), e);
}
/*
--- a/jdk/test/java/util/regex/RegExTest.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/test/java/util/regex/RegExTest.java Tue Apr 20 16:51:13 2010 -0700
@@ -32,7 +32,7 @@
* 4872664 4803179 4892980 4900747 4945394 4938995 4979006 4994840 4997476
* 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940
* 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133
- * 6350801 6676425 6878475 6919132
+ * 6350801 6676425 6878475 6919132 6931676
*/
import java.util.regex.*;
@@ -3515,7 +3515,7 @@
report("NamedGroupCapture");
}
- // This is for bug 6969132
+ // This is for bug 6919132
private static void nonBmpClassComplementTest() throws Exception {
Pattern p = Pattern.compile("\\P{Lu}");
Matcher m = p.matcher(new String(new int[] {0x1d400}, 0, 1));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/Krb5NameEquals.java Tue Apr 20 16:51:13 2010 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2007-2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @bug 4634392
+ * @summary JDK code doesn't respect contract for equals and hashCode
+ * @author Andrew Fan
+ */
+
+import org.ietf.jgss.*;
+
+public class Krb5NameEquals {
+
+ private static String NAME_STR1 = "service@host";
+ private static String NAME_STR2 = "service@host2";
+ private static final Oid MECH;
+
+ static {
+ Oid temp = null;
+ try {
+ temp = new Oid("1.2.840.113554.1.2.2"); // KRB5
+ } catch (Exception e) {
+ // should never happen
+ }
+ MECH = temp;
+ }
+
+ public static void main(String[] argv) throws Exception {
+ GSSManager mgr = GSSManager.getInstance();
+
+ boolean result = true;
+ // Create GSSName and check their equals(), hashCode() impl
+ GSSName name1 = mgr.createName(NAME_STR1,
+ GSSName.NT_HOSTBASED_SERVICE, MECH);
+ GSSName name2 = mgr.createName(NAME_STR2,
+ GSSName.NT_HOSTBASED_SERVICE, MECH);
+ GSSName name3 = mgr.createName(NAME_STR1,
+ GSSName.NT_HOSTBASED_SERVICE, MECH);
+
+ if (!name1.equals(name3) || !name1.equals(name3) ||
+ !name1.equals((Object) name1) ||
+ !name1.equals((Object) name3)) {
+ System.out.println("Error: should be the same name");
+ result = false;
+ } else if (name1.hashCode() != name3.hashCode()) {
+ System.out.println("Error: should have same hash");
+ result = false;
+ }
+
+ if (name1.equals(name2) || name1.equals((Object) name2)) {
+ System.out.println("Error: should be different names");
+ result = false;
+ }
+ if (result) {
+ System.out.println("Done");
+ } else System.exit(1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/runNameEquals.sh Tue Apr 20 16:51:13 2010 -0700
@@ -0,0 +1,106 @@
+#
+# Copyright 2009-2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6317711 6944847
+# @summary Ensure the GSSName has the correct impl which respects
+# the contract for equals and hashCode across different configurations.
+
+# set a few environment variables so that the shell-script can run stand-alone
+# in the source directory
+
+if [ "${TESTSRC}" = "" ] ; then
+ TESTSRC="."
+fi
+
+if [ "${TESTCLASSES}" = "" ] ; then
+ TESTCLASSES="."
+fi
+
+if [ "${TESTJAVA}" = "" ] ; then
+ echo "TESTJAVA not set. Test cannot execute."
+ echo "FAILED!!!"
+ exit 1
+fi
+
+NATIVE=false
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ SunOS )
+ PATHSEP=":"
+ FILESEP="/"
+ NATIVE=true
+ ;;
+ Linux )
+ PATHSEP=":"
+ FILESEP="/"
+ NATIVE=true
+ ;;
+ CYGWIN* )
+ PATHSEP=";"
+ FILESEP="/"
+ ;;
+ Windows* )
+ PATHSEP=";"
+ FILESEP="\\"
+ ;;
+ * )
+ echo "Unrecognized system!"
+ exit 1;
+ ;;
+esac
+
+TEST=Krb5NameEquals
+
+${TESTJAVA}${FILESEP}bin${FILESEP}javac \
+ -d ${TESTCLASSES}${FILESEP} \
+ ${TESTSRC}${FILESEP}${TEST}.java
+
+EXIT_STATUS=0
+
+if [ "${NATIVE}" = "true" ] ; then
+ echo "Testing native provider"
+ ${TESTJAVA}${FILESEP}bin${FILESEP}java \
+ -classpath ${TESTCLASSES} \
+ -Dsun.security.jgss.native=true \
+ ${TEST}
+ if [ $? != 0 ] ; then
+ echo "Native provider fails"
+ EXIT_STATUS=1
+ fi
+fi
+
+echo "Testing java provider"
+${TESTJAVA}${FILESEP}bin${FILESEP}java \
+ -classpath ${TESTCLASSES} \
+ -Djava.security.krb5.realm=R \
+ -Djava.security.krb5.kdc=127.0.0.1 \
+ ${TEST}
+if [ $? != 0 ] ; then
+ echo "Java provider fails"
+ EXIT_STATUS=1
+fi
+
+exit ${EXIT_STATUS}
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/DNSIdentities.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/DNSIdentities.java Tue Apr 20 16:51:13 2010 -0700
@@ -624,6 +624,11 @@
volatile static boolean serverReady = false;
/*
+ * Is the connection ready to close?
+ */
+ volatile static boolean closeReady = false;
+
+ /*
* Turn on SSL debugging?
*/
static boolean debug = false;
@@ -652,9 +657,6 @@
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
sslSocket.setNeedClientAuth(true);
- if (sslSocket instanceof SSLSocketImpl) {
- ((SSLSocketImpl)sslSocket).trySetHostnameVerification("HTTPS");
- }
PrintStream out =
new PrintStream(sslSocket.getOutputStream());
@@ -670,11 +672,14 @@
out.print("Testing\r\n");
out.flush();
} finally {
- // close the socket
- Thread.sleep(2000);
- System.out.println("Server closing socket");
- sslSocket.close();
- serverReady = false;
+ // close the socket
+ while (!closeReady) {
+ Thread.sleep(50);
+ }
+
+ System.out.println("Server closing socket");
+ sslSocket.close();
+ serverReady = false;
}
}
@@ -704,12 +709,17 @@
URL url = new URL("https://localhost:" + serverPort+"/");
System.out.println("url is "+url.toString());
- http = (HttpsURLConnection)url.openConnection();
+ try {
+ http = (HttpsURLConnection)url.openConnection();
- int respCode = http.getResponseCode();
- System.out.println("respCode = "+respCode);
-
- http.disconnect();
+ int respCode = http.getResponseCode();
+ System.out.println("respCode = "+respCode);
+ } finally {
+ if (http != null) {
+ http.disconnect();
+ }
+ closeReady = true;
+ }
}
/*
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsPost.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsPost.java Tue Apr 20 16:51:13 2010 -0700
@@ -61,6 +61,11 @@
volatile static boolean serverReady = false;
/*
+ * Is the connection ready to close?
+ */
+ volatile static boolean closeReady = false;
+
+ /*
* Turn on SSL debugging?
*/
static boolean debug = false;
@@ -98,25 +103,34 @@
serverReady = true;
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
- InputStream sslIS = sslSocket.getInputStream();
- OutputStream sslOS = sslSocket.getOutputStream();
- BufferedReader br = new BufferedReader(new InputStreamReader(sslIS));
- PrintStream ps = new PrintStream(sslOS);
- // process HTTP POST request from client
- System.out.println("status line: "+br.readLine());
- String msg = null;
- while ((msg = br.readLine()) != null && msg.length() > 0);
+ try {
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+ BufferedReader br =
+ new BufferedReader(new InputStreamReader(sslIS));
+ PrintStream ps = new PrintStream(sslOS);
+
+ // process HTTP POST request from client
+ System.out.println("status line: "+br.readLine());
+ String msg = null;
+ while ((msg = br.readLine()) != null && msg.length() > 0);
- msg = br.readLine();
- if (msg.equals(postMsg)) {
- ps.println("HTTP/1.1 200 OK\n\n");
- } else {
- ps.println("HTTP/1.1 500 Not OK\n\n");
+ msg = br.readLine();
+ if (msg.equals(postMsg)) {
+ ps.println("HTTP/1.1 200 OK\n\n");
+ } else {
+ ps.println("HTTP/1.1 500 Not OK\n\n");
+ }
+ ps.flush();
+
+ // close the socket
+ while (!closeReady) {
+ Thread.sleep(50);
+ }
+ } finally {
+ sslSocket.close();
+ sslServerSocket.close();
}
- ps.flush();
- Thread.sleep(2000);
- sslSocket.close();
- sslServerSocket.close();
}
/*
@@ -144,12 +158,17 @@
http.setRequestMethod("POST");
PrintStream ps = new PrintStream(http.getOutputStream());
- ps.println(postMsg);
- ps.flush();
- if (http.getResponseCode() != 200) {
- throw new RuntimeException("test Failed");
+ try {
+ ps.println(postMsg);
+ ps.flush();
+ if (http.getResponseCode() != 200) {
+ throw new RuntimeException("test Failed");
+ }
+ } finally {
+ ps.close();
+ http.disconnect();
+ closeReady = true;
}
- ps.close();
}
static class NameVerifier implements HostnameVerifier {
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressDNSIdentities.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressDNSIdentities.java Tue Apr 20 16:51:13 2010 -0700
@@ -624,6 +624,11 @@
volatile static boolean serverReady = false;
/*
+ * Is the connection ready to close?
+ */
+ volatile static boolean closeReady = false;
+
+ /*
* Turn on SSL debugging?
*/
static boolean debug = false;
@@ -652,9 +657,6 @@
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
sslSocket.setNeedClientAuth(true);
- if (sslSocket instanceof SSLSocketImpl) {
- ((SSLSocketImpl)sslSocket).trySetHostnameVerification("HTTPS");
- }
PrintStream out =
new PrintStream(sslSocket.getOutputStream());
@@ -670,11 +672,14 @@
out.print("Testing\r\n");
out.flush();
} finally {
- // close the socket
- Thread.sleep(2000);
- System.out.println("Server closing socket");
- sslSocket.close();
- serverReady = false;
+ // close the socket
+ while (!closeReady) {
+ Thread.sleep(50);
+ }
+
+ System.out.println("Server closing socket");
+ sslSocket.close();
+ serverReady = false;
}
}
@@ -716,7 +721,10 @@
// no subject alternative names matching IP address 127.0.0.1 found
// that's the expected exception, ignore it.
} finally {
- http.disconnect();
+ if (http != null) {
+ http.disconnect();
+ }
+ closeReady = true;
}
}
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressIPIdentities.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressIPIdentities.java Tue Apr 20 16:51:13 2010 -0700
@@ -625,6 +625,11 @@
volatile static boolean serverReady = false;
/*
+ * Is the connection ready to close?
+ */
+ volatile static boolean closeReady = false;
+
+ /*
* Turn on SSL debugging?
*/
static boolean debug = false;
@@ -653,9 +658,6 @@
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
sslSocket.setNeedClientAuth(true);
- if (sslSocket instanceof SSLSocketImpl) {
- ((SSLSocketImpl)sslSocket).trySetHostnameVerification("HTTPS");
- }
PrintStream out =
new PrintStream(sslSocket.getOutputStream());
@@ -672,7 +674,10 @@
out.flush();
} finally {
// close the socket
- Thread.sleep(2000);
+ while (!closeReady) {
+ Thread.sleep(50);
+ }
+
System.out.println("Server closing socket");
sslSocket.close();
serverReady = false;
@@ -705,12 +710,17 @@
URL url = new URL("https://127.0.0.1:" + serverPort+"/");
System.out.println("url is "+url.toString());
- http = (HttpsURLConnection)url.openConnection();
+ try {
+ http = (HttpsURLConnection)url.openConnection();
- int respCode = http.getResponseCode();
- System.out.println("respCode = "+respCode);
-
- http.disconnect();
+ int respCode = http.getResponseCode();
+ System.out.println("respCode = "+respCode);
+ } finally {
+ if (http != null) {
+ http.disconnect();
+ }
+ closeReady = true;
+ }
}
/*
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPIdentities.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPIdentities.java Tue Apr 20 16:51:13 2010 -0700
@@ -625,6 +625,11 @@
volatile static boolean serverReady = false;
/*
+ * Is the connection ready to close?
+ */
+ volatile static boolean closeReady = false;
+
+ /*
* Turn on SSL debugging?
*/
static boolean debug = false;
@@ -653,9 +658,6 @@
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
sslSocket.setNeedClientAuth(true);
- if (sslSocket instanceof SSLSocketImpl) {
- ((SSLSocketImpl)sslSocket).trySetHostnameVerification("HTTPS");
- }
PrintStream out =
new PrintStream(sslSocket.getOutputStream());
@@ -672,7 +674,10 @@
out.flush();
} finally {
// close the socket
- Thread.sleep(2000);
+ while (!closeReady) {
+ Thread.sleep(50);
+ }
+
System.out.println("Server closing socket");
sslSocket.close();
serverReady = false;
@@ -705,12 +710,17 @@
URL url = new URL("https://localhost:" + serverPort+"/");
System.out.println("url is "+url.toString());
- http = (HttpsURLConnection)url.openConnection();
+ try {
+ http = (HttpsURLConnection)url.openConnection();
- int respCode = http.getResponseCode();
- System.out.println("respCode = "+respCode);
-
- http.disconnect();
+ int respCode = http.getResponseCode();
+ System.out.println("respCode = "+respCode);
+ } finally {
+ if (http != null) {
+ http.disconnect();
+ }
+ closeReady = true;
+ }
}
/*
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/Identities.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/Identities.java Tue Apr 20 16:51:13 2010 -0700
@@ -624,6 +624,11 @@
volatile static boolean serverReady = false;
/*
+ * Is the connection ready to close?
+ */
+ volatile static boolean closeReady = false;
+
+ /*
* Turn on SSL debugging?
*/
static boolean debug = false;
@@ -652,9 +657,6 @@
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
sslSocket.setNeedClientAuth(true);
- if (sslSocket instanceof SSLSocketImpl) {
- ((SSLSocketImpl)sslSocket).trySetHostnameVerification("HTTPS");
- }
PrintStream out =
new PrintStream(sslSocket.getOutputStream());
@@ -671,7 +673,10 @@
out.flush();
} finally {
// close the socket
- Thread.sleep(2000);
+ while (!closeReady) {
+ Thread.sleep(50);
+ }
+
System.out.println("Server closing socket");
sslSocket.close();
serverReady = false;
@@ -704,12 +709,17 @@
URL url = new URL("https://localhost:" + serverPort+"/");
System.out.println("url is "+url.toString());
- http = (HttpsURLConnection)url.openConnection();
+ try {
+ http = (HttpsURLConnection)url.openConnection();
- int respCode = http.getResponseCode();
- System.out.println("respCode = "+respCode);
-
- http.disconnect();
+ int respCode = http.getResponseCode();
+ System.out.println("respCode = "+respCode);
+ } finally {
+ if (http != null) {
+ http.disconnect();
+ }
+ closeReady = true;
+ }
}
/*
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/Redirect.java Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/Redirect.java Tue Apr 20 16:51:13 2010 -0700
@@ -61,6 +61,11 @@
volatile static boolean serverReady = false;
/*
+ * Is the connection ready to close?
+ */
+ volatile static boolean closeReady = false;
+
+ /*
* Turn on SSL debugging?
*/
static boolean debug = false;
@@ -98,24 +103,33 @@
serverReady = true;
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
- InputStream sslIS = sslSocket.getInputStream();
- OutputStream sslOS = sslSocket.getOutputStream();
- BufferedReader br = new BufferedReader(new InputStreamReader(sslIS));
- PrintStream ps = new PrintStream(sslOS);
- // process HTTP POST request from client
- System.out.println("status line: "+br.readLine());
+ try {
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+ BufferedReader br =
+ new BufferedReader(new InputStreamReader(sslIS));
+ PrintStream ps = new PrintStream(sslOS);
+
+ // process HTTP POST request from client
+ System.out.println("status line: "+br.readLine());
- ps.println("HTTP/1.1 307 Redirect");
- ps.println("Location: https://localhost:"+serverPort+"/index.html\n\n");
- ps.flush();
- sslSocket = (SSLSocket) sslServerSocket.accept();
- sslOS = sslSocket.getOutputStream();
- ps = new PrintStream(sslOS);
- ps.println("HTTP/1.1 200 Redirect succeeded\n\n");
- ps.flush();
- Thread.sleep(2000);
- sslSocket.close();
- sslServerSocket.close();
+ ps.println("HTTP/1.1 307 Redirect");
+ ps.println("Location: https://localhost:" + serverPort +
+ "/index.html\n\n");
+ ps.flush();
+ sslSocket = (SSLSocket) sslServerSocket.accept();
+ sslOS = sslSocket.getOutputStream();
+ ps = new PrintStream(sslOS);
+ ps.println("HTTP/1.1 200 Redirect succeeded\n\n");
+ ps.flush();
+ } finally {
+ // close the socket
+ while (!closeReady) {
+ Thread.sleep(50);
+ }
+ sslSocket.close();
+ sslServerSocket.close();
+ }
}
/*
@@ -139,10 +153,14 @@
HttpsURLConnection.setDefaultHostnameVerifier(
new NameVerifier());
HttpsURLConnection http = (HttpsURLConnection)url.openConnection();
-
- System.out.println("response header: "+http.getHeaderField(0));
- if (http.getResponseCode() != 200) {
- throw new RuntimeException("test Failed");
+ try {
+ System.out.println("response header: "+http.getHeaderField(0));
+ if (http.getResponseCode() != 200) {
+ throw new RuntimeException("test Failed");
+ }
+ } finally {
+ http.disconnect();
+ closeReady = true;
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Tue Apr 20 16:51:13 2010 -0700
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2003-2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import com.sun.net.httpserver.*;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.net.InetSocketAddress;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Calendar;
+import sun.security.pkcs.ContentInfo;
+import sun.security.pkcs.PKCS7;
+import sun.security.pkcs.SignerInfo;
+import sun.security.util.DerOutputStream;
+import sun.security.util.DerValue;
+import sun.security.util.ObjectIdentifier;
+import sun.security.x509.AlgorithmId;
+import sun.security.x509.X500Name;
+
+public class TimestampCheck {
+ static final String TSKS = "tsks";
+ static final String JAR = "old.jar";
+
+ static class Handler implements HttpHandler {
+ public void handle(HttpExchange t) throws IOException {
+ int len = 0;
+ for (String h: t.getRequestHeaders().keySet()) {
+ if (h.equalsIgnoreCase("Content-length")) {
+ len = Integer.valueOf(t.getRequestHeaders().get(h).get(0));
+ }
+ }
+ byte[] input = new byte[len];
+ t.getRequestBody().read(input);
+
+ try {
+ int path = 0;
+ if (t.getRequestURI().getPath().length() > 1) {
+ path = Integer.parseInt(
+ t.getRequestURI().getPath().substring(1));
+ }
+ byte[] output = sign(input, path);
+ Headers out = t.getResponseHeaders();
+ out.set("Content-Type", "application/timestamp-reply");
+
+ t.sendResponseHeaders(200, output.length);
+ OutputStream os = t.getResponseBody();
+ os.write(output);
+ } catch (Exception e) {
+ e.printStackTrace();
+ t.sendResponseHeaders(500, 0);
+ }
+ t.close();
+ }
+
+ /**
+ * @param input The data to sign
+ * @param path different cases to simulate, impl on URL path
+ * 0: normal
+ * 1: Missing nonce
+ * 2: Different nonce
+ * 3: Bad digets octets in messageImprint
+ * 4: Different algorithmId in messageImprint
+ * 5: whole chain in cert set
+ * 6: extension is missing
+ * 7: extension is non-critical
+ * 8: extension does not have timestamping
+ * @returns the signed
+ */
+ byte[] sign(byte[] input, int path) throws Exception {
+ // Read TSRequest
+ DerValue value = new DerValue(input);
+ System.err.println("\nIncoming Request\n===================");
+ System.err.println("Version: " + value.data.getInteger());
+ DerValue messageImprint = value.data.getDerValue();
+ AlgorithmId aid = AlgorithmId.parse(
+ messageImprint.data.getDerValue());
+ System.err.println("AlgorithmId: " + aid);
+
+ BigInteger nonce = null;
+ while (value.data.available() > 0) {
+ DerValue v = value.data.getDerValue();
+ if (v.tag == DerValue.tag_Integer) {
+ nonce = v.getBigInteger();
+ System.err.println("nonce: " + nonce);
+ } else if (v.tag == DerValue.tag_Boolean) {
+ System.err.println("certReq: " + v.getBoolean());
+ }
+ }
+
+ // Write TSResponse
+ System.err.println("\nResponse\n===================");
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(new FileInputStream(TSKS), "changeit".toCharArray());
+
+ String alias = "ts";
+ if (path == 6) alias = "tsbad1";
+ if (path == 7) alias = "tsbad2";
+ if (path == 8) alias = "tsbad3";
+
+ DerOutputStream statusInfo = new DerOutputStream();
+ statusInfo.putInteger(0);
+
+ DerOutputStream token = new DerOutputStream();
+ AlgorithmId[] algorithms = {aid};
+ Certificate[] chain = ks.getCertificateChain(alias);
+ X509Certificate[] signerCertificateChain = null;
+ X509Certificate signer = (X509Certificate)chain[0];
+ if (path == 5) { // Only case 5 uses full chain
+ signerCertificateChain = new X509Certificate[chain.length];
+ for (int i=0; i<chain.length; i++) {
+ signerCertificateChain[i] = (X509Certificate)chain[i];
+ }
+ } else if (path == 9) {
+ signerCertificateChain = new X509Certificate[0];
+ } else {
+ signerCertificateChain = new X509Certificate[1];
+ signerCertificateChain[0] = (X509Certificate)chain[0];
+ }
+
+ DerOutputStream tst = new DerOutputStream();
+
+ tst.putInteger(1);
+ tst.putOID(new ObjectIdentifier("1.2.3.4")); // policy
+
+ if (path != 3 && path != 4) {
+ tst.putDerValue(messageImprint);
+ } else {
+ byte[] data = messageImprint.toByteArray();
+ if (path == 4) {
+ data[6] = (byte)0x01;
+ } else {
+ data[data.length-1] = (byte)0x01;
+ data[data.length-2] = (byte)0x02;
+ data[data.length-3] = (byte)0x03;
+ }
+ tst.write(data);
+ }
+
+ tst.putInteger(1);
+
+ Calendar cal = Calendar.getInstance();
+ tst.putGeneralizedTime(cal.getTime());
+
+ if (path == 2) {
+ tst.putInteger(1234);
+ } else if (path == 1) {
+ // do nothing
+ } else {
+ tst.putInteger(nonce);
+ }
+
+ DerOutputStream tstInfo = new DerOutputStream();
+ tstInfo.write(DerValue.tag_Sequence, tst);
+
+ DerOutputStream tstInfo2 = new DerOutputStream();
+ tstInfo2.putOctetString(tstInfo.toByteArray());
+
+ Signature sig = Signature.getInstance("SHA1withDSA");
+ sig.initSign((PrivateKey)(ks.getKey(
+ alias, "changeit".toCharArray())));
+ sig.update(tstInfo.toByteArray());
+
+ ContentInfo contentInfo = new ContentInfo(new ObjectIdentifier(
+ "1.2.840.113549.1.9.16.1.4"),
+ new DerValue(tstInfo2.toByteArray()));
+
+ System.err.println("Signing...");
+ System.err.println(new X500Name(signer
+ .getIssuerX500Principal().getName()));
+ System.err.println(signer.getSerialNumber());
+
+ SignerInfo signerInfo = new SignerInfo(
+ new X500Name(signer.getIssuerX500Principal().getName()),
+ signer.getSerialNumber(),
+ aid, AlgorithmId.get("DSA"), sig.sign());
+
+ SignerInfo[] signerInfos = {signerInfo};
+ PKCS7 p7 =
+ new PKCS7(algorithms, contentInfo, signerCertificateChain,
+ signerInfos);
+ ByteArrayOutputStream p7out = new ByteArrayOutputStream();
+ p7.encodeSignedData(p7out);
+
+ DerOutputStream response = new DerOutputStream();
+ response.write(DerValue.tag_Sequence, statusInfo);
+ response.putDerValue(new DerValue(p7out.toByteArray()));
+
+ DerOutputStream out = new DerOutputStream();
+ out.write(DerValue.tag_Sequence, response);
+
+ return out.toByteArray();
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ Handler h = new Handler();
+ HttpServer server = HttpServer.create(new InetSocketAddress(0), 0);
+ int port = server.getAddress().getPort();
+ HttpContext ctx = server.createContext("/", h);
+ server.start();
+
+ String cmd = null;
+ // Use -J-Djava.security.egd=file:/dev/./urandom to speed up
+ // nonce generation in timestamping request. Not avaibale on
+ // Windows and defaults to thread seed generator, not too bad.
+ if (System.getProperty("java.home").endsWith("jre")) {
+ cmd = System.getProperty("java.home") + "/../bin/jarsigner" +
+ " -J-Djava.security.egd=file:/dev/./urandom" +
+ " -debug -keystore " + TSKS + " -storepass changeit" +
+ " -tsa http://localhost:" + port + "/%d" +
+ " -signedjar new.jar " + JAR + " old";
+ } else {
+ cmd = System.getProperty("java.home") + "/bin/jarsigner" +
+ " -J-Djava.security.egd=file:/dev/./urandom" +
+ " -debug -keystore " + TSKS + " -storepass changeit" +
+ " -tsa http://localhost:" + port + "/%d" +
+ " -signedjar new.jar " + JAR + " old";
+ }
+
+ try {
+ if (args.length == 0) { // Run this test
+ jarsigner(cmd, 0, true); // Success, normal call
+ jarsigner(cmd, 1, false); // These 4 should fail
+ jarsigner(cmd, 2, false);
+ jarsigner(cmd, 3, false);
+ jarsigner(cmd, 4, false);
+ jarsigner(cmd, 5, true); // Success, 6543440 solved.
+ jarsigner(cmd, 6, false); // tsbad1
+ jarsigner(cmd, 7, false); // tsbad2
+ jarsigner(cmd, 8, false); // tsbad3
+ jarsigner(cmd, 9, false); // no cert in timestamp
+ } else { // Run as a standalone server
+ System.err.println("Press Enter to quit server");
+ System.in.read();
+ }
+ } finally {
+ server.stop(0);
+ new File("x.jar").delete();
+ }
+ }
+
+ /**
+ * @param cmd the command line (with a hole to plug in)
+ * @param path the path in the URL, i.e, http://localhost/path
+ * @param expected if this command should succeed
+ */
+ static void jarsigner(String cmd, int path, boolean expected)
+ throws Exception {
+ System.err.println("Test " + path);
+ Process p = Runtime.getRuntime().exec(String.format(cmd, path));
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(p.getErrorStream()));
+ while (true) {
+ String s = reader.readLine();
+ if (s == null) break;
+ System.err.println(s);
+ }
+ int result = p.waitFor();
+ if (expected && result != 0 || !expected && result == 0) {
+ throw new Exception("Failed");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/ts.sh Tue Apr 20 16:51:13 2010 -0700
@@ -0,0 +1,91 @@
+#
+# Copyright 2007-2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6543842 6543440 6939248
+# @summary checking response of timestamp
+#
+# @run shell/timeout=600 ts.sh
+
+# Run for a long time because jarsigner with timestamp needs to create a
+# 64-bit random number and it might be extremely slow on a machine with
+# not enough entropy pool
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ Windows_* )
+ FS="\\"
+ ;;
+ * )
+ FS="/"
+ ;;
+esac
+
+if [ "${TESTSRC}" = "" ] ; then
+ TESTSRC="."
+fi
+if [ "${TESTJAVA}" = "" ] ; then
+ JAVAC_CMD=`which javac`
+ TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+JAR="${TESTJAVA}${FS}bin${FS}jar"
+JAVA="${TESTJAVA}${FS}bin${FS}java"
+JAVAC="${TESTJAVA}${FS}bin${FS}javac"
+KT="${TESTJAVA}${FS}bin${FS}keytool -keystore tsks -storepass changeit -keypass changeit"
+
+rm tsks
+echo Nothing > A
+rm old.jar
+$JAR cvf old.jar A
+
+# ca is CA
+# old is signer for code
+# ts is signer for timestamp
+# tsbad1 has no extendedKeyUsage
+# tsbad2's extendedKeyUsage is non-critical
+# tsbad3's extendedKeyUsage has no timestamping
+
+$KT -alias ca -genkeypair -ext bc -dname CN=CA
+$KT -alias old -genkeypair -dname CN=old
+$KT -alias ts -genkeypair -dname CN=ts
+$KT -alias tsbad1 -genkeypair -dname CN=tsbad1
+$KT -alias tsbad2 -genkeypair -dname CN=tsbad2
+$KT -alias tsbad3 -genkeypair -dname CN=tsbad3
+$KT -alias ts -certreq | \
+ $KT -alias ca -gencert -ext eku:critical=ts | \
+ $KT -alias ts -importcert
+$KT -alias tsbad1 -certreq | \
+ $KT -alias ca -gencert | \
+ $KT -alias tsbad1 -importcert
+$KT -alias tsbad2 -certreq | \
+ $KT -alias ca -gencert -ext eku=ts | \
+ $KT -alias tsbad2 -importcert
+$KT -alias tsbad3 -certreq | \
+ $KT -alias ca -gencert -ext eku:critical=cs | \
+ $KT -alias tsbad3 -importcert
+
+$JAVAC -d . ${TESTSRC}/TimestampCheck.java
+$JAVA TimestampCheck
+
--- a/jdk/test/sun/security/tools/keytool/selfissued.sh Tue Apr 20 16:50:10 2010 -0700
+++ b/jdk/test/sun/security/tools/keytool/selfissued.sh Tue Apr 20 16:51:13 2010 -0700
@@ -1,5 +1,5 @@
#
-# Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 2009-2010 Sun Microsystems, Inc. All Rights Reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -22,8 +22,8 @@
#
# @test
-# @bug 6825352
-# @summary support self-issued certificate in keytool
+# @bug 6825352 6937978
+# @summary support self-issued certificate in keytool and let -gencert generate the chain
#
# @run shell selfissued.sh
#
@@ -50,20 +50,22 @@
rm $KS
$KT -alias ca -dname CN=CA -genkeypair
-$KT -alias me -dname CN=CA -genkeypair
+$KT -alias ca1 -dname CN=CA -genkeypair
+$KT -alias ca2 -dname CN=CA -genkeypair
$KT -alias e1 -dname CN=E1 -genkeypair
-$KT -alias e2 -dname CN=E2 -genkeypair
-
-# me signed by ca, self-issued
-$KT -alias me -certreq | $KT -alias ca -gencert | $KT -alias me -importcert
-# Import e1 signed by me, should add me and ca
-$KT -alias e1 -certreq | $KT -alias me -gencert | $KT -alias e1 -importcert
-$KT -alias e1 -list -v | grep '\[3\]' || { echo Bad E1; exit 1; }
+# ca signs ca1, ca1 signs ca2, all self-issued
+$KT -alias ca1 -certreq | $KT -alias ca -gencert -ext san=dns:ca1 \
+ | $KT -alias ca1 -importcert
+$KT -alias ca2 -certreq | $KT -alias ca1 -gencert -ext san=dns:ca2 \
+ | $KT -alias ca2 -importcert
-# Import (e2 signed by me,ca,me), should reorder to (e2,me,ca)
-( $KT -alias e2 -certreq | $KT -alias me -gencert; $KT -exportcert -alias ca; $KT -exportcert -alias me ) | $KT -alias e2 -importcert
-$KT -alias e2 -list -v | grep '\[3\]' || { echo Bad E2; exit 1; }
+# Import e1 signed by ca2, should add ca2 and ca1, at least 3 certs in the chain
+$KT -alias e1 -certreq | $KT -alias ca2 -gencert > e1.cert
+$KT -alias ca1 -delete
+$KT -alias ca2 -delete
+cat e1.cert | $KT -alias e1 -importcert
+$KT -alias e1 -list -v | grep '\[3\]' || { echo Bad E1; exit 1; }
echo Good