提交 33be9462 编写于 作者: L lana

Merge

#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
#
...@@ -13830,8 +13830,21 @@ ...@@ -13830,8 +13830,21 @@
0xF9D4 0x9F49 # <CJK> 0xF9D4 0x9F49 # <CJK>
0xF9D5 0x9F98 # <CJK> 0xF9D5 0x9F98 # <CJK>
# #
# from Big5.b2c-irreversible
#
0xA15A 0xFF3F #SPACING UNDERSCORE 0xA15A 0xFF3F #SPACING UNDERSCORE
0xA1FE 0x2571 #LT DIAG UP RIGHT TO LOW LEFT 0xA1FE 0x2571 #LT DIAG UP RIGHT TO LOW LEFT
0xA240 0x2572 #LT DIAG UP LEFT TO LOW RIGHTG 0xA240 0x2572 #LT DIAG UP LEFT TO LOW RIGHTG
0xA2CC 0x5341 #HANGHZOU NUMERAL TEN 0xA2CC 0x5341 #HANGHZOU NUMERAL TEN
0xA2CE 0x5345 #HANGZHOU NUMERAL THIRTY 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
#
...@@ -221,11 +221,12 @@ public final class NetworkInterface { ...@@ -221,11 +221,12 @@ public final class NetworkInterface {
* A display name is a human readable String describing the network * A display name is a human readable String describing the network
* device. * device.
* *
* @return the display name of this network interface, * @return a non-empty string representing the display name of this network
* or null if no display name is available. * interface, or null if no display name is available.
*/ */
public String getDisplayName() { public String getDisplayName() {
return displayName; /* strict TCK conformance */
return "".equals(displayName) ? null : displayName;
} }
/** /**
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -29,6 +29,7 @@ import java.util.jar.JarFile; ...@@ -29,6 +29,7 @@ import java.util.jar.JarFile;
import java.io.Console; import java.io.Console;
import java.io.File; import java.io.File;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.security.ProtectionDomain;
/** A repository of "shared secrets", which are a mechanism for /** A repository of "shared secrets", which are a mechanism for
calling implementation-private methods in another package without calling implementation-private methods in another package without
...@@ -121,6 +122,8 @@ public class SharedSecrets { ...@@ -121,6 +122,8 @@ public class SharedSecrets {
public static JavaSecurityProtectionDomainAccess public static JavaSecurityProtectionDomainAccess
getJavaSecurityProtectionDomainAccess() { getJavaSecurityProtectionDomainAccess() {
if (javaSecurityProtectionDomainAccess == null)
unsafe.ensureClassInitialized(ProtectionDomain.class);
return javaSecurityProtectionDomainAccess; return javaSecurityProtectionDomainAccess;
} }
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -77,26 +77,34 @@ public final class SunNativeProvider extends Provider { ...@@ -77,26 +77,34 @@ public final class SunNativeProvider extends Provider {
if (DEBUG) err.printStackTrace(); if (DEBUG) err.printStackTrace();
return null; return null;
} }
String gssLib = System.getProperty(LIB_PROP); String gssLibs[] = new String[0];
if (gssLib == null || gssLib.trim().equals("")) { String defaultLib = System.getProperty(LIB_PROP);
if (defaultLib == null || defaultLib.trim().equals("")) {
String osname = System.getProperty("os.name"); String osname = System.getProperty("os.name");
if (osname.startsWith("SunOS")) { if (osname.startsWith("SunOS")) {
gssLib = "libgss.so"; gssLibs = new String[]{ "libgss.so" };
} else if (osname.startsWith("Linux")) { } 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)) { for (String libName: gssLibs) {
debug("Loaded GSS library: " + gssLib); if (GSSLibStub.init(libName)) {
Oid[] mechs = GSSLibStub.indicateMechs(); debug("Loaded GSS library: " + libName);
HashMap<String, String> map = Oid[] mechs = GSSLibStub.indicateMechs();
new HashMap<String, String>(); HashMap<String, String> map =
for (int i = 0; i < mechs.length; i++) { new HashMap<String, String>();
debug("Native MF for " + mechs[i]); for (int i = 0; i < mechs.length; i++) {
map.put("GssApiMechanism." + mechs[i], debug("Native MF for " + mechs[i]);
MF_CLASS); map.put("GssApiMechanism." + mechs[i],
MF_CLASS);
}
return map;
} }
return map;
} }
return null; return null;
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -192,7 +192,6 @@ final class P11Cipher extends CipherSpi { ...@@ -192,7 +192,6 @@ final class P11Cipher extends CipherSpi {
// should not happen // should not happen
throw new ProviderException(nspe); throw new ProviderException(nspe);
} }
session = token.getOpSession();
} }
protected void engineSetMode(String mode) throws NoSuchAlgorithmException { protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
...@@ -847,18 +846,6 @@ final class P11Cipher extends CipherSpi { ...@@ -847,18 +846,6 @@ final class P11Cipher extends CipherSpi {
return n; 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) { private final void bufferInputBytes(byte[] in, int inOfs, int len) {
System.arraycopy(in, inOfs, padBuffer, padBufferLen, len); System.arraycopy(in, inOfs, padBuffer, padBufferLen, len);
padBufferLen += len; padBufferLen += len;
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -308,16 +308,4 @@ final class P11Digest extends MessageDigestSpi { ...@@ -308,16 +308,4 @@ final class P11Digest extends MessageDigestSpi {
throw new ProviderException("update() failed", e); 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();
}
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -85,7 +85,7 @@ abstract class P11Key implements Key { ...@@ -85,7 +85,7 @@ abstract class P11Key implements Key {
// flags indicating whether the key is a token object, sensitive, extractable // flags indicating whether the key is a token object, sensitive, extractable
final boolean tokenObject, 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; private final SessionKeyRef sessionKeyRef;
P11Key(String type, Session session, long keyID, String algorithm, P11Key(String type, Session session, long keyID, String algorithm,
...@@ -1051,7 +1051,12 @@ abstract class P11Key implements Key { ...@@ -1051,7 +1051,12 @@ abstract class P11Key implements Key {
} }
} }
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> { implements Comparable<SessionKeyRef> {
private static ReferenceQueue<P11Key> refQueue = private static ReferenceQueue<P11Key> refQueue =
new ReferenceQueue<P11Key>(); new ReferenceQueue<P11Key>();
...@@ -1062,14 +1067,11 @@ final class SessionKeyRef extends WeakReference<P11Key> ...@@ -1062,14 +1067,11 @@ final class SessionKeyRef extends WeakReference<P11Key>
return refQueue; return refQueue;
} }
static final private int MAX_ITERATIONS = 2;
private static void drainRefQueueBounded() { private static void drainRefQueueBounded() {
int iterations = 0; while (true) {
while (iterations < MAX_ITERATIONS) {
SessionKeyRef next = (SessionKeyRef) refQueue.poll(); SessionKeyRef next = (SessionKeyRef) refQueue.poll();
if (next != null) next.dispose(); if (next == null) break;
++iterations; next.dispose();
} }
} }
...@@ -1087,7 +1089,7 @@ final class SessionKeyRef extends WeakReference<P11Key> ...@@ -1087,7 +1089,7 @@ final class SessionKeyRef extends WeakReference<P11Key>
drainRefQueueBounded(); drainRefQueueBounded();
} }
void dispose() { private void dispose() {
refList.remove(this); refList.remove(this);
if (session.token.isValid()) { if (session.token.isValid()) {
Session newSession = null; Session newSession = null;
...@@ -1097,6 +1099,7 @@ final class SessionKeyRef extends WeakReference<P11Key> ...@@ -1097,6 +1099,7 @@ final class SessionKeyRef extends WeakReference<P11Key>
} catch (PKCS11Exception e) { } catch (PKCS11Exception e) {
// ignore // ignore
} finally { } finally {
this.clear();
session.token.releaseSession(newSession); session.token.releaseSession(newSession);
session.removeObject(); session.removeObject();
} }
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -263,16 +263,4 @@ final class P11Mac extends MacSpi { ...@@ -263,16 +263,4 @@ final class P11Mac extends MacSpi {
throw new ProviderException("update() failed", e); 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();
}
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -485,18 +485,6 @@ final class P11RSACipher extends CipherSpi { ...@@ -485,18 +485,6 @@ final class P11RSACipher extends CipherSpi {
int n = P11KeyFactory.convertKey(token, key, algorithm).keyLength(); int n = P11KeyFactory.convertKey(token, key, algorithm).keyLength();
return n; return n;
} }
protected void finalize() throws Throwable {
try {
if ((session != null) && token.isValid()) {
cancelOperation();
session = token.releaseSession(session);
}
} finally {
super.finalize();
}
}
} }
final class ConstructKeys { final class ConstructKeys {
......
...@@ -226,7 +226,6 @@ final class P11Signature extends SignatureSpi { ...@@ -226,7 +226,6 @@ final class P11Signature extends SignatureSpi {
this.buffer = buffer; this.buffer = buffer;
this.digestOID = digestOID; this.digestOID = digestOID;
this.md = md; this.md = md;
session = token.getOpSession();
} }
private void ensureInitialized() { private void ensureInitialized() {
...@@ -732,16 +731,4 @@ final class P11Signature extends SignatureSpi { ...@@ -732,16 +731,4 @@ final class P11Signature extends SignatureSpi {
throws InvalidParameterException { throws InvalidParameterException {
throw new UnsupportedOperationException("getParameter() not supported"); 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();
}
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
package sun.security.pkcs11; package sun.security.pkcs11;
import java.lang.ref.*;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
...@@ -59,11 +60,14 @@ final class Session implements Comparable<Session> { ...@@ -59,11 +60,14 @@ final class Session implements Comparable<Session> {
// this could lead to idle sessions being closed early, but that is harmless // this could lead to idle sessions being closed early, but that is harmless
private long lastAccess; private long lastAccess;
private final SessionRef sessionRef;
Session(Token token, long id) { Session(Token token, long id) {
this.token = token; this.token = token;
this.id = id; this.id = id;
createdObjects = new AtomicInteger(); createdObjects = new AtomicInteger();
id(); id();
sessionRef = new SessionRef(this, id, token);
} }
public int compareTo(Session other) { public int compareTo(Session other) {
...@@ -108,4 +112,76 @@ final class Session implements Comparable<Session> { ...@@ -108,4 +112,76 @@ final class Session implements Comparable<Session> {
return createdObjects.get() != 0; 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;
}
}
} }
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -51,10 +51,12 @@ import static sun.security.pkcs11.wrapper.PKCS11Constants.*; ...@@ -51,10 +51,12 @@ import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
* number of such sessions low. Note that we occasionally want to explicitly * number of such sessions low. Note that we occasionally want to explicitly
* close a session, see P11Signature. * close a session, see P11Signature.
* *
* NOTE that all sessions obtained from this class MUST be returned using * NOTE that sessions obtained from this class SHOULD be returned using
* either releaseSession() or closeSession() using a finally block or a * either releaseSession() or closeSession() using a finally block when
* finalizer where appropriate. Otherwise, they will be "lost", i.e. there * not needed anymore. Otherwise, they will be left for cleanup via the
* will be a resource leak eventually leading to exhaustion. * 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 * Note that sessions are automatically closed when they are not used for a
* period of time, see Session. * period of time, see Session.
...@@ -74,9 +76,6 @@ final class SessionManager { ...@@ -74,9 +76,6 @@ final class SessionManager {
// maximum number of sessions to open with this token // maximum number of sessions to open with this token
private final int maxSessions; private final int maxSessions;
// total number of active sessions
private int activeSessions;
// pool of available object sessions // pool of available object sessions
private final Pool objSessions; private final Pool objSessions;
...@@ -116,6 +115,11 @@ final class SessionManager { ...@@ -116,6 +115,11 @@ final class SessionManager {
return (maxSessions <= DEFAULT_MAX_SESSIONS); return (maxSessions <= DEFAULT_MAX_SESSIONS);
} }
// returns the total number of active sessions
int totalSessionCount() {
return SessionRef.totalCount();
}
synchronized Session getObjSession() throws PKCS11Exception { synchronized Session getObjSession() throws PKCS11Exception {
Session session = objSessions.poll(); Session session = objSessions.poll();
if (session != null) { if (session != null) {
...@@ -136,7 +140,8 @@ final class SessionManager { ...@@ -136,7 +140,8 @@ final class SessionManager {
} }
// create a new session rather than re-using an obj session // create a new session rather than re-using an obj session
// that avoids potential expensive cancels() for Signatures & RSACipher // that avoids potential expensive cancels() for Signatures & RSACipher
if (activeSessions < maxSessions) { if (maxSessions == Integer.MAX_VALUE ||
totalSessionCount() < maxSessions) {
session = openSession(); session = openSession();
return ensureValid(session); return ensureValid(session);
} }
...@@ -159,14 +164,10 @@ final class SessionManager { ...@@ -159,14 +164,10 @@ final class SessionManager {
if (debug != null) { if (debug != null) {
String location = new Exception().getStackTrace()[2].toString(); String location = new Exception().getStackTrace()[2].toString();
System.out.println("Killing session (" + location + ") active: " 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) { synchronized Session releaseSession(Session session) {
...@@ -187,7 +188,8 @@ final class SessionManager { ...@@ -187,7 +188,8 @@ final class SessionManager {
return; return;
} }
if (debug != null) { if (debug != null) {
System.out.println("Demoting session, active: " + activeSessions); System.out.println("Demoting session, active: " +
totalSessionCount());
} }
boolean present = objSessions.remove(session); boolean present = objSessions.remove(session);
if (present == false) { if (present == false) {
...@@ -199,16 +201,17 @@ final class SessionManager { ...@@ -199,16 +201,17 @@ final class SessionManager {
} }
private Session openSession() throws PKCS11Exception { private Session openSession() throws PKCS11Exception {
if (activeSessions >= maxSessions) { if ((maxSessions != Integer.MAX_VALUE) &&
(totalSessionCount() >= maxSessions)) {
throw new ProviderException("No more sessions available"); throw new ProviderException("No more sessions available");
} }
long id = token.p11.C_OpenSession long id = token.p11.C_OpenSession
(token.provider.slotID, openSessionFlags, null, null); (token.provider.slotID, openSessionFlags, null, null);
Session session = new Session(token, id); Session session = new Session(token, id);
activeSessions++;
if (debug != null) { if (debug != null) {
if (activeSessions > maxActiveSessions) { int currTotal = totalSessionCount();
maxActiveSessions = activeSessions; if (currTotal > maxActiveSessions) {
maxActiveSessions = currTotal;
if (maxActiveSessions % 10 == 0) { if (maxActiveSessions % 10 == 0) {
System.out.println("Open sessions: " + maxActiveSessions); System.out.println("Open sessions: " + maxActiveSessions);
} }
...@@ -217,13 +220,8 @@ final class SessionManager { ...@@ -217,13 +220,8 @@ final class SessionManager {
return session; return session;
} }
private void closeSession(Session session) throws PKCS11Exception { private void closeSession(Session session) {
if (session.hasObjects()) { session.close();
throw new ProviderException
("Internal error: close session with active objects");
}
token.p11.C_CloseSession(session.id());
activeSessions--;
} }
private static final class Pool { private static final class Pool {
...@@ -267,28 +265,20 @@ final class SessionManager { ...@@ -267,28 +265,20 @@ final class SessionManager {
} }
Collections.sort(pool); Collections.sort(pool);
int i = 0; int i = 0;
PKCS11Exception exc = null;
while (i < n - 1) { // always keep at least 1 session open while (i < n - 1) { // always keep at least 1 session open
oldestSession = pool.get(i); oldestSession = pool.get(i);
if (oldestSession.isLive(time)) { if (oldestSession.isLive(time)) {
break; break;
} }
i++; i++;
try { mgr.closeSession(oldestSession);
mgr.closeSession(oldestSession);
} catch (PKCS11Exception e) {
exc = e;
}
} }
if (debug != null) { if (debug != null) {
System.out.println("Closing " + i + " idle sessions, active: " System.out.println("Closing " + i + " idle sessions, active: "
+ mgr.activeSessions); + mgr.totalSessionCount());
} }
List<Session> subList = pool.subList(0, i); List<Session> subList = pool.subList(0, i);
subList.clear(); subList.clear();
if (exc != null) {
throw new ProviderException(exc);
}
} }
} }
......
...@@ -148,6 +148,7 @@ public class PKCS11Exception extends Exception { ...@@ -148,6 +148,7 @@ public class PKCS11Exception extends Exception {
0x00000115, 0x00000115,
0x00000120, 0x00000120,
0x00000121, 0x00000121,
0x00000130,
0x00000150, 0x00000150,
0x00000160, 0x00000160,
0x00000170, 0x00000170,
...@@ -156,6 +157,7 @@ public class PKCS11Exception extends Exception { ...@@ -156,6 +157,7 @@ public class PKCS11Exception extends Exception {
0x00000191, 0x00000191,
0x000001A0, 0x000001A0,
0x000001A1, 0x000001A1,
0x00000200,
0x80000000, 0x80000000,
}; };
String[] errorMessages = new String[] { String[] errorMessages = new String[] {
...@@ -234,6 +236,7 @@ public class PKCS11Exception extends Exception { ...@@ -234,6 +236,7 @@ public class PKCS11Exception extends Exception {
"CKR_WRAPPING_KEY_TYPE_INCONSISTENT", "CKR_WRAPPING_KEY_TYPE_INCONSISTENT",
"CKR_RANDOM_SEED_NOT_SUPPORTED", "CKR_RANDOM_SEED_NOT_SUPPORTED",
"CKR_RANDOM_NO_RNG", "CKR_RANDOM_NO_RNG",
"CKR_DOMAIN_PARAMS_INVALID",
"CKR_BUFFER_TOO_SMALL", "CKR_BUFFER_TOO_SMALL",
"CKR_SAVED_STATE_INVALID", "CKR_SAVED_STATE_INVALID",
"CKR_INFORMATION_SENSITIVE", "CKR_INFORMATION_SENSITIVE",
...@@ -242,6 +245,7 @@ public class PKCS11Exception extends Exception { ...@@ -242,6 +245,7 @@ public class PKCS11Exception extends Exception {
"CKR_CRYPTOKI_ALREADY_INITIALIZED", "CKR_CRYPTOKI_ALREADY_INITIALIZED",
"CKR_MUTEX_BAD", "CKR_MUTEX_BAD",
"CKR_MUTEX_NOT_LOCKED", "CKR_MUTEX_NOT_LOCKED",
"CKR_FUNCTION_REJECTED",
"CKR_VENDOR_DEFINED", "CKR_VENDOR_DEFINED",
}; };
errorMap = new HashMap<Long,String>(); errorMap = new HashMap<Long,String>();
......
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -214,7 +214,7 @@ final class CardImpl extends Card { ...@@ -214,7 +214,7 @@ final class CardImpl extends Card {
SCardEndTransaction(cardId, SCARD_LEAVE_CARD); SCardEndTransaction(cardId, SCARD_LEAVE_CARD);
} catch (PCSCException e) { } catch (PCSCException e) {
handleError(e); handleError(e);
throw new CardException("beginExclusive() failed", e); throw new CardException("endExclusive() failed", e);
} finally { } finally {
exclusiveThread = null; exclusiveThread = null;
} }
......
...@@ -1211,6 +1211,14 @@ public final class KeyTool { ...@@ -1211,6 +1211,14 @@ public final class KeyTool {
X509CertImpl cert = new X509CertImpl(info); X509CertImpl cert = new X509CertImpl(info);
cert.sign(privateKey, sigAlgName); cert.sign(privateKey, sigAlgName);
dumpCert(cert, out); 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 @@ public final class KeyTool { ...@@ -2640,19 +2648,33 @@ public final class KeyTool {
} }
/** /**
* 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) private static Certificate getTrustedSigner(Certificate cert, KeyStore ks)
throws Exception throws Exception {
{ if (ks.getCertificateAlias(cert) != null) {
if (keyStore.getCertificateAlias(cert) != null) { return cert;
return true; // found in own keystore
} }
if (trustcacerts && (caks != null) && for (Enumeration<String> aliases = ks.aliases();
(caks.getCertificateAlias(cert) != null)) { aliases.hasMoreElements(); ) {
return true; // found in CA keystore 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 @@ public final class KeyTool { ...@@ -2985,48 +3007,33 @@ public final class KeyTool {
return replyCerts; 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]; Certificate topCert = replyCerts[replyCerts.length-1];
if (!isTrusted(topCert)) { Certificate root = getTrustedSigner(topCert, keyStore);
boolean verified = false; if (root == null && trustcacerts && caks != null) {
Certificate rootCert = null; root = getTrustedSigner(topCert, caks);
if (trustcacerts && (caks!= null)) { }
for (Enumeration<String> aliases = caks.aliases(); if (root == null) {
aliases.hasMoreElements(); ) { System.err.println();
String name = aliases.nextElement(); System.err.println
rootCert = caks.getCertificate(name); (rb.getString("Top-level certificate in reply:\n"));
if (rootCert != null) { printX509Cert((X509Certificate)topCert, System.out);
try { System.err.println();
topCert.verify(rootCert.getPublicKey()); System.err.print(rb.getString("... is not trusted. "));
verified = true; String reply = getYesNoReply
break; (rb.getString("Install reply anyway? [no]: "));
} catch (Exception e) { if ("NO".equals(reply)) {
} return null;
}
}
} }
if (!verified) { } else {
System.err.println(); if (root != topCert) {
System.err.println // append the root CA cert to the chain
(rb.getString("Top-level certificate in reply:\n")); Certificate[] tmpCerts =
printX509Cert((X509Certificate)topCert, System.out); new Certificate[replyCerts.length+1];
System.err.println(); System.arraycopy(replyCerts, 0, tmpCerts, 0,
System.err.print(rb.getString("... is not trusted. ")); replyCerts.length);
String reply = getYesNoReply tmpCerts[tmpCerts.length-1] = root;
(rb.getString("Install reply anyway? [no]: ")); replyCerts = tmpCerts;
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;
}
} }
} }
......
...@@ -81,6 +81,11 @@ public final class TimestampedSigner extends ContentSigner { ...@@ -81,6 +81,11 @@ public final class TimestampedSigner extends ContentSigner {
*/ */
private static final String KP_TIMESTAMPING_OID = "1.3.6.1.5.5.7.3.8"; 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. * Object identifier for the timestamping access descriptors.
*/ */
...@@ -357,34 +362,26 @@ public final class TimestampedSigner extends ContentSigner { ...@@ -357,34 +362,26 @@ public final class TimestampedSigner extends ContentSigner {
} }
// Examine the TSA's certificate (if present) // Examine the TSA's certificate (if present)
List<String> keyPurposes = null; for (SignerInfo si: tsToken.getSignerInfos()) {
X509Certificate[] certs = tsToken.getCertificates(); X509Certificate cert = si.getCertificate(tsToken);
if (certs != null && certs.length > 0) { if (cert == null) {
// Use certficate from the TSP reply // Error, we've already set tsRequestCertificate = true
// Pick out the cert for the TS server, which is the end-entity throw new CertificateException(
// one inside the chain. "Certificate not included in timestamp token");
for (X509Certificate cert: certs) { } else {
boolean isSigner = false; if (!cert.getCriticalExtensionOIDs().contains(
for (X509Certificate cert2: certs) { EXTENDED_KEY_USAGE_OID)) {
if (cert != cert2) { throw new CertificateException(
if (cert.getSubjectDN().equals(cert2.getIssuerDN())) { "Certificate is not valid for timestamping");
isSigner = true;
break;
}
}
} }
if (!isSigner) { List keyPurposes = cert.getExtendedKeyUsage();
keyPurposes = cert.getExtendedKeyUsage(); if (keyPurposes == null ||
if (keyPurposes == null || ! keyPurposes.contains(KP_TIMESTAMPING_OID)) {
! keyPurposes.contains(KP_TIMESTAMPING_OID)) { throw new CertificateException(
throw new CertificateException( "Certificate is not valid for timestamping");
"Certificate is not valid for timestamping");
}
break;
} }
} }
} }
return tsReply.getEncodedToken(); return tsReply.getEncodedToken();
} }
} }
...@@ -171,7 +171,7 @@ public class X509Key implements PublicKey { ...@@ -171,7 +171,7 @@ public class X509Key implements PublicKey {
in.data.getUnalignedBitString()); in.data.getUnalignedBitString());
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {
throw new IOException("subject key, " + e.getMessage()); throw new IOException("subject key, " + e.getMessage(), e);
} }
if (in.data.available() != 0) if (in.data.available() != 0)
...@@ -224,7 +224,7 @@ public class X509Key implements PublicKey { ...@@ -224,7 +224,7 @@ public class X509Key implements PublicKey {
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
// Return generic X509Key with opaque key data (see below) // Return generic X509Key with opaque key data (see below)
} catch (InvalidKeySpecException e) { } catch (InvalidKeySpecException e) {
throw new InvalidKeyException(e.getMessage()); throw new InvalidKeyException(e.getMessage(), e);
} }
/* /*
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
* 4872664 4803179 4892980 4900747 4945394 4938995 4979006 4994840 4997476 * 4872664 4803179 4892980 4900747 4945394 4938995 4979006 4994840 4997476
* 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940 * 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940
* 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133 * 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133
* 6350801 6676425 6878475 6919132 * 6350801 6676425 6878475 6919132 6931676
*/ */
import java.util.regex.*; import java.util.regex.*;
...@@ -3515,7 +3515,7 @@ public class RegExTest { ...@@ -3515,7 +3515,7 @@ public class RegExTest {
report("NamedGroupCapture"); report("NamedGroupCapture");
} }
// This is for bug 6969132 // This is for bug 6919132
private static void nonBmpClassComplementTest() throws Exception { private static void nonBmpClassComplementTest() throws Exception {
Pattern p = Pattern.compile("\\P{Lu}"); Pattern p = Pattern.compile("\\P{Lu}");
Matcher m = p.matcher(new String(new int[] {0x1d400}, 0, 1)); Matcher m = p.matcher(new String(new int[] {0x1d400}, 0, 1));
......
/*
* 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);
}
}
#
# 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}
...@@ -623,6 +623,11 @@ public class DNSIdentities { ...@@ -623,6 +623,11 @@ public class DNSIdentities {
*/ */
volatile static boolean serverReady = false; volatile static boolean serverReady = false;
/*
* Is the connection ready to close?
*/
volatile static boolean closeReady = false;
/* /*
* Turn on SSL debugging? * Turn on SSL debugging?
*/ */
...@@ -652,9 +657,6 @@ public class DNSIdentities { ...@@ -652,9 +657,6 @@ public class DNSIdentities {
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
sslSocket.setNeedClientAuth(true); sslSocket.setNeedClientAuth(true);
if (sslSocket instanceof SSLSocketImpl) {
((SSLSocketImpl)sslSocket).trySetHostnameVerification("HTTPS");
}
PrintStream out = PrintStream out =
new PrintStream(sslSocket.getOutputStream()); new PrintStream(sslSocket.getOutputStream());
...@@ -670,11 +672,14 @@ public class DNSIdentities { ...@@ -670,11 +672,14 @@ public class DNSIdentities {
out.print("Testing\r\n"); out.print("Testing\r\n");
out.flush(); out.flush();
} finally { } finally {
// close the socket // close the socket
Thread.sleep(2000); while (!closeReady) {
System.out.println("Server closing socket"); Thread.sleep(50);
sslSocket.close(); }
serverReady = false;
System.out.println("Server closing socket");
sslSocket.close();
serverReady = false;
} }
} }
...@@ -704,12 +709,17 @@ public class DNSIdentities { ...@@ -704,12 +709,17 @@ public class DNSIdentities {
URL url = new URL("https://localhost:" + serverPort+"/"); URL url = new URL("https://localhost:" + serverPort+"/");
System.out.println("url is "+url.toString()); 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;
}
} }
/* /*
......
...@@ -60,6 +60,11 @@ public class HttpsPost { ...@@ -60,6 +60,11 @@ public class HttpsPost {
*/ */
volatile static boolean serverReady = false; volatile static boolean serverReady = false;
/*
* Is the connection ready to close?
*/
volatile static boolean closeReady = false;
/* /*
* Turn on SSL debugging? * Turn on SSL debugging?
*/ */
...@@ -98,25 +103,34 @@ public class HttpsPost { ...@@ -98,25 +103,34 @@ public class HttpsPost {
serverReady = true; serverReady = true;
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
InputStream sslIS = sslSocket.getInputStream(); try {
OutputStream sslOS = sslSocket.getOutputStream(); InputStream sslIS = sslSocket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(sslIS)); OutputStream sslOS = sslSocket.getOutputStream();
PrintStream ps = new PrintStream(sslOS); BufferedReader br =
// process HTTP POST request from client new BufferedReader(new InputStreamReader(sslIS));
System.out.println("status line: "+br.readLine()); PrintStream ps = new PrintStream(sslOS);
String msg = null;
while ((msg = br.readLine()) != null && msg.length() > 0); // process HTTP POST request from client
System.out.println("status line: "+br.readLine());
msg = br.readLine(); String msg = null;
if (msg.equals(postMsg)) { while ((msg = br.readLine()) != null && msg.length() > 0);
ps.println("HTTP/1.1 200 OK\n\n");
} else { msg = br.readLine();
ps.println("HTTP/1.1 500 Not OK\n\n"); 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 @@ public class HttpsPost { ...@@ -144,12 +158,17 @@ public class HttpsPost {
http.setRequestMethod("POST"); http.setRequestMethod("POST");
PrintStream ps = new PrintStream(http.getOutputStream()); PrintStream ps = new PrintStream(http.getOutputStream());
ps.println(postMsg); try {
ps.flush(); ps.println(postMsg);
if (http.getResponseCode() != 200) { ps.flush();
throw new RuntimeException("test Failed"); if (http.getResponseCode() != 200) {
throw new RuntimeException("test Failed");
}
} finally {
ps.close();
http.disconnect();
closeReady = true;
} }
ps.close();
} }
static class NameVerifier implements HostnameVerifier { static class NameVerifier implements HostnameVerifier {
......
...@@ -623,6 +623,11 @@ public class IPAddressDNSIdentities { ...@@ -623,6 +623,11 @@ public class IPAddressDNSIdentities {
*/ */
volatile static boolean serverReady = false; volatile static boolean serverReady = false;
/*
* Is the connection ready to close?
*/
volatile static boolean closeReady = false;
/* /*
* Turn on SSL debugging? * Turn on SSL debugging?
*/ */
...@@ -652,9 +657,6 @@ public class IPAddressDNSIdentities { ...@@ -652,9 +657,6 @@ public class IPAddressDNSIdentities {
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
sslSocket.setNeedClientAuth(true); sslSocket.setNeedClientAuth(true);
if (sslSocket instanceof SSLSocketImpl) {
((SSLSocketImpl)sslSocket).trySetHostnameVerification("HTTPS");
}
PrintStream out = PrintStream out =
new PrintStream(sslSocket.getOutputStream()); new PrintStream(sslSocket.getOutputStream());
...@@ -670,11 +672,14 @@ public class IPAddressDNSIdentities { ...@@ -670,11 +672,14 @@ public class IPAddressDNSIdentities {
out.print("Testing\r\n"); out.print("Testing\r\n");
out.flush(); out.flush();
} finally { } finally {
// close the socket // close the socket
Thread.sleep(2000); while (!closeReady) {
System.out.println("Server closing socket"); Thread.sleep(50);
sslSocket.close(); }
serverReady = false;
System.out.println("Server closing socket");
sslSocket.close();
serverReady = false;
} }
} }
...@@ -716,7 +721,10 @@ public class IPAddressDNSIdentities { ...@@ -716,7 +721,10 @@ public class IPAddressDNSIdentities {
// no subject alternative names matching IP address 127.0.0.1 found // no subject alternative names matching IP address 127.0.0.1 found
// that's the expected exception, ignore it. // that's the expected exception, ignore it.
} finally { } finally {
http.disconnect(); if (http != null) {
http.disconnect();
}
closeReady = true;
} }
} }
......
...@@ -624,6 +624,11 @@ public class IPAddressIPIdentities { ...@@ -624,6 +624,11 @@ public class IPAddressIPIdentities {
*/ */
volatile static boolean serverReady = false; volatile static boolean serverReady = false;
/*
* Is the connection ready to close?
*/
volatile static boolean closeReady = false;
/* /*
* Turn on SSL debugging? * Turn on SSL debugging?
*/ */
...@@ -653,9 +658,6 @@ public class IPAddressIPIdentities { ...@@ -653,9 +658,6 @@ public class IPAddressIPIdentities {
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
sslSocket.setNeedClientAuth(true); sslSocket.setNeedClientAuth(true);
if (sslSocket instanceof SSLSocketImpl) {
((SSLSocketImpl)sslSocket).trySetHostnameVerification("HTTPS");
}
PrintStream out = PrintStream out =
new PrintStream(sslSocket.getOutputStream()); new PrintStream(sslSocket.getOutputStream());
...@@ -672,7 +674,10 @@ public class IPAddressIPIdentities { ...@@ -672,7 +674,10 @@ public class IPAddressIPIdentities {
out.flush(); out.flush();
} finally { } finally {
// close the socket // close the socket
Thread.sleep(2000); while (!closeReady) {
Thread.sleep(50);
}
System.out.println("Server closing socket"); System.out.println("Server closing socket");
sslSocket.close(); sslSocket.close();
serverReady = false; serverReady = false;
...@@ -705,12 +710,17 @@ public class IPAddressIPIdentities { ...@@ -705,12 +710,17 @@ public class IPAddressIPIdentities {
URL url = new URL("https://127.0.0.1:" + serverPort+"/"); URL url = new URL("https://127.0.0.1:" + serverPort+"/");
System.out.println("url is "+url.toString()); 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;
}
} }
/* /*
......
...@@ -624,6 +624,11 @@ public class IPIdentities { ...@@ -624,6 +624,11 @@ public class IPIdentities {
*/ */
volatile static boolean serverReady = false; volatile static boolean serverReady = false;
/*
* Is the connection ready to close?
*/
volatile static boolean closeReady = false;
/* /*
* Turn on SSL debugging? * Turn on SSL debugging?
*/ */
...@@ -653,9 +658,6 @@ public class IPIdentities { ...@@ -653,9 +658,6 @@ public class IPIdentities {
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
sslSocket.setNeedClientAuth(true); sslSocket.setNeedClientAuth(true);
if (sslSocket instanceof SSLSocketImpl) {
((SSLSocketImpl)sslSocket).trySetHostnameVerification("HTTPS");
}
PrintStream out = PrintStream out =
new PrintStream(sslSocket.getOutputStream()); new PrintStream(sslSocket.getOutputStream());
...@@ -672,7 +674,10 @@ public class IPIdentities { ...@@ -672,7 +674,10 @@ public class IPIdentities {
out.flush(); out.flush();
} finally { } finally {
// close the socket // close the socket
Thread.sleep(2000); while (!closeReady) {
Thread.sleep(50);
}
System.out.println("Server closing socket"); System.out.println("Server closing socket");
sslSocket.close(); sslSocket.close();
serverReady = false; serverReady = false;
...@@ -705,12 +710,17 @@ public class IPIdentities { ...@@ -705,12 +710,17 @@ public class IPIdentities {
URL url = new URL("https://localhost:" + serverPort+"/"); URL url = new URL("https://localhost:" + serverPort+"/");
System.out.println("url is "+url.toString()); 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;
}
} }
/* /*
......
...@@ -623,6 +623,11 @@ public class Identities { ...@@ -623,6 +623,11 @@ public class Identities {
*/ */
volatile static boolean serverReady = false; volatile static boolean serverReady = false;
/*
* Is the connection ready to close?
*/
volatile static boolean closeReady = false;
/* /*
* Turn on SSL debugging? * Turn on SSL debugging?
*/ */
...@@ -652,9 +657,6 @@ public class Identities { ...@@ -652,9 +657,6 @@ public class Identities {
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
sslSocket.setNeedClientAuth(true); sslSocket.setNeedClientAuth(true);
if (sslSocket instanceof SSLSocketImpl) {
((SSLSocketImpl)sslSocket).trySetHostnameVerification("HTTPS");
}
PrintStream out = PrintStream out =
new PrintStream(sslSocket.getOutputStream()); new PrintStream(sslSocket.getOutputStream());
...@@ -671,7 +673,10 @@ public class Identities { ...@@ -671,7 +673,10 @@ public class Identities {
out.flush(); out.flush();
} finally { } finally {
// close the socket // close the socket
Thread.sleep(2000); while (!closeReady) {
Thread.sleep(50);
}
System.out.println("Server closing socket"); System.out.println("Server closing socket");
sslSocket.close(); sslSocket.close();
serverReady = false; serverReady = false;
...@@ -704,12 +709,17 @@ public class Identities { ...@@ -704,12 +709,17 @@ public class Identities {
URL url = new URL("https://localhost:" + serverPort+"/"); URL url = new URL("https://localhost:" + serverPort+"/");
System.out.println("url is "+url.toString()); 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;
}
} }
/* /*
......
...@@ -60,6 +60,11 @@ public class Redirect { ...@@ -60,6 +60,11 @@ public class Redirect {
*/ */
volatile static boolean serverReady = false; volatile static boolean serverReady = false;
/*
* Is the connection ready to close?
*/
volatile static boolean closeReady = false;
/* /*
* Turn on SSL debugging? * Turn on SSL debugging?
*/ */
...@@ -98,24 +103,33 @@ public class Redirect { ...@@ -98,24 +103,33 @@ public class Redirect {
serverReady = true; serverReady = true;
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
InputStream sslIS = sslSocket.getInputStream(); try {
OutputStream sslOS = sslSocket.getOutputStream(); InputStream sslIS = sslSocket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(sslIS)); OutputStream sslOS = sslSocket.getOutputStream();
PrintStream ps = new PrintStream(sslOS); BufferedReader br =
// process HTTP POST request from client new BufferedReader(new InputStreamReader(sslIS));
System.out.println("status line: "+br.readLine()); PrintStream ps = new PrintStream(sslOS);
ps.println("HTTP/1.1 307 Redirect"); // process HTTP POST request from client
ps.println("Location: https://localhost:"+serverPort+"/index.html\n\n"); System.out.println("status line: "+br.readLine());
ps.flush();
sslSocket = (SSLSocket) sslServerSocket.accept(); ps.println("HTTP/1.1 307 Redirect");
sslOS = sslSocket.getOutputStream(); ps.println("Location: https://localhost:" + serverPort +
ps = new PrintStream(sslOS); "/index.html\n\n");
ps.println("HTTP/1.1 200 Redirect succeeded\n\n"); ps.flush();
ps.flush(); sslSocket = (SSLSocket) sslServerSocket.accept();
Thread.sleep(2000); sslOS = sslSocket.getOutputStream();
sslSocket.close(); ps = new PrintStream(sslOS);
sslServerSocket.close(); 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 @@ public class Redirect { ...@@ -139,10 +153,14 @@ public class Redirect {
HttpsURLConnection.setDefaultHostnameVerifier( HttpsURLConnection.setDefaultHostnameVerifier(
new NameVerifier()); new NameVerifier());
HttpsURLConnection http = (HttpsURLConnection)url.openConnection(); HttpsURLConnection http = (HttpsURLConnection)url.openConnection();
try {
System.out.println("response header: "+http.getHeaderField(0)); System.out.println("response header: "+http.getHeaderField(0));
if (http.getResponseCode() != 200) { if (http.getResponseCode() != 200) {
throw new RuntimeException("test Failed"); throw new RuntimeException("test Failed");
}
} finally {
http.disconnect();
closeReady = true;
} }
} }
......
/*
* 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");
}
}
}
#
# 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
# #
# 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. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
# #
# This code is free software; you can redistribute it and/or modify it # This code is free software; you can redistribute it and/or modify it
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
# #
# @test # @test
# @bug 6825352 # @bug 6825352 6937978
# @summary support self-issued certificate in keytool # @summary support self-issued certificate in keytool and let -gencert generate the chain
# #
# @run shell selfissued.sh # @run shell selfissued.sh
# #
...@@ -50,20 +50,22 @@ KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystor ...@@ -50,20 +50,22 @@ KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystor
rm $KS rm $KS
$KT -alias ca -dname CN=CA -genkeypair $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 e1 -dname CN=E1 -genkeypair
$KT -alias e2 -dname CN=E2 -genkeypair
# me signed by ca, self-issued # ca signs ca1, ca1 signs ca2, all self-issued
$KT -alias me -certreq | $KT -alias ca -gencert | $KT -alias me -importcert $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 e1 signed by me, should add me and ca # Import e1 signed by ca2, should add ca2 and ca1, at least 3 certs in the chain
$KT -alias e1 -certreq | $KT -alias me -gencert | $KT -alias e1 -importcert $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; } $KT -alias e1 -list -v | grep '\[3\]' || { echo Bad E1; exit 1; }
# 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; }
echo Good echo Good
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册