Merge
authorsrl
Tue Sep 29 15:31:18 2009 -0700 (5 months ago)
changeset 1694e8a764450aa7
parent 1693c74d38ef118c
parent 1692e6ced7714609
child 1695e8b1b4c00e8a
Merge
src/share/classes/sun/net/www/protocol/http/InMemoryCookieStore.java
src/share/native/sun/security/ec/ec.c
--- a/.hgtags Tue Sep 29 14:06:13 2009 -0700
+++ b/.hgtags Tue Sep 29 15:31:18 2009 -0700
@@ -46,3 +46,4 @@ 226b20019b1f020c09ea97d137d98e011ce65d76
226b20019b1f020c09ea97d137d98e011ce65d76 jdk7-b69
893bcca951b747ddcf6986362b877f0e1dbb835b jdk7-b70
b3f3240135f0c10b9f2481c174b81b7fcf0daa60 jdk7-b71
+460639b036f327282832a4fe52b7aa45688afd50 jdk7-b72
--- a/make/java/java/FILES_java.gmk Tue Sep 29 14:06:13 2009 -0700
+++ b/make/java/java/FILES_java.gmk Tue Sep 29 15:31:18 2009 -0700
@@ -454,6 +454,8 @@ JAVA_JAVA_java = \
sun/misc/JavaLangAccess.java \
sun/misc/JavaIOAccess.java \
sun/misc/JavaIOFileDescriptorAccess.java \
- sun/misc/JavaNioAccess.java
+ sun/misc/JavaNioAccess.java \
+ sun/misc/Perf.java \
+ sun/misc/PerfCounter.java
FILES_java = $(JAVA_JAVA_java)
--- a/make/java/logging/Makefile Tue Sep 29 14:06:13 2009 -0700
+++ b/make/java/logging/Makefile Tue Sep 29 15:31:18 2009 -0700
@@ -31,7 +31,7 @@ include $(BUILDDIR)/common/Defs.gmk
#
# Files to compile.
#
-AUTO_FILES_JAVA_DIRS = java/util/logging
+AUTO_FILES_JAVA_DIRS = java/util/logging sun/util/logging
#
# Resources
@@ -46,7 +46,6 @@ include $(BUILDDIR)/common/Classes.gmk
include $(BUILDDIR)/common/Classes.gmk
properties: $(LIBDIR)/logging.properties
-
$(LIBDIR)/logging.properties: $(SHARE_SRC)/lib/logging.properties
$(install-file)
--- a/make/sun/net/FILES_java.gmk Tue Sep 29 14:06:13 2009 -0700
+++ b/make/sun/net/FILES_java.gmk Tue Sep 29 15:31:18 2009 -0700
@@ -86,9 +86,11 @@ FILES_java = \
sun/net/www/protocol/http/AuthCache.java \
sun/net/www/protocol/http/AuthCacheImpl.java \
sun/net/www/protocol/http/AuthCacheValue.java \
+ sun/net/www/protocol/http/AuthScheme.java \
sun/net/www/protocol/http/BasicAuthentication.java \
sun/net/www/protocol/http/DigestAuthentication.java \
sun/net/www/protocol/http/NTLMAuthentication.java \
+ sun/net/www/protocol/http/NTLMAuthenticationProxy.java \
sun/net/www/protocol/http/NegotiateAuthentication.java \
sun/net/www/protocol/http/NegotiatorImpl.java \
sun/net/www/protocol/http/NegotiateCallbackHandler.java \
@@ -123,8 +125,7 @@ FILES_java = \
sun/net/idn/UCharacterEnums.java \
sun/net/idn/UCharacterDirection.java \
sun/net/idn/StringPrepDataReader.java \
- sun/net/idn/StringPrep.java \
- sun/net/www/protocol/http/InMemoryCookieStore.java
+ sun/net/idn/StringPrep.java
ifeq ($(PLATFORM), windows)
FILES_java += sun/net/www/protocol/http/NTLMAuthSequence.java
--- a/make/sun/security/Makefile Tue Sep 29 14:06:13 2009 -0700
+++ b/make/sun/security/Makefile Tue Sep 29 15:31:18 2009 -0700
@@ -60,8 +60,15 @@ ifeq ($(PLATFORM), windows)
endif
endif
-SUBDIRS = ec other action util tools jgss krb5 smartcardio $(PKCS11) \
- $(JGSS_WRAPPER) $(MSCAPI)
+# Build in-tree elliptic curve crypto provider only when
+# DISABLE_INTREE_EC is not set
+INTREE_EC = ec
+ifdef DISABLE_INTREE_EC
+ INTREE_EC =
+endif
+
+SUBDIRS = $(INTREE_EC) other action util tools jgss krb5 smartcardio \
+ $(PKCS11) $(JGSS_WRAPPER) $(MSCAPI)
all build clean clobber::
$(SUBDIRS-loop)
--- a/make/sun/security/ec/Makefile Tue Sep 29 14:06:13 2009 -0700
+++ b/make/sun/security/ec/Makefile Tue Sep 29 15:31:18 2009 -0700
@@ -24,7 +24,7 @@
#
#
-# Makefile for building sunec.jar and sunecc native library.
+# Makefile for building sunec.jar and sunec native library.
#
# This file was derived from make/com/sun/crypto/provider/Makefile.
#
@@ -121,7 +121,15 @@ CLASSDESTDIR = $(TEMPDIR)/classes
#
AUTO_FILES_JAVA_DIRS = $(PKGDIR)
-include $(BUILDDIR)/common/Classes.gmk
+#
+# Exclude the sources that get built by ../other/Makefile
+#
+AUTO_JAVA_PRUNE = \
+ ECKeyFactory.java \
+ ECParameters.java \
+ ECPrivateKeyImpl.java \
+ ECPublicKeyImpl.java \
+ NamedCurve.java
#
# Some licensees do not get the native ECC sources, but we still need to
@@ -130,7 +138,7 @@ include $(BUILDDIR)/common/Classes.gmk
#
NATIVE_ECC_AVAILABLE := $(shell \
- if [ -d $(SHARE_SRC)/native/$(PKGDIR) ] ; then \
+ if [ -d $(SHARE_SRC)/native/$(PKGDIR)/impl ] ; then \
$(ECHO) true; \
else \
$(ECHO) false; \
@@ -138,7 +146,7 @@ NATIVE_ECC_AVAILABLE := $(shell \
ifeq ($(NATIVE_ECC_AVAILABLE), true)
- LIBRARY = sunecc
+ LIBRARY = sunec
#
# Java files that define native methods
@@ -166,12 +174,12 @@ ifeq ($(NATIVE_ECC_AVAILABLE), true)
#
vpath %.cpp $(SHARE_SRC)/native/$(PKGDIR)
- vpath %.c $(SHARE_SRC)/native/$(PKGDIR)
+ vpath %.c $(SHARE_SRC)/native/$(PKGDIR)/impl
#
# Find include files
#
- OTHER_INCLUDES += -I$(SHARE_SRC)/native/$(PKGDIR)
+ OTHER_INCLUDES += -I$(SHARE_SRC)/native/$(PKGDIR)/impl
#
# Compiler flags
@@ -191,6 +199,10 @@ ifeq ($(NATIVE_ECC_AVAILABLE), true)
include $(BUILDDIR)/common/Library.gmk
+else # NATIVE_ECC_AVAILABLE
+
+ include $(BUILDDIR)/common/Classes.gmk
+
endif # NATIVE_ECC_AVAILABLE
#
--- a/make/sun/security/other/Makefile Tue Sep 29 14:06:13 2009 -0700
+++ b/make/sun/security/other/Makefile Tue Sep 29 15:31:18 2009 -0700
@@ -45,6 +45,16 @@ AUTO_FILES_JAVA_DIRS = \
com/sun/net/ssl/internal/ssl
#
+# EC classes used by the packages above
+#
+FILES_java += \
+ sun/security/ec/ECKeyFactory.java \
+ sun/security/ec/ECParameters.java \
+ sun/security/ec/ECPrivateKeyImpl.java \
+ sun/security/ec/ECPublicKeyImpl.java \
+ sun/security/ec/NamedCurve.java
+
+#
# Rules
#
include $(BUILDDIR)/common/Classes.gmk
--- a/src/share/bin/java.h Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/bin/java.h Tue Sep 29 15:31:18 2009 -0700
@@ -187,9 +187,6 @@ void InitLauncher(jboolean javaw);
*
*/
typedef jclass (JNICALL FindClassFromBootLoader_t(JNIEnv *env,
- const char *name,
- jboolean init,
- jobject loader,
- jboolean throwError));
+ const char *name));
jclass FindBootStrapClass(JNIEnv *env, const char *classname);
#endif /* _JAVA_H_ */
--- a/src/share/bin/parse_manifest.c Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/bin/parse_manifest.c Tue Sep 29 15:31:18 2009 -0700
@@ -59,7 +59,7 @@ inflate_file(int fd, zentry *entry, int
char *out;
z_stream zs;
- if (entry->csize == 0xffffffff || entry->isize == 0xffffffff)
+ if (entry->csize == (size_t) -1 || entry->isize == (size_t) -1 )
return (NULL);
if (lseek(fd, entry->offset, SEEK_SET) < (off_t)0)
return (NULL);
--- a/src/share/classes/com/sun/rowset/JdbcRowSetResourceBundle.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/com/sun/rowset/JdbcRowSetResourceBundle.java Tue Sep 29 15:31:18 2009 -0700
@@ -133,7 +133,7 @@ public class JdbcRowSetResourceBundle im
* This method returns an enumerated handle of the keys
* which correspond to values translated to various locales.
*
- * @returns an enumerated keys which have messages tranlated to
+ * @return an enumeration of keys which have messages tranlated to
* corresponding locales.
*/
public Enumeration getKeys() {
@@ -146,7 +146,7 @@ public class JdbcRowSetResourceBundle im
* returns the corresponding value reading it
* from the Resource Bundle loaded earlier.
*
- * @returns value in locale specific language
+ * @return value in locale specific language
* according to the key passed.
*/
public Object handleGetObject(String key) {
--- a/src/share/classes/com/sun/rowset/JoinRowSetImpl.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/com/sun/rowset/JoinRowSetImpl.java Tue Sep 29 15:31:18 2009 -0700
@@ -3737,7 +3737,6 @@ public class JoinRowSetImpl extends WebR
* Returns a result set containing the original value of the current
* row only.
*
- * @return the original result set of the row
* @throws SQLException if there is no current row
* @see #setOriginalRow
*/
--- a/src/share/classes/com/sun/rowset/internal/WebRowSetXmlReader.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/com/sun/rowset/internal/WebRowSetXmlReader.java Tue Sep 29 15:31:18 2009 -0700
@@ -45,6 +45,17 @@ import javax.sql.rowset.spi.*;
* as its parser.
*/
public class WebRowSetXmlReader implements XmlReader, Serializable {
+
+
+ private JdbcRowSetResourceBundle resBundle;
+
+ public WebRowSetXmlReader(){
+ try {
+ resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
+ } catch(IOException ioe) {
+ throw new RuntimeException(ioe);
+ }
+ }
/**
* Parses the given <code>WebRowSet</code> object, getting its input from
@@ -69,17 +80,6 @@ public class WebRowSetXmlReader implemen
* reader for the given rowset
* @see XmlReaderContentHandler
*/
-
- private JdbcRowSetResourceBundle resBundle;
-
- public WebRowSetXmlReader(){
- try {
- resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
- } catch(IOException ioe) {
- throw new RuntimeException(ioe);
- }
- }
-
public void readXML(WebRowSet caller, java.io.Reader reader) throws SQLException {
try {
// Crimson Parser(as in J2SE 1.4.1 is NOT able to handle
--- a/src/share/classes/java/lang/Class.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/lang/Class.java Tue Sep 29 15:31:18 2009 -0700
@@ -565,8 +565,9 @@ public final
* represented by this object.
*/
public String getName() {
+ String name = this.name;
if (name == null)
- name = getName0();
+ this.name = name = getName0();
return name;
}
--- a/src/share/classes/java/lang/ClassLoader.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/lang/ClassLoader.java Tue Sep 29 15:31:18 2009 -0700
@@ -380,16 +380,28 @@ public abstract class ClassLoader {
// First, check if the class has already been loaded
Class c = findLoadedClass(name);
if (c == null) {
+ long t0 = System.nanoTime();
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
- c = findBootstrapClass0(name);
+ c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
+ // ClassNotFoundException thrown if class not found
+ // from the non-null parent class loader
+ }
+
+ if (c == null) {
// If still not found, then invoke findClass in order
// to find the class.
+ long t1 = System.nanoTime();
c = findClass(name);
+
+ // this is the defining class loader; record the stats
+ sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
+ sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
+ sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
@@ -1008,22 +1020,29 @@ public abstract class ClassLoader {
if (system == null) {
if (!checkName(name))
throw new ClassNotFoundException(name);
- return findBootstrapClass(name);
+ Class cls = findBootstrapClass(name);
+ if (cls == null) {
+ throw new ClassNotFoundException(name);
+ }
+ return cls;
}
return system.loadClass(name);
}
- private Class findBootstrapClass0(String name)
- throws ClassNotFoundException
+ /**
+ * Returns a class loaded by the bootstrap class loader;
+ * or return null if not found.
+ */
+ private Class findBootstrapClassOrNull(String name)
{
check();
- if (!checkName(name))
- throw new ClassNotFoundException(name);
+ if (!checkName(name)) return null;
+
return findBootstrapClass(name);
}
- private native Class findBootstrapClass(String name)
- throws ClassNotFoundException;
+ // return null if not found
+ private native Class findBootstrapClass(String name);
// Check to make sure the class loader has been initialized.
private void check() {
--- a/src/share/classes/java/net/CookieManager.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/net/CookieManager.java Tue Sep 29 15:31:18 2009 -0700
@@ -157,7 +157,7 @@ public class CookieManager extends Cooki
// if not specify CookieStore to use, use default one
if (store == null) {
- cookieJar = new sun.net.www.protocol.http.InMemoryCookieStore();
+ cookieJar = new InMemoryCookieStore();
} else {
cookieJar = store;
}
--- a/src/share/classes/java/net/URLClassLoader.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/net/URLClassLoader.java Tue Sep 29 15:31:18 2009 -0700
@@ -340,6 +340,7 @@ public class URLClassLoader extends Secu
* used.
*/
private Class defineClass(String name, Resource res) throws IOException {
+ long t0 = System.nanoTime();
int i = name.lastIndexOf('.');
URL url = res.getCodeSourceURL();
if (i != -1) {
@@ -370,12 +371,14 @@ public class URLClassLoader extends Secu
// Use (direct) ByteBuffer:
CodeSigner[] signers = res.getCodeSigners();
CodeSource cs = new CodeSource(url, signers);
+ sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
return defineClass(name, bb, cs);
} else {
byte[] b = res.getBytes();
// must read certificates AFTER reading bytes.
CodeSigner[] signers = res.getCodeSigners();
CodeSource cs = new CodeSource(url, signers);
+ sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
return defineClass(name, b, 0, b.length, cs);
}
}
--- a/src/share/classes/java/net/doc-files/net-properties.html Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/net/doc-files/net-properties.html Tue Sep 29 15:31:18 2009 -0700
@@ -71,12 +71,12 @@ of proxies.</P>
<LI><P>HTTP</P>
<P>The following proxy settings are used by the HTTP protocol handler.</P>
<UL>
- <LI><P><B>http.proxyHost</FONT></B> (default: &lt;none&gt;)<BR>
+ <LI><P><B>http.proxyHost</B> (default: &lt;none&gt;)<BR>
The hostname, or address, of the proxy server
</P>
<LI><P><B>http.proxyPort</B> (default: 80)<BR>
The port number of the proxy server.</P>
- <LI><P><B>http.nonProxyHosts</B> (default: &lt;none&gt;)<BR>
+ <LI><P><B>http.nonProxyHosts</B> (default: localhost|127.*|[::1])<BR>
Indicates the hosts that should be accessed without going
through the proxy. Typically this defines internal hosts.
The value of this property is a list of hosts,
@@ -86,7 +86,8 @@ of proxies.</P>
will indicate that every hosts in the foo.com domain and the
localhost should be accessed directly even if a proxy server is
specified.</P>
- </UL>
+ <P>The default value excludes all common variations of the loopback address.</P>
+ </UL>
<LI><P>HTTPS<BR>This is HTTP over SSL, a secure version of HTTP
mainly used when confidentiality (like on payment sites) is needed.</P>
<P>The following proxy settings are used by the HTTPS protocol handler.</P>
@@ -107,7 +108,7 @@ of proxies.</P>
</P>
<LI><P><B>ftp.proxyPort</B> (default: 80)<BR>
The port number of the proxy server.</P>
- <LI><P><B>ftp.nonProxyHosts</B> (default: &lt;none&gt;)<BR>
+ <LI><P><B>ftp.nonProxyHosts</B> (default: localhost|127.*|[::1])<BR>
Indicates the hosts that should be accessed without going
through the proxy. Typically this defines internal hosts.
The value of this property is a list of hosts, separated by
@@ -117,6 +118,7 @@ of proxies.</P>
will indicate that every hosts in the foo.com domain and the
localhost should be accessed directly even if a proxy server is
specified.</P>
+ <P>The default value excludes all common variations of the loopback address.</P>
</UL>
<LI><P>SOCKS<BR>This is another type of proxy. It allows for lower
level type of tunneling since it works at the TCP level. In effect,
--- a/src/share/classes/java/nio/file/FileTreeWalker.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/nio/file/FileTreeWalker.java Tue Sep 29 15:31:18 2009 -0700
@@ -41,8 +41,12 @@ class FileTreeWalker {
private final boolean detectCycles;
private final LinkOption[] linkOptions;
private final FileVisitor<? super Path> visitor;
-
- FileTreeWalker(Set<FileVisitOption> options, FileVisitor<? super Path> visitor) {
+ private final int maxDepth;
+
+ FileTreeWalker(Set<FileVisitOption> options,
+ FileVisitor<? super Path> visitor,
+ int maxDepth)
+ {
boolean fl = false;
boolean dc = false;
for (FileVisitOption option: options) {
@@ -58,18 +62,15 @@ class FileTreeWalker {
this.linkOptions = (fl) ? new LinkOption[0] :
new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
this.visitor = visitor;
+ this.maxDepth = maxDepth;
}
/**
* Walk file tree starting at the given file
*/
- void walk(Path start, int maxDepth) {
- // don't use attributes of starting file as they may be stale
- if (start instanceof BasicFileAttributesHolder) {
- ((BasicFileAttributesHolder)start).invalidate();
- }
+ void walk(Path start) {
FileVisitResult result = walk(start,
- maxDepth,
+ 0,
new ArrayList<AncestorDirectory>());
if (result == null) {
throw new NullPointerException("Visitor returned 'null'");
@@ -89,12 +90,15 @@ class FileTreeWalker {
List<AncestorDirectory> ancestors)
{
// depth check
- if (depth-- < 0)
+ if (depth > maxDepth)
return FileVisitResult.CONTINUE;
// if attributes are cached then use them if possible
BasicFileAttributes attrs = null;
- if (file instanceof BasicFileAttributesHolder) {
+ if ((depth > 0) &&
+ (file instanceof BasicFileAttributesHolder) &&
+ (System.getSecurityManager() == null))
+ {
BasicFileAttributes cached = ((BasicFileAttributesHolder)file).get();
if (!followLinks || !cached.isSymbolicLink())
attrs = cached;
@@ -120,6 +124,10 @@ class FileTreeWalker {
}
}
} catch (SecurityException x) {
+ // If access to starting file is denied then SecurityException
+ // is thrown, otherwise the file is ignored.
+ if (depth == 0)
+ throw x;
return FileVisitResult.CONTINUE;
}
}
@@ -196,7 +204,7 @@ class FileTreeWalker {
try {
for (Path entry: stream) {
inAction = true;
- result = walk(entry, depth, ancestors);
+ result = walk(entry, depth+1, ancestors);
inAction = false;
// returning null will cause NPE to be thrown
--- a/src/share/classes/java/nio/file/Files.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/nio/file/Files.java Tue Sep 29 15:31:18 2009 -0700
@@ -223,7 +223,7 @@ public final class Files {
{
if (maxDepth < 0)
throw new IllegalArgumentException("'maxDepth' is negative");
- new FileTreeWalker(options, visitor).walk(start, maxDepth);
+ new FileTreeWalker(options, visitor, maxDepth).walk(start);
}
/**
--- a/src/share/classes/java/util/Currency.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/Currency.java Tue Sep 29 15:31:18 2009 -0700
@@ -35,12 +35,12 @@ import java.security.AccessController;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.logging.Level;
-import java.util.logging.Logger;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.spi.CurrencyNameProvider;
import java.util.spi.LocaleServiceProvider;
import sun.util.LocaleServiceProviderPool;
+import sun.util.logging.PlatformLogger;
import sun.util.resources.LocaleData;
import sun.util.resources.OpenListResourceBundle;
@@ -244,7 +244,7 @@ public final class Currency implements S
}
}
} catch (IOException e) {
- log(Level.INFO, "currency.properties is ignored because of an IOException", e);
+ info("currency.properties is ignored because of an IOException", e);
}
return null;
}
@@ -686,7 +686,7 @@ public final class Currency implements S
.append("The entry in currency.properties for ")
.append(ctry).append(" is ignored because of the invalid country code.")
.toString();
- log(Level.INFO, message, null);
+ info(message, null);
return;
}
@@ -698,7 +698,7 @@ public final class Currency implements S
.append(ctry)
.append(" is ignored because the value format is not recognized.")
.toString();
- log(Level.INFO, message, null);
+ info(message, null);
return;
}
@@ -726,13 +726,13 @@ public final class Currency implements S
setMainTableEntry(ctry.charAt(0), ctry.charAt(1), entry);
}
- private static void log(Level level, String message, Throwable t) {
- Logger logger = Logger.getLogger("java.util.Currency");
- if (logger.isLoggable(level)) {
+ private static void info(String message, Throwable t) {
+ PlatformLogger logger = PlatformLogger.getLogger("java.util.Currency");
+ if (logger.isLoggable(PlatformLogger.INFO)) {
if (t != null) {
- logger.log(level, message, t);
+ logger.info(message, t);
} else {
- logger.log(level, message);
+ logger.info(message);
}
}
}
--- a/src/share/classes/java/util/jar/Attributes.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/jar/Attributes.java Tue Sep 29 15:31:18 2009 -0700
@@ -34,7 +34,7 @@ import java.util.Collection;
import java.util.Collection;
import java.util.AbstractSet;
import java.util.Iterator;
-import java.util.logging.Logger;
+import sun.util.logging.PlatformLogger;
import java.util.Comparator;
import sun.misc.ASCIICaseInsensitiveComparator;
@@ -419,7 +419,7 @@ public class Attributes implements Map<O
}
try {
if ((putValue(name, value) != null) && (!lineContinued)) {
- Logger.getLogger("java.util.jar").warning(
+ PlatformLogger.getLogger("java.util.jar").warning(
"Duplicate name in Manifest: " + name
+ ".\n"
+ "Ensure that the manifest does not "
--- a/src/share/classes/java/util/logging/ErrorManager.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/logging/ErrorManager.java Tue Sep 29 15:31:18 2009 -0700
@@ -28,7 +28,7 @@ package java.util.logging;
/**
* ErrorManager objects can be attached to Handlers to process
- * any error that occur on a Handler during Logging.
+ * any error that occurs on a Handler during Logging.
* <p>
* When processing logging output, if a Handler encounters problems
* then rather than throwing an Exception back to the issuer of
@@ -72,7 +72,7 @@ public class ErrorManager {
/**
* The error method is called when a Handler failure occurs.
* <p>
- * This method may be overriden in subclasses. The default
+ * This method may be overridden in subclasses. The default
* behavior in this base class is that the first call is
* reported to System.err, and subsequent calls are ignored.
*
--- a/src/share/classes/java/util/logging/FileHandler.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/logging/FileHandler.java Tue Sep 29 15:31:18 2009 -0700
@@ -39,7 +39,7 @@ import java.security.*;
* For a rotating set of files, as each file reaches a given size
* limit, it is closed, rotated out, and a new file opened.
* Successively older files are named by adding "0", "1", "2",
- * etc into the base filename.
+ * etc. into the base filename.
* <p>
* By default buffering is enabled in the IO libraries but each log
* record is flushed out when it is complete.
@@ -391,7 +391,7 @@ public class FileHandler extends StreamH
// Generate a lock file name from the "unique" int.
lockFileName = generate(pattern, 0, unique).toString() + ".lck";
// Now try to lock that filename.
- // Because some systems (e.g. Solaris) can only do file locks
+ // Because some systems (e.g., Solaris) can only do file locks
// between processes (and not within a process), we first check
// if we ourself already have the file locked.
synchronized(locks) {
--- a/src/share/classes/java/util/logging/Formatter.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/logging/Formatter.java Tue Sep 29 15:31:18 2009 -0700
@@ -52,7 +52,7 @@ public abstract class Formatter {
* Format the given log record and return the formatted string.
* <p>
* The resulting formatted String will normally include a
- * localized and formated version of the LogRecord's message field.
+ * localized and formatted version of the LogRecord's message field.
* It is recommended to use the {@link Formatter#formatMessage}
* convenience method to localize and format the message field.
*
@@ -66,7 +66,7 @@ public abstract class Formatter {
* Return the header string for a set of formatted records.
* <p>
* This base class returns an empty string, but this may be
- * overriden by subclasses.
+ * overridden by subclasses.
*
* @param h The target handler (can be null)
* @return header string
@@ -79,7 +79,7 @@ public abstract class Formatter {
* Return the tail string for a set of formatted records.
* <p>
* This base class returns an empty string, but this may be
- * overriden by subclasses.
+ * overridden by subclasses.
*
* @param h The target handler (can be null)
* @return tail string
--- a/src/share/classes/java/util/logging/Handler.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/logging/Handler.java Tue Sep 29 15:31:18 2009 -0700
@@ -274,7 +274,7 @@ public abstract class Handler {
* <tt>Level</tt> and whether it satisfies any <tt>Filter</tt>. It also
* may make other <tt>Handler</tt> specific checks that might prevent a
* handler from logging the <tt>LogRecord</tt>. It will return false if
- * the <tt>LogRecord</tt> is Null.
+ * the <tt>LogRecord</tt> is null.
* <p>
* @param record a <tt>LogRecord</tt>
* @return true if the <tt>LogRecord</tt> would be logged.
--- a/src/share/classes/java/util/logging/Level.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/logging/Level.java Tue Sep 29 15:31:18 2009 -0700
@@ -110,7 +110,7 @@ public class Level implements java.io.Se
* Typically INFO messages will be written to the console
* or its equivalent. So the INFO level should only be
* used for reasonably significant messages that will
- * make sense to end users and system admins.
+ * make sense to end users and system administrators.
* This level is initialized to <CODE>800</CODE>.
*/
public static final Level INFO = new Level("INFO", 800, defaultBundle);
@@ -245,6 +245,8 @@ public class Level implements java.io.Se
}
/**
+ * Returns a string representation of this Level.
+ *
* @return the non-localized name of the Level, for example "INFO".
*/
public final String toString() {
@@ -299,14 +301,14 @@ public class Level implements java.io.Se
* @throws IllegalArgumentException if the value is not valid.
* Valid values are integers between <CODE>Integer.MIN_VALUE</CODE>
* and <CODE>Integer.MAX_VALUE</CODE>, and all known level names.
- * Known names are the levels defined by this class (i.e. <CODE>FINE</CODE>,
+ * Known names are the levels defined by this class (e.g., <CODE>FINE</CODE>,
* <CODE>FINER</CODE>, <CODE>FINEST</CODE>), or created by this class with
* appropriate package access, or new levels defined or created
* by subclasses.
*
* @return The parsed value. Passing an integer that corresponds to a known name
- * (eg 700) will return the associated name (eg <CODE>CONFIG</CODE>).
- * Passing an integer that does not (eg 1) will return a new level name
+ * (e.g., 700) will return the associated name (e.g., <CODE>CONFIG</CODE>).
+ * Passing an integer that does not (e.g., 1) will return a new level name
* initialized to that value.
*/
public static synchronized Level parse(String name) throws IllegalArgumentException {
--- a/src/share/classes/java/util/logging/LogManager.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/logging/LogManager.java Tue Sep 29 15:31:18 2009 -0700
@@ -283,6 +283,10 @@ public class LogManager {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
readConfiguration();
+
+ // Platform loggers begin to delegate to java.util.logging.Logger
+ sun.util.logging.PlatformLogger.redirectPlatformLoggers();
+
return null;
}
});
--- a/src/share/classes/java/util/logging/LogRecord.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/logging/LogRecord.java Tue Sep 29 15:31:18 2009 -0700
@@ -188,7 +188,7 @@ public class LogRecord implements java.i
}
/**
- * Get the source Logger name's
+ * Get the source Logger's name.
*
* @return source logger name (may be null)
*/
@@ -197,7 +197,7 @@ public class LogRecord implements java.i
}
/**
- * Set the source Logger name.
+ * Set the source Logger's name.
*
* @param name the source logger name (may be null)
*/
@@ -530,6 +530,7 @@ public class LogRecord implements java.i
int depth = access.getStackTraceDepth(throwable);
String logClassName = "java.util.logging.Logger";
+ String plogClassName = "sun.util.logging.PlatformLogger";
boolean lookingForLogger = true;
for (int ix = 0; ix < depth; ix++) {
// Calling getStackTraceElement directly prevents the VM
@@ -539,15 +540,18 @@ public class LogRecord implements java.i
String cname = frame.getClassName();
if (lookingForLogger) {
// Skip all frames until we have found the first logger frame.
- if (cname.equals(logClassName)) {
+ if (cname.equals(logClassName) || cname.startsWith(plogClassName)) {
lookingForLogger = false;
}
} else {
- if (!cname.equals(logClassName)) {
- // We've found the relevant frame.
- setSourceClassName(cname);
- setSourceMethodName(frame.getMethodName());
- return;
+ if (!cname.equals(logClassName) && !cname.startsWith(plogClassName)) {
+ // skip reflection call
+ if (!cname.startsWith("java.lang.reflect.") && !cname.startsWith("sun.reflect.")) {
+ // We've found the relevant frame.
+ setSourceClassName(cname);
+ setSourceMethodName(frame.getMethodName());
+ return;
+ }
}
}
}
--- a/src/share/classes/java/util/logging/Logger.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/logging/Logger.java Tue Sep 29 15:31:18 2009 -0700
@@ -66,7 +66,7 @@ import java.lang.ref.WeakReference;
* effective level from its parent.
* <p>
* On each logging call the Logger initially performs a cheap
- * check of the request level (e.g. SEVERE or FINE) against the
+ * check of the request level (e.g., SEVERE or FINE) against the
* effective log level of the logger. If the request level is
* lower than the log level, the logging call returns immediately.
* <p>
@@ -230,7 +230,7 @@ public class Logger {
* Protected method to construct a logger for a named subsystem.
* <p>
* The logger will be initially configured with a null Level
- * and with useParentHandlers true.
+ * and with useParentHandlers set to true.
*
* @param name A name for the logger. This should
* be a dot-separated name and should normally
@@ -240,7 +240,7 @@ public class Logger {
* @param resourceBundleName name of ResourceBundle to be used for localizing
* messages for this logger. May be null if none
* of the messages require localization.
- * @throws MissingResourceException if the ResourceBundleName is non-null and
+ * @throws MissingResourceException if the resourceBundleName is non-null and
* no corresponding resource can be found.
*/
protected Logger(String name, String resourceBundleName) {
@@ -285,7 +285,7 @@ public class Logger {
* <p>
* If a new logger is created its log level will be configured
* based on the LogManager configuration and it will configured
- * to also send logging output to its parent's handlers. It will
+ * to also send logging output to its parent's Handlers. It will
* be registered in the LogManager global namespace.
*
* @param name A name for the logger. This should
@@ -308,7 +308,7 @@ public class Logger {
* <p>
* If a new logger is created its log level will be configured
* based on the LogManager and it will configured to also send logging
- * output to its parent loggers Handlers. It will be registered in
+ * output to its parent's Handlers. It will be registered in
* the LogManager global namespace.
* <p>
* If the named Logger already exists and does not yet have a
@@ -326,7 +326,8 @@ public class Logger {
* messages for this logger. May be <CODE>null</CODE> if none of
* the messages require localization.
* @return a suitable Logger
- * @throws MissingResourceException if the named ResourceBundle cannot be found.
+ * @throws MissingResourceException if the resourceBundleName is non-null and
+ * no corresponding resource can be found.
* @throws IllegalArgumentException if the Logger already exists and uses
* a different resource bundle name.
* @throws NullPointerException if the name is null.
@@ -395,7 +396,8 @@ public class Logger {
* messages for this logger.
* May be null if none of the messages require localization.
* @return a newly created private Logger
- * @throws MissingResourceException if the named ResourceBundle cannot be found.
+ * @throws MissingResourceException if the resourceBundleName is non-null and
+ * no corresponding resource can be found.
*/
public static synchronized Logger getAnonymousLogger(String resourceBundleName) {
LogManager manager = LogManager.getLogManager();
@@ -514,7 +516,7 @@ public class Logger {
* level then the given message is forwarded to all the
* registered output Handler objects.
* <p>
- * @param level One of the message level identifiers, e.g. SEVERE
+ * @param level One of the message level identifiers, e.g., SEVERE
* @param msg The string message (or a key in the message catalog)
*/
public void log(Level level, String msg) {
@@ -532,7 +534,7 @@ public class Logger {
* level then a corresponding LogRecord is created and forwarded
* to all the registered output Handler objects.
* <p>
- * @param level One of the message level identifiers, e.g. SEVERE
+ * @param level One of the message level identifiers, e.g., SEVERE
* @param msg The string message (or a key in the message catalog)
* @param param1 parameter to the message
*/
@@ -553,7 +555,7 @@ public class Logger {
* level then a corresponding LogRecord is created and forwarded
* to all the registered output Handler objects.
* <p>
- * @param level One of the message level identifiers, e.g. SEVERE
+ * @param level One of the message level identifiers, e.g., SEVERE
* @param msg The string message (or a key in the message catalog)
* @param params array of parameters to the message
*/
@@ -578,7 +580,7 @@ public class Logger {
* processed specially by output Formatters and is not treated
* as a formatting parameter to the LogRecord message property.
* <p>
- * @param level One of the message level identifiers, e.g. SEVERE
+ * @param level One of the message level identifiers, e.g., SEVERE
* @param msg The string message (or a key in the message catalog)
* @param thrown Throwable associated with log message.
*/
@@ -603,7 +605,7 @@ public class Logger {
* level then the given message is forwarded to all the
* registered output Handler objects.
* <p>
- * @param level One of the message level identifiers, e.g. SEVERE
+ * @param level One of the message level identifiers, e.g., SEVERE
* @param sourceClass name of class that issued the logging request
* @param sourceMethod name of method that issued the logging request
* @param msg The string message (or a key in the message catalog)
@@ -626,7 +628,7 @@ public class Logger {
* level then a corresponding LogRecord is created and forwarded
* to all the registered output Handler objects.
* <p>
- * @param level One of the message level identifiers, e.g. SEVERE
+ * @param level One of the message level identifiers, e.g., SEVERE
* @param sourceClass name of class that issued the logging request
* @param sourceMethod name of method that issued the logging request
* @param msg The string message (or a key in the message catalog)
@@ -653,7 +655,7 @@ public class Logger {
* level then a corresponding LogRecord is created and forwarded
* to all the registered output Handler objects.
* <p>
- * @param level One of the message level identifiers, e.g. SEVERE
+ * @param level One of the message level identifiers, e.g., SEVERE
* @param sourceClass name of class that issued the logging request
* @param sourceMethod name of method that issued the logging request
* @param msg The string message (or a key in the message catalog)
@@ -684,7 +686,7 @@ public class Logger {
* processed specially by output Formatters and is not treated
* as a formatting parameter to the LogRecord message property.
* <p>
- * @param level One of the message level identifiers, e.g. SEVERE
+ * @param level One of the message level identifiers, e.g., SEVERE
* @param sourceClass name of class that issued the logging request
* @param sourceMethod name of method that issued the logging request
* @param msg The string message (or a key in the message catalog)
@@ -731,7 +733,7 @@ public class Logger {
* resource bundle name is null, or an empty String or invalid
* then the msg string is not localized.
* <p>
- * @param level One of the message level identifiers, e.g. SEVERE
+ * @param level One of the message level identifiers, e.g., SEVERE
* @param sourceClass name of class that issued the logging request
* @param sourceMethod name of method that issued the logging request
* @param bundleName name of resource bundle to localize msg,
@@ -762,7 +764,7 @@ public class Logger {
* resource bundle name is null, or an empty String or invalid
* then the msg string is not localized.
* <p>
- * @param level One of the message level identifiers, e.g. SEVERE
+ * @param level One of the message level identifiers, e.g., SEVERE
* @param sourceClass name of class that issued the logging request
* @param sourceMethod name of method that issued the logging request
* @param bundleName name of resource bundle to localize msg,
@@ -795,7 +797,7 @@ public class Logger {
* resource bundle name is null, or an empty String or invalid
* then the msg string is not localized.
* <p>
- * @param level One of the message level identifiers, e.g. SEVERE
+ * @param level One of the message level identifiers, e.g., SEVERE
* @param sourceClass name of class that issued the logging request
* @param sourceMethod name of method that issued the logging request
* @param bundleName name of resource bundle to localize msg,
@@ -832,7 +834,7 @@ public class Logger {
* processed specially by output Formatters and is not treated
* as a formatting parameter to the LogRecord message property.
* <p>
- * @param level One of the message level identifiers, e.g. SEVERE
+ * @param level One of the message level identifiers, e.g., SEVERE
* @param sourceClass name of class that issued the logging request
* @param sourceMethod name of method that issued the logging request
* @param bundleName name of resource bundle to localize msg,
@@ -1214,7 +1216,7 @@ public class Logger {
/**
* Specify whether or not this logger should send its output
- * to it's parent Logger. This means that any LogRecords will
+ * to its parent Logger. This means that any LogRecords will
* also be written to the parent's Handlers, and potentially
* to its parent, recursively up the namespace.
*
--- a/src/share/classes/java/util/logging/LoggingMXBean.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/logging/LoggingMXBean.java Tue Sep 29 15:31:18 2009 -0700
@@ -105,8 +105,8 @@ public interface LoggingMXBean extends P
*
* @param loggerName The name of the <tt>Logger</tt> to be set.
* Must be non-null.
- * @param levelName The name of the level to set the specified logger to,
- * or <tt>null</tt> if to set the level to inherit
+ * @param levelName The name of the level to set on the specified logger,
+ * or <tt>null</tt> if setting the level to inherit
* from its nearest ancestor.
*
* @throws IllegalArgumentException if the specified logger
--- a/src/share/classes/java/util/logging/MemoryHandler.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/logging/MemoryHandler.java Tue Sep 29 15:31:18 2009 -0700
@@ -136,7 +136,7 @@ public class MemoryHandler extends Handl
* @param size the number of log records to buffer (must be greater than zero)
* @param pushLevel message level to push on
*
- * @throws IllegalArgumentException is size is <= 0
+ * @throws IllegalArgumentException if size is <= 0
*/
public MemoryHandler(Handler target, int size, Level pushLevel) {
if (target == null || pushLevel == null) {
@@ -258,7 +258,7 @@ public class MemoryHandler extends Handl
* This method checks if the <tt>LogRecord</tt> has an appropriate level and
* whether it satisfies any <tt>Filter</tt>. However it does <b>not</b>
* check whether the <tt>LogRecord</tt> would result in a "push" of the
- * buffer contents. It will return false if the <tt>LogRecord</tt> is Null.
+ * buffer contents. It will return false if the <tt>LogRecord</tt> is null.
* <p>
* @param record a <tt>LogRecord</tt>
* @return true if the <tt>LogRecord</tt> would be logged.
--- a/src/share/classes/java/util/logging/StreamHandler.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/logging/StreamHandler.java Tue Sep 29 15:31:18 2009 -0700
@@ -220,7 +220,7 @@ public class StreamHandler extends Handl
* <p>
* This method checks if the <tt>LogRecord</tt> has an appropriate level and
* whether it satisfies any <tt>Filter</tt>. It will also return false if
- * no output stream has been assigned yet or the LogRecord is Null.
+ * no output stream has been assigned yet or the LogRecord is null.
* <p>
* @param record a <tt>LogRecord</tt>
* @return true if the <tt>LogRecord</tt> would be logged.
--- a/src/share/classes/java/util/zip/ZipEntry.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/zip/ZipEntry.java Tue Sep 29 15:31:18 2009 -0700
@@ -253,14 +253,10 @@ class ZipEntry implements ZipConstants,
* the first 0xFFFF bytes are output to the ZIP file entry.
*
* @param comment the comment string
- * @exception IllegalArgumentException if the length of the specified
- * comment string is greater than 0xFFFF bytes
+ *
* @see #getComment()
*/
public void setComment(String comment) {
- if (comment != null && comment.length() > 0xffff) {
- throw new IllegalArgumentException("invalid entry comment length");
- }
this.comment = comment;
}
--- a/src/share/classes/java/util/zip/ZipFile.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/java/util/zip/ZipFile.java Tue Sep 29 15:31:18 2009 -0700
@@ -195,7 +195,10 @@ class ZipFile implements ZipConstants, C
if (charset == null)
throw new NullPointerException("charset is null");
this.zc = ZipCoder.get(charset);
+ long t0 = System.nanoTime();
jzfile = open(name, mode, file.lastModified());
+ sun.misc.PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0);
+ sun.misc.PerfCounter.getZipFileCount().increment();
this.name = name;
this.total = getTotal(jzfile);
}
--- a/src/share/classes/javax/sql/rowset/BaseRowSet.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/javax/sql/rowset/BaseRowSet.java Tue Sep 29 15:31:18 2009 -0700
@@ -168,8 +168,8 @@ import javax.sql.rowset.serial.*;
* The majority of methods for setting placeholder parameters take two parameters,
* with the first parameter
* indicating which placeholder parameter is to be set, and the second parameter
- * giving the value to be set. Methods such as <code>getInt</code>,
- * <code>getString</code>, <code>getBoolean</code>, and <code>getLong</code> fall into
+ * giving the value to be set. Methods such as <code>setInt</code>,
+ * <code>setString</code>, <code>setBoolean</code>, and <code>setLong</code> fall into
* this category. After these methods have been called, a call to the method
* <code>getParams</code> will return an array with the values that have been set. Each
* element in the array is an <code>Object</code> instance representing the
@@ -3259,9 +3259,9 @@ public static final int ASCII_STREAM_PAR
* @param x the parameter value
* @exception SQLException if a database access error occurs or
* this method is called on a closed <code>CallableStatement</code>
- * @see #getBoolean
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
+ * @see #getParams
* @since 1.4
*/
public void setBoolean(String parameterName, boolean x) throws SQLException{
@@ -3281,7 +3281,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getByte
+ * @see #getParams
* @since 1.4
*/
public void setByte(String parameterName, byte x) throws SQLException{
@@ -3301,7 +3301,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getShort
+ * @see #getParams
* @since 1.4
*/
public void setShort(String parameterName, short x) throws SQLException{
@@ -3320,7 +3320,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getInt
+ * @see #getParams
* @since 1.4
*/
public void setInt(String parameterName, int x) throws SQLException{
@@ -3339,7 +3339,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getLong
+ * @see #getParams
* @since 1.4
*/
public void setLong(String parameterName, long x) throws SQLException{
@@ -3358,7 +3358,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getFloat
+ * @see #getParams
* @since 1.4
*/
public void setFloat(String parameterName, float x) throws SQLException{
@@ -3377,7 +3377,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getDouble
+ * @see #getParams
* @since 1.4
*/
public void setDouble(String parameterName, double x) throws SQLException{
@@ -3398,7 +3398,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getBigDecimal
+ * @see #getParams
* @since 1.4
*/
public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{
@@ -3421,7 +3421,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getString
+ * @see #getParams
* @since 1.4
*/
public void setString(String parameterName, String x) throws SQLException{
@@ -3443,7 +3443,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getBytes
+ * @see #getParams
* @since 1.4
*/
public void setBytes(String parameterName, byte x[]) throws SQLException{
@@ -3464,7 +3464,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getTimestamp
+ * @see #getParams
* @since 1.4
*/
public void setTimestamp(String parameterName, java.sql.Timestamp x)
@@ -3712,7 +3712,7 @@ public static final int ASCII_STREAM_PAR
* or <code>STRUCT</code> data type and the JDBC driver does not support
* this data type
* @see Types
- * @see #getObject
+ * @see #getParams
* @since 1.4
*/
public void setObject(String parameterName, Object x, int targetSqlType, int scale)
@@ -3740,7 +3740,7 @@ public static final int ASCII_STREAM_PAR
* <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
* or <code>STRUCT</code> data type and the JDBC driver does not support
* this data type
- * @see #getObject
+ * @see #getParams
* @since 1.4
*/
public void setObject(String parameterName, Object x, int targetSqlType)
@@ -3782,7 +3782,7 @@ public static final int ASCII_STREAM_PAR
* <code>Object</code> parameter is ambiguous
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getObject
+ * @see #getParams
* @since 1.4
*/
public void setObject(String parameterName, Object x) throws SQLException{
@@ -4064,7 +4064,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getDate
+ * @see #getParams
* @since 1.4
*/
public void setDate(String parameterName, java.sql.Date x)
@@ -4091,7 +4091,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getDate
+ * @see #getParams
* @since 1.4
*/
public void setDate(String parameterName, java.sql.Date x, Calendar cal)
@@ -4111,7 +4111,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getTime
+ * @see #getParams
* @since 1.4
*/
public void setTime(String parameterName, java.sql.Time x)
@@ -4138,7 +4138,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getTime
+ * @see #getParams
* @since 1.4
*/
public void setTime(String parameterName, java.sql.Time x, Calendar cal)
@@ -4165,7 +4165,7 @@ public static final int ASCII_STREAM_PAR
* this method is called on a closed <code>CallableStatement</code>
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
- * @see #getTimestamp
+ * @see #getParams
* @since 1.4
*/
public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal)
--- a/src/share/classes/sun/net/spi/DefaultProxySelector.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/net/spi/DefaultProxySelector.java Tue Sep 29 15:31:18 2009 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2009 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,11 +25,9 @@
package sun.net.spi;
-import sun.net.www.http.*;
import sun.net.NetProperties;
import java.net.*;
import java.util.*;
-import java.util.regex.*;
import java.io.*;
import sun.misc.RegexpPool;
import java.security.AccessController;
@@ -102,17 +100,22 @@ public class DefaultProxySelector extend
*/
static class NonProxyInfo {
+ // Default value for nonProxyHosts, this provides backward compatibility
+ // by excluding localhost and its litteral notations.
+ static final String defStringVal = "localhost|127.*|[::1]";
+
String hostsSource;
RegexpPool hostsPool;
- String property;
-
- static NonProxyInfo ftpNonProxyInfo = new NonProxyInfo("ftp.nonProxyHosts", null, null);
- static NonProxyInfo httpNonProxyInfo = new NonProxyInfo("http.nonProxyHosts", null, null);
-
- NonProxyInfo(String p, String s, RegexpPool pool) {
+ final String property;
+ final String defaultVal;
+ static NonProxyInfo ftpNonProxyInfo = new NonProxyInfo("ftp.nonProxyHosts", null, null, defStringVal);
+ static NonProxyInfo httpNonProxyInfo = new NonProxyInfo("http.nonProxyHosts", null, null, defStringVal);
+
+ NonProxyInfo(String p, String s, RegexpPool pool, String d) {
property = p;
hostsSource = s;
hostsPool = pool;
+ defaultVal = d;
}
}
@@ -130,7 +133,6 @@ public class DefaultProxySelector extend
}
String protocol = uri.getScheme();
String host = uri.getHost();
- int port = uri.getPort();
if (host == null) {
// This is a hack to ensure backward compatibility in two
@@ -149,11 +151,6 @@ public class DefaultProxySelector extend
}
i = auth.lastIndexOf(':');
if (i >= 0) {
- try {
- port = Integer.parseInt(auth.substring(i+1));
- } catch (NumberFormatException e) {
- port = -1;
- }
auth = auth.substring(0,i);
}
host = auth;
@@ -164,13 +161,6 @@ public class DefaultProxySelector extend
throw new IllegalArgumentException("protocol = "+protocol+" host = "+host);
}
List<Proxy> proxyl = new ArrayList<Proxy>(1);
-
- // special case localhost and loopback addresses to
- // not go through proxy
- if (isLoopback(host)) {
- proxyl.add(Proxy.NO_PROXY);
- return proxyl;
- }
NonProxyInfo pinfo = null;
@@ -244,9 +234,14 @@ public class DefaultProxySelector extend
nphosts = NetProperties.get(nprop.property);
synchronized (nprop) {
if (nphosts == null) {
- nprop.hostsSource = null;
- nprop.hostsPool = null;
- } else {
+ if (nprop.defaultVal != null) {
+ nphosts = nprop.defaultVal;
+ } else {
+ nprop.hostsSource = null;
+ nprop.hostsPool = null;
+ }
+ }
+ if (nphosts != null) {
if (!nphosts.equals(nprop.hostsSource)) {
RegexpPool pool = new RegexpPool();
StringTokenizer st = new StringTokenizer(nphosts, "|", false);
@@ -334,107 +329,6 @@ public class DefaultProxySelector extend
}
}
- private boolean isLoopback(String host) {
- if (host == null || host.length() == 0)
- return false;
-
- if (host.equalsIgnoreCase("localhost"))
- return true;
-
- /* The string could represent a numerical IP address.
- * For IPv4 addresses, check whether it starts with 127.
- * For IPv6 addresses, check whether it is ::1 or its equivalent.
- * Don't check IPv4-mapped or IPv4-compatible addresses
- */
-
- if (host.startsWith("127.")) {
- // possible IPv4 loopback address
- int p = 4;
- int q;
- int n = host.length();
- // Per RFC2732: At most three digits per byte
- // Further constraint: Each element fits in a byte
- if ((q = scanByte(host, p, n)) <= p) return false; p = q;
- if ((q = scan(host, p, n, '.')) <= p) return q == n && number > 0; p = q;
- if ((q = scanByte(host, p, n)) <= p) return false; p = q;
- if ((q = scan(host, p, n, '.')) <= p) return q == n && number > 0; p = q;
- if ((q = scanByte(host, p, n)) <= p) return false;
- return q == n && number > 0;
- }
-
- if (host.endsWith(":1")) {
- final Pattern p6 = Pattern.compile("::1|(0:){7}1|(0:){1,6}:1");
- return p6.matcher(host).matches();
- }
- return false;
- }
-
- // Character-class masks, in reverse order from RFC2396 because
- // initializers for static fields cannot make forward references.
-
- // Compute a low-order mask for the characters
- // between first and last, inclusive
- private static long lowMask(char first, char last) {
- long m = 0;
- int f = Math.max(Math.min(first, 63), 0);
- int l = Math.max(Math.min(last, 63), 0);
- for (int i = f; i <= l; i++)
- m |= 1L << i;
- return m;
- }
- // digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
- // "8" | "9"
- private static final long L_DIGIT = lowMask('0', '9');
- private static final long H_DIGIT = 0L;
-
- // Scan a string of decimal digits whose value fits in a byte
- //
- private int number;
- private int scanByte(String input, int start, int n)
- {
- int p = start;
- int q = scan(input, p, n, L_DIGIT, H_DIGIT);
- if (q <= p) return q;
- number = Integer.parseInt(input.substring(p, q));
- if (number > 255) return p;
- return q;
- }
-
- // Scan a specific char: If the char at the given start position is
- // equal to c, return the index of the next char; otherwise, return the
- // start position.
- //
- private int scan(String input, int start, int end, char c) {
- if ((start < end) && (input.charAt(start) == c))
- return start + 1;
- return start;
- }
-
- // Scan chars that match the given mask pair
- //
- private int scan(String input, int start, int n, long lowMask, long highMask)
- {
- int p = start;
- while (p < n) {
- char c = input.charAt(p);
- if (match(c, lowMask, highMask)) {
- p++;
- continue;
- }
- break;
- }
- return p;
- }
-
- // Tell whether the given character is permitted by the given mask pair
- private boolean match(char c, long lowMask, long highMask) {
- if (c < 64)
- return ((1L << c) & lowMask) != 0;
- if (c < 128)
- return ((1L << (c - 64)) & highMask) != 0;
- return false;
- }
-
private native static boolean init();
private native Proxy getSystemProxy(String protocol, String host);
}
--- a/src/share/classes/sun/net/www/http/HttpCapture.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/net/www/http/HttpCapture.java Tue Sep 29 15:31:18 2009 -0700
@@ -24,14 +24,12 @@
*/
package sun.net.www.http;
+
import java.io.*;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.util.ArrayList;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import java.util.regex.*;
import sun.net.NetProperties;
-import java.util.regex.*;
+import sun.util.logging.PlatformLogger;
/**
* Main class of the HTTP traffic capture tool.
@@ -62,76 +60,6 @@ public class HttpCapture {
private static boolean initialized = false;
private static volatile ArrayList<Pattern> patterns = null;
private static volatile ArrayList<String> capFiles = null;
- /* Logging is done in an ugly way so that it does not require the presence
- * the java.util.logging package. If the Logger class is not available, then
- * logging is turned off. This is for helping the modularization effort.
- */
- private static Object logger = null;
- private static boolean logging = false;
-
- static {
- Class cl;
- try {
- cl = Class.forName("java.util.logging.Logger");
- } catch (ClassNotFoundException ex) {
- cl = null;
- }
- if (cl != null) {
- try {
- Method m = cl.getMethod("getLogger", String.class);
- logger = m.invoke(null, "sun.net.www.protocol.http.HttpURLConnection");
- logging = true;
- } catch (NoSuchMethodException noSuchMethodException) {
- } catch (SecurityException securityException) {
- } catch (IllegalAccessException illegalAccessException) {
- } catch (IllegalArgumentException illegalArgumentException) {
- } catch (InvocationTargetException invocationTargetException) {
- }
- }
- }
-
- public static void fine(String s) {
- if (logging) {
- ((Logger)logger).fine(s);
- }
- }
-
- public static void finer(String s) {
- if (logging) {
- ((Logger)logger).finer(s);
- }
- }
-
- public static void finest(String s) {
- if (logging) {
- ((Logger)logger).finest(s);
- }
- }
-
- public static void severe(String s) {
- if (logging) {
- ((Logger)logger).finest(s);
- }
- }
-
- public static void info(String s) {
- if (logging) {
- ((Logger)logger).info(s);
- }
- }
-
- public static void warning(String s) {
- if (logging) {
- ((Logger)logger).warning(s);
- }
- }
-
- public static boolean isLoggable(String level) {
- if (!logging) {
- return false;
- }
- return ((Logger)logger).isLoggable(Level.parse(level));
- }
private static synchronized void init() {
initialized = true;
@@ -187,7 +115,7 @@ public class HttpCapture {
out = new BufferedWriter(new FileWriter(file, true));
out.write("URL: " + url + "\n");
} catch (IOException ex) {
- Logger.getLogger(HttpCapture.class.getName()).log(Level.SEVERE, null, ex);
+ PlatformLogger.getLogger(HttpCapture.class.getName()).severe(null, ex);
}
}
--- a/src/share/classes/sun/net/www/http/HttpClient.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/net/www/http/HttpClient.java Tue Sep 29 15:31:18 2009 -0700
@@ -35,6 +35,7 @@ import sun.net.www.MeteredStream;
import sun.net.www.MeteredStream;
import sun.net.www.ParseUtil;
import sun.net.www.protocol.http.HttpURLConnection;
+import sun.util.logging.PlatformLogger;
/**
* @author Herb Jellinek
@@ -804,8 +805,9 @@ public class HttpClient extends NetworkC
if (isKeepingAlive()) {
// Wrap KeepAliveStream if keep alive is enabled.
- if (HttpCapture.isLoggable("FINEST")) {
- HttpCapture.finest("KeepAlive stream used: " + url);
+ PlatformLogger logger = HttpURLConnection.getHttpLogger();
+ if (logger.isLoggable(PlatformLogger.FINEST)) {
+ logger.finest("KeepAlive stream used: " + url);
}
serverInput = new KeepAliveStream(serverInput, pi, cl, this);
failedOnce = false;
--- a/src/share/classes/sun/net/www/http/KeepAliveCache.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/net/www/http/KeepAliveCache.java Tue Sep 29 15:31:18 2009 -0700
@@ -25,12 +25,11 @@
package sun.net.www.http;
-import java.io.InputStream;
import java.io.IOException;
import java.io.NotSerializableException;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
import java.net.URL;
-import java.util.concurrent.ConcurrentHashMap;
/**
* A class that implements a cache of idle Http connections for keep-alive
@@ -39,7 +38,7 @@ import java.util.concurrent.ConcurrentHa
* @author Dave Brown
*/
public class KeepAliveCache
- extends ConcurrentHashMap<KeepAliveKey, ClientVector>
+ extends HashMap<KeepAliveKey, ClientVector>
implements Runnable {
private static final long serialVersionUID = -2937172892064557949L;
@@ -163,8 +162,8 @@ public class KeepAliveCache
* Errs on the side of caution (leave connections idle for a relatively
* short time).
*/
+ @Override
public void run() {
- int total_cache;
do {
try {
Thread.sleep(LIFETIME);
@@ -311,6 +310,7 @@ class KeepAliveKey {
/**
* Determine whether or not two objects of this type are equal
*/
+ @Override
public boolean equals(Object obj) {
if ((obj instanceof KeepAliveKey) == false)
return false;
@@ -325,6 +325,7 @@ class KeepAliveKey {
* The hashCode() for this object is the string hashCode() of
* concatenation of the protocol, host name and port.
*/
+ @Override
public int hashCode() {
String str = protocol+host+port;
return this.obj == null? str.hashCode() :
--- a/src/share/classes/sun/net/www/http/KeepAliveStream.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/net/www/http/KeepAliveStream.java Tue Sep 29 15:31:18 2009 -0700
@@ -25,10 +25,7 @@
package sun.net.www.http;
-import java.net.URL;
-import java.net.HttpURLConnection;
import java.io.*;
-import java.util.StringTokenizer;
import sun.net.ProgressSource;
import sun.net.www.MeteredStream;
@@ -50,9 +47,8 @@ class KeepAliveStream extends MeteredStr
// has this KeepAliveStream been put on the queue for asynchronous cleanup.
protected boolean queuedForCleanup = false;
- private static KeepAliveStreamCleaner queue = new KeepAliveStreamCleaner();
- private static Thread cleanerThread = null;
- private static boolean startCleanupThread;
+ private static final KeepAliveStreamCleaner queue = new KeepAliveStreamCleaner();
+ private static Thread cleanerThread; // null
/**
* Constructor
@@ -155,43 +151,46 @@ class KeepAliveStream extends MeteredStr
}
}
- private static synchronized void queueForCleanup(KeepAliveCleanerEntry kace) {
- if(queue != null && !kace.getQueuedForCleanup()) {
- if (!queue.offer(kace)) {
- kace.getHttpClient().closeServer();
- return;
- }
-
- kace.setQueuedForCleanup();
- }
-
- startCleanupThread = (cleanerThread == null);
- if (!startCleanupThread) {
- if (!cleanerThread.isAlive()) {
- startCleanupThread = true;
- }
- }
-
- if (startCleanupThread) {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- // We want to create the Keep-Alive-SocketCleaner in the
- // system threadgroup
- ThreadGroup grp = Thread.currentThread().getThreadGroup();
- ThreadGroup parent = null;
- while ((parent = grp.getParent()) != null) {
- grp = parent;
+ private static void queueForCleanup(KeepAliveCleanerEntry kace) {
+ synchronized(queue) {
+ if(!kace.getQueuedForCleanup()) {
+ if (!queue.offer(kace)) {
+ kace.getHttpClient().closeServer();
+ return;
+ }
+
+ kace.setQueuedForCleanup();
+ queue.notifyAll();
+ }
+
+ boolean startCleanupThread = (cleanerThread == null);
+ if (!startCleanupThread) {
+ if (!cleanerThread.isAlive()) {
+ startCleanupThread = true;
+ }
+ }
+
+ if (startCleanupThread) {
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Void>() {
+ public Void run() {
+ // We want to create the Keep-Alive-SocketCleaner in the
+ // system threadgroup
+ ThreadGroup grp = Thread.currentThread().getThreadGroup();
+ ThreadGroup parent = null;
+ while ((parent = grp.getParent()) != null) {
+ grp = parent;
+ }
+
+ cleanerThread = new Thread(grp, queue, "Keep-Alive-SocketCleaner");
+ cleanerThread.setDaemon(true);
+ cleanerThread.setPriority(Thread.MAX_PRIORITY - 2);
+ cleanerThread.start();
+ return null;
}
-
- cleanerThread = new Thread(grp, queue, "Keep-Alive-SocketCleaner");
- cleanerThread.setDaemon(true);
- cleanerThread.setPriority(Thread.MAX_PRIORITY - 2);
- cleanerThread.start();
- return null;
- }
- });
- }
+ });
+ }
+ } // queue
}
protected long remainingToRead() {
--- a/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java Tue Sep 29 15:31:18 2009 -0700
@@ -25,9 +25,8 @@
package sun.net.www.http;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
import java.io.IOException;
+import java.util.LinkedList;
import sun.net.NetProperties;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -44,7 +43,9 @@ import java.security.PrivilegedAction;
*/
@SuppressWarnings("serial") // never serialized
-public class KeepAliveStreamCleaner extends LinkedBlockingQueue<KeepAliveCleanerEntry> implements Runnable
+class KeepAliveStreamCleaner
+ extends LinkedList<KeepAliveCleanerEntry>
+ implements Runnable
{
// maximum amount of remaining data that we will try to cleanup
protected static int MAX_DATA_REMAINING = 512;
@@ -78,23 +79,39 @@ public class KeepAliveStreamCleaner exte
}
- public KeepAliveStreamCleaner()
- {
- super(MAX_CAPACITY);
+ @Override
+ public boolean offer(KeepAliveCleanerEntry e) {
+ if (size() >= MAX_CAPACITY)
+ return false;
+
+ return super.offer(e);
}
- public KeepAliveStreamCleaner(int capacity)
- {
- super(capacity);
- }
-
+ @Override
public void run()
{
KeepAliveCleanerEntry kace = null;
do {
try {
- kace = poll((long)TIMEOUT, TimeUnit.MILLISECONDS);
+ synchronized(this) {
+ long before = System.currentTimeMillis();
+ long timeout = TIMEOUT;
+ while ((kace = poll()) == null) {
+ this.wait(timeout);
+
+ long after = System.currentTimeMillis();
+ long elapsed = after - before;
+ if (elapsed > timeout) {
+ /* one last try */
+ kace = poll();
+ break;
+ }
+ before = after;
+ timeout -= elapsed;
+ }
+ }
+
if(kace == null)
break;
--- a/src/share/classes/sun/net/www/protocol/http/AuthCache.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/net/www/protocol/http/AuthCache.java Tue Sep 29 15:31:18 2009 -0700
@@ -25,14 +25,6 @@
package sun.net.www.protocol.http;
-import java.io.IOException;
-import java.net.URL;
-import java.util.Hashtable;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Enumeration;
-import java.util.HashMap;
-
/**
* @author Michael McMahon
*
@@ -49,7 +41,7 @@ public interface AuthCache {
* A:[B:]C:D:E[:F] Between 4 and 6 fields separated by ":"
* where the fields have the following meaning:
* A is "s" or "p" for server or proxy authentication respectively
- * B is optional and is "D", "B", or "N" for digest, basic or ntlm auth.
+ * B is optional and is the {@link AuthScheme}, e.g. BASIC, DIGEST, NTLM, etc
* C is either "http" or "https"
* D is the hostname
* E is the port number
--- a/src/share/classes/sun/net/www/protocol/http/AuthCacheValue.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/net/www/protocol/http/AuthCacheValue.java Tue Sep 29 15:31:18 2009 -0700
@@ -25,15 +25,8 @@
package sun.net.www.protocol.http;
-import java.io.IOException;
import java.io.Serializable;
-import java.net.*;
-import java.util.Hashtable;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Enumeration;
-import java.util.HashMap;
-
+import java.net.PasswordAuthentication;
/**
* AuthCacheValue: interface to minimise exposure to authentication cache
@@ -62,7 +55,15 @@ public abstract class AuthCacheValue imp
AuthCacheValue() {}
+ /**
+ * Proxy or Server
+ */
abstract Type getAuthType ();
+
+ /**
+ * Authentication scheme
+ */
+ abstract AuthScheme getAuthScheme();
/**
* name of server/proxy
--- a/src/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java Tue Sep 29 15:31:18 2009 -0700
@@ -85,6 +85,11 @@ abstract class AuthenticationInfo extend
AuthCacheValue.Type.Server:
AuthCacheValue.Type.Proxy;
}
+
+ AuthScheme getAuthScheme() {
+ return authScheme;
+ }
+
public String getHost() {
return host;
}
@@ -151,7 +156,7 @@ abstract class AuthenticationInfo extend
}
//public String toString () {
- //return ("{"+type+":"+authType+":"+protocol+":"+host+":"+port+":"+realm+":"+path+"}");
+ //return ("{"+type+":"+authScheme+":"+protocol+":"+host+":"+port+":"+realm+":"+path+"}");
//}
// REMIND: This cache just grows forever. We should put in a bounded
@@ -160,8 +165,8 @@ abstract class AuthenticationInfo extend
/** The type (server/proxy) of authentication this is. Used for key lookup */
char type;
- /** The authentication type (basic/digest). Also used for key lookup */
- char authType;
+ /** The authentication scheme (basic/digest). Also used for key lookup */
+ AuthScheme authScheme;
/** The protocol/scheme (i.e. http or https ). Need to keep the caches
* logically separate for the two protocols. This field is only used
@@ -183,9 +188,9 @@ abstract class AuthenticationInfo extend
String path;
/** Use this constructor only for proxy entries */
- AuthenticationInfo(char type, char authType, String host, int port, String realm) {
+ AuthenticationInfo(char type, AuthScheme authScheme, String host, int port, String realm) {
this.type = type;
- this.authType = authType;
+ this.authScheme = authScheme;
this.protocol = "";
this.host = host.toLowerCase();
this.port = port;
@@ -206,9 +211,9 @@ abstract class AuthenticationInfo extend
* Constructor used to limit the authorization to the path within
* the URL. Use this constructor for origin server entries.
*/
- AuthenticationInfo(char type, char authType, URL url, String realm) {
+ AuthenticationInfo(char type, AuthScheme authScheme, URL url, String realm) {
this.type = type;
- this.authType = authType;
+ this.authScheme = authScheme;
this.protocol = url.getProtocol().toLowerCase();
this.host = url.getHost().toLowerCase();
this.port = url.getPort();
@@ -264,12 +269,12 @@ abstract class AuthenticationInfo extend
* In this case we do not use the path because the protection space
* is identified by the host:port:realm only
*/
- static AuthenticationInfo getServerAuth(URL url, String realm, char atype) {
+ static AuthenticationInfo getServerAuth(URL url, String realm, AuthScheme scheme) {
int port = url.getPort();
if (port == -1) {
port = url.getDefaultPort();
}
- String key = SERVER_AUTHENTICATION + ":" + atype + ":" + url.getProtocol().toLowerCase()
+ String key = SERVER_AUTHENTICATION + ":" + scheme + ":" + url.getProtocol().toLowerCase()
+ ":" + url.getHost().toLowerCase() + ":" + port + ":" + realm;
AuthenticationInfo cached = getAuth(key, null);
if ((cached == null) && requestIsInProgress (key)) {
@@ -308,8 +313,8 @@ abstract class AuthenticationInfo extend
* Used in response to a challenge. Note, the protocol field is always
* blank for proxies.
*/
- static AuthenticationInfo getProxyAuth(String host, int port, String realm, char atype) {
- String key = PROXY_AUTHENTICATION + ":" + atype + "::" + host.toLowerCase()
+ static AuthenticationInfo getProxyAuth(String host, int port, String realm, AuthScheme scheme) {
+ String key = PROXY_AUTHENTICATION + ":" + scheme + "::" + host.toLowerCase()
+ ":" + port + ":" + realm;
AuthenticationInfo cached = (AuthenticationInfo) cache.get(key, null);
if ((cached == null) && requestIsInProgress (key)) {
@@ -409,7 +414,7 @@ abstract class AuthenticationInfo extend
// This must be kept in sync with the getXXXAuth() methods in this
// class.
if (includeRealm) {
- return type + ":" + authType + ":" + protocol + ":"
+ return type + ":" + authScheme + ":" + protocol + ":"
+ host + ":" + port + ":" + realm;
} else {
return type + ":" + protocol + ":" + host + ":" + port;
--- a/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/net/www/protocol/http/BasicAuthentication.java Tue Sep 29 15:31:18 2009 -0700
@@ -44,8 +44,6 @@ class BasicAuthentication extends Authen
private static final long serialVersionUID = 100L;
- static final char BASIC_AUTH = 'B';
-
/** The authentication string for this host, port, and realm. This is
a simple BASE64 encoding of "login:password". */
String auth;
@@ -56,7 +54,7 @@ class BasicAuthentication extends Authen
public BasicAuthentication(boolean isProxy, String host, int port,
String realm, PasswordAuthentication pw) {
super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
- BASIC_AUTH, host, port, realm);
+ AuthScheme.BASIC, host, port, realm);
String plain = pw.getUserName() + ":";
byte[] nameBytes = null;
try {
@@ -86,7 +84,7 @@ class BasicAuthentication extends Authen
public BasicAuthentication(boolean isProxy, String host, int port,
String realm, String auth) {
super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
- BASIC_AUTH, host, port, realm);
+ AuthScheme.BASIC, host, port, realm);
this.auth = "Basic " + auth;
}
@@ -96,7 +94,7 @@ class BasicAuthentication extends Authen
public BasicAuthentication(boolean isProxy, URL url, String realm,
PasswordAuthentication pw) {
super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
- BASIC_AUTH, url, realm);
+ AuthScheme.BASIC, url, realm);
String plain = pw.getUserName() + ":";
byte[] nameBytes = null;
try {
@@ -126,7 +124,7 @@ class BasicAuthentication extends Authen
public BasicAuthentication(boolean isProxy, URL url, String realm,
String auth) {
super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
- BASIC_AUTH, url, realm);
+ AuthScheme.BASIC, url, realm);
this.auth = "Basic " + auth;
}
--- a/src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/net/www/protocol/http/DigestAuthentication.java Tue Sep 29 15:31:18 2009 -0700
@@ -38,7 +38,6 @@ import java.security.NoSuchAlgorithmExce
import java.security.NoSuchAlgorithmException;
import static sun.net.www.protocol.http.HttpURLConnection.HTTP_CONNECT;
-
/**
* DigestAuthentication: Encapsulate an http server authentication using
* the "Digest" scheme, as described in RFC2069 and updated in RFC2617
@@ -49,8 +48,6 @@ class DigestAuthentication extends Authe
class DigestAuthentication extends AuthenticationInfo {
private static final long serialVersionUID = 100L;
-
- static final char DIGEST_AUTH = 'D';
private String authMethod;
@@ -178,7 +175,10 @@ class DigestAuthentication extends Authe
public DigestAuthentication(boolean isProxy, URL url, String realm,
String authMethod, PasswordAuthentication pw,
Parameters params) {
- super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION, DIGEST_AUTH,url, realm);
+ super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
+ AuthScheme.DIGEST,
+ url,
+ realm);
this.authMethod = authMethod;
this.pw = pw;
this.params = params;
@@ -187,7 +187,11 @@ class DigestAuthentication extends Authe
public DigestAuthentication(boolean isProxy, String host, int port, String realm,
String authMethod, PasswordAuthentication pw,
Parameters params) {
- super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION, DIGEST_AUTH,host, port, realm);
+ super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
+ AuthScheme.DIGEST,
+ host,
+ port,
+ realm);
this.authMethod = authMethod;
this.pw = pw;
this.params = params;
--- a/src/share/classes/sun/net/www/protocol/http/HttpLogFormatter.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/net/www/protocol/http/HttpLogFormatter.java Tue Sep 29 15:31:18 2009 -0700
@@ -49,8 +49,10 @@ public class HttpLogFormatter extends ja
@Override
public String format(LogRecord record) {
- if (!"sun.net.www.http.HttpCapture".equalsIgnoreCase(record.getSourceClassName())) {
- // Don't change format for stuff that doesn't concern us
+ String sourceClassName = record.getSourceClassName();
+ if (sourceClassName == null ||
+ !(sourceClassName.startsWith("sun.net.www.protocol.http") ||
+ sourceClassName.startsWith("sun.net.www.http"))) {
return super.format(record);
}
String src = record.getMessage();
--- a/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Tue Sep 29 15:31:18 2009 -0700
@@ -57,11 +57,17 @@ import sun.net.www.http.PosterOutputStre
import sun.net.www.http.PosterOutputStream;
import sun.net.www.http.ChunkedInputStream;
import sun.net.www.http.ChunkedOutputStream;
-import sun.net.www.http.HttpCapture;
+import sun.util.logging.PlatformLogger;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
import java.net.MalformedURLException;
import java.nio.ByteBuffer;
+import static sun.net.www.protocol.http.AuthScheme.BASIC;
+import static sun.net.www.protocol.http.AuthScheme.DIGEST;
+import static sun.net.www.protocol.http.AuthScheme.NTLM;
+import static sun.net.www.protocol.http.AuthScheme.NEGOTIATE;
+import static sun.net.www.protocol.http.AuthScheme.KERBEROS;
+import static sun.net.www.protocol.http.AuthScheme.UNKNOWN;
/**
* A class to represent an HTTP connection to a remote object.
@@ -231,9 +237,11 @@ public class HttpURLConnection extends j
boolean needToCheck = true;
private boolean doingNTLM2ndStage = false; /* doing the 2nd stage of an NTLM server authentication */
private boolean doingNTLMp2ndStage = false; /* doing the 2nd stage of an NTLM proxy authentication */
- /* try auth without calling Authenticator */
- private boolean tryTransparentNTLMServer = NTLMAuthentication.supportsTransparentAuth();
- private boolean tryTransparentNTLMProxy = NTLMAuthentication.supportsTransparentAuth();
+
+ /* try auth without calling Authenticator. Used for transparent NTLM authentication */
+ private boolean tryTransparentNTLMServer = true;
+ private boolean tryTransparentNTLMProxy = true;
+
/* Used by Windows specific code */
Object authObj;
@@ -283,6 +291,10 @@ public class HttpURLConnection extends j
*/
private int connectTimeout = -1;
private int readTimeout = -1;
+
+ /* Logging support */
+ private static final PlatformLogger logger =
+ PlatformLogger.getLogger("sun.net.www.protocol.http.HttpURLConnection");
/*
* privileged request password authentication
@@ -301,18 +313,23 @@ public class HttpURLConnection extends j
return java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<PasswordAuthentication>() {
public PasswordAuthentication run() {
- if (HttpCapture.isLoggable("FINEST")) {
- HttpCapture.finest("Requesting Authentication: host =" + host + " url = " + url);
+ if (logger.isLoggable(PlatformLogger.FINEST)) {
+ logger.finest("Requesting Authentication: host =" + host + " url = " + url);
}
PasswordAuthentication pass = Authenticator.requestPasswordAuthentication(
host, addr, port, protocol,
prompt, scheme, url, authType);
- if (HttpCapture.isLoggable("FINEST")) {
- HttpCapture.finest("Authentication returned: " + (pass != null ? pass.toString() : "null"));
+ if (logger.isLoggable(PlatformLogger.FINEST)) {
+ logger.finest("Authentication returned: " + (pass != null ? pass.toString() : "null"));
}
return pass;
}
});
+ }
+
+ /* Logging support */
+ public static PlatformLogger getHttpLogger() {
+ return logger;
}
/*
@@ -463,8 +480,8 @@ public class HttpURLConnection extends j
setRequests=true;
}
- if (HttpCapture.isLoggable("FINE")) {
- HttpCapture.fine(requests.toString());
+ if (logger.isLoggable(PlatformLogger.FINE)) {
+ logger.fine(requests.toString());
}
http.writeRequests(requests, poster);
if (ps.checkError()) {
@@ -728,9 +745,9 @@ public class HttpURLConnection extends j
&& !(cachedResponse instanceof SecureCacheResponse)) {
cachedResponse = null;
}
- if (HttpCapture.isLoggable("FINEST")) {
- HttpCapture.finest("Cache Request for " + uri + " / " + getRequestMethod());
- HttpCapture.finest("From cache: " + (cachedResponse != null ? cachedResponse.toString() : "null"));
+ if (logger.isLoggable(PlatformLogger.FINEST)) {
+ logger.finest("Cache Request for " + uri + " / " + getRequestMethod());
+ logger.finest("From cache: " + (cachedResponse != null ? cachedResponse.toString() : "null"));
}
if (cachedResponse != null) {
cachedHeaders = mapToMessageHeader(cachedResponse.getHeaders());
@@ -769,8 +786,8 @@ public class HttpURLConnection extends j
});
if (sel != null) {
URI uri = sun.net.www.ParseUtil.toURI(url);
- if (HttpCapture.isLoggable("FINEST")) {
- HttpCapture.finest("ProxySelector Request for " + uri);
+ if (logger.isLoggable(PlatformLogger.FINEST)) {
+ logger.finest("ProxySelector Request for " + uri);
}
Iterator<Proxy> it = sel.select(uri).iterator();
Proxy p;
@@ -786,9 +803,9 @@ public class HttpURLConnection extends j
http = getNewHttpClient(url, p, connectTimeout, false);
http.setReadTimeout(readTimeout);
}
- if (HttpCapture.isLoggable("FINEST")) {
+ if (logger.isLoggable(PlatformLogger.FINEST)) {
if (p != null) {
- HttpCapture.finest("Proxy used: " + p.toString());
+ logger.finest("Proxy used: " + p.toString());
}
}
break;
@@ -1018,15 +1035,15 @@ public class HttpURLConnection extends j
URI uri = ParseUtil.toURI(url);
if (uri != null) {
- if (HttpCapture.isLoggable("FINEST")) {
- HttpCapture.finest("CookieHandler request for " + uri);
+ if (logger.isLoggable(PlatformLogger.FINEST)) {
+ logger.finest("CookieHandler request for " + uri);
}
Map<String, List<String>> cookies
= cookieHandler.get(
uri, requests.getHeaders(EXCLUDE_HEADERS));
if (!cookies.isEmpty()) {
- if (HttpCapture.isLoggable("FINEST")) {
- HttpCapture.finest("Cookies retrieved: " + cookies.toString());
+ if (logger.isLoggable(PlatformLogger.FINEST)) {
+ logger.finest("Cookies retrieved: " + cookies.toString());
}
for (Map.Entry<String, List<String>> entry :
cookies.entrySet()) {
@@ -1157,8 +1174,8 @@ public class HttpURLConnection extends j
writeRequests();
}
http.parseHTTP(responses, pi, this);
- if (HttpCapture.isLoggable("FINE")) {
- HttpCapture.fine(responses.toString());
+ if (logger.isLoggable(PlatformLogger.FINE)) {
+ logger.fine(responses.toString());
}
inputStream = http.getInputStream();
@@ -1270,7 +1287,7 @@ public class HttpURLConnection extends j
String raw = srvHdr.raw();
if (!doingNTLM2ndStage) {
if ((serverAuthentication != null)&&
- !(serverAuthentication instanceof NTLMAuthentication)) {
+ serverAuthentication.getAuthScheme() != NTLM) {
if (serverAuthentication.isAuthorizationStale (raw)) {
/* we can retry with the current credentials */
disconnectInternal();
@@ -1523,8 +1540,8 @@ public class HttpURLConnection extends j
*/
private AuthenticationInfo
resetProxyAuthentication(AuthenticationInfo proxyAuthentication, AuthenticationHeader auth) {
- if ((proxyAuthentication != null )&& ! (proxyAuthentication instanceof
- NTLMAuthentication)) {
+ if ((proxyAuthentication != null )&&
+ proxyAuthentication.getAuthScheme() != NTLM) {
String raw = auth.raw();
if (proxyAuthentication.isAuthorizationStale (raw)) {
/* we can retry with the current credentials */
@@ -1602,8 +1619,8 @@ public class HttpURLConnection extends j
http.parseHTTP(responses, null, this);
/* Log the response to the CONNECT */
- if (HttpCapture.isLoggable("FINE")) {
- HttpCapture.fine(responses.toString());
+ if (logger.isLoggable(PlatformLogger.FINE)) {
+ logger.fine(responses.toString());
}
statusLine = responses.getValue(0);
@@ -1730,8 +1747,8 @@ public class HttpURLConnection extends j
setPreemptiveProxyAuthentication(requests);
/* Log the CONNECT request */
- if (HttpCapture.isLoggable("FINE")) {
- HttpCapture.fine(requests.toString());
+ if (logger.isLoggable(PlatformLogger.FINE)) {
+ logger.fine(requests.toString());
}
http.writeRequests(requests, null);
@@ -1776,28 +1793,31 @@ public class HttpURLConnection extends j
HeaderParser p = authhdr.headerParser();
String realm = p.findValue("realm");
String scheme = authhdr.scheme();
- char schemeID;
+ AuthScheme authScheme = UNKNOWN;
if ("basic".equalsIgnoreCase(scheme)) {
- schemeID = BasicAuthentication.BASIC_AUTH;
+ authScheme = BASIC;
} else if ("digest".equalsIgnoreCase(scheme)) {
- schemeID = DigestAuthentication.DIGEST_AUTH;
+ authScheme = DIGEST;
} else if ("ntlm".equalsIgnoreCase(scheme)) {
- schemeID = NTLMAuthentication.NTLM_AUTH;
+ authScheme = NTLM;
doingNTLMp2ndStage = true;
} else if ("Kerberos".equalsIgnoreCase(scheme)) {
- schemeID = NegotiateAuthentication.KERBEROS_AUTH;
+ authScheme = KERBEROS;
doingNTLMp2ndStage = true;
} else if ("Negotiate".equalsIgnoreCase(scheme)) {
- schemeID = NegotiateAuthentication.NEGOTIATE_AUTH;
+ authScheme = NEGOTIATE;
doingNTLMp2ndStage = true;
- } else {
- schemeID = 0;
- }
+ }
+
if (realm == null)
realm = "";
- ret = AuthenticationInfo.getProxyAuth(host, port, realm, schemeID);
+ ret = AuthenticationInfo.getProxyAuth(host,
+ port,
+ realm,
+ authScheme);
if (ret == null) {
- if (schemeID == BasicAuthentication.BASIC_AUTH) {
+ switch (authScheme) {
+ case BASIC:
InetAddress addr = null;
try {
final String finalHost = host;
@@ -1818,9 +1838,9 @@ public class HttpURLConnection extends j
if (a != null) {
ret = new BasicAuthentication(true, host, port, realm, a);
}
- } else if (schemeID == DigestAuthentication.DIGEST_AUTH) {
- PasswordAuthentication a =
- privilegedRequestPasswordAuthentication(
+ break;
+ case DIGEST:
+ a = privilegedRequestPasswordAuthentication(
host, null, port, url.getProtocol(),
realm, scheme, url, RequestorType.PROXY);
if (a != null) {
@@ -1829,29 +1849,49 @@ public class HttpURLConnection extends j
ret = new DigestAuthentication(true, host, port, realm,
scheme, a, params);
}
- } else if (schemeID == NTLMAuthentication.NTLM_AUTH) {
- PasswordAuthentication a = null;
- if (!tryTransparentNTLMProxy) {
- a = privilegedRequestPasswordAuthentication(
- host, null, port, url.getProtocol(),
- "", scheme, url, RequestorType.PROXY);
- }
- /* If we are not trying transparent authentication then
- * we need to have a PasswordAuthentication instance. For
- * transparent authentication (Windows only) the username
- * and password will be picked up from the current logged
- * on users credentials.
- */
- if (tryTransparentNTLMProxy ||
- (!tryTransparentNTLMProxy && a != null)) {
- ret = new NTLMAuthentication(true, host, port, a);
- }
-
- tryTransparentNTLMProxy = false;
- } else if (schemeID == NegotiateAuthentication.NEGOTIATE_AUTH) {
+ break;
+ case NTLM:
+ if (NTLMAuthenticationProxy.proxy.supported) {
+ /* tryTransparentNTLMProxy will always be true the first
+ * time around, but verify that the platform supports it
+ * otherwise don't try. */
+ if (tryTransparentNTLMProxy) {
+ tryTransparentNTLMProxy =
+ NTLMAuthenticationProxy.proxy.supportsTransparentAuth;
+ }
+ a = null;
+ if (tryTransparentNTLMProxy) {
+ logger.finest("Trying Transparent NTLM authentication");
+ } else {
+ a = privilegedRequestPasswordAuthentication(
+ host, null, port, url.getProtocol(),
+ "", scheme, url, RequestorType.PROXY);
+ }
+ /* If we are not trying transparent authentication then
+ * we need to have a PasswordAuthentication instance. For
+ * transparent authentication (Windows only) the username
+ * and password will be picked up from the current logged
+ * on users credentials.
+ */
+ if (tryTransparentNTLMProxy ||
+ (!tryTransparentNTLMProxy && a != null)) {
+ ret = NTLMAuthenticationProxy.proxy.create(true, host, port, a);
+ }
+
+ /* set to false so that we do not try again */
+ tryTransparentNTLMProxy = false;
+ }
+ break;
+ case NEGOTIATE:
ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Negotiate"));
- } else if (schemeID == NegotiateAuthentication.KERBEROS_AUTH) {
+ break;
+ case KERBEROS:
ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Kerberos"));
+ break;
+ case UNKNOWN:
+ logger.finest("Unknown/Unsupported authentication scheme: " + scheme);
+ default:
+ throw new AssertionError("should not reach here");
}
}
// For backwards compatibility, we also try defaultAuth
@@ -1875,8 +1915,8 @@ public class HttpURLConnection extends j
}
}
}
- if (HttpCapture.isLoggable("FINER")) {
- HttpCapture.finer("Proxy Authentication for " + authhdr.toString() +" returned " + (ret != null ? ret.toString() : "null"));
+ if (logger.isLoggable(PlatformLogger.FINER)) {
+ logger.finer("Proxy Authentication for " + authhdr.toString() +" returned " + (ret != null ? ret.toString() : "null"));
}
return ret;
}
@@ -1896,27 +1936,26 @@ public class HttpURLConnection extends j
HeaderParser p = authhdr.headerParser();
String realm = p.findValue("realm");
String scheme = authhdr.scheme();
- char schemeID;
+ AuthScheme authScheme = UNKNOWN;
if ("basic".equalsIgnoreCase(scheme)) {
- schemeID = BasicAuthentication.BASIC_AUTH;
+ authScheme = BASIC;
} else if ("digest".equalsIgnoreCase(scheme)) {
- schemeID = DigestAuthentication.DIGEST_AUTH;
+ authScheme = DIGEST;
} else if ("ntlm".equalsIgnoreCase(scheme)) {
- schemeID = NTLMAuthentication.NTLM_AUTH;
+ authScheme = NTLM;
doingNTLM2ndStage = true;
} else if ("Kerberos".equalsIgnoreCase(scheme)) {
- schemeID = NegotiateAuthentication.KERBEROS_AUTH;
+ authScheme = KERBEROS;
doingNTLM2ndStage = true;
} else if ("Negotiate".equalsIgnoreCase(scheme)) {
- schemeID = NegotiateAuthentication.NEGOTIATE_AUTH;
+ authScheme = NEGOTIATE;
doingNTLM2ndStage = true;
- } else {
- schemeID = 0;
- }
+ }
+
domain = p.findValue ("domain");
if (realm == null)
realm = "";
- ret = AuthenticationInfo.getServerAuth(url, realm, schemeID);
+ ret = AuthenticationInfo.getServerAuth(url, realm, authScheme);
InetAddress addr = null;
if (ret == null) {
try {
@@ -1931,13 +1970,14 @@ public class HttpURLConnection extends j
port = url.getDefaultPort();
}
if (ret == null) {
- if (schemeID == NegotiateAuthentication.KERBEROS_AUTH) {
+ switch(authScheme) {
+ case KERBEROS:
ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Kerberos"));
- }
- if (schemeID == NegotiateAuthentication.NEGOTIATE_AUTH) {
+ break;
+ case NEGOTIATE:
ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Negotiate"));
- }
- if (schemeID == BasicAuthentication.BASIC_AUTH) {
+ break;
+ case BASIC:
PasswordAuthentication a =
privilegedRequestPasswordAuthentication(
url.getHost(), addr, port, url.getProtocol(),
@@ -1945,45 +1985,60 @@ public class HttpURLConnection extends j
if (a != null) {
ret = new BasicAuthentication(false, url, realm, a);
}
- }
-
- if (schemeID == DigestAuthentication.DIGEST_AUTH) {
- PasswordAuthentication a =
- privilegedRequestPasswordAuthentication(
+ break;
+ case DIGEST:
+ a = privilegedRequestPasswordAuthentication(
url.getHost(), addr, port, url.getProtocol(),
realm, scheme, url, RequestorType.SERVER);
if (a != null) {
digestparams = new DigestAuthentication.Parameters();
ret = new DigestAuthentication(false, url, realm, scheme, a, digestparams);
}
- }
-
- if (schemeID == NTLMAuthentication.NTLM_AUTH) {
- URL url1;
- try {
- url1 = new URL (url, "/"); /* truncate the path */
- } catch (Exception e) {
- url1 = url;
- }
- PasswordAuthentication a = null;
- if (!tryTransparentNTLMServer) {
- a = privilegedRequestPasswordAuthentication(
- url.getHost(), addr, port, url.getProtocol(),
- "", scheme, url, RequestorType.SERVER);
- }
-
- /* If we are not trying transparent authentication then
- * we need to have a PasswordAuthentication instance. For
- * transparent authentication (Windows only) the username
- * and password will be picked up from the current logged
- * on users credentials.
- */
- if (tryTransparentNTLMServer ||
- (!tryTransparentNTLMServer && a != null)) {
- ret = new NTLMAuthentication(false, url1, a);
- }
-
- tryTransparentNTLMServer = false;
+ break;
+ case NTLM:
+ if (NTLMAuthenticationProxy.proxy.supported) {
+ URL url1;
+ try {
+ url1 = new URL (url, "/"); /* truncate the path */
+ } catch (Exception e) {
+ url1 = url;
+ }
+
+ /* tryTransparentNTLMServer will always be true the first
+ * time around, but verify that the platform supports it
+ * otherwise don't try. */
+ if (tryTransparentNTLMServer) {
+ tryTransparentNTLMServer =
+ NTLMAuthenticationProxy.proxy.supportsTransparentAuth;
+ }
+ a = null;
+ if (tryTransparentNTLMServer) {
+ logger.finest("Trying Transparent NTLM authentication");
+ } else {
+ a = privilegedRequestPasswordAuthentication(
+ url.getHost(), addr, port, url.getProtocol(),
+ "", scheme, url, RequestorType.SERVER);
+ }
+
+ /* If we are not trying transparent authentication then
+ * we need to have a PasswordAuthentication instance. For
+ * transparent authentication (Windows only) the username
+ * and password will be picked up from the current logged
+ * on users credentials.
+ */
+ if (tryTransparentNTLMServer ||
+ (!tryTransparentNTLMServer && a != null)) {
+ ret = NTLMAuthenticationProxy.proxy.create(false, url1, a);
+ }
+
+ /* set to false so that we do not try again */
+ tryTransparentNTLMServer = false;
+ }
+ break;
+ case UNKNOWN:
+ logger.finest("Unknown/Unsupported authentication scheme: " + scheme);
+ default:
+ throw new AssertionError("should not reach here");
}
}
@@ -2005,8 +2060,8 @@ public class HttpURLConnection extends j
}
}
}
- if (HttpCapture.isLoggable("FINER")) {
- HttpCapture.finer("Server Authentication for " + authhdr.toString() +" returned " + (ret != null ? ret.toString() : "null"));
+ if (logger.isLoggable(PlatformLogger.FINER)) {
+ logger.finer("Server Authentication for " + authhdr.toString() +" returned " + (ret != null ? ret.toString() : "null"));
}
return ret;
}
@@ -2081,8 +2136,8 @@ public class HttpURLConnection extends j
if (streaming()) {
throw new HttpRetryException (RETRY_MSG3, stat, loc);
}
- if (HttpCapture.isLoggable("FINE")) {
- HttpCapture.fine("Redirected from " + url + " to " + locUrl);
+ if (logger.isLoggable(PlatformLogger.FINE)) {
+ logger.fine("Redirected from " + url + " to " + locUrl);
}
// clear out old response headers!!!!
--- a/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java Tue Sep 29 15:31:18 2009 -0700
@@ -30,11 +30,14 @@ import sun.net.www.HeaderParser;
import sun.net.www.HeaderParser;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
+import sun.util.logging.PlatformLogger;
import java.net.URL;
import java.io.IOException;
import java.net.Authenticator.RequestorType;
-
+import java.lang.reflect.Constructor;
+import static sun.net.www.protocol.http.AuthScheme.NEGOTIATE;
+import static sun.net.www.protocol.http.AuthScheme.KERBEROS;
/**
* NegotiateAuthentication:
@@ -48,9 +51,6 @@ class NegotiateAuthentication extends Au
private static final long serialVersionUID = 100L;
final private HttpCallerInfo hci;
-
- static final char NEGOTIATE_AUTH = 'S';
- static final char KERBEROS_AUTH = 'K';
// These maps are used to manage the GSS availability for diffrent
// hosts. The key for both maps is the host name.
@@ -68,11 +68,10 @@ class NegotiateAuthentication extends Au
* @param hci a schemed object.
*/
public NegotiateAuthentication(HttpCallerInfo hci) {
- super(RequestorType.PROXY==hci.authType?
- PROXY_AUTHENTICATION:SERVER_AUTHENTICATION,
- hci.scheme.equalsIgnoreCase("Negotiate")?
- NEGOTIATE_AUTH:KERBEROS_AUTH,
- hci.url, "");
+ super(RequestorType.PROXY==hci.authType ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
+ hci.scheme.equalsIgnoreCase("Negotiate") ? NEGOTIATE : KERBEROS,
+ hci.url,
+ "");
this.hci = hci;
}
@@ -249,13 +248,41 @@ abstract class Negotiator {
// The current implementation will make sure NegotiatorImpl is not
// directly referenced when compiling, thus smooth the way of building
// the J2SE platform where HttpURLConnection is a bootstrap class.
-
- Class clazz = Class.forName("sun.net.www.protocol.http.NegotiatorImpl");
- java.lang.reflect.Constructor c = clazz.getConstructor(HttpCallerInfo.class);
- return (Negotiator) (c.newInstance(hci));
+ //
+ // Makes NegotiatorImpl, and the security classes it references, a
+ // runtime dependency rather than a static one.
+
+ Class clazz;
+ Constructor c;
+ try {
+ clazz = Class.forName("sun.net.www.protocol.http.NegotiatorImpl", true, null);
+ c = clazz.getConstructor(HttpCallerInfo.class);
+ } catch (ClassNotFoundException cnfe) {
+ finest(cnfe);
+ throw cnfe;
+ } catch (ReflectiveOperationException roe) {
+ // if the class is there then something seriously wrong if
+ // the constructor is not.
+ throw new AssertionError(roe);
+ }
+
+ try {
+ return (Negotiator) (c.newInstance(hci));
+ } catch (ReflectiveOperationException roe) {
+ finest(roe);
+ Throwable t = roe.getCause();
+ if (t != null && t instanceof Exception)
+ finest((Exception)t);
+ throw roe;
+ }
}
abstract byte[] firstToken() throws IOException;
abstract byte[] nextToken(byte[] in) throws IOException;
+
+ static void finest(Exception e) {
+ PlatformLogger logger = HttpURLConnection.getHttpLogger();
+ logger.finest("NegotiateAuthentication: " + e);
+ }
}
--- a/src/share/classes/sun/security/ec/ECDHKeyAgreement.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/ec/ECDHKeyAgreement.java Tue Sep 29 15:31:18 2009 -0700
@@ -39,21 +39,6 @@ import javax.crypto.spec.*;
*/
public final class ECDHKeyAgreement extends KeyAgreementSpi {
- // flag indicating whether the native ECC implementation is present
- private static boolean implementationPresent = true;
- static {
- try {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("sunecc");
- return null;
- }
- });
- } catch (UnsatisfiedLinkError e) {
- implementationPresent = false;
- }
- }
-
// private key, if initialized
private ECPrivateKey privateKey;
@@ -65,16 +50,12 @@ public final class ECDHKeyAgreement exte
/**
* Constructs a new ECDHKeyAgreement.
- *
- * @exception ProviderException if the native ECC library is unavailable.
*/
public ECDHKeyAgreement() {
- if (!implementationPresent) {
- throw new ProviderException("ECDH implementation is not available");
- }
}
// see JCE spec
+ @Override
protected void engineInit(Key key, SecureRandom random)
throws InvalidKeyException {
if (!(key instanceof PrivateKey)) {
@@ -86,6 +67,7 @@ public final class ECDHKeyAgreement exte
}
// see JCE spec
+ @Override
protected void engineInit(Key key, AlgorithmParameterSpec params,
SecureRandom random) throws InvalidKeyException,
InvalidAlgorithmParameterException {
@@ -97,6 +79,7 @@ public final class ECDHKeyAgreement exte
}
// see JCE spec
+ @Override
protected Key engineDoPhase(Key key, boolean lastPhase)
throws InvalidKeyException, IllegalStateException {
if (privateKey == null) {
@@ -130,6 +113,7 @@ public final class ECDHKeyAgreement exte
}
// see JCE spec
+ @Override
protected byte[] engineGenerateSecret() throws IllegalStateException {
if ((privateKey == null) || (publicValue == null)) {
throw new IllegalStateException("Not initialized correctly");
@@ -150,6 +134,7 @@ public final class ECDHKeyAgreement exte
}
// see JCE spec
+ @Override
protected int engineGenerateSecret(byte[] sharedSecret, int
offset) throws IllegalStateException, ShortBufferException {
if (offset + secretLen > sharedSecret.length) {
@@ -162,6 +147,7 @@ public final class ECDHKeyAgreement exte
}
// see JCE spec
+ @Override
protected SecretKey engineGenerateSecret(String algorithm)
throws IllegalStateException, NoSuchAlgorithmException,
InvalidKeyException {
--- a/src/share/classes/sun/security/ec/ECDSASignature.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/ec/ECDSASignature.java Tue Sep 29 15:31:18 2009 -0700
@@ -52,21 +52,6 @@ import sun.security.x509.AlgorithmId;
*/
abstract class ECDSASignature extends SignatureSpi {
- // flag indicating whether the native ECC implementation is present
- private static boolean implementationPresent = true;
- static {
- try {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("sunecc");
- return null;
- }
- });
- } catch (UnsatisfiedLinkError e) {
- implementationPresent = false;
- }
- }
-
// message digest implementation we use
private final MessageDigest messageDigest;
@@ -88,24 +73,13 @@ abstract class ECDSASignature extends Si
* @exception ProviderException if the native ECC library is unavailable.
*/
ECDSASignature() {
- if (!implementationPresent) {
- throw new
- ProviderException("ECDSA implementation is not available");
- }
messageDigest = null;
}
/**
* Constructs a new ECDSASignature. Used by subclasses.
- *
- * @exception ProviderException if the native ECC library is unavailable.
*/
ECDSASignature(String digestName) {
- if (!implementationPresent) {
- throw new
- ProviderException("ECDSA implementation is not available");
- }
-
try {
messageDigest = MessageDigest.getInstance(digestName);
} catch (NoSuchAlgorithmException e) {
@@ -299,8 +273,8 @@ abstract class ECDSASignature extends Si
byte[] encodedParams = ECParameters.encodeParameters(params); // DER OID
int keySize = params.getCurve().getField().getFieldSize();
- // seed is twice the key size (in bytes)
- byte[] seed = new byte[((keySize + 7) >> 3) * 2];
+ // seed is twice the key size (in bytes) plus 1
+ byte[] seed = new byte[(((keySize + 7) >> 3) + 1) * 2];
if (random == null) {
random = JCAUtil.getSecureRandom();
}
@@ -356,6 +330,7 @@ abstract class ECDSASignature extends Si
// Convert the concatenation of R and S into their DER encoding
private byte[] encodeSignature(byte[] signature) throws SignatureException {
+
try {
int n = signature.length >> 1;
--- a/src/share/classes/sun/security/ec/ECKeyPairGenerator.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/ec/ECKeyPairGenerator.java Tue Sep 29 15:31:18 2009 -0700
@@ -46,20 +46,6 @@ import sun.security.jca.JCAUtil;
*/
public final class ECKeyPairGenerator extends KeyPairGeneratorSpi {
- // flag indicating whether the native ECC implementation is present
- private static boolean implementationPresent = true;
- static {
- try {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("sunecc");
- return null;
- }
- });
- } catch (UnsatisfiedLinkError e) {
- implementationPresent = false;
- }
- }
private static final int KEY_SIZE_MIN = 112; // min bits (see ecc_impl.h)
private static final int KEY_SIZE_MAX = 571; // max bits (see ecc_impl.h)
private static final int KEY_SIZE_DEFAULT = 256;
@@ -75,13 +61,8 @@ public final class ECKeyPairGenerator ex
/**
* Constructs a new ECKeyPairGenerator.
- *
- * @exception ProviderException if the native ECC library is unavailable.
*/
public ECKeyPairGenerator() {
- if (!implementationPresent) {
- throw new ProviderException("EC implementation is not available");
- }
// initialize to default in case the app does not call initialize()
initialize(KEY_SIZE_DEFAULT, null);
}
@@ -133,8 +114,8 @@ public final class ECKeyPairGenerator ex
byte[] encodedParams =
ECParameters.encodeParameters((ECParameterSpec)params);
- // seed is twice the key size (in bytes)
- byte[] seed = new byte[2 * ((keySize + 7) >> 3)];
+ // seed is twice the key size (in bytes) plus 1
+ byte[] seed = new byte[(((keySize + 7) >> 3) + 1) * 2];
if (random == null) {
random = JCAUtil.getSecureRandom();
}
--- a/src/share/classes/sun/security/ec/SunEC.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/ec/SunEC.java Tue Sep 29 15:31:18 2009 -0700
@@ -39,13 +39,32 @@ import sun.security.action.PutAllAction;
* via JNI to a C++ wrapper class which in turn calls C functions.
* The Java classes are packaged into the signed sunec.jar in the JRE
* extensions directory and the C++ and C functions are packaged into
- * libsunecc.so or sunecc.dll in the JRE native libraries directory.
+ * libsunec.so or sunec.dll in the JRE native libraries directory.
+ * If the native library is not present then this provider is registered
+ * with support for fewer ECC algorithms (KeyPairGenerator, Signature and
+ * KeyAgreement are omitted).
*
* @since 1.7
*/
public final class SunEC extends Provider {
private static final long serialVersionUID = -2279741672933606418L;
+
+ // flag indicating whether the full EC implementation is present
+ // (when native library is absent then fewer EC algorithms are available)
+ private static boolean useFullImplementation = true;
+ static {
+ try {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("sunec"); // check for native library
+ return null;
+ }
+ });
+ } catch (UnsatisfiedLinkError e) {
+ useFullImplementation = false;
+ }
+ }
public SunEC() {
super("SunEC", 1.7d, "Sun Elliptic Curve provider (EC, ECDSA, ECDH)");
@@ -54,10 +73,10 @@ public final class SunEC extends Provide
// the provider. Otherwise, create a temporary map and use a
// doPrivileged() call at the end to transfer the contents
if (System.getSecurityManager() == null) {
- SunECEntries.putEntries(this);
+ SunECEntries.putEntries(this, useFullImplementation);
} else {
Map<Object, Object> map = new HashMap<Object, Object>();
- SunECEntries.putEntries(map);
+ SunECEntries.putEntries(map, useFullImplementation);
AccessController.doPrivileged(new PutAllAction(this, map));
}
}
--- a/src/share/classes/sun/security/ec/SunECEntries.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/ec/SunECEntries.java Tue Sep 29 15:31:18 2009 -0700
@@ -38,7 +38,93 @@ final class SunECEntries {
// empty
}
- static void putEntries(Map<Object, Object> map) {
+ static void putEntries(Map<Object, Object> map,
+ boolean useFullImplementation) {
+
+ /*
+ * Key Factory engine
+ */
+ map.put("KeyFactory.EC", "sun.security.ec.ECKeyFactory");
+ map.put("Alg.Alias.KeyFactory.EllipticCurve", "EC");
+
+ map.put("KeyFactory.EC ImplementedIn", "Software");
+
+ /*
+ * Algorithm Parameter engine
+ */
+ map.put("AlgorithmParameters.EC", "sun.security.ec.ECParameters");
+ map.put("Alg.Alias.AlgorithmParameters.EllipticCurve", "EC");
+
+ map.put("AlgorithmParameters.EC KeySize", "256");
+
+ map.put("AlgorithmParameters.EC ImplementedIn", "Software");
+
+ map.put("AlgorithmParameters.EC SupportedCurves",
+
+ // A list comprising lists of curve names and object identifiers.
+ // '[' ( <curve-name> ',' )+ <curve-object-identifier> ']' '|'
+
+ // SEC 2 prime curves
+ "[secp112r1,1.3.132.0.6]|" +
+ "[secp112r2,1.3.132.0.7]|" +
+ "[secp128r1,1.3.132.0.28]|" +
+ "[secp128r2,1.3.132.0.29]|" +
+ "[secp160k1,1.3.132.0.9]|" +
+ "[secp160r1,1.3.132.0.8]|" +
+ "[secp160r2,1.3.132.0.30]|" +
+ "[secp192k1,1.3.132.0.31]|" +
+ "[secp192r1,NIST P-192,X9.62 prime192v1,1.2.840.10045.3.1.1]|" +
+ "[secp224k1,1.3.132.0.32]|" +
+ "[secp224r1,NIST P-224,1.3.132.0.33]|" +
+ "[secp256k1,1.3.132.0.10]|" +
+ "[secp256r1,NIST P-256,X9.62 prime256v1,1.2.840.10045.3.1.7]|" +
+ "[secp384r1,NIST P-384,1.3.132.0.34]|" +
+ "[secp521r1,NIST P-521,1.3.132.0.35]|" +
+
+ // ANSI X9.62 prime curves
+ "[X9.62 prime192v2,1.2.840.10045.3.1.2]|" +
+ "[X9.62 prime192v3,1.2.840.10045.3.1.3]|" +
+ "[X9.62 prime239v1,1.2.840.10045.3.1.4]|" +
+ "[X9.62 prime239v2,1.2.840.10045.3.1.5]|" +
+ "[X9.62 prime239v3,1.2.840.10045.3.1.6]|" +
+
+ // SEC 2 binary curves
+ "[sect113r1,1.3.132.0.4]|" +
+ "[sect113r2,1.3.132.0.5]|" +
+ "[sect131r1,1.3.132.0.22]|" +
+ "[sect131r2,1.3.132.0.23]|" +
+ "[sect163k1,NIST K-163,1.3.132.0.1]|" +
+ "[sect163r1,1.3.132.0.2]|" +
+ "[sect163r2,NIST B-163,1.3.132.0.15]|" +
+ "[sect193r1,1.3.132.0.24]|" +
+ "[sect193r2,1.3.132.0.25]|" +
+ "[sect233k1,NIST K-233,1.3.132.0.26]|" +
+ "[sect233r1,NIST B-233,1.3.132.0.27]|" +
+ "[sect239k1,1.3.132.0.3]|" +
+ "[sect283k1,NIST K-283,1.3.132.0.16]|" +
+ "[sect283r1,NIST B-283,1.3.132.0.17]|" +
+ "[sect409k1,NIST K-409,1.3.132.0.36]|" +
+ "[sect409r1,NIST B-409,1.3.132.0.37]|" +
+ "[sect571k1,NIST K-571,1.3.132.0.38]|" +
+ "[sect571r1,NIST B-571,1.3.132.0.39]|" +
+
+ // ANSI X9.62 binary curves
+ "[X9.62 c2tnb191v1,1.2.840.10045.3.0.5]|" +
+ "[X9.62 c2tnb191v2,1.2.840.10045.3.0.6]|" +
+ "[X9.62 c2tnb191v3,1.2.840.10045.3.0.7]|" +
+ "[X9.62 c2tnb239v1,1.2.840.10045.3.0.11]|" +
+ "[X9.62 c2tnb239v2,1.2.840.10045.3.0.12]|" +
+ "[X9.62 c2tnb239v3,1.2.840.10045.3.0.13]|" +
+ "[X9.62 c2tnb359v1,1.2.840.10045.3.0.18]|" +
+ "[X9.62 c2tnb431r1,1.2.840.10045.3.0.20]");
+
+ /*
+ * Register the algorithms below only when the full ECC implementation
+ * is available
+ */
+ if (!useFullImplementation) {
+ return;
+ }
/*
* Signature engines
@@ -62,48 +148,31 @@ final class SunECEntries {
map.put("Signature.SHA384withECDSA SupportedKeyClasses", ecKeyClasses);
map.put("Signature.SHA512withECDSA SupportedKeyClasses", ecKeyClasses);
+ map.put("Signature.SHA1withECDSA KeySize", "256");
+
+ map.put("Signature.NONEwithECDSA ImplementedIn", "Software");
+ map.put("Signature.SHA1withECDSA ImplementedIn", "Software");
+ map.put("Signature.SHA256withECDSA ImplementedIn", "Software");
+ map.put("Signature.SHA384withECDSA ImplementedIn", "Software");
+ map.put("Signature.SHA512withECDSA ImplementedIn", "Software");
+
/*
* Key Pair Generator engine
*/
map.put("KeyPairGenerator.EC", "sun.security.ec.ECKeyPairGenerator");
map.put("Alg.Alias.KeyPairGenerator.EllipticCurve", "EC");
- /*
- * Key Factory engine
- */
- map.put("KeyFactory.EC", "sun.security.ec.ECKeyFactory");
- map.put("Alg.Alias.KeyFactory.EllipticCurve", "EC");
+ map.put("KeyPairGenerator.EC KeySize", "256");
- /*
- * Algorithm Parameter engine
- */
- map.put("AlgorithmParameters.EC", "sun.security.ec.ECParameters");
- map.put("Alg.Alias.AlgorithmParameters.EllipticCurve", "EC");
+ map.put("KeyPairGenerator.EC ImplementedIn", "Software");
/*
* Key Agreement engine
*/
map.put("KeyAgreement.ECDH", "sun.security.ec.ECDHKeyAgreement");
+
map.put("KeyAgreement.ECDH SupportedKeyClasses", ecKeyClasses);
- /*
- * Key sizes
- */
- map.put("Signature.SHA1withECDSA KeySize", "256");
- map.put("KeyPairGenerator.EC KeySize", "256");
- map.put("AlgorithmParameterGenerator.ECDSA KeySize", "256");
-
- /*
- * Implementation type: software or hardware
- */
- map.put("Signature.NONEwithECDSA ImplementedIn", "Software");
- map.put("Signature.SHA1withECDSA ImplementedIn", "Software");
- map.put("Signature.SHA256withECDSA ImplementedIn", "Software");
- map.put("Signature.SHA384withECDSA ImplementedIn", "Software");
- map.put("Signature.SHA512withECDSA ImplementedIn", "Software");
- map.put("KeyPairGenerator.EC ImplementedIn", "Software");
- map.put("KeyFactory.EC ImplementedIn", "Software");
map.put("KeyAgreement.ECDH ImplementedIn", "Software");
- map.put("AlgorithmParameters.EC ImplementedIn", "Software");
}
}
--- a/src/share/classes/sun/security/krb5/KrbKdcReq.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/krb5/KrbKdcReq.java Tue Sep 29 15:31:18 2009 -0700
@@ -1,5 +1,5 @@
/*
- * Portions Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Portions Copyright 2000-2009 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
@@ -149,6 +149,11 @@ public abstract class KrbKdcReq {
send(realm,tempKdc,useTCP);
break;
} catch (Exception e) {
+ if (DEBUG) {
+ System.out.println(">>> KrbKdcReq send: error trying " +
+ tempKdc);
+ e.printStackTrace(System.out);
+ }
savedException = e;
}
}
@@ -179,10 +184,36 @@ public abstract class KrbKdcReq {
/*
* Get port number for this KDC.
*/
- StringTokenizer strTok = new StringTokenizer(tempKdc, ":");
- String kdc = strTok.nextToken();
- if (strTok.hasMoreTokens()) {
- String portStr = strTok.nextToken();
+ String kdc = null;
+ String portStr = null;
+
+ if (tempKdc.charAt(0) == '[') { // Explicit IPv6 in []
+ int pos = tempKdc.indexOf(']', 1);
+ if (pos == -1) {
+ throw new IOException("Illegal KDC: " + tempKdc);
+ }
+ kdc = tempKdc.substring(1, pos);
+ if (pos != tempKdc.length() - 1) { // with port number
+ if (tempKdc.charAt(pos+1) != ':') {
+ throw new IOException("Illegal KDC: " + tempKdc);
+ }
+ portStr = tempKdc.substring(pos+2);
+ }
+ } else {
+ int colon = tempKdc.indexOf(':');
+ if (colon == -1) { // Hostname or IPv4 host only
+ kdc = tempKdc;
+ } else {
+ int nextColon = tempKdc.indexOf(':', colon+1);
+ if (nextColon > 0) { // >=2 ":", IPv6 with no port
+ kdc = tempKdc;
+ } else { // 1 ":", hostname or IPv4 with port
+ kdc = tempKdc.substring(0, colon);
+ portStr = tempKdc.substring(colon+1);
+ }
+ }
+ }
+ if (portStr != null) {
int tempPort = parsePositiveIntString(portStr);
if (tempPort > 0)
port = tempPort;
--- a/src/share/classes/sun/security/provider/certpath/Builder.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/provider/certpath/Builder.java Tue Sep 29 15:31:18 2009 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2009 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,12 +26,14 @@ package sun.security.provider.certpath;
package sun.security.provider.certpath;
import java.io.IOException;
+import java.security.AccessController;
import java.security.GeneralSecurityException;
import java.security.cert.*;
import java.util.*;
import javax.security.auth.x500.X500Principal;
+import sun.security.action.GetBooleanAction;
import sun.security.util.Debug;
import sun.security.x509.GeneralNames;
import sun.security.x509.GeneralNameInterface;
@@ -64,9 +66,8 @@ public abstract class Builder {
* Authority Information Access extension shall be enabled. Currently
* disabled by default for compatibility reasons.
*/
- final static boolean USE_AIA =
- DistributionPointFetcher.getBooleanProperty
- ("com.sun.security.enableAIAcaIssuers", false);
+ final static boolean USE_AIA = AccessController.doPrivileged
+ (new GetBooleanAction("com.sun.security.enableAIAcaIssuers"));
/**
* Initialize the builder with the input parameters.
--- a/src/share/classes/sun/security/provider/certpath/CertId.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/provider/certpath/CertId.java Tue Sep 29 15:31:18 2009 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2009 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,9 +25,11 @@
package sun.security.provider.certpath;
-import java.io.*;
+import java.io.IOException;
import java.math.BigInteger;
import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
import java.util.Arrays;
import sun.misc.HexDumpEncoder;
import sun.security.x509.*;
@@ -54,21 +56,28 @@ public class CertId {
public class CertId {
private static final boolean debug = false;
- private AlgorithmId hashAlgId;
- private byte[] issuerNameHash;
- private byte[] issuerKeyHash;
- private SerialNumber certSerialNumber;
+ private static final AlgorithmId SHA1_ALGID
+ = new AlgorithmId(AlgorithmId.SHA_oid);
+ private final AlgorithmId hashAlgId;
+ private final byte[] issuerNameHash;
+ private final byte[] issuerKeyHash;
+ private final SerialNumber certSerialNumber;
private int myhash = -1; // hashcode for this CertId
/**
* Creates a CertId. The hash algorithm used is SHA-1.
*/
- public CertId(X509CertImpl issuerCert, SerialNumber serialNumber)
- throws Exception {
+ public CertId(X509Certificate issuerCert, SerialNumber serialNumber)
+ throws IOException {
// compute issuerNameHash
- MessageDigest md = MessageDigest.getInstance("SHA1");
- hashAlgId = AlgorithmId.get("SHA1");
+ MessageDigest md = null;
+ try {
+ md = MessageDigest.getInstance("SHA1");
+ } catch (NoSuchAlgorithmException nsae) {
+ throw new IOException("Unable to create CertId", nsae);
+ }
+ hashAlgId = SHA1_ALGID;
md.update(issuerCert.getSubjectX500Principal().getEncoded());
issuerNameHash = md.digest();
@@ -90,6 +99,7 @@ public class CertId {
encoder.encode(issuerNameHash));
System.out.println("issuerKeyHash is " +
encoder.encode(issuerKeyHash));
+ System.out.println("SerialNumber is " + serialNumber.getNumber());
}
}
@@ -97,7 +107,6 @@ public class CertId {
* Creates a CertId from its ASN.1 DER encoding.
*/
public CertId(DerInputStream derIn) throws IOException {
-
hashAlgId = AlgorithmId.parse(derIn.getDerValue());
issuerNameHash = derIn.getOctetString();
issuerKeyHash = derIn.getOctetString();
@@ -157,7 +166,7 @@ public class CertId {
*
* @return the hashcode value.
*/
- public int hashCode() {
+ @Override public int hashCode() {
if (myhash == -1) {
myhash = hashAlgId.hashCode();
for (int i = 0; i < issuerNameHash.length; i++) {
@@ -180,8 +189,7 @@ public class CertId {
* @param other the object to test for equality with this object.
* @return true if the objects are considered equal, false otherwise.
*/
- public boolean equals(Object other) {
-
+ @Override public boolean equals(Object other) {
if (this == other) {
return true;
}
@@ -203,7 +211,7 @@ public class CertId {
/**
* Create a string representation of the CertId.
*/
- public String toString() {
+ @Override public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("CertId \n");
sb.append("Algorithm: " + hashAlgId.toString() +"\n");
--- a/src/share/classes/sun/security/provider/certpath/CrlRevocationChecker.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/provider/certpath/CrlRevocationChecker.java Tue Sep 29 15:31:18 2009 -0700
@@ -80,6 +80,7 @@ class CrlRevocationChecker extends PKIXC
{ false, false, false, false, false, false, true };
private static final boolean[] ALL_REASONS =
{true, true, true, true, true, true, true, true, true};
+ private boolean mOnlyEECert = false;
// Maximum clock skew in milliseconds (15 minutes) allowed when checking
// validity of CRLs
@@ -114,6 +115,12 @@ class CrlRevocationChecker extends PKIXC
CrlRevocationChecker(TrustAnchor anchor, PKIXParameters params,
Collection<X509Certificate> certs) throws CertPathValidatorException
{
+ this(anchor, params, certs, false);
+ }
+
+ CrlRevocationChecker(TrustAnchor anchor, PKIXParameters params,
+ Collection<X509Certificate> certs, boolean onlyEECert)
+ throws CertPathValidatorException {
mAnchor = anchor;
mParams = params;
mStores = new ArrayList<CertStore>(params.getCertStores());
@@ -133,6 +140,7 @@ class CrlRevocationChecker extends PKIXC
}
Date testDate = params.getDate();
mCurrentTime = (testDate != null ? testDate : new Date());
+ mOnlyEECert = onlyEECert;
init(false);
}
@@ -262,6 +270,13 @@ class CrlRevocationChecker extends PKIXC
if (debug != null) {
debug.println("CrlRevocationChecker.verifyRevocationStatus()" +
" ---checking " + msg + "...");
+ }
+
+ if (mOnlyEECert && currCert.getBasicConstraints() != -1) {
+ if (debug != null) {
+ debug.println("Skipping revocation check, not end entity cert");
+ }
+ return;
}
// reject circular dependencies - RFC 3280 is not explicit on how
--- a/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Tue Sep 29 15:31:18 2009 -0700
@@ -32,7 +32,7 @@ import java.security.cert.*;
import java.security.cert.*;
import javax.security.auth.x500.X500Principal;
-import sun.security.action.GetPropertyAction;
+import sun.security.action.GetBooleanAction;
import sun.security.util.Debug;
import sun.security.util.DerOutputStream;
import sun.security.x509.*;
@@ -62,28 +62,8 @@ class DistributionPointFetcher {
* extension shall be enabled. Currently disabled by default for
* compatibility and legal reasons.
*/
- private final static boolean USE_CRLDP =
- getBooleanProperty("com.sun.security.enableCRLDP", false);
-
- /**
- * Return the value of the boolean System property propName.
- */
- public static boolean getBooleanProperty(String propName,
- boolean defaultValue) {
- // if set, require value of either true or false
- String b = AccessController.doPrivileged(
- new GetPropertyAction(propName));
- if (b == null) {
- return defaultValue;
- } else if (b.equalsIgnoreCase("false")) {
- return false;
- } else if (b.equalsIgnoreCase("true")) {
- return true;
- } else {
- throw new RuntimeException("Value of " + propName
- + " must either be 'true' or 'false'");
- }
- }
+ private final static boolean USE_CRLDP = AccessController.doPrivileged
+ (new GetBooleanAction("com.sun.security.enableCRLDP"));
// singleton instance
private static final DistributionPointFetcher INSTANCE =
--- a/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java Tue Sep 29 15:31:18 2009 -0700
@@ -82,6 +82,7 @@ class ForwardBuilder extends Builder {
TrustAnchor trustAnchor;
private Comparator<X509Certificate> comparator;
private boolean searchAllCertStores = true;
+ private boolean onlyEECert = false;
/**
* Initialize the builder with the input parameters.
@@ -89,7 +90,8 @@ class ForwardBuilder extends Builder {
* @param params the parameter set used to build a certification path
*/
ForwardBuilder(PKIXBuilderParameters buildParams,
- X500Principal targetSubjectDN, boolean searchAllCertStores)
+ X500Principal targetSubjectDN, boolean searchAllCertStores,
+ boolean onlyEECert)
{
super(buildParams, targetSubjectDN);
@@ -108,6 +110,7 @@ class ForwardBuilder extends Builder {
}
comparator = new PKIXCertComparator(trustedSubjectDNs);
this.searchAllCertStores = searchAllCertStores;
+ this.onlyEECert = onlyEECert;
}
/**
@@ -875,8 +878,8 @@ class ForwardBuilder extends Builder {
/* Check revocation if it is enabled */
if (buildParams.isRevocationEnabled()) {
try {
- CrlRevocationChecker crlChecker =
- new CrlRevocationChecker(anchor, buildParams);
+ CrlRevocationChecker crlChecker = new CrlRevocationChecker
+ (anchor, buildParams, null, onlyEECert);
crlChecker.check(cert, anchor.getCAPublicKey(), true);
} catch (CertPathValidatorException cpve) {
if (debug != null) {
--- a/src/share/classes/sun/security/provider/certpath/OCSPChecker.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/provider/certpath/OCSPChecker.java Tue Sep 29 15:31:18 2009 -0700
@@ -25,19 +25,20 @@
package sun.security.provider.certpath;
-import java.io.*;
+import java.io.IOException;
import java.math.BigInteger;
import java.util.*;
import java.security.AccessController;
-import java.security.Principal;
import java.security.PrivilegedAction;
import java.security.Security;
import java.security.cert.*;
import java.security.cert.CertPathValidatorException.BasicReason;
-import java.net.*;
+import java.net.URI;
+import java.net.URISyntaxException;
import javax.security.auth.x500.X500Principal;
-import sun.security.util.*;
+import static sun.security.provider.certpath.OCSP.*;
+import sun.security.util.Debug;
import sun.security.x509.*;
/**
@@ -50,27 +51,18 @@ import sun.security.x509.*;
*/
class OCSPChecker extends PKIXCertPathChecker {
- public static final String OCSP_ENABLE_PROP = "ocsp.enable";
- public static final String OCSP_URL_PROP = "ocsp.responderURL";
- public static final String OCSP_CERT_SUBJECT_PROP =
+ static final String OCSP_ENABLE_PROP = "ocsp.enable";
+ static final String OCSP_URL_PROP = "ocsp.responderURL";
+ static final String OCSP_CERT_SUBJECT_PROP =
"ocsp.responderCertSubjectName";
- public static final String OCSP_CERT_ISSUER_PROP =
- "ocsp.responderCertIssuerName";
- public static final String OCSP_CERT_NUMBER_PROP =
+ static final String OCSP_CERT_ISSUER_PROP = "ocsp.responderCertIssuerName";
+ static final String OCSP_CERT_NUMBER_PROP =
"ocsp.responderCertSerialNumber";
private static final String HEX_DIGITS = "0123456789ABCDEFabcdef";
private static final Debug DEBUG = Debug.getInstance("certpath");
private static final boolean dump = false;
- // Supported extensions
- private static final int OCSP_NONCE_DATA[] =
- { 1, 3, 6, 1, 5, 5, 7, 48, 1, 2 };
- private static final ObjectIdentifier OCSP_NONCE_OID;
- static {
- OCSP_NONCE_OID = ObjectIdentifier.newInternal(OCSP_NONCE_DATA);
- }
-
private int remainingCerts;
private X509Certificate[] certs;
@@ -78,20 +70,27 @@ class OCSPChecker extends PKIXCertPathCh
private CertPath cp;
private PKIXParameters pkixParams;
+
+ private boolean onlyEECert = false;
/**
* Default Constructor
*
* @param certPath the X509 certification path
* @param pkixParams the input PKIX parameter set
- * @exception CertPathValidatorException Exception thrown if cert path
- * does not validate.
+ * @throws CertPathValidatorException if OCSPChecker can not be created
*/
OCSPChecker(CertPath certPath, PKIXParameters pkixParams)
throws CertPathValidatorException {
+ this(certPath, pkixParams, false);
+ }
+
+ OCSPChecker(CertPath certPath, PKIXParameters pkixParams, boolean onlyEECert)
+ throws CertPathValidatorException {
this.cp = certPath;
this.pkixParams = pkixParams;
+ this.onlyEECert = onlyEECert;
List<? extends Certificate> tmp = cp.getCertificates();
certs = tmp.toArray(new X509Certificate[tmp.size()]);
init(false);
@@ -101,6 +100,7 @@ class OCSPChecker extends PKIXCertPathCh
* Initializes the internal state of the checker from parameters
* specified in the constructor
*/
+ @Override
public void init(boolean forward) throws CertPathValidatorException {
if (!forward) {
remainingCerts = certs.length + 1;
@@ -110,11 +110,11 @@ class OCSPChecker extends PKIXCertPathCh
}
}
- public boolean isForwardCheckingSupported() {
+ @Override public boolean isForwardCheckingSupported() {
return false;
}
- public Set<String> getSupportedExtensions() {
+ @Override public Set<String> getSupportedExtensions() {
return Collections.<String>emptySet();
}
@@ -127,300 +127,233 @@ class OCSPChecker extends PKIXCertPathCh
* @exception CertPathValidatorException Exception is thrown if the
* certificate has been revoked.
*/
+ @Override
public void check(Certificate cert, Collection<String> unresolvedCritExts)
throws CertPathValidatorException {
- InputStream in = null;
- OutputStream out = null;
-
// Decrement the certificate counter
remainingCerts--;
+ X509CertImpl currCertImpl = null;
try {
- X509Certificate responderCert = null;
- boolean seekResponderCert = false;
- X500Principal responderSubjectName = null;
- X500Principal responderIssuerName = null;
- BigInteger responderSerialNumber = null;
-
- boolean seekIssuerCert = true;
- X509CertImpl issuerCertImpl = null;
- X509CertImpl currCertImpl =
- X509CertImpl.toImpl((X509Certificate)cert);
-
- /*
- * OCSP security property values, in the following order:
- * 1. ocsp.responderURL
- * 2. ocsp.responderCertSubjectName
- * 3. ocsp.responderCertIssuerName
- * 4. ocsp.responderCertSerialNumber
- */
- String[] properties = getOCSPProperties();
-
- // Check whether OCSP is feasible before seeking cert information
- URL url = getOCSPServerURL(currCertImpl, properties);
-
- // When responder's subject name is set then the issuer/serial
- // properties are ignored
- if (properties[1] != null) {
- responderSubjectName = new X500Principal(properties[1]);
-
- } else if (properties[2] != null && properties[3] != null) {
- responderIssuerName = new X500Principal(properties[2]);
- // remove colon or space separators
- String value = stripOutSeparators(properties[3]);
- responderSerialNumber = new BigInteger(value, 16);
-
- } else if (properties[2] != null || properties[3] != null) {
+ currCertImpl = X509CertImpl.toImpl((X509Certificate)cert);
+ } catch (CertificateException ce) {
+ throw new CertPathValidatorException(ce);
+ }
+
+ if (onlyEECert && currCertImpl.getBasicConstraints() != -1) {
+ if (DEBUG != null) {
+ DEBUG.println("Skipping revocation check, not end entity cert");
+ }
+ return;
+ }
+
+ /*
+ * OCSP security property values, in the following order:
+ * 1. ocsp.responderURL
+ * 2. ocsp.responderCertSubjectName
+ * 3. ocsp.responderCertIssuerName
+ * 4. ocsp.responderCertSerialNumber
+ */
+ // should cache these properties to avoid calling every time?
+ String[] properties = getOCSPProperties();
+
+ // Check whether OCSP is feasible before seeking cert information
+ URI uri = getOCSPServerURI(currCertImpl, properties[0]);
+
+ // When responder's subject name is set then the issuer/serial
+ // properties are ignored
+ X500Principal responderSubjectName = null;
+ X500Principal responderIssuerName = null;
+ BigInteger responderSerialNumber = null;
+ if (properties[1] != null) {
+ responderSubjectName = new X500Principal(properties[1]);
+ } else if (properties[2] != null && properties[3] != null) {
+ responderIssuerName = new X500Principal(properties[2]);
+ // remove colon or space separators
+ String value = stripOutSeparators(properties[3]);
+ responderSerialNumber = new BigInteger(value, 16);
+ } else if (properties[2] != null || properties[3] != null) {
+ throw new CertPathValidatorException(
+ "Must specify both ocsp.responderCertIssuerName and " +
+ "ocsp.responderCertSerialNumber properties");
+ }
+
+ // If the OCSP responder cert properties are set then the
+ // identified cert must be located in the trust anchors or
+ // in the cert stores.
+ boolean seekResponderCert = false;
+ if (responderSubjectName != null || responderIssuerName != null) {
+ seekResponderCert = true;
+ }
+
+ // Set the issuer certificate to the next cert in the chain
+ // (unless we're processing the final cert).
+ X509Certificate issuerCert = null;
+ boolean seekIssuerCert = true;
+ X509Certificate responderCert = null;
+ if (remainingCerts < certs.length) {
+ issuerCert = certs[remainingCerts];
+ seekIssuerCert = false; // done
+
+ // By default, the OCSP responder's cert is the same as the
+ // issuer of the cert being validated.
+ if (!seekResponderCert) {
+ responderCert = issuerCert;
+ if (DEBUG != null) {
+ DEBUG.println("Responder's certificate is the same " +
+ "as the issuer of the certificate being validated");
+ }
+ }
+ }
+
+ // Check anchor certs for:
+ // - the issuer cert (of the cert being validated)
+ // - the OCSP responder's cert
+ if (seekIssuerCert || seekResponderCert) {
+
+ if (DEBUG != null && seekResponderCert) {
+ DEBUG.println("Searching trust anchors for responder's " +
+ "certificate");
+ }
+
+ // Extract the anchor certs
+ Iterator<TrustAnchor> anchors
+ = pkixParams.getTrustAnchors().iterator();
+ if (!anchors.hasNext()) {
throw new CertPathValidatorException(
- "Must specify both ocsp.responderCertIssuerName and " +
- "ocsp.responderCertSerialNumber properties");
- }
-
- // If the OCSP responder cert properties are set then the
- // identified cert must be located in the trust anchors or
- // in the cert stores.
- if (responderSubjectName != null || responderIssuerName != null) {
- seekResponderCert = true;
- }
-
- // Set the issuer certificate to the next cert in the chain
- // (unless we're processing the final cert).
- if (remainingCerts < certs.length) {
- issuerCertImpl = X509CertImpl.toImpl(certs[remainingCerts]);
- seekIssuerCert = false; // done
-
- // By default, the OCSP responder's cert is the same as the
- // issuer of the cert being validated.
- if (! seekResponderCert) {
- responderCert = certs[remainingCerts];
- if (DEBUG != null) {
- DEBUG.println("Responder's certificate is the same " +
- "as the issuer of the certificate being validated");
- }
- }
- }
-
- // Check anchor certs for:
- // - the issuer cert (of the cert being validated)
- // - the OCSP responder's cert
- if (seekIssuerCert || seekResponderCert) {
-
- if (DEBUG != null && seekResponderCert) {
- DEBUG.println("Searching trust anchors for responder's " +
- "certificate");
- }
-
- // Extract the anchor certs
- Iterator anchors = pkixParams.getTrustAnchors().iterator();
- if (! anchors.hasNext()) {
- throw new CertPathValidatorException(
- "Must specify at least one trust anchor");
- }
-
- X500Principal certIssuerName =
- currCertImpl.getIssuerX500Principal();
- while (anchors.hasNext() &&
- (seekIssuerCert || seekResponderCert)) {
-
- TrustAnchor anchor = (TrustAnchor)anchors.next();
- X509Certificate anchorCert = anchor.getTrustedCert();
- X500Principal anchorSubjectName =
- anchorCert.getSubjectX500Principal();
-
- if (dump) {
- System.out.println("Issuer DN is " + certIssuerName);
- System.out.println("Subject DN is " +
- anchorSubjectName);
- }
-
- // Check if anchor cert is the issuer cert
- if (seekIssuerCert &&
- certIssuerName.equals(anchorSubjectName)) {
-
- issuerCertImpl = X509CertImpl.toImpl(anchorCert);
- seekIssuerCert = false; // done
-
- // By default, the OCSP responder's cert is the same as
- // the issuer of the cert being validated.
- if (! seekResponderCert && responderCert == null) {
- responderCert = anchorCert;
- if (DEBUG != null) {
- DEBUG.println("Responder's certificate is the" +
- " same as the issuer of the certificate " +
- "being validated");
- }
+ "Must specify at least one trust anchor");
+ }
+
+ X500Principal certIssuerName =
+ currCertImpl.getIssuerX500Principal();
+ while (anchors.hasNext() && (seekIssuerCert || seekResponderCert)) {
+
+ TrustAnchor anchor = anchors.next();
+ X509Certificate anchorCert = anchor.getTrustedCert();
+ X500Principal anchorSubjectName =
+ anchorCert.getSubjectX500Principal();
+
+ if (dump) {
+ System.out.println("Issuer DN is " + certIssuerName);
+ System.out.println("Subject DN is " + anchorSubjectName);
+ }
+
+ // Check if anchor cert is the issuer cert
+ if (seekIssuerCert &&
+ certIssuerName.equals(anchorSubjectName)) {
+
+ issuerCert = anchorCert;
+ seekIssuerCert = false; // done
+
+ // By default, the OCSP responder's cert is the same as
+ // the issuer of the cert being validated.
+ if (!seekResponderCert && responderCert == null) {
+ responderCert = anchorCert;
+ if (DEBUG != null) {
+ DEBUG.println("Responder's certificate is the" +
+ " same as the issuer of the certificate " +
+ "being validated");
}
}
-
- // Check if anchor cert is the responder cert
- if (seekResponderCert) {
- // Satisfy the responder subject name property only, or
- // satisfy the responder issuer name and serial number
- // properties only
- if ((responderSubjectName != null &&
- responderSubjectName.equals(anchorSubjectName)) ||
- (responderIssuerName != null &&
- responderSerialNumber != null &&
- responderIssuerName.equals(
- anchorCert.getIssuerX500Principal()) &&
- responderSerialNumber.equals(
- anchorCert.getSerialNumber()))) {
-
- responderCert = anchorCert;
+ }
+
+ // Check if anchor cert is the responder cert
+ if (seekResponderCert) {
+ // Satisfy the responder subject name property only, or
+ // satisfy the responder issuer name and serial number
+ // properties only
+ if ((responderSubjectName != null &&
+ responderSubjectName.equals(anchorSubjectName)) ||
+ (responderIssuerName != null &&
+ responderSerialNumber != null &&
+ responderIssuerName.equals(
+ anchorCert.getIssuerX500Principal()) &&
+ responderSerialNumber.equals(
+ anchorCert.getSerialNumber()))) {
+
+ responderCert = anchorCert;
+ seekResponderCert = false; // done
+ }
+ }
+ }
+ if (issuerCert == null) {
+ throw new CertPathValidatorException(
+ "No trusted certificate for " + currCertImpl.getIssuerDN());
+ }
+
+ // Check cert stores if responder cert has not yet been found
+ if (seekResponderCert) {
+ if (DEBUG != null) {
+ DEBUG.println("Searching cert stores for responder's " +
+ "certificate");
+ }
+ X509CertSelector filter = null;
+ if (responderSubjectName != null) {
+ filter = new X509CertSelector();
+ filter.setSubject(responderSubjectName);
+ } else if (responderIssuerName != null &&
+ responderSerialNumber != null) {
+ filter = new X509CertSelector();
+ filter.setIssuer(responderIssuerName);
+ filter.setSerialNumber(responderSerialNumber);
+ }
+ if (filter != null) {
+ List<CertStore> certStores = pkixParams.getCertStores();
+ for (CertStore certStore : certStores) {
+ Iterator i = null;
+ try {
+ i = certStore.getCertificates(filter).iterator();
+ } catch (CertStoreException cse) {
+ // ignore and try next certStore
+ if (DEBUG != null) {
+ DEBUG.println("CertStore exception:" + cse);
+ }
+ continue;
+ }
+ if (i.hasNext()) {
+ responderCert = (X509Certificate) i.next();
seekResponderCert = false; // done
+ break;
}
}
}
- if (issuerCertImpl == null) {
- throw new CertPathValidatorException(
- "No trusted certificate for " +
- currCertImpl.getIssuerDN());
- }
-
- // Check cert stores if responder cert has not yet been found
- if (seekResponderCert) {
- if (DEBUG != null) {
- DEBUG.println("Searching cert stores for responder's " +
- "certificate");
- }
- X509CertSelector filter = null;
- if (responderSubjectName != null) {
- filter = new X509CertSelector();
- filter.setSubject(responderSubjectName.getName());
- } else if (responderIssuerName != null &&
- responderSerialNumber != null) {
- filter = new X509CertSelector();
- filter.setIssuer(responderIssuerName.getName());
- filter.setSerialNumber(responderSerialNumber);
- }
- if (filter != null) {
- List<CertStore> certStores = pkixParams.getCertStores();
- for (CertStore certStore : certStores) {
- Iterator i =
- certStore.getCertificates(filter).iterator();
- if (i.hasNext()) {
- responderCert = (X509Certificate) i.next();
- seekResponderCert = false; // done
- break;
- }
- }
- }
- }
- }
-
- // Could not find the certificate identified in the OCSP properties
- if (seekResponderCert) {
- throw new CertPathValidatorException(
- "Cannot find the responder's certificate " +
- "(set using the OCSP security properties).");
- }
-
- // Construct an OCSP Request
- OCSPRequest ocspRequest =
- new OCSPRequest(currCertImpl, issuerCertImpl);
-
- // Use the URL to the OCSP service that was created earlier
- HttpURLConnection con = (HttpURLConnection)url.openConnection();
- if (DEBUG != null) {
- DEBUG.println("connecting to OCSP service at: " + url);
- }
-
- // Indicate that both input and output will be performed,
- // that the method is POST, and that the content length is
- // the length of the byte array
-
- con.setDoOutput(true);
- con.setDoInput(true);
- con.setRequestMethod("POST");
- con.setRequestProperty("Content-type", "application/ocsp-request");
- byte[] bytes = ocspRequest.encodeBytes();
- CertId certId = ocspRequest.getCertId();
-
- con.setRequestProperty("Content-length",
- String.valueOf(bytes.length));
- out = con.getOutputStream();
- out.write(bytes);
- out.flush();
-
- // Check the response
- if (DEBUG != null &&
- con.getResponseCode() != HttpURLConnection.HTTP_OK) {
- DEBUG.println("Received HTTP error: " + con.getResponseCode() +
- " - " + con.getResponseMessage());
- }
- in = con.getInputStream();
-
- byte[] response = null;
- int total = 0;
- int contentLength = con.getContentLength();
- if (contentLength != -1) {
- response = new byte[contentLength];
- } else {
- response = new byte[2048];
- contentLength = Integer.MAX_VALUE;
- }
-
- while (total < contentLength) {
- int count = in.read(response, total, response.length - total);
- if (count < 0)
- break;
-
- total += count;
- if (total >= response.length && total < contentLength) {
- response = Arrays.copyOf(response, total * 2);
- }
- }
- response = Arrays.copyOf(response, total);
-
- OCSPResponse ocspResponse = new OCSPResponse(response, pkixParams,
- responderCert);
- // Check that response applies to the cert that was supplied
- if (! certId.equals(ocspResponse.getCertId())) {
- throw new CertPathValidatorException(
- "Certificate in the OCSP response does not match the " +
- "certificate supplied in the OCSP request.");
- }
- SerialNumber serialNumber = currCertImpl.getSerialNumberObject();
- int certOCSPStatus = ocspResponse.getCertStatus(serialNumber);
-
- if (DEBUG != null) {
- DEBUG.println("Status of certificate (with serial number " +
- serialNumber.getNumber() + ") is: " +
- OCSPResponse.certStatusToText(certOCSPStatus));
- }
-
- if (certOCSPStatus == OCSPResponse.CERT_STATUS_REVOKED) {
- Throwable t = new CertificateRevokedException(
- ocspResponse.getRevocationTime(),
- ocspResponse.getRevocationReason(),
- responderCert.getSubjectX500Principal(),
- ocspResponse.getSingleExtensions());
- throw new CertPathValidatorException(t.getMessage(), t,
- null, -1, BasicReason.REVOKED);
-
- } else if (certOCSPStatus == OCSPResponse.CERT_STATUS_UNKNOWN) {
- throw new CertPathValidatorException(
- "Certificate's revocation status is unknown", null, cp,
- remainingCerts, BasicReason.UNDETERMINED_REVOCATION_STATUS);
- }
- } catch (Exception e) {
- throw new CertPathValidatorException(e);
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (IOException ioe) {
- throw new CertPathValidatorException(ioe);
- }
- }
- if (out != null) {
- try {
- out.close();
- } catch (IOException ioe) {
- throw new CertPathValidatorException(ioe);
- }
- }
+ }
+ }
+
+ // Could not find the certificate identified in the OCSP properties
+ if (seekResponderCert) {
+ throw new CertPathValidatorException(
+ "Cannot find the responder's certificate " +
+ "(set using the OCSP security properties).");
+ }
+
+ CertId certId = null;
+ OCSPResponse response = null;
+ try {
+ certId = new CertId
+ (issuerCert, currCertImpl.getSerialNumberObject());
+ response = OCSP.check(Collections.singletonList(certId), uri,
+ responderCert, pkixParams.getDate());
+ } catch (IOException ioe) {
+ // should allow this to pass if network failures are acceptable
+ throw new CertPathValidatorException
+ ("Unable to send OCSP request", ioe);
+ }
+
+ RevocationStatus rs = (RevocationStatus) response.getSingleResponse(certId);
+ RevocationStatus.CertStatus certStatus = rs.getCertStatus();
+ if (certStatus == RevocationStatus.CertStatus.REVOKED) {
+ Throwable t = new CertificateRevokedException(
+ rs.getRevocationTime(), rs.getRevocationReason(),
+ responderCert.getSubjectX500Principal(),
+ rs.getSingleExtensions());
+ throw new CertPathValidatorException(t.getMessage(), t,
+ null, -1, BasicReason.REVOKED);
+ } else if (certStatus == RevocationStatus.CertStatus.UNKNOWN) {
+ throw new CertPathValidatorException(
+ "Certificate's revocation status is unknown", null, cp,
+ remainingCerts, BasicReason.UNDETERMINED_REVOCATION_STATUS);
}
}
@@ -431,20 +364,18 @@ class OCSPChecker extends PKIXCertPathCh
* 3. ocsp.responderCertIssuerName
* 4. ocsp.responderCertSerialNumber
*/
- private static URL getOCSPServerURL(X509CertImpl currCertImpl,
- String[] properties)
- throws CertificateParsingException, CertPathValidatorException {
-
- if (properties[0] != null) {
- try {
- return new URL(properties[0]);
- } catch (java.net.MalformedURLException e) {
+ private static URI getOCSPServerURI(X509CertImpl currCertImpl,
+ String responderURL) throws CertPathValidatorException {
+
+ if (responderURL != null) {
+ try {
+ return new URI(responderURL);
+ } catch (URISyntaxException e) {
throw new CertPathValidatorException(e);
- }
+ }
}
// Examine the certificate's AuthorityInfoAccess extension
-
AuthorityInfoAccessExtension aia =
currCertImpl.getAuthorityInfoAccessExtension();
if (aia == null) {
@@ -459,13 +390,8 @@ class OCSPChecker extends PKIXCertPathCh
GeneralName generalName = description.getAccessLocation();
if (generalName.getType() == GeneralNameInterface.NAME_URI) {
- try {
- URIName uri = (URIName) generalName.getName();
- return (new URL(uri.getName()));
-
- } catch (java.net.MalformedURLException e) {
- throw new CertPathValidatorException(e);
- }
+ URIName uri = (URIName) generalName.getName();
+ return uri.getURI();
}
}
}
--- a/src/share/classes/sun/security/provider/certpath/OCSPRequest.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/provider/certpath/OCSPRequest.java Tue Sep 29 15:31:18 2009 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2003-2009 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,9 +26,9 @@ package sun.security.provider.certpath;
package sun.security.provider.certpath;
import java.io.IOException;
-import java.security.cert.CertPathValidatorException;
+import java.util.Collections;
+import java.util.List;
import sun.misc.HexDumpEncoder;
-import sun.security.x509.*;
import sun.security.util.*;
/**
@@ -77,47 +77,33 @@ class OCSPRequest {
private static final Debug debug = Debug.getInstance("certpath");
private static final boolean dump = false;
- // Serial number of the certificates to be checked for revocation
- private SerialNumber serialNumber;
-
- // Issuer's certificate (for computing certId hash values)
- private X509CertImpl issuerCert;
-
- // CertId of the certificate to be checked
- private CertId certId = null;
+ // List of request CertIds
+ private final List<CertId> certIds;
/*
* Constructs an OCSPRequest. This constructor is used
* to construct an unsigned OCSP Request for a single user cert.
*/
- // used by OCSPChecker
- OCSPRequest(X509CertImpl userCert, X509CertImpl issuerCert)
- throws CertPathValidatorException {
-
- if (issuerCert == null) {
- throw new CertPathValidatorException("Null IssuerCertificate");
- }
- this.issuerCert = issuerCert;
- serialNumber = userCert.getSerialNumberObject();
+ OCSPRequest(CertId certId) {
+ this.certIds = Collections.singletonList(certId);
}
- // used by OCSPChecker
+ OCSPRequest(List<CertId> certIds) {
+ this.certIds = certIds;
+ }
+
byte[] encodeBytes() throws IOException {
// encode tbsRequest
DerOutputStream tmp = new DerOutputStream();
- DerOutputStream derSingleReqList = new DerOutputStream();
- SingleRequest singleRequest = null;
-
- try {
- singleRequest = new SingleRequest(issuerCert, serialNumber);
- } catch (Exception e) {
- throw new IOException("Error encoding OCSP request");
+ DerOutputStream requestsOut = new DerOutputStream();
+ for (CertId certId : certIds) {
+ DerOutputStream certIdOut = new DerOutputStream();
+ certId.encode(certIdOut);
+ requestsOut.write(DerValue.tag_Sequence, certIdOut);
}
- certId = singleRequest.getCertId();
- singleRequest.encode(derSingleReqList);
- tmp.write(DerValue.tag_Sequence, derSingleReqList);
+ tmp.write(DerValue.tag_Sequence, requestsOut);
// No extensions supported
DerOutputStream tbsRequest = new DerOutputStream();
tbsRequest.write(DerValue.tag_Sequence, tmp);
@@ -130,35 +116,14 @@ class OCSPRequest {
if (dump) {
HexDumpEncoder hexEnc = new HexDumpEncoder();
- System.out.println ("OCSPRequest bytes are... ");
+ System.out.println("OCSPRequest bytes are... ");
System.out.println(hexEnc.encode(bytes));
}
- return(bytes);
+ return bytes;
}
- // used by OCSPChecker
- CertId getCertId() {
- return certId;
- }
-
- private static class SingleRequest {
- private CertId certId;
-
- // No extensions are set
-
- private SingleRequest(X509CertImpl cert, SerialNumber serialNo) throws Exception {
- certId = new CertId(cert, serialNo);
- }
-
- private void encode(DerOutputStream out) throws IOException {
- DerOutputStream tmp = new DerOutputStream();
- certId.encode(tmp);
- out.write(DerValue.tag_Sequence, tmp);
- }
-
- private CertId getCertId() {
- return certId;
- }
+ List<CertId> getCertIds() {
+ return certIds;
}
}
--- a/src/share/classes/sun/security/provider/certpath/OCSPResponse.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/provider/certpath/OCSPResponse.java Tue Sep 29 15:31:18 2009 -0700
@@ -28,17 +28,16 @@ import java.io.*;
import java.io.*;
import java.math.BigInteger;
import java.security.*;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateParsingException;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CRLReason;
import java.security.cert.X509Certificate;
-import java.security.cert.PKIXParameters;
-import javax.security.auth.x500.X500Principal;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
-import java.util.Iterator;
import sun.misc.HexDumpEncoder;
import sun.security.x509.*;
import sun.security.util.*;
@@ -113,32 +112,29 @@ import sun.security.util.*;
* @author Ram Marti
*/
-class OCSPResponse {
-
- // Certificate status CHOICE
- public static final int CERT_STATUS_GOOD = 0;
- public static final int CERT_STATUS_REVOKED = 1;
- public static final int CERT_STATUS_UNKNOWN = 2;
+public final class OCSPResponse {
+
+ public enum ResponseStatus {
+ SUCCESSFUL, // Response has valid confirmations
+ MALFORMED_REQUEST, // Illegal confirmation request
+ INTERNAL_ERROR, // Internal error in issuer
+ TRY_LATER, // Try again later
+ UNUSED, // is not used
+ SIG_REQUIRED, // Must sign the request
+ UNAUTHORIZED // Request unauthorized
+ };
+ private static ResponseStatus[] rsvalues = ResponseStatus.values();
private static final Debug DEBUG = Debug.getInstance("certpath");
private static final boolean dump = false;
- private static final ObjectIdentifier OCSP_BASIC_RESPONSE_OID;
- private static final ObjectIdentifier OCSP_NONCE_EXTENSION_OID;
- static {
- ObjectIdentifier tmp1 = null;
- ObjectIdentifier tmp2 = null;
- try {
- tmp1 = new ObjectIdentifier("1.3.6.1.5.5.7.48.1.1");
- tmp2 = new ObjectIdentifier("1.3.6.1.5.5.7.48.1.2");
- } catch (Exception e) {
- // should not happen; log and exit
- }
- OCSP_BASIC_RESPONSE_OID = tmp1;
- OCSP_NONCE_EXTENSION_OID = tmp2;
- }
-
- // OCSP response status code
- private static final int OCSP_RESPONSE_OK = 0;
+ private static final ObjectIdentifier OCSP_BASIC_RESPONSE_OID =
+ ObjectIdentifier.newInternal(new int[] { 1, 3, 6, 1, 5, 5, 7, 48, 1, 1});
+ private static final ObjectIdentifier OCSP_NONCE_EXTENSION_OID =
+ ObjectIdentifier.newInternal(new int[] { 1, 3, 6, 1, 5, 5, 7, 48, 1, 2});
+
+ private static final int CERT_STATUS_GOOD = 0;
+ private static final int CERT_STATUS_REVOKED = 1;
+ private static final int CERT_STATUS_UNKNOWN = 2;
// ResponderID CHOICE tags
private static final int NAME_TAG = 1;
@@ -147,7 +143,8 @@ class OCSPResponse {
// Object identifier for the OCSPSigning key purpose
private static final String KP_OCSP_SIGNING_OID = "1.3.6.1.5.5.7.3.9";
- private SingleResponse singleResponse;
+ private final ResponseStatus responseStatus;
+ private final Map<CertId, SingleResponse> singleResponseMap;
// Maximum clock skew in milliseconds (15 minutes) allowed when checking
// validity of OCSP responses
@@ -159,289 +156,289 @@ class OCSPResponse {
/*
* Create an OCSP response from its ASN.1 DER encoding.
*/
- // used by OCSPChecker
- OCSPResponse(byte[] bytes, PKIXParameters params,
+ OCSPResponse(byte[] bytes, Date dateCheckedAgainst,
X509Certificate responderCert)
throws IOException, CertPathValidatorException {
- try {
- int responseStatus;
- ObjectIdentifier responseType;
- int version;
- CertificateIssuerName responderName = null;
- Date producedAtDate;
- AlgorithmId sigAlgId;
- byte[] ocspNonce;
-
- // OCSPResponse
- if (dump) {
- HexDumpEncoder hexEnc = new HexDumpEncoder();
- System.out.println("OCSPResponse bytes are...");
- System.out.println(hexEnc.encode(bytes));
- }
- DerValue der = new DerValue(bytes);
- if (der.tag != DerValue.tag_Sequence) {
- throw new IOException("Bad encoding in OCSP response: " +
- "expected ASN.1 SEQUENCE tag.");
- }
- DerInputStream derIn = der.getData();
-
- // responseStatus
- responseStatus = derIn.getEnumerated();
+ // OCSPResponse
+ if (dump) {
+ HexDumpEncoder hexEnc = new HexDumpEncoder();
+ System.out.println("OCSPResponse bytes are...");
+ System.out.println(hexEnc.encode(bytes));
+ }
+ DerValue der = new DerValue(bytes);
+ if (der.tag != DerValue.tag_Sequence) {
+ throw new IOException("Bad encoding in OCSP response: " +
+ "expected ASN.1 SEQUENCE tag.");
+ }
+ DerInputStream derIn = der.getData();
+
+ // responseStatus
+ int status = derIn.getEnumerated();
+ if (status >= 0 && status < rsvalues.length) {
+ responseStatus = rsvalues[status];
+ } else {
+ // unspecified responseStatus
+ throw new IOException("Unknown OCSPResponse status: " + status);
+ }
+ if (DEBUG != null) {
+ DEBUG.println("OCSP response status: " + responseStatus);
+ }
+ if (responseStatus != ResponseStatus.SUCCESSFUL) {
+ // no need to continue, responseBytes are not set.
+ singleResponseMap = Collections.emptyMap();
+ return;
+ }
+
+ // responseBytes
+ der = derIn.getDerValue();
+ if (!der.isContextSpecific((byte)0)) {
+ throw new IOException("Bad encoding in responseBytes element " +
+ "of OCSP response: expected ASN.1 context specific tag 0.");
+ }
+ DerValue tmp = der.data.getDerValue();
+ if (tmp.tag != DerValue.tag_Sequence) {
+ throw new IOException("Bad encoding in responseBytes element " +
+ "of OCSP response: expected ASN.1 SEQUENCE tag.");
+ }
+
+ // responseType
+ derIn = tmp.data;
+ ObjectIdentifier responseType = derIn.getOID();
+ if (responseType.equals(OCSP_BASIC_RESPONSE_OID)) {
if (DEBUG != null) {
- DEBUG.println("OCSP response: " +
- responseToText(responseStatus));
- }
- if (responseStatus != OCSP_RESPONSE_OK) {
- throw new CertPathValidatorException(
- "OCSP Response Failure: " +
- responseToText(responseStatus));
- }
-
- // responseBytes
- der = derIn.getDerValue();
- if (! der.isContextSpecific((byte)0)) {
- throw new IOException("Bad encoding in responseBytes element " +
- "of OCSP response: expected ASN.1 context specific tag 0.");
- };
- DerValue tmp = der.data.getDerValue();
- if (tmp.tag != DerValue.tag_Sequence) {
- throw new IOException("Bad encoding in responseBytes element " +
- "of OCSP response: expected ASN.1 SEQUENCE tag.");
- }
-
- // responseType
- derIn = tmp.data;
- responseType = derIn.getOID();
- if (responseType.equals(OCSP_BASIC_RESPONSE_OID)) {
- if (DEBUG != null) {
- DEBUG.println("OCSP response type: basic");
- }
- } else {
- if (DEBUG != null) {
- DEBUG.println("OCSP response type: " + responseType);
- }
- throw new IOException("Unsupported OCSP response type: " +
- responseType);
- }
-
- // BasicOCSPResponse
- DerInputStream basicOCSPResponse =
- new DerInputStream(derIn.getOctetString());
-
- DerValue[] seqTmp = basicOCSPResponse.getSequence(2);
- DerValue responseData = seqTmp[0];
-
- // Need the DER encoded ResponseData to verify the signature later
- byte[] responseDataDer = seqTmp[0].toByteArray();
-
- // tbsResponseData
- if (responseData.tag != DerValue.tag_Sequence) {
- throw new IOException("Bad encoding in tbsResponseData " +
- " element of OCSP response: expected ASN.1 SEQUENCE tag.");
- }
- DerInputStream seqDerIn = responseData.data;
- DerValue seq = seqDerIn.getDerValue();
-
- // version
- if (seq.isContextSpecific((byte)0)) {
- // seq[0] is version
- if (seq.isConstructed() && seq.isContextSpecific()) {
- //System.out.println ("version is available");
- seq = seq.data.getDerValue();
- version = seq.getInteger();
- if (seq.data.available() != 0) {
- throw new IOException("Bad encoding in version " +
- " element of OCSP response: bad format");
- }
- seq = seqDerIn.getDerValue();
- }
- }
-
- // responderID
- short tag = (byte)(seq.tag & 0x1f);
- if (tag == NAME_TAG) {
- responderName = new CertificateIssuerName(seq.getData());
- if (DEBUG != null) {
- DEBUG.println("OCSP Responder name: " + responderName);
- }
- } else if (tag == KEY_TAG) {
- // Ignore, for now
- } else {
- throw new IOException("Bad encoding in responderID element " +
- "of OCSP response: expected ASN.1 context specific tag 0 " +
- "or 1");
- }
-
- // producedAt
+ DEBUG.println("OCSP response type: basic");
+ }
+ } else {
+ if (DEBUG != null) {
+ DEBUG.println("OCSP response type: " + responseType);
+ }
+ throw new IOException("Unsupported OCSP response type: " +
+ responseType);
+ }
+
+ // BasicOCSPResponse
+ DerInputStream basicOCSPResponse =
+ new DerInputStream(derIn.getOctetString());
+
+ DerValue[] seqTmp = basicOCSPResponse.getSequence(2);
+ if (seqTmp.length < 3) {
+ throw new IOException("Unexpected BasicOCSPResponse value");
+ }
+
+ DerValue responseData = seqTmp[0];
+
+ // Need the DER encoded ResponseData to verify the signature later
+ byte[] responseDataDer = seqTmp[0].toByteArray();
+
+ // tbsResponseData
+ if (responseData.tag != DerValue.tag_Sequence) {
+ throw new IOException("Bad encoding in tbsResponseData " +
+ "element of OCSP response: expected ASN.1 SEQUENCE tag.");
+ }
+ DerInputStream seqDerIn = responseData.data;
+ DerValue seq = seqDerIn.getDerValue();
+
+ // version
+ if (seq.isContextSpecific((byte)0)) {
+ // seq[0] is version
+ if (seq.isConstructed() && seq.isContextSpecific()) {
+ //System.out.println ("version is available");
+ seq = seq.data.getDerValue();
+ int version = seq.getInteger();
+ if (seq.data.available() != 0) {
+ throw new IOException("Bad encoding in version " +
+ " element of OCSP response: bad format");
+ }
+ seq = seqDerIn.getDerValue();
+ }
+ }
+
+ // responderID
+ short tag = (byte)(seq.tag & 0x1f);
+ if (tag == NAME_TAG) {
+ if (DEBUG != null) {
+ X500Name responderName = new X500Name(seq.getData());
+ DEBUG.println("OCSP Responder name: " + responderName);
+ }
+ } else if (tag == KEY_TAG) {
+ // Ignore, for now
+ } else {
+ throw new IOException("Bad encoding in responderID element of " +
+ "OCSP response: expected ASN.1 context specific tag 0 or 1");
+ }
+
+ // producedAt
+ seq = seqDerIn.getDerValue();
+ if (DEBUG != null) {
+ Date producedAtDate = seq.getGeneralizedTime();
+ DEBUG.println("OCSP response produced at: " + producedAtDate);
+ }
+
+ // responses
+ DerValue[] singleResponseDer = seqDerIn.getSequence(1);
+ singleResponseMap
+ = new HashMap<CertId, SingleResponse>(singleResponseDer.length);
+ if (DEBUG != null) {
+ DEBUG.println("OCSP number of SingleResponses: "
+ + singleResponseDer.length);
+ }
+ for (int i = 0; i < singleResponseDer.length; i++) {
+ SingleResponse singleResponse
+ = new SingleResponse(singleResponseDer[i]);
+ singleResponseMap.put(singleResponse.getCertId(), singleResponse);
+ }
+
+ // responseExtensions
+ if (seqDerIn.available() > 0) {
seq = seqDerIn.getDerValue();
- producedAtDate = seq.getGeneralizedTime();
-
- // responses
- DerValue[] singleResponseDer = seqDerIn.getSequence(1);
- // Examine only the first response
- singleResponse = new SingleResponse(singleResponseDer[0]);
-
- // responseExtensions
- if (seqDerIn.available() > 0) {
- seq = seqDerIn.getDerValue();
- if (seq.isContextSpecific((byte)1)) {
- DerValue[] responseExtDer = seq.data.getSequence(3);
- Extension[] responseExtension =
- new Extension[responseExtDer.length];
- for (int i = 0; i < responseExtDer.length; i++) {
- responseExtension[i] = new Extension(responseExtDer[i]);
- if (DEBUG != null) {
- DEBUG.println("OCSP extension: " +
- responseExtension[i]);
- }
- if ((responseExtension[i].getExtensionId()).equals(
- OCSP_NONCE_EXTENSION_OID)) {
- ocspNonce =
- responseExtension[i].getExtensionValue();
-
- } else if (responseExtension[i].isCritical()) {
- throw new IOException(
- "Unsupported OCSP critical extension: " +
- responseExtension[i].getExtensionId());
- }
- }
- }
- }
-
- // signatureAlgorithmId
- sigAlgId = AlgorithmId.parse(seqTmp[1]);
-
- // signature
- byte[] signature = seqTmp[2].getBitString();
- X509CertImpl[] x509Certs = null;
-
- // if seq[3] is available , then it is a sequence of certificates
- if (seqTmp.length > 3) {
- // certs are available
- DerValue seqCert = seqTmp[3];
- if (! seqCert.isContextSpecific((byte)0)) {
- throw new IOException("Bad encoding in certs element " +
- "of OCSP response: expected ASN.1 context specific tag 0.");
- }
- DerValue[] certs = (seqCert.getData()).getSequence(3);
- x509Certs = new X509CertImpl[certs.length];
+ if (seq.isContextSpecific((byte)1)) {
+ DerValue[] responseExtDer = seq.data.getSequence(3);
+ for (int i = 0; i < responseExtDer.length; i++) {
+ Extension responseExtension
+ = new Extension(responseExtDer[i]);
+ if (DEBUG != null) {
+ DEBUG.println("OCSP extension: " + responseExtension);
+ }
+ if (responseExtension.getExtensionId().equals(
+ OCSP_NONCE_EXTENSION_OID)) {
+ /*
+ ocspNonce =
+ responseExtension[i].getExtensionValue();
+ */
+ } else if (responseExtension.isCritical()) {
+ throw new IOException(
+ "Unsupported OCSP critical extension: " +
+ responseExtension.getExtensionId());
+ }
+ }
+ }
+ }
+
+ // signatureAlgorithmId
+ AlgorithmId sigAlgId = AlgorithmId.parse(seqTmp[1]);
+
+ // signature
+ byte[] signature = seqTmp[2].getBitString();
+ X509CertImpl[] x509Certs = null;
+
+ // if seq[3] is available , then it is a sequence of certificates
+ if (seqTmp.length > 3) {
+ // certs are available
+ DerValue seqCert = seqTmp[3];
+ if (!seqCert.isContextSpecific((byte)0)) {
+ throw new IOException("Bad encoding in certs element of " +
+ "OCSP response: expected ASN.1 context specific tag 0.");
+ }
+ DerValue[] certs = seqCert.getData().getSequence(3);
+ x509Certs = new X509CertImpl[certs.length];
+ try {
for (int i = 0; i < certs.length; i++) {
x509Certs[i] = new X509CertImpl(certs[i].toByteArray());
}
- }
-
- // Check whether the cert returned by the responder is trusted
- if (x509Certs != null && x509Certs[0] != null) {
- X509CertImpl cert = x509Certs[0];
-
- // First check if the cert matches the responder cert which
- // was set locally.
- if (cert.equals(responderCert)) {
- // cert is trusted, now verify the signed response
-
- // Next check if the cert was issued by the responder cert
- // which was set locally.
- } else if (cert.getIssuerX500Principal().equals(
- responderCert.getSubjectX500Principal())) {
-
- // Check for the OCSPSigning key purpose
+ } catch (CertificateException ce) {
+ throw new IOException("Bad encoding in X509 Certificate", ce);
+ }
+ }
+
+ // Check whether the cert returned by the responder is trusted
+ if (x509Certs != null && x509Certs[0] != null) {
+ X509CertImpl cert = x509Certs[0];
+
+ // First check if the cert matches the responder cert which
+ // was set locally.
+ if (cert.equals(responderCert)) {
+ // cert is trusted, now verify the signed response
+
+ // Next check if the cert was issued by the responder cert
+ // which was set locally.
+ } else if (cert.getIssuerX500Principal().equals(
+ responderCert.getSubjectX500Principal())) {
+
+ // Check for the OCSPSigning key purpose
+ try {
List<String> keyPurposes = cert.getExtendedKeyUsage();
if (keyPurposes == null ||
!keyPurposes.contains(KP_OCSP_SIGNING_OID)) {
- if (DEBUG != null) {
- DEBUG.println("Responder's certificate is not " +
- "valid for signing OCSP responses.");
- }
throw new CertPathValidatorException(
"Responder's certificate not valid for signing " +
"OCSP responses");
}
-
- // check the validity
- try {
- Date dateCheckedAgainst = params.getDate();
- if (dateCheckedAgainst == null) {
- cert.checkValidity();
- } else {
- cert.checkValidity(dateCheckedAgainst);
- }
- } catch (GeneralSecurityException e) {
- if (DEBUG != null) {
- DEBUG.println("Responder's certificate is not " +
- "within the validity period.");
- }
- throw new CertPathValidatorException(
- "Responder's certificate not within the " +
- "validity period");
- }
-
- // check for revocation
- //
- // A CA may specify that an OCSP client can trust a
- // responder for the lifetime of the responder's
- // certificate. The CA does so by including the
- // extension id-pkix-ocsp-nocheck.
- //
- Extension noCheck =
- cert.getExtension(PKIXExtensions.OCSPNoCheck_Id);
- if (noCheck != null) {
- if (DEBUG != null) {
- DEBUG.println("Responder's certificate includes " +
- "the extension id-pkix-ocsp-nocheck.");
- }
+ } catch (CertificateParsingException cpe) {
+ // assume cert is not valid for signing
+ throw new CertPathValidatorException(
+ "Responder's certificate not valid for signing " +
+ "OCSP responses", cpe);
+ }
+
+ // check the validity
+ try {
+ if (dateCheckedAgainst == null) {
+ cert.checkValidity();
} else {
- // we should do the revocating checking of the
- // authorized responder in a future update.
- }
-
- // verify the signature
- try {
- cert.verify(responderCert.getPublicKey());
- responderCert = cert;
- // cert is trusted, now verify the signed response
-
- } catch (GeneralSecurityException e) {
- responderCert = null;
+ cert.checkValidity(dateCheckedAgainst);
+ }
+ } catch (GeneralSecurityException e) {
+ throw new CertPathValidatorException(
+ "Responder's certificate not within the " +
+ "validity period", e);
+ }
+
+ // check for revocation
+ //
+ // A CA may specify that an OCSP client can trust a
+ // responder for the lifetime of the responder's
+ // certificate. The CA does so by including the
+ // extension id-pkix-ocsp-nocheck.
+ //
+ Extension noCheck =
+ cert.getExtension(PKIXExtensions.OCSPNoCheck_Id);
+ if (noCheck != null) {
+ if (DEBUG != null) {
+ DEBUG.println("Responder's certificate includes " +
+ "the extension id-pkix-ocsp-nocheck.");
}
} else {
- if (DEBUG != null) {
- DEBUG.println("Responder's certificate is not " +
- "authorized to sign OCSP responses.");
- }
- throw new CertPathValidatorException(
- "Responder's certificate not authorized to sign " +
- "OCSP responses");
- }
- }
-
- // Confirm that the signed response was generated using the public
- // key from the trusted responder cert
- if (responderCert != null) {
-
- if (! verifyResponse(responseDataDer, responderCert,
- sigAlgId, signature, params)) {
- if (DEBUG != null) {
- DEBUG.println("Error verifying OCSP Responder's " +
- "signature");
- }
- throw new CertPathValidatorException(
- "Error verifying OCSP Responder's signature");
+ // we should do the revocation checking of the
+ // authorized responder in a future update.
+ }
+
+ // verify the signature
+ try {
+ cert.verify(responderCert.getPublicKey());
+ responderCert = cert;
+ // cert is trusted, now verify the signed response
+
+ } catch (GeneralSecurityException e) {
+ responderCert = null;
}
} else {
- // Need responder's cert in order to verify the signature
- if (DEBUG != null) {
- DEBUG.println("Unable to verify OCSP Responder's " +
- "signature");
- }
throw new CertPathValidatorException(
- "Unable to verify OCSP Responder's signature");
- }
- } catch (CertPathValidatorException cpve) {
- throw cpve;
- } catch (Exception e) {
- throw new CertPathValidatorException(e);
- }
+ "Responder's certificate is not authorized to sign " +
+ "OCSP responses");
+ }
+ }
+
+ // Confirm that the signed response was generated using the public
+ // key from the trusted responder cert
+ if (responderCert != null) {
+ if (!verifyResponse(responseDataDer, responderCert,
+ sigAlgId, signature)) {
+ throw new CertPathValidatorException(
+ "Error verifying OCSP Responder's signature");
+ }
+ } else {
+ // Need responder's cert in order to verify the signature
+ throw new CertPathValidatorException(
+ "Unable to verify OCSP Responder's signature");
+ }
+ }
+
+ /**
+ * Returns the OCSP ResponseStatus.
+ */
+ ResponseStatus getResponseStatus() {
+ return responseStatus;
}
/*
@@ -449,11 +446,10 @@ class OCSPResponse {
* The responder's cert is implicitly trusted.
*/
private boolean verifyResponse(byte[] responseData, X509Certificate cert,
- AlgorithmId sigAlgId, byte[] signBytes, PKIXParameters params)
- throws SignatureException {
+ AlgorithmId sigAlgId, byte[] signBytes)
+ throws CertPathValidatorException {
try {
-
Signature respSignature = Signature.getInstance(sigAlgId.getName());
respSignature.initVerify(cert);
respSignature.update(responseData);
@@ -472,92 +468,33 @@ class OCSPResponse {
return false;
}
} catch (InvalidKeyException ike) {
- throw new SignatureException(ike);
-
+ throw new CertPathValidatorException(ike);
} catch (NoSuchAlgorithmException nsae) {
- throw new SignatureException(nsae);
+ throw new CertPathValidatorException(nsae);
+ } catch (SignatureException se) {
+ throw new CertPathValidatorException(se);
}
}
- /*
- * Return the revocation status code for a given certificate.
+ /**
+ * Returns the SingleResponse of the specified CertId, or null if
+ * there is no response for that CertId.
*/
- // used by OCSPChecker
- int getCertStatus(SerialNumber sn) {
- // ignore serial number for now; if we support multiple
- // requests/responses then it will be used
- return singleResponse.getStatus();
- }
-
- // used by OCSPChecker
- CertId getCertId() {
- return singleResponse.getCertId();
- }
-
- Date getRevocationTime() {
- return singleResponse.getRevocationTime();
- }
-
- CRLReason getRevocationReason() {
- return singleResponse.getRevocationReason();
- }
-
- Map<String, java.security.cert.Extension> getSingleExtensions() {
- return singleResponse.getSingleExtensions();
- }
-
- /*
- * Map an OCSP response status code to a string.
- */
- static private String responseToText(int status) {
- switch (status) {
- case 0:
- return "Successful";
- case 1:
- return "Malformed request";
- case 2:
- return "Internal error";
- case 3:
- return "Try again later";
- case 4:
- return "Unused status code";
- case 5:
- return "Request must be signed";
- case 6:
- return "Request is unauthorized";
- default:
- return ("Unknown status code: " + status);
- }
- }
-
- /*
- * Map a certificate's revocation status code to a string.
- */
- // used by OCSPChecker
- static String certStatusToText(int certStatus) {
- switch (certStatus) {
- case 0:
- return "Good";
- case 1:
- return "Revoked";
- case 2:
- return "Unknown";
- default:
- return ("Unknown certificate status code: " + certStatus);
- }
+ SingleResponse getSingleResponse(CertId certId) {
+ return singleResponseMap.get(certId);
}
/*
* A class representing a single OCSP response.
*/
- private class SingleResponse {
- private CertId certId;
- private int certStatus;
- private Date thisUpdate;
- private Date nextUpdate;
- private Date revocationTime;
- private CRLReason revocationReason = CRLReason.UNSPECIFIED;
- private HashMap<String, java.security.cert.Extension> singleExtensions;
+ final static class SingleResponse implements OCSP.RevocationStatus {
+ private final CertId certId;
+ private final CertStatus certStatus;
+ private final Date thisUpdate;
+ private final Date nextUpdate;
+ private final Date revocationTime;
+ private final CRLReason revocationReason;
+ private final Map<String, java.security.cert.Extension> singleExtensions;
private SingleResponse(DerValue der) throws IOException {
if (der.tag != DerValue.tag_Sequence) {
@@ -568,35 +505,48 @@ class OCSPResponse {
certId = new CertId(tmp.getDerValue().data);
DerValue derVal = tmp.getDerValue();
short tag = (byte)(derVal.tag & 0x1f);
- if (tag == CERT_STATUS_GOOD) {
- certStatus = CERT_STATUS_GOOD;
- } else if (tag == CERT_STATUS_REVOKED) {
- certStatus = CERT_STATUS_REVOKED;
+ if (tag == CERT_STATUS_REVOKED) {
+ certStatus = CertStatus.REVOKED;
revocationTime = derVal.data.getGeneralizedTime();
if (derVal.data.available() != 0) {
- int reason = derVal.getEnumerated();
- // if reason out-of-range just leave as UNSPECIFIED
- if (reason >= 0 && reason < values.length) {
- revocationReason = values[reason];
- }
+ DerValue dv = derVal.data.getDerValue();
+ tag = (byte)(dv.tag & 0x1f);
+ if (tag == 0) {
+ int reason = dv.data.getEnumerated();
+ // if reason out-of-range just leave as UNSPECIFIED
+ if (reason >= 0 && reason < values.length) {
+ revocationReason = values[reason];
+ } else {
+ revocationReason = CRLReason.UNSPECIFIED;
+ }
+ } else {
+ revocationReason = CRLReason.UNSPECIFIED;
+ }
+ } else {
+ revocationReason = CRLReason.UNSPECIFIED;
}
// RevokedInfo
if (DEBUG != null) {
DEBUG.println("Revocation time: " + revocationTime);
DEBUG.println("Revocation reason: " + revocationReason);
}
-
- } else if (tag == CERT_STATUS_UNKNOWN) {
- certStatus = CERT_STATUS_UNKNOWN;
-
} else {
- throw new IOException("Invalid certificate status");
+ revocationTime = null;
+ revocationReason = CRLReason.UNSPECIFIED;
+ if (tag == CERT_STATUS_GOOD) {
+ certStatus = CertStatus.GOOD;
+ } else if (tag == CERT_STATUS_UNKNOWN) {
+ certStatus = CertStatus.UNKNOWN;
+ } else {
+ throw new IOException("Invalid certificate status");
+ }
}
thisUpdate = tmp.getGeneralizedTime();
if (tmp.available() == 0) {
// we are done
+ nextUpdate = null;
} else {
derVal = tmp.getDerValue();
tag = (byte)(derVal.tag & 0x1f);
@@ -610,6 +560,8 @@ class OCSPResponse {
derVal = tmp.getDerValue();
tag = (byte)(derVal.tag & 0x1f);
}
+ } else {
+ nextUpdate = null;
}
}
// singleExtensions
@@ -627,7 +579,11 @@ class OCSPResponse {
DEBUG.println("OCSP single extension: " + ext);
}
}
- }
+ } else {
+ singleExtensions = Collections.emptyMap();
+ }
+ } else {
+ singleExtensions = Collections.emptyMap();
}
long now = System.currentTimeMillis();
@@ -657,7 +613,7 @@ class OCSPResponse {
/*
* Return the certificate's revocation status code
*/
- private int getStatus() {
+ @Override public CertStatus getCertStatus() {
return certStatus;
}
@@ -665,28 +621,28 @@ class OCSPResponse {
return certId;
}
- private Date getRevocationTime() {
- return revocationTime;
- }
-
- private CRLReason getRevocationReason() {
+ @Override public Date getRevocationTime() {
+ return (Date) revocationTime.clone();
+ }
+
+ @Override public CRLReason getRevocationReason() {
return revocationReason;
}
- private Map<String, java.security.cert.Extension> getSingleExtensions() {
- return singleExtensions;
+ @Override
+ public Map<String, java.security.cert.Extension> getSingleExtensions() {
+ return Collections.unmodifiableMap(singleExtensions);
}
/**
* Construct a string representation of a single OCSP response.
*/
- public String toString() {
+ @Override public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("SingleResponse: \n");
sb.append(certId);
- sb.append("\nCertStatus: "+ certStatusToText(getCertStatus(null)) +
- "\n");
- if (certStatus == CERT_STATUS_REVOKED) {
+ sb.append("\nCertStatus: "+ certStatus + "\n");
+ if (certStatus == CertStatus.REVOKED) {
sb.append("revocationTime is " + revocationTime + "\n");
sb.append("revocationReason is " + revocationReason + "\n");
}
--- a/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Tue Sep 29 15:31:18 2009 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2009 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,8 +28,6 @@ import java.io.IOException;
import java.io.IOException;
import java.security.AccessController;
import java.security.InvalidAlgorithmParameterException;
-import java.security.PrivilegedAction;
-import java.security.Security;
import java.security.cert.CertPath;
import java.security.cert.CertPathParameters;
import java.security.cert.CertPathValidatorException;
@@ -49,6 +47,7 @@ import java.util.Date;
import java.util.Date;
import java.util.Set;
import javax.security.auth.x500.X500Principal;
+import sun.security.action.GetBooleanSecurityPropertyAction;
import sun.security.util.Debug;
/**
@@ -67,7 +66,8 @@ public class PKIXCertPathValidator exten
private List<PKIXCertPathChecker> userCheckers;
private String sigProvider;
private BasicChecker basicChecker;
- private String ocspProperty;
+ private boolean ocspEnabled = false;
+ private boolean onlyEECert = false;
/**
* Default constructor.
@@ -253,13 +253,12 @@ public class PKIXCertPathValidator exten
if (pkixParam.isRevocationEnabled()) {
// Examine OCSP security property
- ocspProperty = AccessController.doPrivileged(
- new PrivilegedAction<String>() {
- public String run() {
- return
- Security.getProperty(OCSPChecker.OCSP_ENABLE_PROP);
- }
- });
+ ocspEnabled = AccessController.doPrivileged(
+ new GetBooleanSecurityPropertyAction
+ (OCSPChecker.OCSP_ENABLE_PROP));
+ onlyEECert = AccessController.doPrivileged(
+ new GetBooleanSecurityPropertyAction
+ ("com.sun.security.onlyCheckRevocationOfEECert"));
}
}
@@ -301,15 +300,15 @@ public class PKIXCertPathValidator exten
if (pkixParam.isRevocationEnabled()) {
// Use OCSP if it has been enabled
- if ("true".equalsIgnoreCase(ocspProperty)) {
+ if (ocspEnabled) {
OCSPChecker ocspChecker =
- new OCSPChecker(cpOriginal, pkixParam);
+ new OCSPChecker(cpOriginal, pkixParam, onlyEECert);
certPathCheckers.add(ocspChecker);
}
// Always use CRLs
- CrlRevocationChecker revocationChecker =
- new CrlRevocationChecker(anchor, pkixParam, certList);
+ CrlRevocationChecker revocationChecker = new
+ CrlRevocationChecker(anchor, pkixParam, certList, onlyEECert);
certPathCheckers.add(revocationChecker);
}
--- a/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java Tue Sep 29 15:31:18 2009 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2009 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.provider.certpath;
package sun.security.provider.certpath;
import java.io.IOException;
+import java.security.AccessController;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.Principal;
@@ -44,6 +45,7 @@ import java.util.Set;
import java.util.Set;
import javax.security.auth.x500.X500Principal;
+import sun.security.action.GetBooleanSecurityPropertyAction;
import sun.security.x509.X500Name;
import sun.security.x509.PKIXExtensions;
import sun.security.util.Debug;
@@ -85,6 +87,7 @@ public final class SunCertPathBuilder ex
private PublicKey finalPublicKey;
private X509CertSelector targetSel;
private List<CertStore> orderedCertStores;
+ private boolean onlyEECert = false;
/**
* Create an instance of <code>SunCertPathBuilder</code>.
@@ -97,6 +100,9 @@ public final class SunCertPathBuilder ex
} catch (CertificateException e) {
throw new CertPathBuilderException(e);
}
+ onlyEECert = AccessController.doPrivileged(
+ new GetBooleanSecurityPropertyAction
+ ("com.sun.security.onlyCheckRevocationOfEECert"));
}
/**
@@ -256,7 +262,6 @@ public final class SunCertPathBuilder ex
/*
* Private build reverse method.
- *
*/
private void buildReverse(List<List<Vertex>> adjacencyList,
LinkedList<X509Certificate> certPathList) throws Exception
@@ -296,7 +301,7 @@ public final class SunCertPathBuilder ex
currentState.updateState(anchor);
// init the crl checker
currentState.crlChecker =
- new CrlRevocationChecker(null, buildParams);
+ new CrlRevocationChecker(null, buildParams, null, onlyEECert);
try {
depthFirstSearchReverse(null, currentState,
new ReverseBuilder(buildParams, targetSubjectDN), adjacencyList,
@@ -341,10 +346,12 @@ public final class SunCertPathBuilder ex
adjacencyList.add(new LinkedList<Vertex>());
// init the crl checker
- currentState.crlChecker = new CrlRevocationChecker(null, buildParams);
+ currentState.crlChecker
+ = new CrlRevocationChecker(null, buildParams, null, onlyEECert);
depthFirstSearchForward(targetSubjectDN, currentState,
- new ForwardBuilder(buildParams, targetSubjectDN, searchAllCertStores),
+ new ForwardBuilder
+ (buildParams, targetSubjectDN, searchAllCertStores, onlyEECert),
adjacencyList, certPathList);
}
@@ -486,8 +493,8 @@ public final class SunCertPathBuilder ex
userCheckers.add(mustCheck, basicChecker);
mustCheck++;
if (buildParams.isRevocationEnabled()) {
- userCheckers.add(mustCheck,
- new CrlRevocationChecker(anchor, buildParams));
+ userCheckers.add(mustCheck, new CrlRevocationChecker
+ (anchor, buildParams, null, onlyEECert));
mustCheck++;
}
}
--- a/src/share/classes/sun/security/x509/AccessDescription.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/security/x509/AccessDescription.java Tue Sep 29 15:31:18 2009 -0700
@@ -113,7 +113,7 @@ public final class AccessDescription {
} else {
method = accessMethod.toString();
}
- return ("accessMethod: " + method +
+ return ("\n accessMethod: " + method +
"\n accessLocation: " + accessLocation.toString() + "\n");
}
}
--- a/src/share/classes/sun/util/LocaleServiceProviderPool.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/classes/sun/util/LocaleServiceProviderPool.java Tue Sep 29 15:31:18 2009 -0700
@@ -39,8 +39,8 @@ import java.util.ServiceConfigurationErr
import java.util.ServiceConfigurationError;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Logger;
import java.util.spi.LocaleServiceProvider;
+import sun.util.logging.PlatformLogger;
import sun.util.resources.LocaleData;
import sun.util.resources.OpenListResourceBundle;
@@ -122,8 +122,13 @@ public final class LocaleServiceProvider
}
});
} catch (PrivilegedActionException e) {
- Logger.getLogger("sun.util.LocaleServiceProviderPool").config(e.toString());
- }
+ config(e.toString());
+ }
+ }
+
+ private static void config(String message) {
+ PlatformLogger logger = PlatformLogger.getLogger("sun.util.LocaleServiceProviderPool");
+ logger.config(message);
}
/**
@@ -337,7 +342,7 @@ public final class LocaleServiceProvider
if (providersObj != null) {
return providersObj;
} else if (isObjectProvider) {
- Logger.getLogger("sun.util.LocaleServiceProviderPool").config(
+ config(
"A locale sensitive service provider returned null for a localized objects, which should not happen. provider: " + lsp + " locale: " + requested);
}
}
--- a/src/share/demo/jvmti/waiters/Agent.cpp Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/demo/jvmti/waiters/Agent.cpp Tue Sep 29 15:31:18 2009 -0700
@@ -72,36 +72,30 @@ Agent::get_monitor(jvmtiEnv *jvmti, JNIE
{
jvmtiError err;
Monitor *m;
-
- /* We use tags to track these, the tag is the Monitor pointer */
- err = jvmti->RawMonitorEnter(lock); {
- check_jvmti_error(jvmti, err, "raw monitor enter");
-
- /* The raw monitor enter/exit protects us from creating two
- * instances for the same object.
- */
- jlong tag;
-
- m = NULL;
- tag = (jlong)0;
- err = jvmti->GetTag(object, &tag);
- check_jvmti_error(jvmti, err, "get tag");
+ jlong tag;
+
+ m = NULL;
+ tag = (jlong)0;
+ err = jvmti->GetTag(object, &tag);
+ check_jvmti_error(jvmti, err, "get tag");
+ /*LINTED*/
+ m = (Monitor *)(void *)(ptrdiff_t)tag;
+ if ( m == NULL ) {
+ m = new Monitor(jvmti, env, object);
+ /* Save monitor on list */
+ if (monitor_count == monitor_list_size) {
+ monitor_list_size += monitor_list_grow_size;
+ monitor_list = (Monitor**)realloc((void*)monitor_list,
+ (monitor_list_size)*(int)sizeof(Monitor*));
+ }
+ monitor_list[monitor_count] = m;
+ m->set_slot(monitor_count);
+ monitor_count++;
/*LINTED*/
- m = (Monitor *)(void *)(ptrdiff_t)tag;
- if ( m == NULL ) {
- m = new Monitor(jvmti, env, object);
- /*LINTED*/
- tag = (jlong)(ptrdiff_t)(void *)m;
- err = jvmti->SetTag(object, tag);
- check_jvmti_error(jvmti, err, "set tag");
- /* Save monitor on list */
- monitor_list = (Monitor**)realloc((void*)monitor_list,
- (monitor_count+1)*(int)sizeof(Monitor*));
- monitor_list[monitor_count++] = m;
- }
- } err = jvmti->RawMonitorExit(lock);
- check_jvmti_error(jvmti, err, "raw monitor exit");
-
+ tag = (jlong)(ptrdiff_t)(void *)m;
+ err = jvmti->SetTag(object, tag);
+ check_jvmti_error(jvmti, err, "set tag");
+ }
return m;
}
@@ -112,12 +106,11 @@ Agent::Agent(jvmtiEnv *jvmti, JNIEnv *en
stdout_message("Agent created..\n");
stdout_message("VMInit...\n");
- /* Create a Monitor lock to use */
- err = jvmti->CreateRawMonitor("waiters Agent lock", &lock);
- check_jvmti_error(jvmti, err, "create raw monitor");
/* Start monitor list */
monitor_count = 0;
- monitor_list = (Monitor**)malloc((int)sizeof(Monitor*));
+ monitor_list_size = initial_monitor_list_size;
+ monitor_list = (Monitor**)
+ malloc(monitor_list_size*(int)sizeof(Monitor*));
}
Agent::~Agent()
@@ -134,9 +127,6 @@ void Agent::vm_death(jvmtiEnv *jvmti, JN
delete monitor_list[i];
}
free(monitor_list);
- /* Destroy the Monitor lock to use */
- err = jvmti->DestroyRawMonitor(lock);
- check_jvmti_error(jvmti, err, "destroy raw monitor");
/* Print death message */
stdout_message("VMDeath...\n");
}
@@ -215,8 +205,16 @@ void Agent::object_free(jvmtiEnv* jvmti,
/* We just cast the tag to a C++ pointer and delete it.
* we know it can only be a Monitor *.
*/
- Monitor *m;
+ Monitor *m;
/*LINTED*/
m = (Monitor *)(ptrdiff_t)tag;
+ if (monitor_count > 1) {
+ /* Move the last element to this Monitor's slot */
+ int slot = m->get_slot();
+ Monitor *last = monitor_list[monitor_count-1];
+ monitor_list[slot] = last;
+ last->set_slot(slot);
+ }
+ monitor_count--;
delete m;
}
--- a/src/share/demo/jvmti/waiters/Agent.hpp Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/demo/jvmti/waiters/Agent.hpp Tue Sep 29 15:31:18 2009 -0700
@@ -34,8 +34,12 @@ class Agent {
class Agent {
private:
- jrawMonitorID lock;
+ enum {
+ initial_monitor_list_size = 64,
+ monitor_list_grow_size = 16
+ };
Monitor **monitor_list;
+ unsigned monitor_list_size;
unsigned monitor_count;
Thread *get_thread(jvmtiEnv *jvmti, JNIEnv *env, jthread thread);
Monitor *get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object);
--- a/src/share/demo/jvmti/waiters/Monitor.cpp Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/demo/jvmti/waiters/Monitor.cpp Tue Sep 29 15:31:18 2009 -0700
@@ -73,6 +73,16 @@ Monitor::~Monitor()
name, contends, waits, timeouts);
}
+int Monitor::get_slot()
+{
+ return slot;
+}
+
+void Monitor::set_slot(int aslot)
+{
+ slot = aslot;
+}
+
void Monitor::contended()
{
contends++;
--- a/src/share/demo/jvmti/waiters/Monitor.hpp Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/demo/jvmti/waiters/Monitor.hpp Tue Sep 29 15:31:18 2009 -0700
@@ -35,6 +35,7 @@ class Monitor {
private:
char name[64];
+ int slot;
unsigned contends;
unsigned waits;
unsigned timeouts;
@@ -42,6 +43,8 @@ class Monitor {
public:
Monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object);
~Monitor();
+ int get_slot();
+ void set_slot(int i);
void contended();
void waited();
void timeout();
--- a/src/share/javavm/export/jvm.h Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/javavm/export/jvm.h Tue Sep 29 15:31:18 2009 -0700
@@ -373,6 +373,12 @@ JVM_FindPrimitiveClass(JNIEnv *env, cons
*/
JNIEXPORT void JNICALL
JVM_ResolveClass(JNIEnv *env, jclass cls);
+
+/*
+ * Find a class from a boot class loader. Returns NULL if class not found.
+ */
+JNIEXPORT jclass JNICALL
+JVM_FindClassFromBootLoader(JNIEnv *env, const char *name);
/*
* Find a class from a given class loader. Throw ClassNotFoundException
--- a/src/share/lib/net.properties Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/lib/net.properties Tue Sep 29 15:31:18 2009 -0700
@@ -32,7 +32,7 @@ java.net.useSystemProxies=false
#
# http.proxyHost=
# http.proxyPort=80
-# http.nonProxyHosts=localhost|127.0.0.1
+http.nonProxyHosts=localhost|127.*|[::1]
#
# HTTPS Proxy Settings. proxyHost is the name of the proxy server
# (e.g. proxy.mydomain.com), proxyPort is the port number to use (default
@@ -49,7 +49,7 @@ java.net.useSystemProxies=false
#
# ftp.proxyHost=
# ftp.proxyPort=80
-# ftp.nonProxyHosts=localhost|127.0.0.1
+ftp.nonProxyHosts=localhost|127.*|[::1]
#
# Gopher Proxy settings. proxyHost is the name of the proxy server
# (e.g. proxy.mydomain.com), proxyPort is the port number to use (default
--- a/src/share/native/java/lang/ClassLoader.c Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/native/java/lang/ClassLoader.c Tue Sep 29 15:31:18 2009 -0700
@@ -237,6 +237,9 @@ Java_java_lang_ClassLoader_resolveClass0
JVM_ResolveClass(env, cls);
}
+/*
+ * Returns NULL if class not found.
+ */
JNIEXPORT jclass JNICALL
Java_java_lang_ClassLoader_findBootstrapClass(JNIEnv *env, jobject loader,
jstring classname)
@@ -246,7 +249,6 @@ Java_java_lang_ClassLoader_findBootstrap
char buf[128];
if (classname == NULL) {
- JNU_ThrowClassNotFoundException(env, 0);
return 0;
}
@@ -258,11 +260,10 @@ Java_java_lang_ClassLoader_findBootstrap
VerifyFixClassname(clname);
if (!VerifyClassname(clname, JNI_TRUE)) { /* expects slashed name */
- JNU_ThrowClassNotFoundException(env, clname);
goto done;
}
- cls = JVM_FindClassFromClassLoader(env, clname, JNI_FALSE, 0, JNI_FALSE);
+ cls = JVM_FindClassFromBootLoader(env, clname);
done:
if (clname != buf) {
--- a/src/share/native/sun/security/ec/ECC_JNI.cpp Tue Sep 29 14:06:13 2009 -0700
+++ b/src/share/native/sun/security/ec/ECC_JNI.cpp Tue Sep 29 15:31:18 2009 -0700
@@ -24,7 +24,7 @@
*/
#include <jni.h>
-#include "ecc_impl.h"
+#include "impl/ecc_impl.h"
#define ILLEGAL_STATE_EXCEPTION "java/lang/IllegalStateException"
#define INVALID_ALGORITHM_PARAMETER_EXCEPTION \
--- a/src/solaris/bin/java_md.c Tue Sep 29 14:06:13 2009 -0700
+++ b/src/solaris/bin/java_md.c Tue Sep 29 15:31:18 2009 -0700
@@ -1324,12 +1324,12 @@ FindBootStrapClass(JNIEnv *env, const ch
{
if (findBootClass == NULL) {
findBootClass = (FindClassFromBootLoader_t *)dlsym(RTLD_DEFAULT,
- "JVM_FindClassFromClassLoader");
+ "JVM_FindClassFromBootLoader");
if (findBootClass == NULL) {
JLI_ReportErrorMessage(DLL_ERROR4,
- "JVM_FindClassFromClassLoader");
+ "JVM_FindClassFromBootLoader");
return NULL;
}
}
- return findBootClass(env, classname, JNI_FALSE, (jobject)NULL, JNI_FALSE);
-}
+ return findBootClass(env, classname);
+}
--- a/src/solaris/classes/sun/net/www/protocol/http/NTLMAuthentication.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/solaris/classes/sun/net/www/protocol/http/NTLMAuthentication.java Tue Sep 29 15:31:18 2009 -0700
@@ -25,17 +25,22 @@
package sun.net.www.protocol.http;
-import java.util.Arrays;
-import java.util.StringTokenizer;
-import java.util.Random;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.net.PasswordAuthentication;
+import java.net.UnknownHostException;
+import java.net.URL;
+import java.security.GeneralSecurityException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.DESKeySpec;
import sun.net.www.HeaderParser;
-
-import java.io.*;
-import javax.crypto.*;
-import javax.crypto.spec.*;
-import java.security.*;
-import java.net.*;
/**
* NTLMAuthentication:
@@ -65,8 +70,6 @@ import java.net.*;
class NTLMAuthentication extends AuthenticationInfo {
private static final long serialVersionUID = -2403849171106437142L;
-
- static char NTLM_AUTH = 'N';
private byte[] type1;
private byte[] type3;
@@ -142,7 +145,10 @@ class NTLMAuthentication extends Authent
* from a system property: "http.auth.ntlm.domain".
*/
public NTLMAuthentication(boolean isProxy, URL url, PasswordAuthentication pw) {
- super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION, NTLM_AUTH, url, "");
+ super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
+ AuthScheme.NTLM,
+ url,
+ "");
init (pw);
}
@@ -166,7 +172,11 @@ class NTLMAuthentication extends Authent
*/
public NTLMAuthentication(boolean isProxy, String host, int port,
PasswordAuthentication pw) {
- super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION, NTLM_AUTH,host, port, "");
+ super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
+ AuthScheme.NTLM,
+ host,
+ port,
+ "");
init (pw);
}
--- a/src/windows/bin/java_md.c Tue Sep 29 14:06:13 2009 -0700
+++ b/src/windows/bin/java_md.c Tue Sep 29 15:31:18 2009 -0700
@@ -1093,12 +1093,6 @@ void SetJavaLauncherPlatformProps() {}
*/
static FindClassFromBootLoader_t *findBootClass = NULL;
-#ifdef _M_AMD64
-#define JVM_BCLOADER "JVM_FindClassFromClassLoader"
-#else
-#define JVM_BCLOADER "_JVM_FindClassFromClassLoader@20"
-#endif /* _M_AMD64 */
-
jclass FindBootStrapClass(JNIEnv *env, const char *classname)
{
HMODULE hJvm;
@@ -1108,13 +1102,13 @@ jclass FindBootStrapClass(JNIEnv *env, c
if (hJvm == NULL) return NULL;
/* need to use the demangled entry point */
findBootClass = (FindClassFromBootLoader_t *)GetProcAddress(hJvm,
- JVM_BCLOADER);
+ "JVM_FindClassFromBootLoader");
if (findBootClass == NULL) {
- JLI_ReportErrorMessage(DLL_ERROR4, JVM_BCLOADER);
+ JLI_ReportErrorMessage(DLL_ERROR4, "JVM_FindClassFromBootLoader");
return NULL;
}
}
- return findBootClass(env, classname, JNI_FALSE, (jobject)NULL, JNI_FALSE);
+ return findBootClass(env, classname);
}
void
--- a/src/windows/classes/java/util/prefs/WindowsPreferences.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/windows/classes/java/util/prefs/WindowsPreferences.java Tue Sep 29 15:31:18 2009 -0700
@@ -29,7 +29,7 @@ import java.util.TreeMap;
import java.util.TreeMap;
import java.util.StringTokenizer;
import java.io.ByteArrayOutputStream;
-import java.util.logging.Logger;
+import sun.util.logging.PlatformLogger;
/**
* Windows registry based implementation of <tt>Preferences</tt>.
@@ -48,7 +48,7 @@ class WindowsPreferences extends Abstrac
/**
* Logger for error messages
*/
- private static Logger logger;
+ private static PlatformLogger logger;
/**
* Windows registry path to <tt>Preferences</tt>'s root nodes.
@@ -1102,9 +1102,9 @@ class WindowsPreferences extends Abstrac
// assert false;
}
- private static synchronized Logger logger() {
+ private static synchronized PlatformLogger logger() {
if (logger == null) {
- logger = Logger.getLogger("java.util.prefs");
+ logger = PlatformLogger.getLogger("java.util.prefs");
}
return logger;
}
--- a/src/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java Tue Sep 29 15:31:18 2009 -0700
@@ -67,6 +67,9 @@ public class D3DGraphicsDevice extends W
if (d3dAvailable) {
// we don't use pixel formats for the d3d pipeline
pfDisabled = true;
+ sun.misc.PerfCounter.getD3DAvailable().set(1);
+ } else {
+ sun.misc.PerfCounter.getD3DAvailable().set(0);
}
}
--- a/src/windows/classes/sun/net/www/protocol/http/NTLMAuthentication.java Tue Sep 29 14:06:13 2009 -0700
+++ b/src/windows/classes/sun/net/www/protocol/http/NTLMAuthentication.java Tue Sep 29 15:31:18 2009 -0700
@@ -25,17 +25,12 @@
package sun.net.www.protocol.http;
-import java.util.Arrays;
-import java.util.StringTokenizer;
-import java.util.Random;
-
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.PasswordAuthentication;
+import java.net.UnknownHostException;
+import java.net.URL;
import sun.net.www.HeaderParser;
-
-import java.io.*;
-import javax.crypto.*;
-import javax.crypto.spec.*;
-import java.security.*;
-import java.net.*;
/**
* NTLMAuthentication:
@@ -47,7 +42,6 @@ class NTLMAuthentication extends Authent
private static final long serialVersionUID = 100L;
- static final char NTLM_AUTH = 'N';
private String hostname;
private static String defaultDomain; /* Domain to use if not specified by user */
@@ -88,7 +82,10 @@ class NTLMAuthentication extends Authent
* from a system property: "http.auth.ntlm.domain".
*/
public NTLMAuthentication(boolean isProxy, URL url, PasswordAuthentication pw) {
- super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION, NTLM_AUTH, url, "");
+ super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
+ AuthScheme.NTLM,
+ url,
+ "");
init (pw);
}
@@ -119,7 +116,11 @@ class NTLMAuthentication extends Authent
*/
public NTLMAuthentication(boolean isProxy, String host, int port,
PasswordAuthentication pw) {
- super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION, NTLM_AUTH,host, port, "");
+ super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION,
+ AuthScheme.NTLM,
+ host,
+ port,
+ "");
init (pw);
}
--- a/test/java/lang/ProcessBuilder/Basic.java Tue Sep 29 14:06:13 2009 -0700
+++ b/test/java/lang/ProcessBuilder/Basic.java Tue Sep 29 15:31:18 2009 -0700
@@ -25,7 +25,7 @@
* @test
* @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689
* 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
- * 6464154 6523983 6206031 4960438 6631352 6631966
+ * 6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958
* @summary Basic tests for Process and Environment Variable code
* @run main/othervm Basic
* @author Martin Buchholz
@@ -302,6 +302,14 @@ public class Basic {
printUTF8(val == null ? "null" : val);
} else if (action.equals("System.getenv()")) {
printUTF8(getenvAsString(System.getenv()));
+ } else if (action.equals("ArrayOOME")) {
+ Object dummy;
+ switch(new Random().nextInt(3)) {
+ case 0: dummy = new Integer[Integer.MAX_VALUE]; break;
+ case 1: dummy = new double[Integer.MAX_VALUE]; break;
+ case 2: dummy = new byte[Integer.MAX_VALUE][]; break;
+ default: throw new InternalError();
+ }
} else if (action.equals("pwd")) {
printUTF8(new File(System.getProperty("user.dir"))
.getCanonicalPath());
@@ -1473,6 +1481,22 @@ public class Basic {
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
+ // OOME in child allocating maximally sized array
+ // Test for hotspot/jvmti bug 6850957
+ //----------------------------------------------------------------
+ try {
+ List<String> list = new ArrayList<String>(javaChildArgs);
+ list.add(1, String.format("-XX:OnOutOfMemoryError=%s -version",
+ javaExe));
+ list.add("ArrayOOME");
+ ProcessResults r = run(new ProcessBuilder(list));
+ check(r.out().contains("java.lang.OutOfMemoryError:"));
+ check(r.out().contains(javaExe));
+ check(r.err().contains(System.getProperty("java.version")));
+ equal(r.exitValue(), 1);
+ } catch (Throwable t) { unexpected(t); }
+
+ //----------------------------------------------------------------
// Windows has tricky semi-case-insensitive semantics
//----------------------------------------------------------------
if (Windows.is())
--- a/test/sun/security/ec/TestEC.java Tue Sep 29 14:06:13 2009 -0700
+++ b/test/sun/security/ec/TestEC.java Tue Sep 29 15:31:18 2009 -0700
@@ -27,6 +27,8 @@
* @summary Provide out-of-the-box support for ECC algorithms
* @library ../pkcs11
* @library ../pkcs11/ec
+ * @library ../pkcs11/sslecc
+ * @compile -XDignore.symbol.file TestEC.java
* @run main TestEC
*/
@@ -35,12 +37,15 @@ import java.security.Provider;
/*
* Leverage the collection of EC tests used by PKCS11
*
- * NOTE: the following files were copied here from the PKCS11 EC Test area
+ * NOTE: the following 6 files were copied here from the PKCS11 EC Test area
* and must be kept in sync with the originals:
*
* ../pkcs11/ec/p12passwords.txt
+ * ../pkcs11/ec/certs/sunlabscerts.pem
* ../pkcs11/ec/pkcs12/secp256r1server-secp384r1ca.p12
* ../pkcs11/ec/pkcs12/sect193r1server-rsa1024ca.p12
+ * ../pkcs11/sslecc/keystore
+ * ../pkcs11/sslecc/truststore
*/
public class TestEC {
@@ -49,18 +54,23 @@ public class TestEC {
Provider p = new sun.security.ec.SunEC();
System.out.println("Running tests with " + p.getName() +
" provider...\n");
+ long start = System.currentTimeMillis();
- long start = System.currentTimeMillis();
+ /*
+ * The entry point used for each test is its instance method
+ * called main (not its static method called main).
+ */
new TestECDH().main(p);
new TestECDSA().main(p);
new TestCurves().main(p);
new TestKeyFactory().main(p);
new TestECGenSpec().main(p);
new ReadPKCS12().main(p);
- //new ReadCertificates().main(p);
+ new ReadCertificates().main(p);
+ new ClientJSSEServerJSSE().main(p);
+
long stop = System.currentTimeMillis();
-
System.out.println("\nCompleted tests with " + p.getName() +
- " provider (" + (stop - start) + " ms).");
+ " provider (" + ((stop - start) / 1000.0) + " seconds).");
}
}
--- a/test/sun/security/pkcs11/ec/ReadCertificates.java Tue Sep 29 14:06:13 2009 -0700
+++ b/test/sun/security/pkcs11/ec/ReadCertificates.java Tue Sep 29 15:31:18 2009 -0700
@@ -100,7 +100,15 @@ public class ReadCertificates extends PK
X509Certificate issuer = certs.get(cert.getIssuerX500Principal());
System.out.println("Verifying " + cert.getSubjectX500Principal() + "...");
PublicKey key = issuer.getPublicKey();
- cert.verify(key, p.getName());
+ // First try the provider under test (if it does not support the
+ // necessary algorithm then try any registered provider).
+ try {
+ cert.verify(key, p.getName());
+ } catch (NoSuchAlgorithmException e) {
+ System.out.println("Warning: " + e.getMessage() +
+ ". Trying another provider...");
+ cert.verify(key);
+ }
}
// try some random invalid signatures to make sure we get the correct
--- a/test/sun/security/pkcs11/sslecc/CipherTest.java Tue Sep 29 14:06:13 2009 -0700
+++ b/test/sun/security/pkcs11/sslecc/CipherTest.java Tue Sep 29 15:31:18 2009 -0700
@@ -298,7 +298,7 @@ public class CipherTest {
throws Exception {
long time = System.currentTimeMillis();
String relPath;
- if ((args.length > 0) && args[0].equals("sh")) {
+ if ((args != null) && (args.length > 0) && args[0].equals("sh")) {
relPath = pathToStoresSH;
} else {
relPath = pathToStores;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/net/InMemoryCookieStore.java Tue Sep 29 15:31:18 2009 -0700
@@ -0,0 +1,393 @@
+/*
+ * Copyright 2005-2008 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 java.net;
+
+import java.net.URI;
+import java.net.CookieStore;
+import java.net.HttpCookie;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ * A simple in-memory java.net.CookieStore implementation
+ *
+ * @author Edward Wang
+ * @since 1.6
+ */
+class InMemoryCookieStore implements CookieStore {
+ // the in-memory representation of cookies
+ private List<HttpCookie> cookieJar = null;
+
+ // the cookies are indexed by its domain and associated uri (if present)
+ // CAUTION: when a cookie removed from main data structure (i.e. cookieJar),
+ // it won't be cleared in domainIndex & uriIndex. Double-check the
+ // presence of cookie when retrieve one form index store.
+ private Map<String, List<HttpCookie>> domainIndex = null;
+ private Map<URI, List<HttpCookie>> uriIndex = null;
+
+ // use ReentrantLock instead of syncronized for scalability
+ private ReentrantLock lock = null;
+
+
+ /**
+ * The default ctor
+ */
+ public InMemoryCookieStore() {
+ cookieJar = new ArrayList<HttpCookie>();
+ domainIndex = new HashMap<String, List<HttpCookie>>();
+ uriIndex = new HashMap<URI, List<HttpCookie>>();
+
+ lock = new ReentrantLock(false);
+ }
+
+ /**
+ * Add one cookie into cookie store.
+ */
+ public void add(URI uri, HttpCookie cookie) {
+ // pre-condition : argument can't be null
+ if (cookie == null) {
+ throw new NullPointerException("cookie is null");
+ }
+
+
+ lock.lock();
+ try {
+ // remove the ole cookie if there has had one
+ cookieJar.remove(cookie);
+
+ // add new cookie if it has a non-zero max-age
+ if (cookie.getMaxAge() != 0) {
+ cookieJar.add(cookie);
+ // and add it to domain index
+ if (cookie.getDomain() != null) {
+ addIndex(domainIndex, cookie.getDomain(), cookie);
+ }
+ // add it to uri index, too
+ addIndex(uriIndex, getEffectiveURI(uri), cookie);
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+
+ /**
+ * Get all cookies, which:
+ * 1) given uri domain-matches with, or, associated with
+ * given uri when added to the cookie store.
+ * 3) not expired.
+ * See RFC 2965 sec. 3.3.4 for more detail.
+ */
+ public List<HttpCookie> get(URI uri) {
+ // argument can't be null
+ if (uri == null) {
+ throw new NullPointerException("uri is null");
+ }
+
+ List<HttpCookie> cookies = new ArrayList<HttpCookie>();
+ boolean secureLink = "https".equalsIgnoreCase(uri.getScheme());
+ lock.lock();
+ try {
+ // check domainIndex first
+ getInternal1(cookies, domainIndex, uri.getHost(), secureLink);
+ // check uriIndex then
+ getInternal2(cookies, uriIndex, getEffectiveURI(uri), secureLink);
+ } finally {
+ lock.unlock();
+ }
+
+ return cookies;
+ }
+
+ /**
+ * Get all cookies in cookie store, except those have expired
+ */
+ public List<HttpCookie> getCookies() {
+ List<HttpCookie> rt;
+
+ lock.lock();
+ try {
+ Iterator<HttpCookie> it = cookieJar.iterator();
+ while (it.hasNext()) {
+ if (it.next().hasExpired()) {
+ it.remove();
+ }
+ }
+ } finally {
+ rt = Collections.unmodifiableList(cookieJar);
+ lock.unlock();
+ }
+
+ return rt;
+ }
+
+ /**
+ * Get all URIs, which are associated with at least one cookie
+ * of this cookie store.
+ */
+ public List<URI> getURIs() {
+ List<URI> uris = new ArrayList<URI>();
+
+ lock.lock();
+ try {
+ Iterator<URI> it = uriIndex.keySet().iterator();
+ while (it.hasNext()) {
+ URI uri = it.next();
+ List<HttpCookie> cookies = uriIndex.get(uri);
+ if (cookies == null || cookies.size() == 0) {
+ // no cookies list or an empty list associated with
+ // this uri entry, delete it
+ it.remove();
+ }
+ }
+ } finally {
+ uris.addAll(uriIndex.keySet());
+ lock.unlock();
+ }
+
+ return uris;
+ }
+
+
+ /**
+ * Remove a cookie from store
+ */
+ public boolean remove(URI uri, HttpCookie ck) {
+ // argument can't be null
+ if (ck == null) {
+ throw new NullPointerException("cookie is null");
+ }
+
+ boolean modified = false;
+ lock.lock();
+ try {
+ modified = cookieJar.remove(ck);
+ } finally {
+ lock.unlock();
+ }
+
+ return modified;
+ }
+
+
+ /**
+ * Remove all cookies in this cookie store.
+ */
+ public boolean removeAll() {
+ lock.lock();
+ try {
+ cookieJar.clear();
+ domainIndex.clear();
+ uriIndex.clear();
+ } finally {
+ lock.unlock();
+ }
+
+ return true;
+ }
+
+
+ /* ---------------- Private operations -------------- */
+
+
+ /*
+ * This is almost the same as HttpCookie.domainMatches except for
+ * one difference: It won't reject cookies when the 'H' part of the
+ * domain contains a dot ('.').
+ * I.E.: RFC 2965 section 3.3.2 says that if host is x.y.domain.com
+ * and the cookie domain is .domain.com, then it should be rejected.
+ * However that's not how the real world works. Browsers don't reject and
+ * some sites, like yahoo.com do actually expect these cookies to be
+ * passed along.
+ * And should be used for 'old' style cookies (aka Netscape type of cookies)
+ */
+ private boolean netscapeDomainMatches(String domain, String host)
+ {
+ if (domain == null || host == null) {
+ return false;
+ }
+
+ // if there's no embedded dot in domain and domain is not .local
+ boolean isLocalDomain = ".local".equalsIgnoreCase(domain);
+ int embeddedDotInDomain = domain.indexOf('.');
+ if (embeddedDotInDomain == 0) {
+ embeddedDotInDomain = domain.indexOf('.', 1);
+ }
+ if (!isLocalDomain && (embeddedDotInDomain == -1 || embeddedDotInDomain == domain.length() - 1)) {
+ return false;
+ }
+
+ // if the host name contains no dot and the domain name is .local
+ int firstDotInHost = host.indexOf('.');
+ if (firstDotInHost == -1 && isLocalDomain) {
+ return true;
+ }
+
+ int domainLength = domain.length();
+ int lengthDiff = host.length() - domainLength;
+ if (lengthDiff == 0) {
+ // if the host name and the domain name are just string-compare euqal
+ return host.equalsIgnoreCase(domain);
+ } else if (lengthDiff > 0) {
+ // need to check H & D component
+ String H = host.substring(0, lengthDiff);
+ String D = host.substring(lengthDiff);
+
+ return (D.equalsIgnoreCase(domain));
+ } else if (lengthDiff == -1) {
+ // if domain is actually .host
+ return (domain.charAt(0) == '.' &&
+ host.equalsIgnoreCase(domain.substring(1)));
+ }
+
+ return false;
+ }
+
+ private void getInternal1(List<HttpCookie> cookies, Map<String, List<HttpCookie>> cookieIndex,
+ String host, boolean secureLink) {
+ // Use a separate list to handle cookies that need to be removed so
+ // that there is no conflict with iterators.
+ ArrayList<HttpCookie> toRemove = new ArrayList<HttpCookie>();
+ for (Map.Entry<String, List<HttpCookie>> entry : cookieIndex.entrySet()) {
+ String domain = entry.getKey();
+ List<HttpCookie> lst = entry.getValue();
+ for (HttpCookie c : lst) {
+ if ((c.getVersion() == 0 && netscapeDomainMatches(domain, host)) ||
+ (c.getVersion() == 1 && HttpCookie.domainMatches(domain, host))) {
+ if ((cookieJar.indexOf(c) != -1)) {
+ // the cookie still in main cookie store
+ if (!c.hasExpired()) {
+ // don't add twice and make sure it's the proper
+ // security level
+ if ((secureLink || !c.getSecure()) &&
+ !cookies.contains(c)) {
+ cookies.add(c);
+ }
+ } else {
+ toRemove.add(c);
+ }
+ } else {
+ // the cookie has beed removed from main store,
+ // so also remove it from domain indexed store
+ toRemove.add(c);
+ }
+ }
+ }
+ // Clear up the cookies that need to be removed
+ for (HttpCookie c : toRemove) {
+ lst.remove(c);
+ cookieJar.remove(c);
+
+ }
+ toRemove.clear();
+ }
+ }
+
+ // @param cookies [OUT] contains the found cookies
+ // @param cookieIndex the index
+ // @param comparator the prediction to decide whether or not
+ // a cookie in index should be returned
+ private <T> void getInternal2(List<HttpCookie> cookies,
+ Map<T, List<HttpCookie>> cookieIndex,
+ Comparable<T> comparator, boolean secureLink)
+ {
+ for (T index : cookieIndex.keySet()) {
+ if (comparator.compareTo(index) == 0) {
+ List<HttpCookie> indexedCookies = cookieIndex.get(index);
+ // check the list of cookies associated with this domain
+ if (indexedCookies != null) {
+ Iterator<HttpCookie> it = indexedCookies.iterator();
+ while (it.hasNext()) {
+ HttpCookie ck = it.next();
+ if (cookieJar.indexOf(ck) != -1) {
+ // the cookie still in main cookie store
+ if (!ck.hasExpired()) {
+ // don't add twice
+ if ((secureLink || !ck.getSecure()) &&
+ !cookies.contains(ck))
+ cookies.add(ck);
+ } else {
+ it.remove();
+ cookieJar.remove(ck);
+ }
+ } else {
+ // the cookie has beed removed from main store,
+ // so also remove it from domain indexed store
+ it.remove();
+ }
+ }
+ } // end of indexedCookies != null
+ } // end of comparator.compareTo(index) == 0
+ } // end of cookieIndex iteration
+ }
+
+ // add 'cookie' indexed by 'index' into 'indexStore'
+ private <T> void addIndex(Map<T, List<HttpCookie>> indexStore,
+ T index,
+ HttpCookie cookie)
+ {
+ if (index != null) {
+ List<HttpCookie> cookies = indexStore.get(index);
+ if (cookies != null) {
+ // there may already have the same cookie, so remove it first
+ cookies.remove(cookie);
+
+ cookies.add(cookie);
+ } else {
+ cookies = new ArrayList<HttpCookie>();
+ cookies.add(cookie);
+ indexStore.put(index, cookies);
+ }
+ }
+ }
+
+
+ //
+ // for cookie purpose, the effective uri should only be http://host
+ // the path will be taken into account when path-match algorithm applied
+ //
+ private URI getEffectiveURI(URI uri) {
+ URI effectiveURI = null;
+ try {
+ effectiveURI = new URI("http",
+ uri.getHost(),
+ null, // path component
+ null, // query component
+ null // fragment component
+ );
+ } catch (URISyntaxException ignored) {
+ effectiveURI = uri;
+ }
+
+ return effectiveURI;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/misc/PerfCounter.java Tue Sep 29 15:31:18 2009 -0700
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2009 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.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.LongBuffer;
+import java.security.AccessController;
+
+/**
+ * Performance counter support for internal JRE classes.
+ * This class defines a fixed list of counters for the platform
+ * to use as an interim solution until RFE# 6209222 is implemented.
+ * The perf counters will be created in the jvmstat perf buffer
+ * that the HotSpot VM creates. The default size is 32K and thus
+ * the number of counters is bounded. You can alter the size
+ * with -XX:PerfDataMemorySize=<bytes> option. If there is
+ * insufficient memory in the jvmstat perf buffer, the C heap memory
+ * will be used and thus the application will continue to run if
+ * the counters added exceeds the buffer size but the counters
+ * will be missing.
+ *
+ * See HotSpot jvmstat implementation for certain circumstances
+ * that the jvmstat perf buffer is not supported.
+ *
+ */
+public class PerfCounter {
+ private static final Perf perf =
+ AccessController.doPrivileged(new Perf.GetPerfAction());
+
+ // Must match values defined in hotspot/src/share/vm/runtime/perfdata.hpp
+ private final static int V_Constant = 1;
+ private final static int V_Monotonic = 2;
+ private final static int V_Variable = 3;
+ private final static int U_None = 1;
+
+ private final String name;
+ private final LongBuffer lb;
+
+ private PerfCounter(String name, int type) {
+ this.name = name;
+ ByteBuffer bb = perf.createLong(name, U_None, type, 0L);
+ bb.order(ByteOrder.nativeOrder());
+ this.lb = bb.asLongBuffer();
+ }
+
+ static PerfCounter newPerfCounter(String name) {
+ return new PerfCounter(name, V_Variable);
+ }
+
+ static PerfCounter newConstantPerfCounter(String name) {
+ PerfCounter c = new PerfCounter(name, V_Constant);
+ return c;
+ }
+
+ /**
+ * Returns the current value of the perf counter.
+ */
+ public synchronized long get() {
+ return lb.get(0);
+ }
+
+ /**
+ * Sets the value of the perf counter to the given newValue.
+ */
+ public synchronized void set(long newValue) {
+ lb.put(0, newValue);
+ }
+
+ /**
+ * Adds the given value to the perf counter.
+ */
+ public synchronized void add(long value) {
+ long res = get() + value;
+ lb.put(0, res);
+ }
+
+ /**
+ * Increments the perf counter with 1.
+ */
+ public void increment() {
+ add(1);
+ }
+
+ /**
+ * Adds the given interval to the perf counter.
+ */
+ public void addTime(long interval) {
+ add(interval);
+ }
+
+ /**
+ * Adds the elapsed time from the given start time (ns) to the perf counter.
+ */
+ public void addElapsedTimeFrom(long startTime) {
+ add(System.nanoTime() - startTime);
+ }
+
+ @Override
+ public String toString() {
+ return name + " = " + get();
+ }
+
+ static class CoreCounters {
+ static final PerfCounter pdt = newPerfCounter("sun.classloader.parentDelegationTime");
+ static final PerfCounter lc = newPerfCounter("sun.classloader.findClasses");
+ static final PerfCounter lct = newPerfCounter("sun.classloader.findClassTime");
+ static final PerfCounter rcbt = newPerfCounter("sun.urlClassLoader.readClassBytesTime");
+ static final PerfCounter zfc = newPerfCounter("sun.zip.zipFiles");
+ static final PerfCounter zfot = newPerfCounter("sun.zip.zipFile.openTime");
+ }
+
+ static class WindowsClientCounters {
+ static final PerfCounter d3dAvailable = newConstantPerfCounter("sun.java2d.d3d.available");
+ }
+
+ /**
+ * Number of findClass calls
+ */
+ public static PerfCounter getFindClasses() {
+ return CoreCounters.lc;
+ }
+
+ /**
+ * Time (ns) spent in finding classes that includes
+ * lookup and read class bytes and defineClass
+ */
+ public static PerfCounter getFindClassTime() {
+ return CoreCounters.lct;
+ }
+
+ /**
+ * Time (ns) spent in finding classes
+ */
+ public static PerfCounter getReadClassBytesTime() {
+ return CoreCounters.rcbt;
+ }
+
+ /**
+ * Time (ns) spent in the parent delegation to
+ * the parent of the defining class loader
+ */
+ public static PerfCounter getParentDelegationTime() {
+ return CoreCounters.pdt;
+ }
+
+ /**
+ * Number of zip files opened.
+ */
+ public static PerfCounter getZipFileCount() {
+ return CoreCounters.zfc;
+ }
+
+ /**
+ * Time (ns) spent in opening the zip files that
+ * includes building the entries hash table
+ */
+ public static PerfCounter getZipFileOpenTime() {
+ return CoreCounters.zfot;
+ }
+
+ /**
+ * D3D graphic pipeline available
+ */
+ public static PerfCounter getD3DAvailable() {
+ return WindowsClientCounters.d3dAvailable;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/sun/net/www/protocol/http/AuthScheme.java Tue Sep 29 15:31:18 2009 -0700
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2009 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