--- a/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/com/sun/jarsigner/ContentSignerParameters.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003 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
@@ -26,7 +26,9 @@
package com.sun.jarsigner;
import java.net.URI;
+import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
+import java.util.Set;
import java.util.zip.ZipFile;
/**
@@ -81,6 +83,13 @@
public X509Certificate[] getSignerCertificateChain();
/**
+ * Retrieves the signer's X.509 CRLs.
+ *
+ * @return An unmodifiable set of X.509 CRLs (never <code>null</code>)
+ */
+ public Set<X509CRL> getCRLs();
+
+ /**
* Retrieves the content that was signed.
* The content is the JAR file's signature file.
*
--- a/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-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
@@ -717,7 +717,7 @@
for (int i = 0; i < encKeys.length; i++) {
System.out.println("EncryptionKey: keyType=" +
encKeys[i].getEType() + " keyBytes (hex dump)=" +
- hd.encode(encKeys[i].getBytes()));
+ hd.encodeBuffer(encKeys[i].getBytes()));
}
}
--- a/jdk/src/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/com/sun/security/jgss/AuthorizationDataEntry.java Tue May 11 16:35:36 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
@@ -63,6 +63,6 @@
public String toString() {
return "AuthorizationDataEntry: type="+type+", data=" +
data.length + " bytes:\n" +
- new sun.misc.HexDumpEncoder().encode(data);
+ new sun.misc.HexDumpEncoder().encodeBuffer(data);
}
}
--- a/jdk/src/share/classes/java/io/ByteArrayOutputStream.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/java/io/ByteArrayOutputStream.java Tue May 11 16:35:36 2010 -0700
@@ -78,17 +78,50 @@
}
/**
+ * Increases the capacity if necessary to ensure that it can hold
+ * at least the number of elements specified by the minimum
+ * capacity argument.
+ *
+ * @param minCapacity the desired minimum capacity
+ * @throws OutOfMemoryError if {@code minCapacity < 0}. This is
+ * interpreted as a request for the unsatisfiably large capacity
+ * {@code (long) Integer.MAX_VALUE + (minCapacity - Integer.MAX_VALUE)}.
+ */
+ private void ensureCapacity(int minCapacity) {
+ // overflow-conscious code
+ if (minCapacity - buf.length > 0)
+ grow(minCapacity);
+ }
+
+ /**
+ * Increases the capacity to ensure that it can hold at least the
+ * number of elements specified by the minimum capacity argument.
+ *
+ * @param minCapacity the desired minimum capacity
+ */
+ private void grow(int minCapacity) {
+ // overflow-conscious code
+ int oldCapacity = buf.length;
+ int newCapacity = oldCapacity << 1;
+ if (newCapacity - minCapacity < 0)
+ newCapacity = minCapacity;
+ if (newCapacity < 0) {
+ if (minCapacity < 0) // overflow
+ throw new OutOfMemoryError();
+ newCapacity = Integer.MAX_VALUE;
+ }
+ buf = Arrays.copyOf(buf, newCapacity);
+ }
+
+ /**
* Writes the specified byte to this byte array output stream.
*
* @param b the byte to be written.
*/
public synchronized void write(int b) {
- int newcount = count + 1;
- if (newcount > buf.length) {
- buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
- }
- buf[count] = (byte)b;
- count = newcount;
+ ensureCapacity(count + 1);
+ buf[count] = (byte) b;
+ count += 1;
}
/**
@@ -101,17 +134,12 @@
*/
public synchronized void write(byte b[], int off, int len) {
if ((off < 0) || (off > b.length) || (len < 0) ||
- ((off + len) > b.length) || ((off + len) < 0)) {
+ ((off + len) - b.length > 0)) {
throw new IndexOutOfBoundsException();
- } else if (len == 0) {
- return;
}
- int newcount = count + len;
- if (newcount > buf.length) {
- buf = Arrays.copyOf(buf, Math.max(buf.length << 1, newcount));
- }
+ ensureCapacity(count + len);
System.arraycopy(b, off, buf, count, len);
- count = newcount;
+ count += len;
}
/**
--- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java Tue May 11 16:35:36 2010 -0700
@@ -36,6 +36,8 @@
* sequence can be changed through certain method calls.
*
* @author Michael McCloskey
+ * @author Martin Buchholz
+ * @author Ulf Zibis
* @since 1.5
*/
abstract class AbstractStringBuilder implements Appendable, CharSequence {
@@ -98,9 +100,16 @@
* @param minimumCapacity the minimum desired capacity.
*/
public void ensureCapacity(int minimumCapacity) {
- if (minimumCapacity > value.length) {
+ ensureCapacityInternal(minimumCapacity);
+ }
+
+ /**
+ * This method has the same contract as ensureCapacity, but is
+ * never synchronized.
+ */
+ private void ensureCapacityInternal(int minimumCapacity) {
+ if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity);
- }
}
/**
@@ -108,11 +117,13 @@
* size check or synchronization.
*/
void expandCapacity(int minimumCapacity) {
- int newCapacity = (value.length + 1) * 2;
+ int newCapacity = value.length * 2;
+ if (newCapacity - minimumCapacity < 0)
+ newCapacity = minimumCapacity;
if (newCapacity < 0) {
+ if (minimumCapacity < 0) // overflow
+ throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
- } else if (minimumCapacity > newCapacity) {
- newCapacity = minimumCapacity;
}
value = Arrays.copyOf(value, newCapacity);
}
@@ -158,8 +169,7 @@
public void setLength(int newLength) {
if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength);
- if (newLength > value.length)
- expandCapacity(newLength);
+ ensureCapacityInternal(newLength);
if (count < newLength) {
for (; count < newLength; count++)
@@ -400,12 +410,9 @@
public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
int len = str.length();
- if (len == 0) return this;
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + len);
str.getChars(0, len, value, count);
- count = newCount;
+ count += len;
return this;
}
@@ -414,11 +421,9 @@
if (sb == null)
return append("null");
int len = sb.length();
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + len);
sb.getChars(0, len, value, count);
- count = newCount;
+ count += len;
return this;
}
@@ -470,14 +475,10 @@
"start " + start + ", end " + end + ", s.length() "
+ s.length());
int len = end - start;
- if (len == 0)
- return this;
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
- for (int i=start; i<end; i++)
- value[count++] = s.charAt(i);
- count = newCount;
+ ensureCapacityInternal(count + len);
+ for (int i = start, j = count; i < end; i++, j++)
+ value[j] = s.charAt(i);
+ count += len;
return this;
}
@@ -498,11 +499,10 @@
* @return a reference to this object.
*/
public AbstractStringBuilder append(char[] str) {
- int newCount = count + str.length;
- if (newCount > value.length)
- expandCapacity(newCount);
- System.arraycopy(str, 0, value, count, str.length);
- count = newCount;
+ int len = str.length;
+ ensureCapacityInternal(count + len);
+ System.arraycopy(str, 0, value, count, len);
+ count += len;
return this;
}
@@ -529,11 +529,9 @@
* or {@code offset+len > str.length}
*/
public AbstractStringBuilder append(char str[], int offset, int len) {
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + len);
System.arraycopy(str, offset, value, count, len);
- count = newCount;
+ count += len;
return this;
}
@@ -551,17 +549,13 @@
*/
public AbstractStringBuilder append(boolean b) {
if (b) {
- int newCount = count + 4;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + 4);
value[count++] = 't';
value[count++] = 'r';
value[count++] = 'u';
value[count++] = 'e';
} else {
- int newCount = count + 5;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + 5);
value[count++] = 'f';
value[count++] = 'a';
value[count++] = 'l';
@@ -587,9 +581,7 @@
* @return a reference to this object.
*/
public AbstractStringBuilder append(char c) {
- int newCount = count + 1;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + 1);
value[count++] = c;
return this;
}
@@ -614,8 +606,7 @@
int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
: Integer.stringSize(i);
int spaceNeeded = count + appendedLength;
- if (spaceNeeded > value.length)
- expandCapacity(spaceNeeded);
+ ensureCapacityInternal(spaceNeeded);
Integer.getChars(i, spaceNeeded, value);
count = spaceNeeded;
return this;
@@ -641,8 +632,7 @@
int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
: Long.stringSize(l);
int spaceNeeded = count + appendedLength;
- if (spaceNeeded > value.length)
- expandCapacity(spaceNeeded);
+ ensureCapacityInternal(spaceNeeded);
Long.getChars(l, spaceNeeded, value);
count = spaceNeeded;
return this;
@@ -738,10 +728,7 @@
if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
n++;
}
- int newCount = count + n;
- if (newCount > value.length) {
- expandCapacity(newCount);
- }
+ ensureCapacityInternal(count + n);
if (n == 1) {
value[count++] = (char) codePoint;
} else {
@@ -807,8 +794,7 @@
end = count;
int len = str.length();
int newCount = count + len - (end - start);
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(newCount);
System.arraycopy(value, end, value, start + len, count - end);
str.getChars(value, start);
@@ -915,12 +901,10 @@
throw new StringIndexOutOfBoundsException(
"offset " + offset + ", len " + len + ", str.length "
+ str.length);
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + len);
System.arraycopy(value, index, value, index + len, count - index);
System.arraycopy(str, offset, value, index, len);
- count = newCount;
+ count += len;
return this;
}
@@ -984,12 +968,10 @@
if (str == null)
str = "null";
int len = str.length();
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + len);
System.arraycopy(value, offset, value, offset + len, count - offset);
str.getChars(value, offset);
- count = newCount;
+ count += len;
return this;
}
@@ -1021,12 +1003,10 @@
if ((offset < 0) || (offset > length()))
throw new StringIndexOutOfBoundsException(offset);
int len = str.length;
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + len);
System.arraycopy(value, offset, value, offset + len, count - offset);
System.arraycopy(str, 0, value, offset, len);
- count = newCount;
+ count += len;
return this;
}
@@ -1114,16 +1094,12 @@
"start " + start + ", end " + end + ", s.length() "
+ s.length());
int len = end - start;
- if (len == 0)
- return this;
- int newCount = count + len;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + len);
System.arraycopy(value, dstOffset, value, dstOffset + len,
count - dstOffset);
for (int i=start; i<end; i++)
value[dstOffset++] = s.charAt(i);
- count = newCount;
+ count += len;
return this;
}
@@ -1170,12 +1146,10 @@
* @throws IndexOutOfBoundsException if the offset is invalid.
*/
public AbstractStringBuilder insert(int offset, char c) {
- int newCount = count + 1;
- if (newCount > value.length)
- expandCapacity(newCount);
+ ensureCapacityInternal(count + 1);
System.arraycopy(value, offset, value, offset + 1, count - offset);
value[offset] = c;
- count = newCount;
+ count += 1;
return this;
}
--- a/jdk/src/share/classes/java/lang/String.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/java/lang/String.java Tue May 11 16:35:36 2010 -0700
@@ -2551,8 +2551,8 @@
* Examples are programming language identifiers, protocol keys, and HTML
* tags.
* For instance, <code>"TITLE".toLowerCase()</code> in a Turkish locale
- * returns <code>"t\u0131tle"</code>, where '\u0131' is the LATIN SMALL
- * LETTER DOTLESS I character.
+ * returns <code>"t\u005Cu0131tle"</code>, where '\u005Cu0131' is the
+ * LATIN SMALL LETTER DOTLESS I character.
* To obtain correct results for locale insensitive strings, use
* <code>toLowerCase(Locale.ENGLISH)</code>.
* <p>
@@ -2714,8 +2714,8 @@
* Examples are programming language identifiers, protocol keys, and HTML
* tags.
* For instance, <code>"title".toUpperCase()</code> in a Turkish locale
- * returns <code>"T\u0130TLE"</code>, where '\u0130' is the LATIN CAPITAL
- * LETTER I WITH DOT ABOVE character.
+ * returns <code>"T\u005Cu0130TLE"</code>, where '\u005Cu0130' is the
+ * LATIN CAPITAL LETTER I WITH DOT ABOVE character.
* To obtain correct results for locale insensitive strings, use
* <code>toUpperCase(Locale.ENGLISH)</code>.
* <p>
--- a/jdk/src/share/classes/java/net/DatagramSocket.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/java/net/DatagramSocket.java Tue May 11 16:35:36 2010 -0700
@@ -401,29 +401,40 @@
* send or receive may throw a PortUnreachableException. Note, there is no
* guarantee that the exception will be thrown.
*
- * <p>A caller's permission to send and receive datagrams to a
- * given host and port are checked at connect time. When a socket
- * is connected, receive and send <b>will not
- * perform any security checks</b> on incoming and outgoing
- * packets, other than matching the packet's and the socket's
- * address and port. On a send operation, if the packet's address
- * is set and the packet's address and the socket's address do not
- * match, an IllegalArgumentException will be thrown. A socket
- * connected to a multicast address may only be used to send packets.
+ * <p> If a security manager has been installed then it is invoked to check
+ * access to the remote address. Specifically, if the given {@code address}
+ * is a {@link InetAddress#isMulticastAddress multicast address},
+ * the security manager's {@link
+ * java.lang.SecurityManager#checkMulticast(InetAddress)
+ * checkMulticast} method is invoked with the given {@code address}.
+ * Otherwise, the security manager's {@link
+ * java.lang.SecurityManager#checkConnect(String,int) checkConnect}
+ * and {@link java.lang.SecurityManager#checkAccept checkAccept} methods
+ * are invoked, with the given {@code address} and {@code port}, to
+ * verify that datagrams are permitted to be sent and received
+ * respectively.
+ *
+ * <p> When a socket is connected, {@link #receive receive} and
+ * {@link #send send} <b>will not perform any security checks</b>
+ * on incoming and outgoing packets, other than matching the packet's
+ * and the socket's address and port. On a send operation, if the
+ * packet's address is set and the packet's address and the socket's
+ * address do not match, an {@code IllegalArgumentException} will be
+ * thrown. A socket connected to a multicast address may only be used
+ * to send packets.
*
* @param address the remote address for the socket
*
* @param port the remote port for the socket.
*
- * @exception IllegalArgumentException if the address is null,
- * or the port is out of range.
+ * @throws IllegalArgumentException
+ * if the address is null, or the port is out of range.
*
- * @exception SecurityException if the caller is not allowed to
- * send datagrams to and receive datagrams from the address and port.
+ * @throws SecurityException
+ * if a security manager has been installed and it does
+ * not permit access to the given remote address
*
* @see #disconnect
- * @see #send
- * @see #receive
*/
public void connect(InetAddress address, int port) {
try {
@@ -435,13 +446,25 @@
/**
* Connects this socket to a remote socket address (IP address + port number).
- * <p>
+ *
+ * <p> If given an {@link InetSocketAddress InetSocketAddress}, this method
+ * behaves as if invoking {@link #connect(InetAddress,int) connect(InetAddress,int)}
+ * with the the given socket addresses IP address and port number.
+ *
* @param addr The remote address.
- * @throws SocketException if the connect fails
- * @throws IllegalArgumentException if addr is null or addr is a SocketAddress
- * subclass not supported by this socket
+ *
+ * @throws SocketException
+ * if the connect fails
+ *
+ * @throws IllegalArgumentException
+ * if {@code addr} is {@code null}, or {@code addr} is a SocketAddress
+ * subclass not supported by this socket
+ *
+ * @throws SecurityException
+ * if a security manager has been installed and it does
+ * not permit access to the given remote address
+ *
* @since 1.4
- * @see #connect
*/
public void connect(SocketAddress addr) throws SocketException {
if (addr == null)
--- a/jdk/src/share/classes/java/security/CodeSigner.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/java/security/CodeSigner.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2004 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
@@ -26,7 +26,10 @@
package java.security;
import java.io.Serializable;
+import java.security.cert.CRL;
import java.security.cert.CertPath;
+import sun.misc.JavaSecurityCodeSignerAccess;
+import sun.misc.SharedSecrets;
/**
* This class encapsulates information about a code signer.
@@ -163,4 +166,43 @@
sb.append(")");
return sb.toString();
}
+
+ // A private attribute attached to this CodeSigner object. Can be accessed
+ // through SharedSecrets.getJavaSecurityCodeSignerAccess().[g|s]etCRLs
+ //
+ // Currently called in SignatureFileVerifier.getSigners
+ private transient CRL[] crls;
+
+ /**
+ * Sets the CRLs attached
+ * @param crls, null to clear
+ */
+ void setCRLs(CRL[] crls) {
+ this.crls = crls;
+ }
+
+ /**
+ * Returns the CRLs attached
+ * @return the crls, initially null
+ */
+ CRL[] getCRLs() {
+ return crls;
+ }
+
+ // Set up JavaSecurityCodeSignerAccess in SharedSecrets
+ static {
+ SharedSecrets.setJavaSecurityCodeSignerAccess(
+ new JavaSecurityCodeSignerAccess() {
+ @Override
+ public void setCRLs(CodeSigner signer, CRL[] crls) {
+ signer.setCRLs(crls);
+ }
+
+ @Override
+ public CRL[] getCRLs(CodeSigner signer) {
+ return signer.getCRLs();
+ }
+ });
+ }
+
}
--- a/jdk/src/share/classes/java/util/AbstractCollection.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/java/util/AbstractCollection.java Tue May 11 16:35:36 2010 -0700
@@ -191,6 +191,14 @@
}
/**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
* Reallocates the array being used within toArray when the iterator
* returned more elements than expected, and finishes filling it from
* the iterator.
@@ -205,13 +213,10 @@
while (it.hasNext()) {
int cap = r.length;
if (i == cap) {
- int newCap = ((cap / 2) + 1) * 3;
- if (newCap <= cap) { // integer overflow
- if (cap == Integer.MAX_VALUE)
- throw new OutOfMemoryError
- ("Required array size too large");
- newCap = Integer.MAX_VALUE;
- }
+ int newCap = cap + (cap >> 1) + 1;
+ // overflow-conscious code
+ if (newCap - MAX_ARRAY_SIZE > 0)
+ newCap = hugeCapacity(cap + 1);
r = Arrays.copyOf(r, newCap);
}
r[i++] = (T)it.next();
@@ -220,6 +225,15 @@
return (i == r.length) ? r : Arrays.copyOf(r, i);
}
+ private static int hugeCapacity(int minCapacity) {
+ if (minCapacity < 0) // overflow
+ throw new OutOfMemoryError
+ ("Required array size too large");
+ return (minCapacity > MAX_ARRAY_SIZE) ?
+ Integer.MAX_VALUE :
+ MAX_ARRAY_SIZE;
+ }
+
// Modification Operations
/**
--- a/jdk/src/share/classes/java/util/ArrayList.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/java/util/ArrayList.java Tue May 11 16:35:36 2010 -0700
@@ -173,18 +173,47 @@
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*
- * @param minCapacity the desired minimum capacity
+ * @param minCapacity the desired minimum capacity
*/
public void ensureCapacity(int minCapacity) {
modCount++;
+ // overflow-conscious code
+ if (minCapacity - elementData.length > 0)
+ grow(minCapacity);
+ }
+
+ /**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
+ * Increases the capacity to ensure that it can hold at least the
+ * number of elements specified by the minimum capacity argument.
+ *
+ * @param minCapacity the desired minimum capacity
+ */
+ private void grow(int minCapacity) {
+ // overflow-conscious code
int oldCapacity = elementData.length;
- if (minCapacity > oldCapacity) {
- int newCapacity = (oldCapacity * 3)/2 + 1;
- if (newCapacity < minCapacity)
- newCapacity = minCapacity;
- // minCapacity is usually close to size, so this is a win:
- elementData = Arrays.copyOf(elementData, newCapacity);
- }
+ int newCapacity = oldCapacity + (oldCapacity >> 1);
+ if (newCapacity - minCapacity < 0)
+ newCapacity = minCapacity;
+ if (newCapacity - MAX_ARRAY_SIZE > 0)
+ newCapacity = hugeCapacity(minCapacity);
+ // minCapacity is usually close to size, so this is a win:
+ elementData = Arrays.copyOf(elementData, newCapacity);
+ }
+
+ private static int hugeCapacity(int minCapacity) {
+ if (minCapacity < 0) // overflow
+ throw new OutOfMemoryError();
+ return (minCapacity > MAX_ARRAY_SIZE) ?
+ Integer.MAX_VALUE :
+ MAX_ARRAY_SIZE;
}
/**
@@ -391,7 +420,7 @@
public void add(int index, E element) {
rangeCheckForAdd(index);
- ensureCapacity(size+1); // Increments modCount!!
+ ensureCapacity(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
--- a/jdk/src/share/classes/java/util/Hashtable.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/java/util/Hashtable.java Tue May 11 16:35:36 2010 -0700
@@ -365,6 +365,14 @@
}
/**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
* Increases the capacity of and internally reorganizes this
* hashtable, in order to accommodate and access its entries more
* efficiently. This method is called automatically when the
@@ -375,7 +383,14 @@
int oldCapacity = table.length;
Entry[] oldMap = table;
- int newCapacity = oldCapacity * 2 + 1;
+ // overflow-conscious code
+ int newCapacity = (oldCapacity << 1) + 1;
+ if (newCapacity - MAX_ARRAY_SIZE > 0) {
+ if (oldCapacity == MAX_ARRAY_SIZE)
+ // Keep running with MAX_ARRAY_SIZE buckets
+ return;
+ newCapacity = MAX_ARRAY_SIZE;
+ }
Entry[] newMap = new Entry[newCapacity];
modCount++;
--- a/jdk/src/share/classes/java/util/PriorityQueue.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/java/util/PriorityQueue.java Tue May 11 16:35:36 2010 -0700
@@ -170,17 +170,21 @@
* @throws NullPointerException if the specified collection or any
* of its elements are null
*/
+ @SuppressWarnings("unchecked")
public PriorityQueue(Collection<? extends E> c) {
- initFromCollection(c);
- if (c instanceof SortedSet)
- comparator = (Comparator<? super E>)
- ((SortedSet<? extends E>)c).comparator();
- else if (c instanceof PriorityQueue)
- comparator = (Comparator<? super E>)
- ((PriorityQueue<? extends E>)c).comparator();
+ if (c instanceof SortedSet<?>) {
+ SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
+ this.comparator = (Comparator<? super E>) ss.comparator();
+ initElementsFromCollection(ss);
+ }
+ else if (c instanceof PriorityQueue<?>) {
+ PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
+ this.comparator = (Comparator<? super E>) pq.comparator();
+ initFromPriorityQueue(pq);
+ }
else {
- comparator = null;
- heapify();
+ this.comparator = null;
+ initFromCollection(c);
}
}
@@ -198,9 +202,10 @@
* @throws NullPointerException if the specified priority queue or any
* of its elements are null
*/
+ @SuppressWarnings("unchecked")
public PriorityQueue(PriorityQueue<? extends E> c) {
- comparator = (Comparator<? super E>)c.comparator();
- initFromCollection(c);
+ this.comparator = (Comparator<? super E>) c.comparator();
+ initFromPriorityQueue(c);
}
/**
@@ -216,9 +221,33 @@
* @throws NullPointerException if the specified sorted set or any
* of its elements are null
*/
+ @SuppressWarnings("unchecked")
public PriorityQueue(SortedSet<? extends E> c) {
- comparator = (Comparator<? super E>)c.comparator();
- initFromCollection(c);
+ this.comparator = (Comparator<? super E>) c.comparator();
+ initElementsFromCollection(c);
+ }
+
+ private void initFromPriorityQueue(PriorityQueue<? extends E> c) {
+ if (c.getClass() == PriorityQueue.class) {
+ this.queue = c.toArray();
+ this.size = c.size();
+ } else {
+ initFromCollection(c);
+ }
+ }
+
+ private void initElementsFromCollection(Collection<? extends E> c) {
+ Object[] a = c.toArray();
+ // If c.toArray incorrectly doesn't return Object[], copy it.
+ if (a.getClass() != Object[].class)
+ a = Arrays.copyOf(a, a.length, Object[].class);
+ int len = a.length;
+ if (len == 1 || this.comparator != null)
+ for (int i = 0; i < len; i++)
+ if (a[i] == null)
+ throw new NullPointerException();
+ this.queue = a;
+ this.size = a.length;
}
/**
@@ -227,34 +256,43 @@
* @param c the collection
*/
private void initFromCollection(Collection<? extends E> c) {
- Object[] a = c.toArray();
- // If c.toArray incorrectly doesn't return Object[], copy it.
- if (a.getClass() != Object[].class)
- a = Arrays.copyOf(a, a.length, Object[].class);
- queue = a;
- size = a.length;
+ initElementsFromCollection(c);
+ heapify();
}
/**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ /**
* Increases the capacity of the array.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
- if (minCapacity < 0) // overflow
- throw new OutOfMemoryError();
int oldCapacity = queue.length;
// Double size if small; else grow by 50%
- int newCapacity = ((oldCapacity < 64)?
- ((oldCapacity + 1) * 2):
- ((oldCapacity / 2) * 3));
- if (newCapacity < 0) // overflow
- newCapacity = Integer.MAX_VALUE;
- if (newCapacity < minCapacity)
- newCapacity = minCapacity;
+ int newCapacity = oldCapacity + ((oldCapacity < 64) ?
+ (oldCapacity + 2) :
+ (oldCapacity >> 1));
+ // overflow-conscious code
+ if (newCapacity - MAX_ARRAY_SIZE > 0)
+ newCapacity = hugeCapacity(minCapacity);
queue = Arrays.copyOf(queue, newCapacity);
}
+ private static int hugeCapacity(int minCapacity) {
+ if (minCapacity < 0) // overflow
+ throw new OutOfMemoryError();
+ return (minCapacity > MAX_ARRAY_SIZE) ?
+ Integer.MAX_VALUE :
+ MAX_ARRAY_SIZE;
+ }
+
/**
* Inserts the specified element into this priority queue.
*
--- a/jdk/src/share/classes/java/util/Random.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/java/util/Random.java Tue May 11 16:35:36 2010 -0700
@@ -86,8 +86,23 @@
* the seed of the random number generator to a value very likely
* to be distinct from any other invocation of this constructor.
*/
- public Random() { this(++seedUniquifier + System.nanoTime()); }
- private static volatile long seedUniquifier = 8682522807148012L;
+ public Random() {
+ this(seedUniquifier() ^ System.nanoTime());
+ }
+
+ private static long seedUniquifier() {
+ // L'Ecuyer, "Tables of Linear Congruential Generators of
+ // Different Sizes and Good Lattice Structure", 1999
+ for (;;) {
+ long current = seedUniquifier.get();
+ long next = current * 181783497276652981L;
+ if (seedUniquifier.compareAndSet(current, next))
+ return next;
+ }
+ }
+
+ private static final AtomicLong seedUniquifier
+ = new AtomicLong(8682522807148012L);
/**
* Creates a new random number generator using a single {@code long} seed.
@@ -103,8 +118,11 @@
* @see #setSeed(long)
*/
public Random(long seed) {
- this.seed = new AtomicLong(0L);
- setSeed(seed);
+ this.seed = new AtomicLong(initialScramble(seed));
+ }
+
+ private static long initialScramble(long seed) {
+ return (seed ^ multiplier) & mask;
}
/**
@@ -127,8 +145,7 @@
* @param seed the initial seed
*/
synchronized public void setSeed(long seed) {
- seed = (seed ^ multiplier) & mask;
- this.seed.set(seed);
+ this.seed.set(initialScramble(seed));
haveNextNextGaussian = false;
}
--- a/jdk/src/share/classes/java/util/Vector.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/java/util/Vector.java Tue May 11 16:35:36 2010 -0700
@@ -235,16 +235,37 @@
* @see #ensureCapacity(int)
*/
private void ensureCapacityHelper(int minCapacity) {
+ // overflow-conscious code
+ if (minCapacity - elementData.length > 0)
+ grow(minCapacity);
+ }
+
+ /**
+ * The maximum size of array to allocate.
+ * Some VMs reserve some header words in an array.
+ * Attempts to allocate larger arrays may result in
+ * OutOfMemoryError: Requested array size exceeds VM limit
+ */
+ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
+
+ private void grow(int minCapacity) {
+ // overflow-conscious code
int oldCapacity = elementData.length;
- if (minCapacity > oldCapacity) {
- Object[] oldData = elementData;
- int newCapacity = (capacityIncrement > 0) ?
- (oldCapacity + capacityIncrement) : (oldCapacity * 2);
- if (newCapacity < minCapacity) {
- newCapacity = minCapacity;
- }
- elementData = Arrays.copyOf(elementData, newCapacity);
- }
+ int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
+ capacityIncrement : oldCapacity);
+ if (newCapacity - minCapacity < 0)
+ newCapacity = minCapacity;
+ if (newCapacity - MAX_ARRAY_SIZE > 0)
+ newCapacity = hugeCapacity(minCapacity);
+ elementData = Arrays.copyOf(elementData, newCapacity);
+ }
+
+ private static int hugeCapacity(int minCapacity) {
+ if (minCapacity < 0) // overflow
+ throw new OutOfMemoryError();
+ return (minCapacity > MAX_ARRAY_SIZE) ?
+ Integer.MAX_VALUE :
+ MAX_ARRAY_SIZE;
}
/**
--- a/jdk/src/share/classes/java/util/jar/JarVerifier.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-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
@@ -27,7 +27,6 @@
import java.io.*;
import java.util.*;
-import java.util.zip.*;
import java.security.*;
import java.security.cert.CertificateException;
--- a/jdk/src/share/classes/java/util/zip/Deflater.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/java/util/zip/Deflater.java Tue May 11 16:35:36 2010 -0700
@@ -40,7 +40,7 @@
* <blockquote><pre>
* try {
* // Encode a String into bytes
- * String inputString = "blahblahblah\u20AC\u20AC";
+ * String inputString = "blahblahblah";
* byte[] input = inputString.getBytes("UTF-8");
*
* // Compress the bytes
--- a/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/javax/security/auth/kerberos/KeyImpl.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-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
@@ -205,7 +205,7 @@
+ " keyBytes (hex dump)="
+ (keyBytes == null || keyBytes.length == 0 ?
" Empty Key" :
- '\n' + hd.encode(keyBytes)
+ '\n' + hd.encodeBuffer(keyBytes)
+ '\n');
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/misc/JavaSecurityCodeSignerAccess.java Tue May 11 16:35:36 2010 -0700
@@ -0,0 +1,33 @@
+/*
+ * Copyright 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. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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.
+ */
+package sun.misc;
+
+import java.security.CodeSigner;
+import java.security.cert.CRL;
+
+public interface JavaSecurityCodeSignerAccess {
+ void setCRLs(CodeSigner signer, CRL[] crls);
+ CRL[] getCRLs(CodeSigner signer);
+}
--- a/jdk/src/share/classes/sun/misc/SharedSecrets.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/misc/SharedSecrets.java Tue May 11 16:35:36 2010 -0700
@@ -27,8 +27,8 @@
import java.util.jar.JarFile;
import java.io.Console;
-import java.io.File;
import java.io.FileDescriptor;
+import java.security.CodeSigner;
import java.security.ProtectionDomain;
/** A repository of "shared secrets", which are a mechanism for
@@ -49,6 +49,7 @@
private static JavaNioAccess javaNioAccess;
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess;
+ private static JavaSecurityCodeSignerAccess javaSecurityCodeSignerAccess;
public static JavaUtilJarAccess javaUtilJarAccess() {
if (javaUtilJarAccess == null) {
@@ -126,4 +127,16 @@
unsafe.ensureClassInitialized(ProtectionDomain.class);
return javaSecurityProtectionDomainAccess;
}
+
+ public static void setJavaSecurityCodeSignerAccess
+ (JavaSecurityCodeSignerAccess jscsa) {
+ javaSecurityCodeSignerAccess = jscsa;
+ }
+
+ public static JavaSecurityCodeSignerAccess
+ getJavaSecurityCodeSignerAccess() {
+ if (javaSecurityCodeSignerAccess == null)
+ unsafe.ensureClassInitialized(CodeSigner.class);
+ return javaSecurityCodeSignerAccess;
+ }
}
--- a/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/net/httpserver/ExchangeImpl.java Tue May 11 16:35:36 2010 -0700
@@ -26,16 +26,12 @@
package sun.net.httpserver;
import java.io.*;
-import java.nio.*;
-import java.nio.channels.*;
import java.net.*;
import javax.net.ssl.*;
import java.util.*;
import java.util.logging.Logger;
import java.text.*;
-import sun.net.www.MessageHeader;
import com.sun.net.httpserver.*;
-import com.sun.net.httpserver.spi.*;
class ExchangeImpl {
@@ -65,6 +61,8 @@
df.setTimeZone (tz);
}
+ private static final String HEAD = "HEAD";
+
/* streams which take care of the HTTP protocol framing
* and are passed up to higher layers
*/
@@ -116,6 +114,10 @@
return connection.getHttpContext();
}
+ private boolean isHeadRequest() {
+ return HEAD.equals(getRequestMethod());
+ }
+
public void close () {
if (closed) {
return;
@@ -220,24 +222,36 @@
}
contentLen = -1;
}
- if (contentLen == 0) {
- if (http10) {
- o.setWrappedStream (new UndefLengthOutputStream (this, ros));
- close = true;
- } else {
- rspHdrs.set ("Transfer-encoding", "chunked");
- o.setWrappedStream (new ChunkedOutputStream (this, ros));
+
+ if (isHeadRequest()) {
+ /* HEAD requests should not set a content length by passing it
+ * through this API, but should instead manually set the required
+ * headers.*/
+ if (contentLen >= 0) {
+ final Logger logger = server.getLogger();
+ String msg =
+ "sendResponseHeaders: being invoked with a content length for a HEAD request";
+ logger.warning (msg);
}
- } else {
- if (contentLen == -1) {
- noContentToSend = true;
- contentLen = 0;
+ noContentToSend = true;
+ contentLen = 0;
+ } else { /* not a HEAD request */
+ if (contentLen == 0) {
+ if (http10) {
+ o.setWrappedStream (new UndefLengthOutputStream (this, ros));
+ close = true;
+ } else {
+ rspHdrs.set ("Transfer-encoding", "chunked");
+ o.setWrappedStream (new ChunkedOutputStream (this, ros));
+ }
+ } else {
+ if (contentLen == -1) {
+ noContentToSend = true;
+ contentLen = 0;
+ }
+ rspHdrs.set("Content-length", Long.toString(contentLen));
+ o.setWrappedStream (new FixedLengthOutputStream (this, ros, contentLen));
}
- /* content len might already be set, eg to implement HEAD resp */
- if (rspHdrs.getFirst ("Content-length") == null) {
- rspHdrs.set ("Content-length", Long.toString(contentLen));
- }
- o.setWrappedStream (new FixedLengthOutputStream (this, ros, contentLen));
}
write (rspHdrs, tmpout);
this.rspContentLen = contentLen;
--- a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java Tue May 11 16:35:36 2010 -0700
@@ -451,6 +451,7 @@
if (requestLine == null) {
/* connection closed */
connection.close();
+ allConnections.remove(connection);
return;
}
int space = requestLine.indexOf (' ');
@@ -592,6 +593,8 @@
sendReply (
code, true, "<h1>"+code+Code.msg(code)+"</h1>"+message
);
+ /* connection is already closed by sendReply, now remove it */
+ allConnections.remove(connection);
}
void sendReply (
--- a/jdk/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java Tue May 11 16:35:36 2010 -0700
@@ -29,8 +29,10 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.net.PasswordAuthentication;
+import java.io.IOException;
+import java.io.OutputStream;
import sun.net.www.HeaderParser;
-
+import sun.misc.BASE64Encoder;
/**
* BasicAuthentication: Encapsulate an http server authentication using
@@ -74,7 +76,7 @@
System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length);
System.arraycopy(passwdBytes, 0, concat, nameBytes.length,
passwdBytes.length);
- this.auth = "Basic " + (new sun.misc.BASE64Encoder()).encode(concat);
+ this.auth = "Basic " + (new BasicBASE64Encoder()).encode(concat);
this.pw = pw;
}
@@ -114,7 +116,7 @@
System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length);
System.arraycopy(passwdBytes, 0, concat, nameBytes.length,
passwdBytes.length);
- this.auth = "Basic " + (new sun.misc.BASE64Encoder()).encode(concat);
+ this.auth = "Basic " + (new BasicBASE64Encoder()).encode(concat);
this.pw = pw;
}
@@ -200,4 +202,11 @@
return npath;
}
+ /* It is never expected that the header value will exceed the bytesPerLine */
+ private class BasicBASE64Encoder extends BASE64Encoder {
+ @Override
+ protected int bytesPerLine() {
+ return (10000);
+ }
+ }
}
--- a/jdk/src/share/classes/sun/security/krb5/Config.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/Config.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Portions Copyright 2000-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
@@ -109,7 +109,7 @@
public static synchronized void refresh() throws KrbException {
singleton = new Config();
KeyTab.refresh();
- KrbKdcReq.KdcAccessibility.reset();
+ KrbKdcReq.initStatic();
}
--- a/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/EncryptionKey.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Portions Copyright 2000-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
@@ -499,8 +499,9 @@
+ " kvno=" + kvno
+ " keyValue (hex dump)="
+ (keyValue == null || keyValue.length == 0 ?
- " Empty Key" : '\n' + Krb5.hexDumper.encode(keyValue)
- + '\n'));
+ " Empty Key" : '\n'
+ + Krb5.hexDumper.encodeBuffer(keyValue)
+ + '\n'));
}
/**
--- a/jdk/src/share/classes/sun/security/krb5/KrbKdcReq.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/KrbKdcReq.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Portions Copyright 2000-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,28 +51,31 @@
public abstract class KrbKdcReq {
- // Currently there is no option to specify retries
- // in the kerberos configuration file
-
- private static final int DEFAULT_KDC_RETRY_LIMIT = Krb5.KDC_RETRY_LIMIT;
+ // The following settings can be configured in [libdefaults]
+ // section of krb5.conf, which are global for all realms. Each of
+ // them can also be defined in a realm, which overrides value here.
/**
- * Default timeout period when requesting a ticket from a KDC.
- * If not specified in the configuration file,
- * a value of 30 seconds is used.
+ * max retry time for a single KDC, default Krb5.KDC_RETRY_LIMIT (3)
+ */
+ private static int defaultKdcRetryLimit;
+ /**
+ * timeout requesting a ticket from KDC, in millisec, default 30 sec
*/
- public static final int DEFAULT_KDC_TIMEOUT; // milliseconds
+ private static int defaultKdcTimeout;
+ /**
+ * max UDP packet size, default unlimited (-1)
+ */
+ private static int defaultUdpPrefLimit;
private static final boolean DEBUG = Krb5.DEBUG;
- private static int udpPrefLimit = -1;
-
private static final String BAD_POLICY_KEY = "krb5.kdc.bad.policy";
/**
* What to do when a KDC is unavailable, specified in the
* java.security file with key krb5.kdc.bad.policy.
- * Possible values can be TRY_LAST or TRY_LESS
+ * Possible values can be TRY_LAST or TRY_LESS. Reloaded when refreshed.
*/
private enum BpType {
NONE, TRY_LAST, TRY_LESS
@@ -80,9 +83,16 @@
private static int tryLessMaxRetries = 1;
private static int tryLessTimeout = 5000;
- private static final BpType badPolicy;
+ private static BpType badPolicy;
static {
+ initStatic();
+ }
+
+ /**
+ * Read global settings
+ */
+ public static void initStatic() {
String value = AccessController.doPrivileged(
new PrivilegedAction<String>() {
public String run() {
@@ -95,9 +105,21 @@
if ("tryless".equals(ss[0])) {
if (ss.length > 1) {
String[] params = ss[1].split(",");
- tryLessMaxRetries = Integer.parseInt(params[0]);
- if (params.length > 1) {
- tryLessTimeout = Integer.parseInt(params[1]);
+ try {
+ int tmp0 = Integer.parseInt(params[0]);
+ if (params.length > 1) {
+ tryLessTimeout = Integer.parseInt(params[1]);
+ }
+ // Assign here in case of exception at params[1]
+ tryLessMaxRetries = tmp0;
+ } catch (NumberFormatException nfe) {
+ // Ignored. Please note that tryLess is recognized and
+ // used, parameters using default values
+ if (DEBUG) {
+ System.out.println("Invalid " + BAD_POLICY_KEY +
+ " parameter for tryLess: " +
+ value + ", use default");
+ }
}
}
badPolicy = BpType.TRY_LESS;
@@ -110,30 +132,33 @@
badPolicy = BpType.NONE;
}
- /*
- * Get default timeout.
- */
int timeout = -1;
+ int max_retries = -1;
+ int udf_pref_limit = -1;
+
try {
Config cfg = Config.getInstance();
String temp = cfg.getDefault("kdc_timeout", "libdefaults");
timeout = parsePositiveIntString(temp);
+ temp = cfg.getDefault("max_retries", "libdefaults");
+ max_retries = parsePositiveIntString(temp);
temp = cfg.getDefault("udp_preference_limit", "libdefaults");
- udpPrefLimit = parsePositiveIntString(temp);
+ udf_pref_limit = parsePositiveIntString(temp);
} catch (Exception exc) {
- // ignore any exceptions; use the default time out values
+ // ignore any exceptions; use default values
if (DEBUG) {
- System.out.println ("Exception in getting kdc_timeout value, " +
- "using default value " +
+ System.out.println ("Exception in getting KDC communication " +
+ "settings, using default value " +
exc.getMessage());
}
}
+ defaultKdcTimeout = timeout > 0 ? timeout : 30*1000; // 30 seconds
+ defaultKdcRetryLimit =
+ max_retries > 0 ? max_retries : Krb5.KDC_RETRY_LIMIT;
+ defaultUdpPrefLimit = udf_pref_limit;
- if (timeout > 0)
- DEFAULT_KDC_TIMEOUT = timeout;
- else
- DEFAULT_KDC_TIMEOUT = 30*1000; // 30 seconds
+ KdcAccessibility.reset();
}
protected byte[] obuf;
@@ -151,6 +176,9 @@
public String send(String realm)
throws IOException, KrbException {
+ int udpPrefLimit = getRealmSpecificValue(
+ realm, "udp_preference_limit", defaultUdpPrefLimit);
+
boolean useTCP = (udpPrefLimit > 0 &&
(obuf != null && obuf.length > udpPrefLimit));
@@ -213,9 +241,10 @@
return;
int port = Krb5.KDC_INET_DEFAULT_PORT;
- int retries = DEFAULT_KDC_RETRY_LIMIT;
- int timeout = getKdcTimeout(realm);
-
+ int retries = getRealmSpecificValue(
+ realm, "max_retries", defaultKdcRetryLimit);
+ int timeout = getRealmSpecificValue(
+ realm, "kdc_timeout", defaultKdcTimeout);
if (badPolicy == BpType.TRY_LESS &&
KdcAccessibility.isBad(tempKdc)) {
if (retries > tryLessMaxRetries) {
@@ -322,6 +351,12 @@
if (useTCP) {
TCPClient kdcClient = new TCPClient(kdc, port);
+ if (DEBUG) {
+ System.out.println(">>> KDCCommunication: kdc=" + kdc
+ + " TCP:"
+ + port
+ + ", #bytes=" + obuf.length);
+ }
try {
/*
* Send the data to the kdc.
@@ -336,7 +371,7 @@
}
} else {
- // For each KDC we try DEFAULT_KDC_RETRY_LIMIT (3) times to
+ // For each KDC we try defaultKdcRetryLimit times to
// get the response
for (int i=1; i <= retries; i++) {
UDPClient kdcClient = new UDPClient(kdc, port, timeout);
@@ -382,37 +417,37 @@
}
/**
- * Returns a timeout value for the KDC of the given realm.
- * A KDC-specific timeout, if specified in the config file,
- * overrides the default timeout (which may also be specified
- * in the config file). Default timeout is returned if null
- * is specified for realm.
- * @param realm the realm which kdc's timeout is requested
- * @return KDC timeout
+ * Returns krb5.conf setting of {@code key} for a specfic realm,
+ * which can be:
+ * 1. defined in the sub-stanza for the given realm inside [realms], or
+ * 2. defined in [libdefaults], or
+ * 3. defValue
+ * @param realm the given realm in which the setting is requested. Returns
+ * the global setting if null
+ * @param key the key for the setting
+ * @param defValue default value
+ * @return a value for the key
*/
- private int getKdcTimeout(String realm)
- {
- int timeout = DEFAULT_KDC_TIMEOUT;
+ private int getRealmSpecificValue(String realm, String key, int defValue) {
+ int v = defValue;
- if (realm == null)
- return timeout;
+ if (realm == null) return v;
- int tempTimeout = -1;
+ int temp = -1;
try {
- String temp =
- Config.getInstance().getDefault("kdc_timeout", realm);
- tempTimeout = parsePositiveIntString(temp);
+ String value =
+ Config.getInstance().getDefault(key, realm);
+ temp = parsePositiveIntString(value);
} catch (Exception exc) {
+ // Ignored, defValue will be picked up
}
- if (tempTimeout > 0)
- timeout = tempTimeout;
+ if (temp > 0) v = temp;
- return timeout;
+ return v;
}
- private static int parsePositiveIntString(String intString)
- {
+ private static int parsePositiveIntString(String intString) {
if (intString == null)
return -1;
@@ -461,7 +496,7 @@
return bads.contains(kdc);
}
- public static synchronized void reset() {
+ private static synchronized void reset() {
if (DEBUG) {
System.out.println(">>> KdcAccessibility: reset");
}
--- a/jdk/src/share/classes/sun/security/krb5/PrincipalName.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/security/krb5/PrincipalName.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Portions Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Portions Copyright 2000-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
@@ -101,7 +101,7 @@
private Realm nameRealm; // optional; a null realm means use default
// Note: the nameRealm is not included in the default ASN.1 encoding
- // salt for principal
+ // cached salt, might be changed by KDC info, not used in clone
private String salt = null;
protected PrincipalName() {
@@ -123,18 +123,19 @@
}
public Object clone() {
- PrincipalName pName = new PrincipalName();
- pName.nameType = nameType;
- if (nameStrings != null) {
- pName.nameStrings =
- new String[nameStrings.length];
- System.arraycopy(nameStrings,0,pName.nameStrings,0,
- nameStrings.length);
+ try {
+ PrincipalName pName = (PrincipalName) super.clone();
+ // Re-assign mutable fields
+ if (nameStrings != null) {
+ pName.nameStrings = nameStrings.clone();
+ }
+ if (nameRealm != null) {
+ pName.nameRealm = (Realm)nameRealm.clone();
+ }
+ return pName;
+ } catch (CloneNotSupportedException ex) {
+ throw new AssertionError("Should never happen");
}
- if (nameRealm != null) {
- pName.nameRealm = (Realm)nameRealm.clone();
- }
- return pName;
}
/*
--- a/jdk/src/share/classes/sun/security/pkcs/PKCS7.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/security/pkcs/PKCS7.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1996-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
@@ -28,7 +28,6 @@
import java.io.*;
import java.math.BigInteger;
import java.util.*;
-import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509CRL;
@@ -173,20 +172,30 @@
* @param digestAlgorithmIds the message digest algorithm identifiers.
* @param contentInfo the content information.
* @param certificates an array of X.509 certificates.
+ * @param crls an array of CRLs
* @param signerInfos an array of signer information.
*/
public PKCS7(AlgorithmId[] digestAlgorithmIds,
ContentInfo contentInfo,
X509Certificate[] certificates,
+ X509CRL[] crls,
SignerInfo[] signerInfos) {
version = BigInteger.ONE;
this.digestAlgorithmIds = digestAlgorithmIds;
this.contentInfo = contentInfo;
this.certificates = certificates;
+ this.crls = crls;
this.signerInfos = signerInfos;
}
+ public PKCS7(AlgorithmId[] digestAlgorithmIds,
+ ContentInfo contentInfo,
+ X509Certificate[] certificates,
+ SignerInfo[] signerInfos) {
+ this(digestAlgorithmIds, contentInfo, certificates, null, signerInfos);
+ }
+
private void parseNetscapeCertChain(DerValue val)
throws ParsingException, IOException {
DerInputStream dis = new DerInputStream(val.toByteArray());
@@ -312,7 +321,7 @@
ByteArrayInputStream bais = null;
try {
if (certfac == null)
- crls[i] = (X509CRL) new X509CRLImpl(crlVals[i]);
+ crls[i] = new X509CRLImpl(crlVals[i]);
else {
byte[] encoded = crlVals[i].toByteArray();
bais = new ByteArrayInputStream(encoded);
@@ -480,7 +489,30 @@
signedData.putOrderedSetOf((byte)0xA0, implCerts);
}
- // no crls (OPTIONAL field)
+ // CRLs (optional)
+ if (crls != null && crls.length != 0) {
+ // cast to X509CRLImpl[] since X509CRLImpl implements DerEncoder
+ Set<X509CRLImpl> implCRLs = new HashSet<X509CRLImpl>(crls.length);
+ for (X509CRL crl: crls) {
+ if (crl instanceof X509CRLImpl)
+ implCRLs.add((X509CRLImpl) crl);
+ else {
+ try {
+ byte[] encoded = crl.getEncoded();
+ implCRLs.add(new X509CRLImpl(encoded));
+ } catch (CRLException ce) {
+ IOException ie = new IOException(ce.getMessage());
+ ie.initCause(ce);
+ throw ie;
+ }
+ }
+ }
+
+ // Add the CRL set (tagged with [1] IMPLICIT)
+ // to the signed data
+ signedData.putOrderedSetOf((byte)0xA1,
+ implCRLs.toArray(new X509CRLImpl[implCRLs.size()]));
+ }
// signerInfos
signedData.putOrderedSetOf(DerValue.tag_Set, signerInfos);
--- a/jdk/src/share/classes/sun/security/provider/certpath/CertId.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/security/provider/certpath/CertId.java Tue May 11 16:35:36 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
@@ -96,9 +96,9 @@
HexDumpEncoder encoder = new HexDumpEncoder();
System.out.println("Issuer Certificate is " + issuerCert);
System.out.println("issuerNameHash is " +
- encoder.encode(issuerNameHash));
+ encoder.encodeBuffer(issuerNameHash));
System.out.println("issuerKeyHash is " +
- encoder.encode(issuerKeyHash));
+ encoder.encodeBuffer(issuerKeyHash));
System.out.println("SerialNumber is " + serialNumber.getNumber());
}
}
--- a/jdk/src/share/classes/sun/security/tools/JarSigner.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/security/tools/JarSigner.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-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
@@ -26,6 +26,7 @@
package sun.security.tools;
import java.io.*;
+import java.security.cert.X509CRL;
import java.util.*;
import java.util.zip.*;
import java.util.jar.*;
@@ -35,6 +36,7 @@
import java.text.Collator;
import java.text.MessageFormat;
import java.security.cert.Certificate;
+import java.security.cert.CRL;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.*;
@@ -56,6 +58,7 @@
import sun.security.x509.*;
import sun.security.util.*;
import sun.misc.BASE64Encoder;
+import sun.misc.SharedSecrets;
/**
@@ -114,14 +117,16 @@
static final int SIGNED_BY_ALIAS = 0x08; // signer is in alias list
X509Certificate[] certChain; // signer's cert chain (when composing)
+ Set<X509CRL> crls; // signer provided CRLs
PrivateKey privateKey; // private key
KeyStore store; // the keystore specified by -keystore
// or the default keystore, never null
String keystore; // key store file
+ List<String> crlfiles = new ArrayList<String>(); // CRL files to add
boolean nullStream = false; // null keystore input stream (NONE)
boolean token = false; // token-based keystore
- String jarfile; // jar file to sign or verify
+ String jarfile; // jar files to sign or verify
String alias; // alias to sign jar with
List<String> ckaliases = new ArrayList<String>(); // aliases in -verify
char[] storepass; // keystore password
@@ -146,6 +151,7 @@
boolean signManifest = true; // "sign" the whole manifest
boolean externalSF = true; // leave the .SF out of the PKCS7 block
boolean strict = false; // treat warnings as error
+ boolean autoCRL = false; // Automatcially add CRL defined in cert
// read zip entry raw bytes
private ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
@@ -226,6 +232,29 @@
} else {
loadKeyStore(keystore, true);
getAliasInfo(alias);
+ crls = new HashSet<X509CRL>();
+ if (crlfiles.size() > 0 || autoCRL) {
+ CertificateFactory fac =
+ CertificateFactory.getInstance("X509");
+ List<CRL> list = new ArrayList<CRL>();
+ for (String file: crlfiles) {
+ Collection<? extends CRL> tmp = KeyTool.loadCRLs(file);
+ for (CRL crl: tmp) {
+ if (crl instanceof X509CRL) {
+ crls.add((X509CRL)crl);
+ }
+ }
+ }
+ if (autoCRL) {
+ List<CRL> crlsFromCert =
+ KeyTool.readCRLsFromCert(certChain[0]);
+ for (CRL crl: crlsFromCert) {
+ if (crl instanceof X509CRL) {
+ crls.add((X509CRL)crl);
+ }
+ }
+ }
+ }
// load the alternative signing mechanism
if (altSignerClass != null) {
@@ -367,6 +396,13 @@
} else if (collator.compare(flags, "-digestalg") ==0) {
if (++n == args.length) usageNoArg();
digestalg = args[n];
+ } else if (collator.compare(flags, "-crl") ==0) {
+ if ("auto".equals(modifier)) {
+ autoCRL = true;
+ } else {
+ if (++n == args.length) usageNoArg();
+ crlfiles.add(args[n]);
+ }
} else if (collator.compare(flags, "-certs") ==0) {
showcerts = true;
} else if (collator.compare(flags, "-strict") ==0) {
@@ -516,6 +552,9 @@
("[-sigalg <algorithm>] name of signature algorithm"));
System.out.println();
System.out.println(rb.getString
+ ("[-crl[:auto| <file>] include CRL in signed jar"));
+ System.out.println();
+ System.out.println(rb.getString
("[-verify] verify a signed JAR file"));
System.out.println();
System.out.println(rb.getString
@@ -654,6 +693,20 @@
if (showcerts) {
sb.append(si);
sb.append('\n');
+ CRL[] crls = SharedSecrets
+ .getJavaSecurityCodeSignerAccess()
+ .getCRLs(signer);
+ if (crls != null) {
+ for (CRL crl: crls) {
+ if (crl instanceof X509CRLImpl) {
+ sb.append(tab).append("[");
+ sb.append(String.format(
+ rb.getString("with a CRL including %d entries"),
+ ((X509CRLImpl)crl).getRevokedCertificates().size()))
+ .append("]\n");
+ }
+ }
+ }
}
}
} else if (showcerts && !verbose.equals("all")) {
@@ -1123,6 +1176,8 @@
BASE64Encoder encoder = new JarBASE64Encoder();
Vector<ZipEntry> mfFiles = new Vector<ZipEntry>();
+ boolean wasSigned = false;
+
for (Enumeration<? extends ZipEntry> enum_=zipFile.entries();
enum_.hasMoreElements();) {
ZipEntry ze = enum_.nextElement();
@@ -1132,6 +1187,11 @@
// out first
mfFiles.addElement(ze);
+ if (SignatureFileVerifier.isBlockOrSF(
+ ze.getName().toUpperCase(Locale.ENGLISH))) {
+ wasSigned = true;
+ }
+
if (signatureRelated(ze.getName())) {
// ignore signature-related and manifest files
continue;
@@ -1159,37 +1219,41 @@
if (mfModified) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
manifest.write(baos);
- byte[] newBytes = baos.toByteArray();
- if (mfRawBytes != null
- && oldAttr.equals(manifest.getMainAttributes())) {
+ if (wasSigned) {
+ byte[] newBytes = baos.toByteArray();
+ if (mfRawBytes != null
+ && oldAttr.equals(manifest.getMainAttributes())) {
- /*
- * Note:
- *
- * The Attributes object is based on HashMap and can handle
- * continuation columns. Therefore, even if the contents are
- * not changed (in a Map view), the bytes that it write()
- * may be different from the original bytes that it read()
- * from. Since the signature on the main attributes is based
- * on raw bytes, we must retain the exact bytes.
- */
+ /*
+ * Note:
+ *
+ * The Attributes object is based on HashMap and can handle
+ * continuation columns. Therefore, even if the contents are
+ * not changed (in a Map view), the bytes that it write()
+ * may be different from the original bytes that it read()
+ * from. Since the signature on the main attributes is based
+ * on raw bytes, we must retain the exact bytes.
+ */
- int newPos = findHeaderEnd(newBytes);
- int oldPos = findHeaderEnd(mfRawBytes);
+ int newPos = findHeaderEnd(newBytes);
+ int oldPos = findHeaderEnd(mfRawBytes);
- if (newPos == oldPos) {
- System.arraycopy(mfRawBytes, 0, newBytes, 0, oldPos);
- } else {
- // cat oldHead newTail > newBytes
- byte[] lastBytes = new byte[oldPos +
- newBytes.length - newPos];
- System.arraycopy(mfRawBytes, 0, lastBytes, 0, oldPos);
- System.arraycopy(newBytes, newPos, lastBytes, oldPos,
- newBytes.length - newPos);
- newBytes = lastBytes;
+ if (newPos == oldPos) {
+ System.arraycopy(mfRawBytes, 0, newBytes, 0, oldPos);
+ } else {
+ // cat oldHead newTail > newBytes
+ byte[] lastBytes = new byte[oldPos +
+ newBytes.length - newPos];
+ System.arraycopy(mfRawBytes, 0, lastBytes, 0, oldPos);
+ System.arraycopy(newBytes, newPos, lastBytes, oldPos,
+ newBytes.length - newPos);
+ newBytes = lastBytes;
+ }
}
+ mfRawBytes = newBytes;
+ } else {
+ mfRawBytes = baos.toByteArray();
}
- mfRawBytes = newBytes;
}
// Write out the manifest
@@ -1222,7 +1286,7 @@
try {
block =
- sf.generateBlock(privateKey, sigalg, certChain,
+ sf.generateBlock(privateKey, sigalg, certChain, crls,
externalSF, tsaUrl, tsaCert, signingMechanism, args,
zipFile);
} catch (SocketTimeoutException e) {
@@ -1411,23 +1475,31 @@
}
/**
- * Find the position of an empty line inside bs
+ * Find the length of header inside bs. The header is a multiple (>=0)
+ * lines of attributes plus an empty line. The empty line is included
+ * in the header.
*/
private int findHeaderEnd(byte[] bs) {
- // An empty line can be at the beginning...
- if (bs.length > 1 && bs[0] == '\r' && bs[1] == '\n') {
- return 0;
- }
- // ... or after another line
- for (int i=0; i<bs.length-3; i++) {
- if (bs[i] == '\r' && bs[i+1] == '\n' &&
- bs[i+2] == '\r' && bs[i+3] == '\n') {
- return i;
+ // Initial state true to deal with empty header
+ boolean newline = true; // just met a newline
+ int len = bs.length;
+ for (int i=0; i<len; i++) {
+ switch (bs[i]) {
+ case '\r':
+ if (i < len && bs[i+1] == '\n') i++;
+ // fallthrough
+ case '\n':
+ if (newline) return i+1; //+1 to get length
+ newline = true;
+ break;
+ default:
+ newline = false;
}
}
- // If header end is not found, return 0,
- // which means no behavior change.
- return 0;
+ // If header end is not found, it means the MANIFEST.MF has only
+ // the main attributes section and it does not end with 2 newlines.
+ // Returns the whole length so that it can be completely replaced.
+ return len;
}
/**
@@ -2178,6 +2250,7 @@
public Block generateBlock(PrivateKey privateKey,
String sigalg,
X509Certificate[] certChain,
+ Set<X509CRL> crls,
boolean externalSF, String tsaUrl,
X509Certificate tsaCert,
ContentSigner signingMechanism,
@@ -2185,7 +2258,7 @@
throws NoSuchAlgorithmException, InvalidKeyException, IOException,
SignatureException, CertificateException
{
- return new Block(this, privateKey, sigalg, certChain, externalSF,
+ return new Block(this, privateKey, sigalg, certChain, crls, externalSF,
tsaUrl, tsaCert, signingMechanism, args, zipFile);
}
@@ -2199,7 +2272,8 @@
* Construct a new signature block.
*/
Block(SignatureFile sfg, PrivateKey privateKey, String sigalg,
- X509Certificate[] certChain, boolean externalSF, String tsaUrl,
+ X509Certificate[] certChain, Set<X509CRL> crls,
+ boolean externalSF, String tsaUrl,
X509Certificate tsaCert, ContentSigner signingMechanism,
String[] args, ZipFile zipFile)
throws NoSuchAlgorithmException, InvalidKeyException, IOException,
@@ -2286,7 +2360,7 @@
// Assemble parameters for the signing mechanism
ContentSignerParameters params =
new JarSignerParameters(args, tsaUri, tsaCert, signature,
- signatureAlgorithm, certChain, content, zipFile);
+ signatureAlgorithm, certChain, crls, content, zipFile);
// Generate the signature block
block = signingMechanism.generateSignedData(
@@ -2327,6 +2401,7 @@
private byte[] signature;
private String signatureAlgorithm;
private X509Certificate[] signerCertificateChain;
+ private Set<X509CRL> crls;
private byte[] content;
private ZipFile source;
@@ -2335,7 +2410,8 @@
*/
JarSignerParameters(String[] args, URI tsa, X509Certificate tsaCertificate,
byte[] signature, String signatureAlgorithm,
- X509Certificate[] signerCertificateChain, byte[] content,
+ X509Certificate[] signerCertificateChain, Set<X509CRL> crls,
+ byte[] content,
ZipFile source) {
if (signature == null || signatureAlgorithm == null ||
@@ -2348,6 +2424,7 @@
this.signature = signature;
this.signatureAlgorithm = signatureAlgorithm;
this.signerCertificateChain = signerCertificateChain;
+ this.crls = crls;
this.content = content;
this.source = source;
}
@@ -2423,4 +2500,13 @@
public ZipFile getSource() {
return source;
}
+
+ @Override
+ public Set<X509CRL> getCRLs() {
+ if (crls == null) {
+ return Collections.emptySet();
+ } else {
+ return Collections.unmodifiableSet(crls);
+ }
+ }
}
--- a/jdk/src/share/classes/sun/security/tools/JarSignerResources.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/security/tools/JarSignerResources.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-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
@@ -74,6 +74,8 @@
"[-digestalg <algorithm>] name of digest algorithm"},
{"[-sigalg <algorithm>] name of signature algorithm",
"[-sigalg <algorithm>] name of signature algorithm"},
+ {"[-crl[:auto| <file>] include CRL in signed jar",
+ "[-crl[:auto| <file>] include CRL in signed jar"},
{"[-verify] verify a signed JAR file",
"[-verify] verify a signed JAR file"},
{"[-verbose[:suboptions]] verbose output when signing/verifying.",
@@ -191,6 +193,7 @@
{"using an alternative signing mechanism",
"using an alternative signing mechanism"},
{"entry was signed on", "entry was signed on {0}"},
+ {"with a CRL including %d entries", "with a CRL including %d entries"},
{"Warning: ", "Warning: "},
{"This jar contains unsigned entries which have not been integrity-checked. ",
"This jar contains unsigned entries which have not been integrity-checked. "},
--- a/jdk/src/share/classes/sun/security/tools/KeyTool.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/security/tools/KeyTool.java Tue May 11 16:35:36 2010 -0700
@@ -25,6 +25,7 @@
package sun.security.tools;
+import sun.misc.SharedSecrets;
import java.io.*;
import java.security.CodeSigner;
import java.security.KeyStore;
@@ -42,6 +43,7 @@
import java.security.Provider;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
+import java.security.cert.CRL;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.text.Collator;
@@ -50,14 +52,20 @@
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.lang.reflect.Constructor;
+import java.math.BigInteger;
+import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
-
+import java.security.cert.CertStore;
+
+import java.security.cert.X509CRL;
+import java.security.cert.X509CRLEntry;
+import java.security.cert.X509CRLSelector;
+import javax.security.auth.x500.X500Principal;
import sun.misc.BASE64Encoder;
import sun.security.util.ObjectIdentifier;
import sun.security.pkcs.PKCS10;
import sun.security.provider.X509Factory;
-import sun.security.util.DerOutputStream;
import sun.security.util.Password;
import sun.security.util.PathList;
import javax.crypto.KeyGenerator;
@@ -72,6 +80,7 @@
import sun.misc.BASE64Decoder;
import sun.security.pkcs.PKCS10Attribute;
import sun.security.pkcs.PKCS9Attribute;
+import sun.security.provider.certpath.ldap.LDAPCertStoreHelper;
import sun.security.util.DerValue;
import sun.security.x509.*;
@@ -147,6 +156,7 @@
private Set<char[]> passwords = new HashSet<char[]> ();
private String startDate = null;
+ private List <String> ids = new ArrayList <String> (); // used in GENCRL
private List <String> v3ext = new ArrayList <String> ();
enum Command {
@@ -180,9 +190,6 @@
STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
- IDENTITYDB("Imports entries from a JDK 1.1.x-style identity database",
- FILEIN, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
- PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
IMPORTCERT("Imports a certificate or a certificate chain",
NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN,
KEYPASS, KEYSTORE, STOREPASS, STORETYPE,
@@ -195,10 +202,6 @@
SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS,
NOPROMPT, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH,
V),
- KEYCLONE("Clones a key entry",
- ALIAS, DESTALIAS, KEYPASS, NEW, STORETYPE,
- KEYSTORE, STOREPASS, PROVIDERNAME, PROVIDERCLASS,
- PROVIDERARG, PROVIDERPATH, V),
KEYPASSWD("Changes the key password of an entry",
ALIAS, KEYPASS, NEW, KEYSTORE, STOREPASS,
STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
@@ -211,12 +214,29 @@
RFC, FILEIN, SSLSERVER, JARFILE, V),
PRINTCERTREQ("Prints the content of a certificate request",
FILEIN, V),
+ PRINTCRL("Prints the content of a CRL file",
+ FILEIN, V),
+ STOREPASSWD("Changes the store password of a keystore",
+ NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME,
+ PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
+
+ // Undocumented start here, KEYCLONE is used a marker in -help;
+
+ KEYCLONE("Clones a key entry",
+ ALIAS, DESTALIAS, KEYPASS, NEW, STORETYPE,
+ KEYSTORE, STOREPASS, PROVIDERNAME, PROVIDERCLASS,
+ PROVIDERARG, PROVIDERPATH, V),
SELFCERT("Generates a self-signed certificate",
ALIAS, SIGALG, DNAME, STARTDATE, VALIDITY, KEYPASS,
STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
- STOREPASSWD("Changes the store password of a keystore",
- NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME,
+ GENCRL("Generates CRL",
+ RFC, FILEOUT, ID,
+ ALIAS, SIGALG, EXT, KEYPASS, KEYSTORE,
+ STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
+ PROVIDERARG, PROVIDERPATH, V, PROTECTED),
+ IDENTITYDB("Imports entries from a JDK 1.1.x-style identity database",
+ FILEIN, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V);
final String description;
@@ -244,6 +264,7 @@
EXT("ext", "<value>", "X.509 extension"),
FILEOUT("file", "<filename>", "output file name"),
FILEIN("file", "<filename>", "input file name"),
+ ID("id", "<id:reason>", "Serial ID of cert to revoke"),
INFILE("infile", "<filename>", "input file name"),
KEYALG("keyalg", "<keyalg>", "key algorithm name"),
KEYPASS("keypass", "<arg>", "key password"),
@@ -458,6 +479,8 @@
validity = Long.parseLong(args[++i]);
} else if (collator.compare(flags, "-ext") == 0) {
v3ext.add(args[++i]);
+ } else if (collator.compare(flags, "-id") == 0) {
+ ids.add(args[++i]);
} else if (collator.compare(flags, "-file") == 0) {
filename = args[++i];
} else if (collator.compare(flags, "-infile") == 0) {
@@ -720,7 +743,8 @@
command != GENSECKEY &&
command != IDENTITYDB &&
command != IMPORTCERT &&
- command != IMPORTKEYSTORE) {
+ command != IMPORTKEYSTORE &&
+ command != PRINTCRL) {
throw new Exception(rb.getString
("Keystore file does not exist: ") + ksfname);
}
@@ -855,10 +879,12 @@
&& !KeyStoreUtil.isWindowsKeyStore(storetype)
&& isKeyStoreRelated(command)) {
// here we have EXPORTCERT and LIST (info valid until STOREPASSWD)
- System.err.print(rb.getString("Enter keystore password: "));
- System.err.flush();
- storePass = Password.readPassword(System.in);
- passwords.add(storePass);
+ if (command != PRINTCRL) {
+ System.err.print(rb.getString("Enter keystore password: "));
+ System.err.flush();
+ storePass = Password.readPassword(System.in);
+ passwords.add(storePass);
+ }
}
// Now load a nullStream-based keystore,
@@ -895,7 +921,7 @@
// Create a certificate factory
if (command == PRINTCERT || command == IMPORTCERT
- || command == IDENTITYDB) {
+ || command == IDENTITYDB || command == PRINTCRL) {
cf = CertificateFactory.getInstance("X509");
}
@@ -1086,6 +1112,22 @@
ps.close();
}
}
+ } else if (command == GENCRL) {
+ if (alias == null) {
+ alias = keyAlias;
+ }
+ PrintStream ps = null;
+ if (filename != null) {
+ ps = new PrintStream(new FileOutputStream(filename));
+ out = ps;
+ }
+ try {
+ doGenCRL(out);
+ } finally {
+ if (ps != null) {
+ ps.close();
+ }
+ }
} else if (command == PRINTCERTREQ) {
InputStream inStream = System.in;
if (filename != null) {
@@ -1098,6 +1140,8 @@
inStream.close();
}
}
+ } else if (command == PRINTCRL) {
+ doPrintCRL(filename, out);
}
// If we need to save the keystore, do so.
@@ -1152,7 +1196,8 @@
CertificateValidity interval = new CertificateValidity(firstDate,
lastDate);
- PrivateKey privateKey = (PrivateKey)recoverKey(alias, storePass, keyPass).fst;
+ PrivateKey privateKey =
+ (PrivateKey)recoverKey(alias, storePass, keyPass).fst;
if (sigAlgName == null) {
sigAlgName = getCompatibleSigAlgName(privateKey.getAlgorithm());
}
@@ -1221,6 +1266,56 @@
}
}
+ private void doGenCRL(PrintStream out)
+ throws Exception {
+ if (ids == null) {
+ throw new Exception("Must provide -id when -gencrl");
+ }
+ Certificate signerCert = keyStore.getCertificate(alias);
+ byte[] encoded = signerCert.getEncoded();
+ X509CertImpl signerCertImpl = new X509CertImpl(encoded);
+ X509CertInfo signerCertInfo = (X509CertInfo)signerCertImpl.get(
+ X509CertImpl.NAME + "." + X509CertImpl.INFO);
+ X500Name owner = (X500Name)signerCertInfo.get(X509CertInfo.SUBJECT + "." +
+ CertificateSubjectName.DN_NAME);
+
+ Date firstDate = getStartDate(startDate);
+ Date lastDate = (Date) firstDate.clone();
+ lastDate.setTime(lastDate.getTime() + (long)validity*1000*24*60*60);
+ CertificateValidity interval = new CertificateValidity(firstDate,
+ lastDate);
+
+
+ PrivateKey privateKey =
+ (PrivateKey)recoverKey(alias, storePass, keyPass).fst;
+ if (sigAlgName == null) {
+ sigAlgName = getCompatibleSigAlgName(privateKey.getAlgorithm());
+ }
+
+ X509CRLEntry[] badCerts = new X509CRLEntry[ids.size()];
+ for (int i=0; i<ids.size(); i++) {
+ String id = ids.get(i);
+ int d = id.indexOf(':');
+ if (d >= 0) {
+ CRLExtensions ext = new CRLExtensions();
+ ext.set("Reason", new CRLReasonCodeExtension(Integer.parseInt(id.substring(d+1))));
+ badCerts[i] = new X509CRLEntryImpl(new BigInteger(id.substring(0, d)),
+ firstDate, ext);
+ } else {
+ badCerts[i] = new X509CRLEntryImpl(new BigInteger(ids.get(i)), firstDate);
+ }
+ }
+ X509CRLImpl crl = new X509CRLImpl(owner, firstDate, lastDate, badCerts);
+ crl.sign(privateKey, sigAlgName);
+ if (rfc) {
+ out.println("-----BEGIN X509 CRL-----");
+ new BASE64Encoder().encodeBuffer(crl.getEncodedInternal(), out);
+ out.println("-----END X509 CRL-----");
+ } else {
+ out.write(crl.getEncodedInternal());
+ }
+ }
+
/**
* Creates a PKCS#10 cert signing request, corresponding to the
* keys (and name) associated with a given alias.
@@ -1925,6 +2020,177 @@
}
}
+ private static <T> Iterable<T> e2i(final Enumeration<T> e) {
+ return new Iterable<T>() {
+ @Override
+ public Iterator<T> iterator() {
+ return new Iterator<T>() {
+ @Override
+ public boolean hasNext() {
+ return e.hasMoreElements();
+ }
+ @Override
+ public T next() {
+ return e.nextElement();
+ }
+ public void remove() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ };
+ }
+ };
+ }
+
+ /**
+ * Loads CRLs from a source. This method is also called in JarSigner.
+ * @param src the source, which means System.in if null, or a URI,
+ * or a bare file path name
+ */
+ public static Collection<? extends CRL> loadCRLs(String src) throws Exception {
+ InputStream in = null;
+ URI uri = null;
+ if (src == null) {
+ in = System.in;
+ } else {
+ try {
+ uri = new URI(src);
+ if (uri.getScheme().equals("ldap")) {
+ // No input stream for LDAP
+ } else {
+ in = uri.toURL().openStream();
+ }
+ } catch (Exception e) {
+ try {
+ in = new FileInputStream(src);
+ } catch (Exception e2) {
+ if (uri == null || uri.getScheme() == null) {
+ throw e2; // More likely a bare file path
+ } else {
+ throw e; // More likely a protocol or network problem
+ }
+ }
+ }
+ }
+ if (in != null) {
+ try {
+ // Read the full stream before feeding to X509Factory,
+ // otherwise, keytool -gencrl | keytool -printcrl
+ // might not work properly, since -gencrl is slow
+ // and there's no data in the pipe at the beginning.
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ byte[] b = new byte[4096];
+ while (true) {
+ int len = in.read(b);
+ if (len < 0) break;
+ bout.write(b, 0, len);
+ }
+ return CertificateFactory.getInstance("X509").generateCRLs(
+ new ByteArrayInputStream(bout.toByteArray()));
+ } finally {
+ if (in != System.in) {
+ in.close();
+ }
+ }
+ } else { // must be LDAP, and uri is not null
+ String path = uri.getPath();
+ if (path.charAt(0) == '/') path = path.substring(1);
+ LDAPCertStoreHelper h = new LDAPCertStoreHelper();
+ CertStore s = h.getCertStore(uri);
+ X509CRLSelector sel =
+ h.wrap(new X509CRLSelector(), null, path);
+ return s.getCRLs(sel);
+ }
+ }
+
+ /**
+ * Returns CRLs described in a X509Certificate's CRLDistributionPoints
+ * Extension. Only those containing a general name of type URI are read.
+ */
+ public static List<CRL> readCRLsFromCert(X509Certificate cert)
+ throws Exception {
+ List<CRL> crls = new ArrayList<CRL>();
+ CRLDistributionPointsExtension ext =
+ X509CertImpl.toImpl(cert).getCRLDistributionPointsExtension();
+ if (ext == null) return crls;
+ for (DistributionPoint o: (List<DistributionPoint>)
+ ext.get(CRLDistributionPointsExtension.POINTS)) {
+ GeneralNames names = o.getFullName();
+ if (names != null) {
+ for (GeneralName name: names.names()) {
+ if (name.getType() == GeneralNameInterface.NAME_URI) {
+ URIName uriName = (URIName)name.getName();
+ for (CRL crl: KeyTool.loadCRLs(uriName.getName())) {
+ if (crl instanceof X509CRL) {
+ crls.add((X509CRL)crl);
+ }
+ }
+ break; // Different name should point to same CRL
+ }
+ }
+ }
+ }
+ return crls;
+ }
+
+ private static String verifyCRL(KeyStore ks, CRL crl)
+ throws Exception {
+ X509CRLImpl xcrl = (X509CRLImpl)crl;
+ X500Principal issuer = xcrl.getIssuerX500Principal();
+ for (String s: e2i(ks.aliases())) {
+ Certificate cert = ks.getCertificate(s);
+ if (cert instanceof X509Certificate) {
+ X509Certificate xcert = (X509Certificate)cert;
+ if (xcert.getSubjectX500Principal().equals(issuer)) {
+ try {
+ ((X509CRLImpl)crl).verify(cert.getPublicKey());
+ return s;
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ private void doPrintCRL(String src, PrintStream out)
+ throws Exception {
+ for (CRL crl: loadCRLs(src)) {
+ printCRL(crl, out);
+ String issuer = null;
+ if (caks != null) {
+ issuer = verifyCRL(caks, crl);
+ if (issuer != null) {
+ System.out.println("Verified by " + issuer + " in cacerts");
+ }
+ }
+ if (issuer == null && keyStore != null) {
+ issuer = verifyCRL(keyStore, crl);
+ if (issuer != null) {
+ System.out.println("Verified by " + issuer + " in keystore");
+ }
+ }
+ if (issuer == null) {
+ out.println(rb.getString
+ ("*******************************************"));
+ out.println("WARNING: not verified. Make sure -keystore and -alias are correct.");
+ out.println(rb.getString
+ ("*******************************************\n\n"));
+ }
+ }
+ }
+
+ private void printCRL(CRL crl, PrintStream out)
+ throws Exception {
+ if (rfc) {
+ X509CRL xcrl = (X509CRL)crl;
+ out.println("-----BEGIN X509 CRL-----");
+ new BASE64Encoder().encodeBuffer(xcrl.getEncoded(), out);
+ out.println("-----END X509 CRL-----");
+ } else {
+ out.println(crl.toString());
+ }
+ }
+
private void doPrintCertReq(InputStream in, PrintStream out)
throws Exception {
@@ -2063,6 +2329,16 @@
out.println();
}
}
+ CRL[] crls = SharedSecrets
+ .getJavaSecurityCodeSignerAccess()
+ .getCRLs(signer);
+ if (crls != null) {
+ out.println(rb.getString("CRLs:"));
+ out.println();
+ for (CRL crl: crls) {
+ printCRL(crl, out);
+ }
+ }
}
}
}
@@ -2620,7 +2896,7 @@
if (v.length == 0) {
out.println(rb.getString("(Empty value)"));
} else {
- new sun.misc.HexDumpEncoder().encode(ext.getExtensionValue(), out);
+ new sun.misc.HexDumpEncoder().encodeBuffer(ext.getExtensionValue(), out);
out.println();
}
}
@@ -3330,15 +3606,22 @@
/**
* Match a command (may be abbreviated) with a command set.
* @param s the command provided
- * @param list the legal command set
+ * @param list the legal command set. If there is a null, commands after it
+ * are regarded experimental, which means they are supported but their
+ * existence should not be revealed to user.
* @return the position of a single match, or -1 if none matched
* @throws Exception if s is ambiguous
*/
private static int oneOf(String s, String... list) throws Exception {
int[] match = new int[list.length];
int nmatch = 0;
+ int experiment = Integer.MAX_VALUE;
for (int i = 0; i<list.length; i++) {
String one = list[i];
+ if (one == null) {
+ experiment = i;
+ continue;
+ }
if (one.toLowerCase(Locale.ENGLISH)
.startsWith(s.toLowerCase(Locale.ENGLISH))) {
match[nmatch++] = i;
@@ -3360,17 +3643,27 @@
}
}
}
- if (nmatch == 0) return -1;
- if (nmatch == 1) return match[0];
- StringBuffer sb = new StringBuffer();
- MessageFormat form = new MessageFormat(rb.getString
- ("command {0} is ambiguous:"));
- Object[] source = {s};
- sb.append(form.format(source) +"\n ");
- for (int i=0; i<nmatch; i++) {
- sb.append(" " + list[match[i]]);
+ if (nmatch == 0) {
+ return -1;
+ } else if (nmatch == 1) {
+ return match[0];
+ } else {
+ // If multiple matches is in experimental commands, ignore them
+ if (match[1] > experiment) {
+ return match[0];
+ }
+ StringBuffer sb = new StringBuffer();
+ MessageFormat form = new MessageFormat(rb.getString
+ ("command {0} is ambiguous:"));
+ Object[] source = {s};
+ sb.append(form.format(source));
+ sb.append("\n ");
+ for (int i=0; i<nmatch && match[i]<experiment; i++) {
+ sb.append(' ');
+ sb.append(list[match[i]]);
+ }
+ throw new Exception(sb.toString());
}
- throw new Exception(sb.toString());
}
/**
@@ -3405,6 +3698,8 @@
"IssuerAlternativeName",
"SubjectInfoAccess",
"AuthorityInfoAccess",
+ null,
+ "CRLDistributionPoints",
};
private ObjectIdentifier findOidForExtName(String type)
@@ -3417,6 +3712,7 @@
case 4: return PKIXExtensions.IssuerAlternativeName_Id;
case 5: return PKIXExtensions.SubjectInfoAccess_Id;
case 6: return PKIXExtensions.AuthInfoAccess_Id;
+ case 8: return PKIXExtensions.CRLDistributionPoints_Id;
default: return new ObjectIdentifier(type);
}
}
@@ -3712,6 +4008,28 @@
("Illegal value: ") + extstr);
}
break;
+ case 8: // CRL, experimental, only support 1 distributionpoint
+ if(value != null) {
+ String[] ps = value.split(",");
+ GeneralNames gnames = new GeneralNames();
+ for(String item: ps) {
+ colonpos = item.indexOf(':');
+ if (colonpos < 0) {
+ throw new Exception("Illegal item " + item + " in " + extstr);
+ }
+ String t = item.substring(0, colonpos);
+ String v = item.substring(colonpos+1);
+ gnames.add(createGeneralName(t, v));
+ }
+ ext.set(CRLDistributionPointsExtension.NAME,
+ new CRLDistributionPointsExtension(
+ isCritical, Collections.singletonList(
+ new DistributionPoint(gnames, null, null))));
+ } else {
+ throw new Exception(rb.getString
+ ("Illegal value: ") + extstr);
+ }
+ break;
case -1:
ObjectIdentifier oid = new ObjectIdentifier(name);
byte[] data = null;
@@ -3748,6 +4066,9 @@
new DerValue(DerValue.tag_OctetString, data)
.toByteArray()));
break;
+ default:
+ throw new Exception(rb.getString(
+ "Unknown extension type: ") + extstr);
}
}
// always non-critical
@@ -3810,11 +4131,8 @@
System.err.println(rb.getString("Commands:"));
System.err.println();
for (Command c: Command.values()) {
- if (c != IDENTITYDB
- && c != KEYCLONE
- && c != SELFCERT) { // Deprecated commands
- System.err.printf(" %-20s%s\n", c, rb.getString(c.description));
- }
+ if (c == KEYCLONE) break;
+ System.err.printf(" %-20s%s\n", c, rb.getString(c.description));
}
System.err.println();
System.err.println(rb.getString(
--- a/jdk/src/share/classes/sun/security/tools/TimestampedSigner.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/security/tools/TimestampedSigner.java Tue May 11 16:35:36 2010 -0700
@@ -38,6 +38,7 @@
import java.util.List;
import com.sun.jarsigner.*;
+import java.security.cert.X509CRL;
import java.util.Arrays;
import sun.security.pkcs.*;
import sun.security.timestamp.*;
@@ -239,7 +240,7 @@
// Create the PKCS #7 signed data message
PKCS7 p7 =
new PKCS7(algorithms, contentInfo, signerCertificateChain,
- signerInfos);
+ parameters.getCRLs().toArray(new X509CRL[parameters.getCRLs().size()]), signerInfos);
ByteArrayOutputStream p7out = new ByteArrayOutputStream();
p7.encodeSignedData(p7out);
--- a/jdk/src/share/classes/sun/security/util/Resources.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/security/util/Resources.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-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
@@ -71,6 +71,7 @@
"Generates a secret key"}, //-genseckey
{"Generates certificate from a certificate request",
"Generates certificate from a certificate request"}, //-gencert
+ {"Generates CRL", "Generates CRL"}, //-gencrl
{"Imports entries from a JDK 1.1.x-style identity database",
"Imports entries from a JDK 1.1.x-style identity database"}, //-identitydb
{"Imports a certificate or a certificate chain",
@@ -87,6 +88,8 @@
"Prints the content of a certificate"}, //-printcert
{"Prints the content of a certificate request",
"Prints the content of a certificate request"}, //-printcertreq
+ {"Prints the content of a CRL file",
+ "Prints the content of a CRL file"}, //-printcrl
{"Generates a self-signed certificate",
"Generates a self-signed certificate"}, //-selfcert
{"Changes the store password of a keystore",
@@ -176,6 +179,8 @@
"verbose output"}, //-v
{"validity number of days",
"validity number of days"}, //-validity
+ {"Serial ID of cert to revoke",
+ "Serial ID of cert to revoke"}, //-id
// keytool: Running part
{"keytool error: ", "keytool error: "},
{"Illegal option: ", "Illegal option: "},
@@ -375,6 +380,7 @@
{"Signer #%d:", "Signer #%d:"},
{"Timestamp:", "Timestamp:"},
{"Signature:", "Signature:"},
+ {"CRLs:", "CRLs:"},
{"Certificate owner: ", "Certificate owner: "},
{"Not a signed jar file", "Not a signed jar file"},
{"No certificate from the SSL server",
@@ -433,6 +439,7 @@
{"This extension cannot be marked as critical. ",
"This extension cannot be marked as critical. "},
{"Odd number of hex digits found: ", "Odd number of hex digits found: "},
+ {"Unknown extension type: ", "Unknown extension type: "},
{"command {0} is ambiguous:", "command {0} is ambiguous:"},
// policytool
--- a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-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,7 +25,6 @@
package sun.security.util;
-import java.security.CodeSigner;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
@@ -34,11 +33,11 @@
import java.io.*;
import java.util.*;
import java.util.jar.*;
-import java.io.ByteArrayOutputStream;
import sun.security.pkcs.*;
import sun.security.timestamp.TimestampToken;
import sun.misc.BASE64Decoder;
+import sun.misc.SharedSecrets;
import sun.security.jca.Providers;
@@ -479,7 +478,12 @@
signers = new ArrayList<CodeSigner>();
}
// Append the new code signer
- signers.add(new CodeSigner(certChain, getTimestamp(info)));
+ CodeSigner signer = new CodeSigner(certChain, getTimestamp(info));
+ if (block.getCRLs() != null) {
+ SharedSecrets.getJavaSecurityCodeSignerAccess().setCRLs(
+ signer, block.getCRLs());
+ }
+ signers.add(signer);
if (debug != null) {
debug.println("Signature Block Certificate: " +
--- a/jdk/src/share/classes/sun/security/x509/X509CRLImpl.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/share/classes/sun/security/x509/X509CRLImpl.java Tue May 11 16:35:36 2010 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-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
@@ -89,7 +89,7 @@
* @author Hemma Prafullchandra
* @see X509CRL
*/
-public class X509CRLImpl extends X509CRL {
+public class X509CRLImpl extends X509CRL implements DerEncoder {
// CRL data, and its envelope
private byte[] signedCRL = null; // DER encoded crl
@@ -1189,6 +1189,13 @@
}
}
+ @Override
+ public void derEncode(OutputStream out) throws IOException {
+ if (signedCRL == null)
+ throw new IOException("Null CRL to encode");
+ out.write(signedCRL.clone());
+ }
+
/**
* Immutable X.509 Certificate Issuer DN and serial number pair
*/
--- a/jdk/src/windows/native/java/net/net_util_md.h Tue May 11 16:34:07 2010 -0700
+++ b/jdk/src/windows/native/java/net/net_util_md.h Tue May 11 16:35:36 2010 -0700
@@ -222,7 +222,8 @@
#define IN6_IS_ADDR_ANY(a) \
(((a)->s6_words[0] == 0) && ((a)->s6_words[1] == 0) && \
((a)->s6_words[2] == 0) && ((a)->s6_words[3] == 0) && \
- ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0))
+ ((a)->s6_words[4] == 0) && ((a)->s6_words[5] == 0) && \
+ ((a)->s6_words[6] == 0) && ((a)->s6_words[7] == 0))
#endif
#ifndef IPV6_V6ONLY
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/net/httpserver/bugs/HeadTest.java Tue May 11 16:35:36 2010 -0700
@@ -0,0 +1,117 @@
+/*
+ * Copyright 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 6886723
+ * @summary light weight http server doesn't return correct status code for HEAD requests
+ */
+
+import java.net.InetSocketAddress;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+
+public class HeadTest {
+
+ public static void main(String[] args) throws Exception {
+ server();
+ }
+
+ static void server() throws Exception {
+ InetSocketAddress inetAddress = new InetSocketAddress(0);
+ HttpServer server = HttpServer.create(inetAddress, 5);
+ try {
+ server.setExecutor(Executors.newFixedThreadPool(5));
+ HttpContext chunkedContext = server.createContext("/chunked");
+ chunkedContext.setHandler(new HttpHandler() {
+ @Override
+ public void handle(HttpExchange msg) {
+ try {
+ try {
+ if (msg.getRequestMethod().equals("HEAD")) {
+ msg.getRequestBody().close();
+ msg.getResponseHeaders().add("Transfer-encoding", "chunked");
+ msg.sendResponseHeaders(200, -1);
+ }
+ } catch(IOException ioe) {
+ ioe.printStackTrace();
+ }
+ } finally {
+ msg.close();
+ }
+ }
+ });
+ HttpContext clContext = server.createContext("/content");
+ clContext.setHandler(new HttpHandler() {
+ @Override
+ public void handle(HttpExchange msg) {
+ try {
+ try {
+ if (msg.getRequestMethod().equals("HEAD")) {
+ msg.getRequestBody().close();
+ msg.getResponseHeaders().add("Content-length", "1024");
+ msg.sendResponseHeaders(200, -1);
+ }
+ } catch(IOException ioe) {
+ ioe.printStackTrace();
+ }
+ } finally {
+ msg.close();
+ }
+ }
+ });
+ server.start();
+ String urlStr = "http://localhost:" + server.getAddress().getPort() + "/";
+ System.out.println("Server is at " + urlStr);
+
+ // Run the chunked client
+ for(int i=0; i < 10; i++) {
+ runClient(urlStr + "chunked/");
+ }
+ // Run the content length client
+ for(int i=0; i < 10; i++) {
+ runClient(urlStr + "content/");
+ }
+ } finally {
+ // Stop the server
+ ((ExecutorService)server.getExecutor()).shutdown();
+ server.stop(0);
+ }
+ }
+
+ static void runClient(String urlStr) throws Exception {
+ HttpURLConnection conn = (HttpURLConnection) new URL(urlStr).openConnection();
+ conn.setRequestMethod("HEAD");
+ int status = conn.getResponseCode();
+ if (status != 200) {
+ throw new RuntimeException("HEAD request doesn't return 200, but returns " + status);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/net/DatagramSocket/LocalSocketAddress.java Tue May 11 16:35:36 2010 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright 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 6718504
+ * @summary IN6_IS_ADDR_ANY tests only 12 bytes of 16-byte address
+ */
+
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.Inet6Address;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.util.*;
+
+public class LocalSocketAddress {
+ public static void main(String[] args) throws SocketException {
+ InetAddress IPv6LoopbackAddr = null;
+ DatagramSocket soc = null;
+
+ try {
+ List<NetworkInterface> nics = Collections.list(NetworkInterface.getNetworkInterfaces());
+ for (NetworkInterface nic : nics) {
+ if (!nic.isLoopback())
+ continue;
+
+ List<InetAddress> addrs = Collections.list(nic.getInetAddresses());
+ for (InetAddress addr : addrs) {
+ if (addr instanceof Inet6Address) {
+ IPv6LoopbackAddr = addr;
+ break;
+ }
+ }
+ }
+
+ if (IPv6LoopbackAddr == null) {
+ System.out.println("IPv6 is not available, exiting test.");
+ return;
+ }
+
+ soc = new DatagramSocket(0, IPv6LoopbackAddr);
+
+ if (!IPv6LoopbackAddr.equals(soc.getLocalAddress())) {
+ throw new RuntimeException("Bound address is " + soc.getLocalAddress() +
+ ", but should be " + IPv6LoopbackAddr);
+ }
+ } finally {
+ if (soc != null) { soc.close(); }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/PriorityQueue/NoNulls.java Tue May 11 16:35:36 2010 -0700
@@ -0,0 +1,204 @@
+/*
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file:
+ *
+ * Written by Martin Buchholz with assistance from members of JCP JSR-166
+ * Expert Group and released to the public domain, as explained at
+ * http://creativecommons.org/licenses/publicdomain
+ */
+
+/*
+ * @test
+ * @bug 6950540
+ * @summary Attempt to add a null throws NullPointerException
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.PriorityQueue;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.PriorityBlockingQueue;
+
+public class NoNulls {
+ void test(String[] args) throws Throwable {
+ final Comparator<String> nullTolerantComparator
+ = new Comparator<>() {
+ public int compare(String x, String y) {
+ return (x == null ? -1 :
+ y == null ? 1 :
+ x.compareTo(y));
+ }};
+
+ final SortedSet<String> nullSortedSet
+ = new TreeSet<>(nullTolerantComparator);
+ nullSortedSet.add(null);
+
+ final PriorityQueue<String> nullPriorityQueue
+ = new PriorityQueue<>() {
+ public Object[] toArray() { return new Object[] { null };}};
+
+ final Collection<String> nullCollection = new ArrayList<>();
+ nullCollection.add(null);
+
+ THROWS(NullPointerException.class,
+ new F() { void f() {
+ new PriorityQueue<String>(nullCollection);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>(nullCollection);
+ }},
+ new F() { void f() {
+ new ArrayBlockingQueue<String>(10, false, nullCollection);
+ }},
+ new F() { void f() {
+ new ArrayBlockingQueue<String>(10, true, nullCollection);
+ }},
+ new F() { void f() {
+ new LinkedBlockingQueue<String>(nullCollection);
+ }},
+ new F() { void f() {
+ new LinkedBlockingDeque<String>(nullCollection);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>((Collection<String>) nullPriorityQueue);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>((Collection<String>) nullPriorityQueue);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>(nullSortedSet);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>(nullSortedSet);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>((Collection<String>) nullSortedSet);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>((Collection<String>) nullSortedSet);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>(nullPriorityQueue);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>(nullPriorityQueue);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>().add(null);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>().add(null);
+ }},
+ new F() { void f() {
+ new ArrayBlockingQueue<String>(10, false).add(null);
+ }},
+ new F() { void f() {
+ new ArrayBlockingQueue<String>(10, true).add(null);
+ }},
+ new F() { void f() {
+ new LinkedBlockingQueue<String>().add(null);
+ }},
+ new F() { void f() {
+ new LinkedBlockingDeque<String>().add(null);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>().offer(null);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>().offer(null);
+ }});
+
+ nullSortedSet.add("foo");
+ nullCollection.add("foo");
+ THROWS(NullPointerException.class,
+ new F() { void f() {
+ new PriorityQueue<String>(nullCollection);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>(nullCollection);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>((Collection<String>) nullPriorityQueue);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>((Collection<String>) nullPriorityQueue);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>(nullSortedSet);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>(nullSortedSet);
+ }},
+
+ new F() { void f() {
+ new PriorityQueue<String>((Collection<String>) nullSortedSet);
+ }},
+ new F() { void f() {
+ new PriorityBlockingQueue<String>((Collection<String>) nullSortedSet);
+ }});
+
+ }
+
+ //--------------------- Infrastructure ---------------------------
+ volatile int passed = 0, failed = 0;
+ void pass() {passed++;}
+ void fail() {failed++; Thread.dumpStack();}
+ void fail(String msg) {System.err.println(msg); fail();}
+ void unexpected(Throwable t) {failed++; t.printStackTrace();}
+ void check(boolean cond) {if (cond) pass(); else fail();}
+ void equal(Object x, Object y) {
+ if (x == null ? y == null : x.equals(y)) pass();
+ else fail(x + " not equal to " + y);}
+ public static void main(String[] args) throws Throwable {
+ new NoNulls().instanceMain(args);}
+ public void instanceMain(String[] args) throws Throwable {
+ try {test(args);} catch (Throwable t) {unexpected(t);}
+ System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+ if (failed > 0) throw new AssertionError("Some tests failed");}
+ abstract class F {abstract void f() throws Throwable;}
+ void THROWS(Class<? extends Throwable> k, F... fs) {
+ for (F f : fs)
+ try {f.f(); fail("Expected " + k.getName() + " not thrown");}
+ catch (Throwable t) {
+ if (k.isAssignableFrom(t.getClass())) pass();
+ else unexpected(t);}}
+}
--- a/jdk/test/java/util/Random/DistinctSeeds.java Tue May 11 16:34:07 2010 -0700
+++ b/jdk/test/java/util/Random/DistinctSeeds.java Tue May 11 16:35:36 2010 -0700
@@ -33,18 +33,54 @@
/*
* @test
- * @bug 4949279
+ * @bug 4949279 6937857
* @summary Independent instantiations of Random() have distinct seeds.
*/
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
import java.util.Random;
public class DistinctSeeds {
public static void main(String[] args) throws Exception {
// Strictly speaking, it is possible for these to randomly fail,
- // but the probability should be *extremely* small (< 2**-63).
+ // but the probability should be small (approximately 2**-48).
if (new Random().nextLong() == new Random().nextLong() ||
new Random().nextLong() == new Random().nextLong())
throw new RuntimeException("Random() seeds not unique.");
+
+ // Now try generating seeds concurrently
+ class RandomCollector implements Runnable {
+ long[] randoms = new long[1<<17];
+ public void run() {
+ for (int i = 0; i < randoms.length; i++)
+ randoms[i] = new Random().nextLong();
+ }
+ }
+ final int threadCount = 2;
+ List<RandomCollector> collectors = new ArrayList<RandomCollector>();
+ List<Thread> threads = new ArrayList<Thread>();
+ for (int i = 0; i < threadCount; i++) {
+ RandomCollector r = new RandomCollector();
+ collectors.add(r);
+ threads.add(new Thread(r));
+ }
+ for (Thread thread : threads)
+ thread.start();
+ for (Thread thread : threads)
+ thread.join();
+ int collisions = 0;
+ HashSet<Long> s = new HashSet<Long>();
+ for (RandomCollector r : collectors) {
+ for (long x : r.randoms) {
+ if (s.contains(x))
+ collisions++;
+ s.add(x);
+ }
+ }
+ System.out.printf("collisions=%d%n", collisions);
+ if (collisions > 10)
+ throw new Error("too many collisions");
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/net/www/protocol/http/BasicLongCredentials.java Tue May 11 16:35:36 2010 -0700
@@ -0,0 +1,111 @@
+/*
+ * Copyright 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 6947917
+ * @summary Error in basic authentication when user name and password are long
+ */
+
+import com.sun.net.httpserver.BasicAuthenticator;
+import com.sun.net.httpserver.HttpContext;
+import com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpPrincipal;
+import com.sun.net.httpserver.HttpServer;
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.Authenticator;
+import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+public class BasicLongCredentials {
+
+ static final String USERNAME = "ThisIsMyReallyReallyReallyReallyReallyReally" +
+ "LongFirstNameDotLastNameAtCompanyEmailAddress";
+ static final String PASSWORD = "AndThisIsALongLongLongLongLongLongLongLongLong" +
+ "LongLongLongLongLongLongLongLongLongPassword";
+ static final String REALM = "foobar@test.realm";
+
+ public static void main (String[] args) throws Exception {
+ HttpServer server = HttpServer.create(new InetSocketAddress(0), 0);
+ try {
+ Handler handler = new Handler();
+ HttpContext ctx = server.createContext("/test", handler);
+
+ BasicAuthenticator a = new BasicAuthenticator(REALM) {
+ public boolean checkCredentials (String username, String pw) {
+ return USERNAME.equals(username) && PASSWORD.equals(pw);
+ }
+ };
+ ctx.setAuthenticator(a);
+ server.start();
+
+ Authenticator.setDefault(new MyAuthenticator());
+
+ URL url = new URL("http://localhost:"+server.getAddress().getPort()+"/test/");
+ HttpURLConnection urlc = (HttpURLConnection)url.openConnection();
+ InputStream is = urlc.getInputStream();
+ int c = 0;
+ while (is.read()!= -1) { c ++; }
+
+ if (c != 0) { throw new RuntimeException("Test failed c = " + c); }
+ if (error) { throw new RuntimeException("Test failed: error"); }
+
+ System.out.println ("OK");
+ } finally {
+ server.stop(0);
+ }
+ }
+
+ public static boolean error = false;
+
+ static class MyAuthenticator extends java.net.Authenticator {
+ @Override
+ public PasswordAuthentication getPasswordAuthentication () {
+ if (!getRequestingPrompt().equals(REALM)) {
+ BasicLongCredentials.error = true;
+ }
+ return new PasswordAuthentication (USERNAME, PASSWORD.toCharArray());
+ }
+ }
+
+ static class Handler implements HttpHandler {
+ public void handle (HttpExchange t) throws IOException {
+ InputStream is = t.getRequestBody();
+ while (is.read () != -1) ;
+ is.close();
+ t.sendResponseHeaders(200, -1);
+ HttpPrincipal p = t.getPrincipal();
+ if (!p.getUsername().equals(USERNAME)) {
+ error = true;
+ }
+ if (!p.getRealm().equals(REALM)) {
+ error = true;
+ }
+ t.close();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/ServiceNameClone.java Tue May 11 16:35:36 2010 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright 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 6856069
+ * @summary PrincipalName.clone() does not invoke super.clone()
+ */
+
+import sun.security.krb5.ServiceName;
+
+public class ServiceNameClone {
+ public static void main(String[] args) throws Exception {
+ ServiceName sn = new ServiceName("me@HERE");
+ if (sn.clone().getClass() != ServiceName.class) {
+ throw new Exception("ServiceName's clone is not a ServiceName");
+ }
+ if (!sn.clone().equals(sn)) {
+ throw new Exception("ServiceName's clone changed");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/krb5/auto/MaxRetries.java Tue May 11 16:35:36 2010 -0700
@@ -0,0 +1,203 @@
+/*
+ * Copyright 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 6844193
+ * @run main/timeout=300 MaxRetries
+ * @summary support max_retries in krb5.conf
+ */
+
+import java.io.*;
+import java.security.Security;
+
+public class MaxRetries {
+ public static void main(String[] args)
+ throws Exception {
+
+ System.setProperty("sun.security.krb5.debug", "true");
+ new OneKDC(null).writeJAASConf();
+ System.setProperty("java.security.krb5.conf", "alternative-krb5.conf");
+
+ // For tryLast
+ Security.setProperty("krb5.kdc.bad.policy", "trylast");
+ rewriteMaxRetries(4);
+ test1(4000, 6); // 1 1 1 1 2 2
+ test1(4000, 2); // 2 2
+
+ rewriteMaxRetries(1);
+ test1(1000, 3); // 1 2 2
+ test1(1000, 2); // 2 2
+
+ rewriteMaxRetries(-1);
+ test1(5000, 4); // 1 1 2 2
+ test1(5000, 2); // 2 2
+
+ // For tryLess
+ Security.setProperty("krb5.kdc.bad.policy", "tryless");
+ rewriteMaxRetries(4);
+ test1(4000, 7); // 1 1 1 1 2 1 2
+ test1(4000, 4); // 1 2 1 2
+
+ rewriteMaxRetries(1);
+ test1(1000, 4); // 1 2 1 2
+ test1(1000, 4); // 1 2 1 2
+
+ rewriteMaxRetries(-1);
+ test1(5000, 5); // 1 1 2 1 2
+ test1(5000, 4); // 1 2 1 2
+
+ rewriteUdpPrefLimit(-1, -1); // default, no limit
+ test2("UDP");
+
+ rewriteUdpPrefLimit(10, -1); // global rules
+ test2("TCP");
+
+ rewriteUdpPrefLimit(10, 10000); // realm rules
+ test2("UDP");
+
+ rewriteUdpPrefLimit(10000, 10); // realm rules
+ test2("TCP");
+ }
+
+ /**
+ * One round of test for max_retries and timeout.
+ * @param timeout the expected timeout
+ * @param count the expected total try
+ */
+ private static void test1(int timeout, int count) throws Exception {
+ String timeoutTag = "timeout=" + timeout;
+ ByteArrayOutputStream bo = new ByteArrayOutputStream();
+ PrintStream oldout = System.out;
+ System.setOut(new PrintStream(bo));
+ Context c = Context.fromJAAS("client");
+ System.setOut(oldout);
+
+ String[] lines = new String(bo.toByteArray()).split("\n");
+ System.out.println("----------------- TEST (" + timeout + "," +
+ count + ") -----------------");
+ for (String line: lines) {
+ if (line.startsWith(">>> KDCCommunication")) {
+ System.out.println(line);
+ if (line.indexOf(timeoutTag) < 0) {
+ throw new Exception("Wrong timeout value");
+ }
+ count--;
+ }
+ }
+ if (count != 0) {
+ throw new Exception("Retry count is " + count + " less");
+ }
+ }
+
+ /**
+ * One round of test for udp_preference_limit.
+ * @param proto the expected protocol used
+ */
+ private static void test2(String proto) throws Exception {
+ ByteArrayOutputStream bo = new ByteArrayOutputStream();
+ PrintStream oldout = System.out;
+ System.setOut(new PrintStream(bo));
+ Context c = Context.fromJAAS("client");
+ System.setOut(oldout);
+
+ int count = 2;
+ String[] lines = new String(bo.toByteArray()).split("\n");
+ System.out.println("----------------- TEST -----------------");
+ for (String line: lines) {
+ if (line.startsWith(">>> KDCCommunication")) {
+ System.out.println(line);
+ count--;
+ if (line.indexOf(proto) < 0) {
+ throw new Exception("Wrong timeout value");
+ }
+ }
+ }
+ if (count != 0) {
+ throw new Exception("Retry count is " + count + " less");
+ }
+ }
+
+ /**
+ * Set udp_preference_limit for global and realm
+ */
+ private static void rewriteUdpPrefLimit(int global, int realm)
+ throws Exception {
+ BufferedReader fr = new BufferedReader(new FileReader(OneKDC.KRB5_CONF));
+ FileWriter fw = new FileWriter("alternative-krb5.conf");
+ while (true) {
+ String s = fr.readLine();
+ if (s == null) {
+ break;
+ }
+ if (s.startsWith("[realms]")) {
+ // Reconfig global setting
+ if (global != -1) {
+ fw.write("udp_preference_limit = " + global + "\n");
+ }
+ } else if (s.trim().startsWith("kdc = ")) {
+ if (realm != -1) {
+ // Reconfig for realm
+ fw.write(" udp_preference_limit = " + realm + "\n");
+ }
+ }
+ fw.write(s + "\n");
+ }
+ fr.close();
+ fw.close();
+ sun.security.krb5.Config.refresh();
+ }
+
+ /**
+ * Set max_retries and timeout value for realm. The global value is always
+ * 2 and 5000.
+ * @param value max_retries and timeout/1000 for a realm, -1 means none.
+ */
+ private static void rewriteMaxRetries(int value) throws Exception {
+ BufferedReader fr = new BufferedReader(new FileReader(OneKDC.KRB5_CONF));
+ FileWriter fw = new FileWriter("alternative-krb5.conf");
+ while (true) {
+ String s = fr.readLine();
+ if (s == null) {
+ break;
+ }
+ if (s.startsWith("[realms]")) {
+ // Reconfig global setting
+ fw.write("max_retries = 2\n");
+ fw.write("kdc_timeout = 5000\n");
+ } else if (s.trim().startsWith("kdc = ")) {
+ if (value != -1) {
+ // Reconfig for realm
+ fw.write(" max_retries = " + value + "\n");
+ fw.write(" kdc_timeout = " + (value*1000) + "\n");
+ }
+ // Add a bad KDC as the first candidate
+ fw.write(" kdc = localhost:33333\n");
+ }
+ fw.write(s + "\n");
+ }
+ fr.close();
+ fw.close();
+ sun.security.krb5.Config.refresh();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/crl.sh Tue May 11 16:35:36 2010 -0700
@@ -0,0 +1,91 @@
+#
+# Copyright 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 6890876
+# @summary jarsigner can add CRL info into signed jar
+#
+
+if [ "${TESTJAVA}" = "" ] ; then
+ JAVAC_CMD=`which javac`
+ TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+# set platform-dependent variables
+# PF: platform name, say, solaris-sparc
+
+PF=""
+
+OS=`uname -s`
+case "$OS" in
+ Windows* )
+ FS="\\"
+ ;;
+ * )
+ FS="/"
+ ;;
+esac
+
+KS=crl.jks
+JFILE=crl.jar
+
+KT="$TESTJAVA${FS}bin${FS}keytool -storepass changeit -keypass changeit -keystore $KS"
+JAR=$TESTJAVA${FS}bin${FS}jar
+JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner
+
+rm $KS $JFILE
+
+# Generates some crl files, each containing two entries
+
+$KT -alias a -dname CN=a -keyalg rsa -genkey -validity 300
+$KT -alias a -gencrl -id 1:1 -id 2:2 -file crl1
+$KT -alias a -gencrl -id 3:3 -id 4:4 -file crl2
+$KT -alias b -dname CN=b -keyalg rsa -genkey -validity 300
+$KT -alias b -gencrl -id 5:1 -id 6:2 -file crl3
+
+$KT -alias c -dname CN=c -keyalg rsa -genkey -validity 300 \
+ -ext crl=uri:file://`pwd`/crl1
+
+echo A > A
+
+# Test -crl:auto, cRLDistributionPoints is a local file
+
+$JAR cvf $JFILE A
+$JARSIGNER -keystore $KS -storepass changeit $JFILE c \
+ -crl:auto || exit 1
+$JARSIGNER -keystore $KS -verify -debug -strict $JFILE || exit 6
+$KT -printcert -jarfile $JFILE | grep CRLs || exit 7
+
+# Test -crl <file>
+
+$JAR cvf $JFILE A
+$JARSIGNER -keystore $KS -storepass changeit $JFILE a \
+ -crl crl1 -crl crl2 || exit 1
+$JARSIGNER -keystore $KS -storepass changeit $JFILE b \
+ -crl crl3 -crl crl2 || exit 1
+$JARSIGNER -keystore $KS -verify -debug -strict $JFILE || exit 3
+$KT -printcert -jarfile $JFILE | grep CRLs || exit 4
+CRLCOUNT=`$KT -printcert -jarfile $JFILE | grep SerialNumber | wc -l`
+if [ $CRLCOUNT != 8 ]; then exit 5; fi
+
+exit 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/diffend.sh Tue May 11 16:35:36 2010 -0700
@@ -0,0 +1,113 @@
+#
+# Copyright 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 6948909
+# @summary Jarsigner removes MANIFEST.MF info for badly packages jar's
+#
+
+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
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ SunOS | Linux )
+ NULL=/dev/null
+ PS=":"
+ FS="/"
+ CP="${FS}bin${FS}cp -f"
+ TMP=/tmp
+ ;;
+ CYGWIN* )
+ NULL=/dev/null
+ PS=";"
+ FS="/"
+ CP="cp -f"
+ TMP=/tmp
+ ;;
+ Windows_* )
+ NULL=NUL
+ PS=";"
+ FS="\\"
+ CP="cp -f"
+ TMP="c:/temp"
+ ;;
+ * )
+ echo "Unrecognized operating system!"
+ exit 1;
+ ;;
+esac
+
+echo 1 > 1
+mkdir META-INF
+
+# Create a fake .RSA file so that jarsigner believes it's signed
+
+touch META-INF/x.RSA
+
+# A MANIFEST.MF using \n as newlines and no double newlines at the end
+
+cat > META-INF/MANIFEST.MF <<EOF
+Manifest-Version: 1.0
+Created-By: 1.7.0-internal (Sun Microsystems Inc.)
+Today: Monday
+EOF
+
+# With the fake .RSA file, to trigger the if (wasSigned) block
+
+rm diffend.jar
+zip diffend.jar META-INF/MANIFEST.MF META-INF/x.RSA 1
+
+${TESTJAVA}${FS}bin${FS}jarsigner \
+ -keystore ${TESTSRC}${FS}JarSigning.keystore \
+ -storepass bbbbbb \
+ -digestalg SHA1 \
+ -signedjar diffend.new.jar \
+ diffend.jar c
+
+unzip -p diffend.new.jar META-INF/MANIFEST.MF | grep Today || exit 1
+
+# Without the fake .RSA file, to trigger the else block
+
+rm diffend.jar
+zip diffend.jar META-INF/MANIFEST.MF 1
+
+${TESTJAVA}${FS}bin${FS}jarsigner \
+ -keystore ${TESTSRC}${FS}JarSigning.keystore \
+ -storepass bbbbbb \
+ -digestalg SHA1 \
+ -signedjar diffend.new.jar \
+ diffend.jar c
+
+unzip -p diffend.new.jar META-INF/MANIFEST.MF | grep Today || exit 2
+