--- a/jdk/make/java/java/FILES_java.gmk Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/make/java/java/FILES_java.gmk Wed Sep 16 09:23:50 2009 -0700
@@ -454,6 +454,8 @@
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/jdk/src/share/bin/java.h Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/bin/java.h Wed Sep 16 09:23:50 2009 -0700
@@ -187,9 +187,6 @@
*
*/
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/jdk/src/share/bin/parse_manifest.c Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/bin/parse_manifest.c Wed Sep 16 09:23:50 2009 -0700
@@ -59,7 +59,7 @@
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/jdk/src/share/classes/com/sun/rowset/JdbcRowSetResourceBundle.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/JdbcRowSetResourceBundle.java Wed Sep 16 09:23:50 2009 -0700
@@ -133,7 +133,7 @@
* 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 @@
* 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/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/JoinRowSetImpl.java Wed Sep 16 09:23:50 2009 -0700
@@ -3737,7 +3737,6 @@
* 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/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlReader.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/com/sun/rowset/internal/WebRowSetXmlReader.java Wed Sep 16 09:23:50 2009 -0700
@@ -46,6 +46,17 @@
*/
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
* the given <code>java.io.Reader</code> object. The parser will send
@@ -69,17 +80,6 @@
* 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/jdk/src/share/classes/java/lang/Class.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/lang/Class.java Wed Sep 16 09:23:50 2009 -0700
@@ -565,8 +565,9 @@
* represented by this object.
*/
public String getName() {
+ String name = this.name;
if (name == null)
- name = getName0();
+ this.name = name = getName0();
return name;
}
--- a/jdk/src/share/classes/java/lang/ClassLoader.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/lang/ClassLoader.java Wed Sep 16 09:23:50 2009 -0700
@@ -380,16 +380,28 @@
// 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 @@
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/jdk/src/share/classes/java/net/URLClassLoader.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/net/URLClassLoader.java Wed Sep 16 09:23:50 2009 -0700
@@ -340,6 +340,7 @@
* 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 @@
// 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/jdk/src/share/classes/java/nio/file/FileTreeWalker.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/nio/file/FileTreeWalker.java Wed Sep 16 09:23:50 2009 -0700
@@ -41,8 +41,12 @@
private final boolean detectCycles;
private final LinkOption[] linkOptions;
private final FileVisitor<? super Path> visitor;
+ private final int maxDepth;
- FileTreeWalker(Set<FileVisitOption> options, FileVisitor<? super Path> visitor) {
+ FileTreeWalker(Set<FileVisitOption> options,
+ FileVisitor<? super Path> visitor,
+ int maxDepth)
+ {
boolean fl = false;
boolean dc = false;
for (FileVisitOption option: options) {
@@ -58,18 +62,15 @@
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 @@
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 @@
}
}
} 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 @@
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/jdk/src/share/classes/java/nio/file/Files.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/nio/file/Files.java Wed Sep 16 09:23:50 2009 -0700
@@ -223,7 +223,7 @@
{
if (maxDepth < 0)
throw new IllegalArgumentException("'maxDepth' is negative");
- new FileTreeWalker(options, visitor).walk(start, maxDepth);
+ new FileTreeWalker(options, visitor, maxDepth).walk(start);
}
/**
--- a/jdk/src/share/classes/java/util/logging/ErrorManager.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/ErrorManager.java Wed Sep 16 09:23:50 2009 -0700
@@ -28,7 +28,7 @@
/**
* 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 @@
/**
* 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/jdk/src/share/classes/java/util/logging/FileHandler.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/FileHandler.java Wed Sep 16 09:23:50 2009 -0700
@@ -39,7 +39,7 @@
* 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 @@
// 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/jdk/src/share/classes/java/util/logging/Formatter.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/Formatter.java Wed Sep 16 09:23:50 2009 -0700
@@ -52,7 +52,7 @@
* 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 @@
* 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 @@
* 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/jdk/src/share/classes/java/util/logging/Handler.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/Handler.java Wed Sep 16 09:23:50 2009 -0700
@@ -274,7 +274,7 @@
* <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/jdk/src/share/classes/java/util/logging/Level.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/Level.java Wed Sep 16 09:23:50 2009 -0700
@@ -110,7 +110,7 @@
* 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 @@
}
/**
+ * 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 @@
* @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/jdk/src/share/classes/java/util/logging/LogRecord.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/LogRecord.java Wed Sep 16 09:23:50 2009 -0700
@@ -188,7 +188,7 @@
}
/**
- * Get the source Logger name's
+ * Get the source Logger's name.
*
* @return source logger name (may be null)
*/
@@ -197,7 +197,7 @@
}
/**
- * Set the source Logger name.
+ * Set the source Logger's name.
*
* @param name the source logger name (may be null)
*/
--- a/jdk/src/share/classes/java/util/logging/Logger.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/Logger.java Wed Sep 16 09:23:50 2009 -0700
@@ -66,7 +66,7 @@
* 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 @@
* 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 @@
* @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 @@
* <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 @@
* <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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
/**
* 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/jdk/src/share/classes/java/util/logging/LoggingMXBean.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/LoggingMXBean.java Wed Sep 16 09:23:50 2009 -0700
@@ -105,8 +105,8 @@
*
* @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/jdk/src/share/classes/java/util/logging/MemoryHandler.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/MemoryHandler.java Wed Sep 16 09:23:50 2009 -0700
@@ -136,7 +136,7 @@
* @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 @@
* 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/jdk/src/share/classes/java/util/logging/StreamHandler.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/logging/StreamHandler.java Wed Sep 16 09:23:50 2009 -0700
@@ -220,7 +220,7 @@
* <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/jdk/src/share/classes/java/util/zip/ZipEntry.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/zip/ZipEntry.java Wed Sep 16 09:23:50 2009 -0700
@@ -253,14 +253,10 @@
* 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/jdk/src/share/classes/java/util/zip/ZipFile.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java Wed Sep 16 09:23:50 2009 -0700
@@ -195,7 +195,10 @@
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/jdk/src/share/classes/javax/sql/rowset/BaseRowSet.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/javax/sql/rowset/BaseRowSet.java Wed Sep 16 09:23:50 2009 -0700
@@ -168,8 +168,8 @@
* 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 @@
* @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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* <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 @@
* <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 @@
* 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 @@
* 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 @@
* 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 @@
* 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 @@
* 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)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/misc/PerfCounter.java Wed Sep 16 09:23:50 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/jdk/src/share/classes/sun/security/action/GetBooleanSecurityPropertyAction.java Wed Sep 16 09:23:50 2009 -0700
@@ -0,0 +1,74 @@
+/*
+ * 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.security.action;
+
+import java.security.Security;
+
+/**
+ * A convenience class for retrieving the boolean value of a security property
+ * as a privileged action.
+ *
+ * <p>An instance of this class can be used as the argument of
+ * <code>AccessController.doPrivileged</code>.
+ *
+ * <p>The following code retrieves the boolean value of the security
+ * property named <code>"prop"</code> as a privileged action: <p>
+ *
+ * <pre>
+ * boolean b = java.security.AccessController.doPrivileged
+ * (new GetBooleanSecurityPropertyAction("prop")).booleanValue();
+ * </pre>
+ *
+ */
+public class GetBooleanSecurityPropertyAction
+ implements java.security.PrivilegedAction<Boolean> {
+ private String theProp;
+
+ /**
+ * Constructor that takes the name of the security property whose boolean
+ * value needs to be determined.
+ *
+ * @param theProp the name of the security property
+ */
+ public GetBooleanSecurityPropertyAction(String theProp) {
+ this.theProp = theProp;
+ }
+
+ /**
+ * Determines the boolean value of the security property whose name was
+ * specified in the constructor.
+ *
+ * @return the <code>Boolean</code> value of the security property.
+ */
+ public Boolean run() {
+ boolean b = false;
+ try {
+ String value = Security.getProperty(theProp);
+ b = (value != null) && value.equalsIgnoreCase("true");
+ } catch (NullPointerException e) {}
+ return b;
+ }
+}
--- a/jdk/src/share/classes/sun/security/provider/certpath/Builder.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/Builder.java Wed Sep 16 09:23:50 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;
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 @@
* 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/jdk/src/share/classes/sun/security/provider/certpath/CertId.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/CertId.java Wed Sep 16 09:23:50 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 {
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 @@
encoder.encode(issuerNameHash));
System.out.println("issuerKeyHash is " +
encoder.encode(issuerKeyHash));
+ System.out.println("SerialNumber is " + serialNumber.getNumber());
}
}
@@ -97,7 +107,6 @@
* 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 @@
*
* @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 @@
* @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 @@
/**
* 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/jdk/src/share/classes/sun/security/provider/certpath/CrlRevocationChecker.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/CrlRevocationChecker.java Wed Sep 16 09:23:50 2009 -0700
@@ -80,6 +80,7 @@
{ 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 @@
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 @@
}
Date testDate = params.getDate();
mCurrentTime = (testDate != null ? testDate : new Date());
+ mOnlyEECert = onlyEECert;
init(false);
}
@@ -264,6 +272,13 @@
" ---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
// to handle this, so we feel it is safest to reject them until
// the issue is resolved in the PKIX WG.
--- a/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Wed Sep 16 09:23:50 2009 -0700
@@ -32,7 +32,7 @@
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 @@
* 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/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java Wed Sep 16 09:23:50 2009 -0700
@@ -82,6 +82,7 @@
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 @@
* @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 @@
}
comparator = new PKIXCertComparator(trustedSubjectDNs);
this.searchAllCertStores = searchAllCertStores;
+ this.onlyEECert = onlyEECert;
}
/**
@@ -875,8 +878,8 @@
/* 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) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSP.java Wed Sep 16 09:23:50 2009 -0700
@@ -0,0 +1,329 @@
+/*
+ * 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.security.provider.certpath;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URL;
+import java.net.HttpURLConnection;
+import java.security.cert.CertificateException;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.CRLReason;
+import java.security.cert.Extension;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import static sun.security.provider.certpath.OCSPResponse.*;
+import sun.security.util.Debug;
+import sun.security.x509.AccessDescription;
+import sun.security.x509.AuthorityInfoAccessExtension;
+import sun.security.x509.GeneralName;
+import sun.security.x509.GeneralNameInterface;
+import sun.security.x509.URIName;
+import sun.security.x509.X509CertImpl;
+
+/**
+ * This is a class that checks the revocation status of a certificate(s) using
+ * OCSP. It is not a PKIXCertPathChecker and therefore can be used outside of
+ * the CertPathValidator framework. It is useful when you want to
+ * just check the revocation status of a certificate, and you don't want to
+ * incur the overhead of validating all of the certificates in the
+ * associated certificate chain.
+ *
+ * @author Sean Mullan
+ */
+public final class OCSP {
+
+ private static final Debug debug = Debug.getInstance("certpath");
+
+ private OCSP() {}
+
+ /**
+ * Obtains the revocation status of a certificate using OCSP using the most
+ * common defaults. The OCSP responder URI is retrieved from the
+ * certificate's AIA extension. The OCSP responder certificate is assumed
+ * to be the issuer's certificate (or issued by the issuer CA).
+ *
+ * @param cert the certificate to be checked
+ * @param issuerCert the issuer certificate
+ * @return the RevocationStatus
+ * @throws IOException if there is an exception connecting to or
+ * communicating with the OCSP responder
+ * @throws CertPathValidatorException if an exception occurs while
+ * encoding the OCSP Request or validating the OCSP Response
+ */
+ public static RevocationStatus check(X509Certificate cert,
+ X509Certificate issuerCert)
+ throws IOException, CertPathValidatorException {
+ CertId certId = null;
+ URI responderURI = null;
+ try {
+ X509CertImpl certImpl = X509CertImpl.toImpl(cert);
+ responderURI = getResponderURI(certImpl);
+ if (responderURI == null) {
+ throw new CertPathValidatorException
+ ("No OCSP Responder URI in certificate");
+ }
+ certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
+ } catch (CertificateException ce) {
+ throw new CertPathValidatorException
+ ("Exception while encoding OCSPRequest", ce);
+ } catch (IOException ioe) {
+ throw new CertPathValidatorException
+ ("Exception while encoding OCSPRequest", ioe);
+ }
+ OCSPResponse ocspResponse = check(Collections.singletonList(certId),
+ responderURI, issuerCert, null);
+ return (RevocationStatus) ocspResponse.getSingleResponse(certId);
+ }
+
+ /**
+ * Obtains the revocation status of a certificate using OCSP.
+ *
+ * @param cert the certificate to be checked
+ * @param issuerCert the issuer certificate
+ * @param responderURI the URI of the OCSP responder
+ * @param responderCert the OCSP responder's certificate
+ * @param date the time the validity of the OCSP responder's certificate
+ * should be checked against. If null, the current time is used.
+ * @return the RevocationStatus
+ * @throws IOException if there is an exception connecting to or
+ * communicating with the OCSP responder
+ * @throws CertPathValidatorException if an exception occurs while
+ * encoding the OCSP Request or validating the OCSP Response
+ */
+ public static RevocationStatus check(X509Certificate cert,
+ X509Certificate issuerCert, URI responderURI, X509Certificate
+ responderCert, Date date)
+ throws IOException, CertPathValidatorException {
+ CertId certId = null;
+ try {
+ X509CertImpl certImpl = X509CertImpl.toImpl(cert);
+ certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
+ } catch (CertificateException ce) {
+ throw new CertPathValidatorException
+ ("Exception while encoding OCSPRequest", ce);
+ } catch (IOException ioe) {
+ throw new CertPathValidatorException
+ ("Exception while encoding OCSPRequest", ioe);
+ }
+ OCSPResponse ocspResponse = check(Collections.singletonList(certId),
+ responderURI, responderCert, date);
+ return (RevocationStatus) ocspResponse.getSingleResponse(certId);
+ }
+
+ /**
+ * Checks the revocation status of a list of certificates using OCSP.
+ *
+ * @param certs the CertIds to be checked
+ * @param responderURI the URI of the OCSP responder
+ * @param responderCert the OCSP responder's certificate
+ * @param date the time the validity of the OCSP responder's certificate
+ * should be checked against. If null, the current time is used.
+ * @return the OCSPResponse
+ * @throws IOException if there is an exception connecting to or
+ * communicating with the OCSP responder
+ * @throws CertPathValidatorException if an exception occurs while
+ * encoding the OCSP Request or validating the OCSP Response
+ */
+ static OCSPResponse check(List<CertId> certIds, URI responderURI,
+ X509Certificate responderCert, Date date)
+ throws IOException, CertPathValidatorException {
+
+ byte[] bytes = null;
+ try {
+ OCSPRequest request = new OCSPRequest(certIds);
+ bytes = request.encodeBytes();
+ } catch (IOException ioe) {
+ throw new CertPathValidatorException
+ ("Exception while encoding OCSPRequest", ioe);
+ }
+
+ InputStream in = null;
+ OutputStream out = null;
+ byte[] response = null;
+ try {
+ URL url = responderURI.toURL();
+ if (debug != null) {
+ debug.println("connecting to OCSP service at: " + url);
+ }
+ HttpURLConnection con = (HttpURLConnection)url.openConnection();
+ con.setDoOutput(true);
+ con.setDoInput(true);
+ con.setRequestMethod("POST");
+ con.setRequestProperty
+ ("Content-type", "application/ocsp-request");
+ 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();
+ int contentLength = con.getContentLength();
+ if (contentLength == -1) {
+ contentLength = Integer.MAX_VALUE;
+ }
+ response = new byte[contentLength > 2048 ? 2048 : contentLength];
+ int total = 0;
+ 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);
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException ioe) {
+ throw ioe;
+ }
+ }
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException ioe) {
+ throw ioe;
+ }
+ }
+ }
+
+ OCSPResponse ocspResponse = null;
+ try {
+ ocspResponse = new OCSPResponse(response, date, responderCert);
+ } catch (IOException ioe) {
+ // response decoding exception
+ throw new CertPathValidatorException(ioe);
+ }
+ if (ocspResponse.getResponseStatus() != ResponseStatus.SUCCESSFUL) {
+ throw new CertPathValidatorException
+ ("OCSP response error: " + ocspResponse.getResponseStatus());
+ }
+
+ // Check that the response includes a response for all of the
+ // certs that were supplied in the request
+ for (CertId certId : certIds) {
+ SingleResponse sr = ocspResponse.getSingleResponse(certId);
+ if (sr == null) {
+ if (debug != null) {
+ debug.println("No response found for CertId: " + certId);
+ }
+ throw new CertPathValidatorException(
+ "OCSP response does not include a response for a " +
+ "certificate supplied in the OCSP request");
+ }
+ if (debug != null) {
+ debug.println("Status of certificate (with serial number " +
+ certId.getSerialNumber() + ") is: " + sr.getCertStatus());
+ }
+ }
+ return ocspResponse;
+ }
+
+ /**
+ * Returns the URI of the OCSP Responder as specified in the
+ * certificate's Authority Information Access extension, or null if
+ * not specified.
+ *
+ * @param cert the certificate
+ * @return the URI of the OCSP Responder, or null if not specified
+ */
+ public static URI getResponderURI(X509Certificate cert) {
+ try {
+ return getResponderURI(X509CertImpl.toImpl(cert));
+ } catch (CertificateException ce) {
+ // treat this case as if the cert had no extension
+ return null;
+ }
+ }
+
+ static URI getResponderURI(X509CertImpl certImpl) {
+
+ // Examine the certificate's AuthorityInfoAccess extension
+ AuthorityInfoAccessExtension aia =
+ certImpl.getAuthorityInfoAccessExtension();
+ if (aia == null) {
+ return null;
+ }
+
+ List<AccessDescription> descriptions = aia.getAccessDescriptions();
+ for (AccessDescription description : descriptions) {
+ if (description.getAccessMethod().equals(
+ AccessDescription.Ad_OCSP_Id)) {
+
+ GeneralName generalName = description.getAccessLocation();
+ if (generalName.getType() == GeneralNameInterface.NAME_URI) {
+ URIName uri = (URIName) generalName.getName();
+ return uri.getURI();
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * The Revocation Status of a certificate.
+ */
+ public static interface RevocationStatus {
+ public enum CertStatus { GOOD, REVOKED, UNKNOWN };
+
+ /**
+ * Returns the revocation status.
+ */
+ CertStatus getCertStatus();
+ /**
+ * Returns the time when the certificate was revoked, or null
+ * if it has not been revoked.
+ */
+ Date getRevocationTime();
+ /**
+ * Returns the reason the certificate was revoked, or null if it
+ * has not been revoked.
+ */
+ CRLReason getRevocationReason();
+
+ /**
+ * Returns a Map of additional extensions.
+ */
+ Map<String, Extension> getSingleExtensions();
+ }
+}
--- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java Wed Sep 16 09:23:50 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 @@
*/
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;
@@ -79,19 +71,26 @@
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 @@
* 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 @@
}
}
- 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 @@
* @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;
+ 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;
+ }
- 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
+ */
+ // 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]);
- /*
- * OCSP security property values, in the following order:
- * 1. ocsp.responderURL
- * 2. ocsp.responderCertSubjectName
- * 3. ocsp.responderCertIssuerName
- * 4. ocsp.responderCertSerialNumber
- */
- String[] properties = getOCSPProperties();
+ // 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");
+ }
- // Check whether OCSP is feasible before seeking cert information
- URL url = getOCSPServerURL(currCertImpl, 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;
+ }
- // When responder's subject name is set then the issuer/serial
- // properties are ignored
- if (properties[1] != null) {
- responderSubjectName = new X500Principal(properties[1]);
+ // 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
- } 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);
+ // 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");
+ }
+ }
+ }
- } else if (properties[2] != null || properties[3] != null) {
- throw new CertPathValidatorException(
- "Must specify both ocsp.responderCertIssuerName and " +
- "ocsp.responderCertSerialNumber properties");
+ // 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");
}
- // 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;
+ // Extract the anchor certs
+ Iterator<TrustAnchor> anchors
+ = pkixParams.getTrustAnchors().iterator();
+ if (!anchors.hasNext()) {
+ throw new CertPathValidatorException(
+ "Must specify at least one trust anchor");
}
- // 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
+ 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 = certs[remainingCerts];
- if (DEBUG != null) {
- DEBUG.println("Responder's certificate is the same " +
- "as the issuer of the certificate being validated");
+ // 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;
+ seekResponderCert = false; // done
}
}
}
+ if (issuerCert == null) {
+ throw new CertPathValidatorException(
+ "No trusted certificate for " + currCertImpl.getIssuerDN());
+ }
- // 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 " +
+ // 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");
}
-
- // Extract the anchor certs
- Iterator anchors = pkixParams.getTrustAnchors().iterator();
- if (! anchors.hasNext()) {
- throw new CertPathValidatorException(
- "Must specify at least one trust anchor");
+ 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);
}
-
- 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 (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("Responder's certificate is the" +
- " same as the issuer of the certificate " +
- "being validated");
+ DEBUG.println("CertStore exception:" + cse);
}
+ continue;
}
- }
-
- // 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;
+ if (i.hasNext()) {
+ responderCert = (X509Certificate) i.next();
seekResponderCert = false; // done
- }
- }
- }
- 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;
- }
+ 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;
- }
+ // 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).");
+ }
- 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));
- }
+ 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);
+ }
- 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);
- }
- }
+ 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 @@
* 3. ocsp.responderCertIssuerName
* 4. ocsp.responderCertSerialNumber
*/
- private static URL getOCSPServerURL(X509CertImpl currCertImpl,
- String[] properties)
- throws CertificateParsingException, CertPathValidatorException {
+ private static URI getOCSPServerURI(X509CertImpl currCertImpl,
+ String responderURL) throws CertPathValidatorException {
- if (properties[0] != null) {
- try {
- return new URL(properties[0]);
- } catch (java.net.MalformedURLException e) {
+ 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 @@
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/jdk/src/share/classes/sun/security/provider/certpath/OCSPRequest.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPRequest.java Wed Sep 16 09:23:50 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;
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 @@
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 @@
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);
- }
-
- // used by OCSPChecker
- CertId getCertId() {
- return certId;
+ return bytes;
}
- 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/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java Wed Sep 16 09:23:50 2009 -0700
@@ -28,17 +28,16 @@
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 @@
* @author Ram Marti
*/
-class OCSPResponse {
+public final 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 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;
- }
+ 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});
- // OCSP response status code
- private static final int OCSP_RESPONSE_OK = 0;
+ 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 @@
// 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,301 +156,300 @@
/*
* 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();
- // 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();
- if (DEBUG != null) {
- DEBUG.println("OCSP response: " +
- responseToText(responseStatus));
- }
- if (responseStatus != OCSP_RESPONSE_OK) {
- throw new CertPathValidatorException(
- "OCSP Response Failure: " +
- responseToText(responseStatus));
- }
+ // 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.");
- }
+ // 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);
+ // responseType
+ derIn = tmp.data;
+ ObjectIdentifier 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());
+ // BasicOCSPResponse
+ DerInputStream basicOCSPResponse =
+ new DerInputStream(derIn.getOctetString());
- DerValue[] seqTmp = basicOCSPResponse.getSequence(2);
- DerValue responseData = seqTmp[0];
+ DerValue[] seqTmp = basicOCSPResponse.getSequence(2);
+ if (seqTmp.length < 3) {
+ throw new IOException("Unexpected BasicOCSPResponse value");
+ }
- // Need the DER encoded ResponseData to verify the signature later
- byte[] responseDataDer = seqTmp[0].toByteArray();
+ 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();
+ // 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);
+ // 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");
}
- } 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");
+ seq = seqDerIn.getDerValue();
}
+ }
- // producedAt
- seq = seqDerIn.getDerValue();
- producedAtDate = seq.getGeneralizedTime();
+ // 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");
+ }
- // responses
- DerValue[] singleResponseDer = seqDerIn.getSequence(1);
- // Examine only the first response
- singleResponse = new SingleResponse(singleResponseDer[0]);
+ // producedAt
+ seq = seqDerIn.getDerValue();
+ if (DEBUG != null) {
+ Date producedAtDate = seq.getGeneralizedTime();
+ DEBUG.println("OCSP response produced at: " + producedAtDate);
+ }
- // 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();
+ // 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);
+ }
- } else if (responseExtension[i].isCritical()) {
- throw new IOException(
- "Unsupported OCSP critical extension: " +
- responseExtension[i].getExtensionId());
- }
+ // responseExtensions
+ if (seqDerIn.available() > 0) {
+ seq = seqDerIn.getDerValue();
+ 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
- sigAlgId = AlgorithmId.parse(seqTmp[1]);
+ }
- // signature
- byte[] signature = seqTmp[2].getBitString();
- X509CertImpl[] x509Certs = null;
+ // 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];
+ // 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());
}
+ } 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];
+ // 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
+ // 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())) {
+ // 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
+ // 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");
- }
+ } catch (CertificateParsingException cpe) {
+ // assume cert is not valid for signing
+ throw new CertPathValidatorException(
+ "Responder's certificate not valid for signing " +
+ "OCSP responses", cpe);
+ }
- // 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.");
- }
+ // check the validity
+ try {
+ if (dateCheckedAgainst == null) {
+ cert.checkValidity();
} else {
- // we should do the revocating checking of the
- // authorized responder in a future update.
+ cert.checkValidity(dateCheckedAgainst);
}
+ } catch (GeneralSecurityException e) {
+ throw new CertPathValidatorException(
+ "Responder's certificate not within the " +
+ "validity period", e);
+ }
- // verify the signature
- try {
- cert.verify(responderCert.getPublicKey());
- responderCert = cert;
- // cert is trusted, now verify the signed response
-
- } catch (GeneralSecurityException e) {
- responderCert = null;
+ // 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");
+ // we should do the revocation checking of the
+ // authorized responder in a future update.
}
- }
- // Confirm that the signed response was generated using the public
- // key from the trusted responder cert
- if (responderCert != null) {
+ // verify the signature
+ try {
+ cert.verify(responderCert.getPublicKey());
+ responderCert = cert;
+ // cert is trusted, now verify the signed response
- 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");
+ } 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(
+ "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(
- "Unable to verify OCSP Responder's signature");
+ "Error verifying OCSP Responder's signature");
}
- } catch (CertPathValidatorException cpve) {
- throw cpve;
- } catch (Exception e) {
- throw new CertPathValidatorException(e);
+ } 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;
+ }
+
/*
* Verify the signature of the OCSP response.
* 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 @@
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.
- */
- // 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.
+ /**
+ * Returns the SingleResponse of the specified CertId, or null if
+ * there is no response for that CertId.
*/
- 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 @@
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 @@
derVal = tmp.getDerValue();
tag = (byte)(derVal.tag & 0x1f);
}
+ } else {
+ nextUpdate = null;
}
}
// singleExtensions
@@ -627,7 +579,11 @@
DEBUG.println("OCSP single extension: " + ext);
}
}
+ } else {
+ singleExtensions = Collections.emptyMap();
}
+ } else {
+ singleExtensions = Collections.emptyMap();
}
long now = System.currentTimeMillis();
@@ -657,7 +613,7 @@
/*
* Return the certificate's revocation status code
*/
- private int getStatus() {
+ @Override public CertStatus getCertStatus() {
return certStatus;
}
@@ -665,28 +621,28 @@
return certId;
}
- private Date getRevocationTime() {
- return revocationTime;
+ @Override public Date getRevocationTime() {
+ return (Date) revocationTime.clone();
}
- private CRLReason getRevocationReason() {
+ @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/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Wed Sep 16 09:23:50 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.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.Set;
import javax.security.auth.x500.X500Principal;
+import sun.security.action.GetBooleanSecurityPropertyAction;
import sun.security.util.Debug;
/**
@@ -67,7 +66,8 @@
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 @@
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 @@
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/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java Wed Sep 16 09:23:50 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;
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 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 @@
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 @@
} catch (CertificateException e) {
throw new CertPathBuilderException(e);
}
+ onlyEECert = AccessController.doPrivileged(
+ new GetBooleanSecurityPropertyAction
+ ("com.sun.security.onlyCheckRevocationOfEECert"));
}
/**
@@ -256,7 +262,6 @@
/*
* Private build reverse method.
- *
*/
private void buildReverse(List<List<Vertex>> adjacencyList,
LinkedList<X509Certificate> certPathList) throws Exception
@@ -296,7 +301,7 @@
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 @@
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 @@
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/jdk/src/share/classes/sun/security/x509/AccessDescription.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/classes/sun/security/x509/AccessDescription.java Wed Sep 16 09:23:50 2009 -0700
@@ -113,7 +113,7 @@
} else {
method = accessMethod.toString();
}
- return ("accessMethod: " + method +
+ return ("\n accessMethod: " + method +
"\n accessLocation: " + accessLocation.toString() + "\n");
}
}
--- a/jdk/src/share/demo/jvmti/waiters/Agent.cpp Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/demo/jvmti/waiters/Agent.cpp Wed Sep 16 09:23:50 2009 -0700
@@ -72,36 +72,30 @@
{
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");
+ jlong tag;
- /* 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");
+ 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 @@
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 @@
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 @@
/* 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/jdk/src/share/demo/jvmti/waiters/Agent.hpp Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/demo/jvmti/waiters/Agent.hpp Wed Sep 16 09:23:50 2009 -0700
@@ -34,8 +34,12 @@
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/jdk/src/share/demo/jvmti/waiters/Monitor.cpp Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/demo/jvmti/waiters/Monitor.cpp Wed Sep 16 09:23:50 2009 -0700
@@ -73,6 +73,16 @@
name, contends, waits, timeouts);
}
+int Monitor::get_slot()
+{
+ return slot;
+}
+
+void Monitor::set_slot(int aslot)
+{
+ slot = aslot;
+}
+
void Monitor::contended()
{
contends++;
--- a/jdk/src/share/demo/jvmti/waiters/Monitor.hpp Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/demo/jvmti/waiters/Monitor.hpp Wed Sep 16 09:23:50 2009 -0700
@@ -35,6 +35,7 @@
private:
char name[64];
+ int slot;
unsigned contends;
unsigned waits;
unsigned timeouts;
@@ -42,6 +43,8 @@
public:
Monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object);
~Monitor();
+ int get_slot();
+ void set_slot(int i);
void contended();
void waited();
void timeout();
--- a/jdk/src/share/javavm/export/jvm.h Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/javavm/export/jvm.h Wed Sep 16 09:23:50 2009 -0700
@@ -375,6 +375,12 @@
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
* or NoClassDefFoundError depending on the value of the last
* argument.
--- a/jdk/src/share/native/java/lang/ClassLoader.c Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/share/native/java/lang/ClassLoader.c Wed Sep 16 09:23:50 2009 -0700
@@ -237,6 +237,9 @@
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 @@
char buf[128];
if (classname == NULL) {
- JNU_ThrowClassNotFoundException(env, 0);
return 0;
}
@@ -258,11 +260,10 @@
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/jdk/src/solaris/bin/java_md.c Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/solaris/bin/java_md.c Wed Sep 16 09:23:50 2009 -0700
@@ -1324,12 +1324,12 @@
{
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/jdk/src/windows/bin/java_md.c Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/windows/bin/java_md.c Wed Sep 16 09:23:50 2009 -0700
@@ -1093,12 +1093,6 @@
*/
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 @@
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/jdk/src/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/src/windows/classes/sun/java2d/d3d/D3DGraphicsDevice.java Wed Sep 16 09:23:50 2009 -0700
@@ -67,6 +67,9 @@
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);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jdi/BreakpointWithFullGC.sh Wed Sep 16 09:23:50 2009 -0700
@@ -0,0 +1,128 @@
+#!/bin/sh
+
+#
+# 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.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6862295
+# @summary Verify breakpoints still work after a full GC.
+# @author dcubed (based on the test program posted to the following
+# Eclipse thread https://bugs.eclipse.org/bugs/show_bug.cgi?id=279137)
+#
+# @run shell BreakpointWithFullGC.sh
+
+compileOptions=-g
+# Hijacking the mode parameter to make sure we use a small amount
+# of memory and can see what GC is doing.
+mode="-Xmx32m -verbose:gc"
+# Force use of a GC framework collector to see the original failure.
+#mode="$mode -XX:+UseSerialGC"
+
+# Uncomment this to see the JDI trace
+#jdbOptions=-dbgtrace
+
+createJavaFile()
+{
+ cat <<EOF > $1.java.1
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class $1 {
+ public static List<Object> objList = new ArrayList<Object>();
+
+ private static void init(int numObjs) {
+ for (int i = 0; i < numObjs; i++) {
+ objList.add(new Object());
+ }
+ }
+
+ public static void main(String[] args) {
+ for (int i = 0; i < 10; i++) {
+ System.out.println("top of loop"); // @1 breakpoint
+ init(1000000);
+ objList.clear();
+ System.out.println("bottom of loop"); // @1 breakpoint
+ }
+ System.out.println("end of test"); // @1 breakpoint
+ }
+}
+
+EOF
+}
+
+# This is called to feed cmds to jdb.
+dojdbCmds()
+{
+ setBkpts @1
+
+ # get to the first loop breakpoint
+ runToBkpt
+ # 19 "cont" commands gets us through all the loop breakpoints.
+ # Use for-loop instead of while-loop to avoid creating processes
+ # for '[' and 'expr'.
+ for ii in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19; do
+ contToBkpt
+ done
+ # get to the last breakpoint
+ contToBkpt
+}
+
+
+mysetup()
+{
+ if [ -z "$TESTSRC" ] ; then
+ TESTSRC=.
+ fi
+
+ for ii in . $TESTSRC $TESTSRC/.. ; do
+ if [ -r "$ii/ShellScaffold.sh" ] ; then
+ . $ii/ShellScaffold.sh
+ break
+ fi
+ done
+}
+
+# You could replace this next line with the contents
+# of ShellScaffold.sh and this script will run just the same.
+mysetup
+
+runit
+
+# make sure we hit the first breakpoint at least once
+jdbFailIfNotPresent 'System\..*top of loop'
+
+# make sure we hit the second breakpoint at least once
+jdbFailIfNotPresent 'System\..*bottom of loop'
+
+# make sure we hit the last breakpoint
+jdbFailIfNotPresent 'System\..*end of test'
+
+# make sure we had at least one full GC
+debuggeeFailIfNotPresent 'Full GC'
+
+# check for error message due to thread ID change
+debuggeeFailIfPresent \
+ 'Exception in thread "event-handler" java.lang.NullPointerException'
+
+pass
--- a/jdk/test/java/lang/ProcessBuilder/Basic.java Wed Jul 05 17:00:34 2017 +0200
+++ b/jdk/test/java/lang/ProcessBuilder/Basic.java Wed Sep 16 09:23:50 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 @@
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 @@
} 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())
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/WalkWithSecurity.java Wed Sep 16 09:23:50 2009 -0700
@@ -0,0 +1,132 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 6876541
+ * @summary Test Files.walkFileTree in the presence of a security manager
+ * @build WalkWithSecurity
+ * @run main/othervm WalkWithSecurity grantAll.policy pass
+ * @run main/othervm WalkWithSecurity denyAll.policy fail
+ * @run main/othervm WalkWithSecurity grantTopOnly.policy top_only
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.IOException;
+
+public class WalkWithSecurity {
+
+ public static void main(String[] args) throws IOException {
+ String policyFile = args[0];
+ ExpectedResult expectedResult = ExpectedResult.valueOf(args[1].toUpperCase());
+
+ String here = System.getProperty("user.dir");
+ String testSrc = System.getProperty("test.src");
+ if (testSrc == null)
+ throw new RuntimeException("This test must be run by jtreg");
+ Path dir = Paths.get(testSrc);
+
+ // Sanity check the environment
+ if (Paths.get(here).isSameFile(dir))
+ throw new RuntimeException("Working directory cannot be " + dir);
+ DirectoryStream<Path> stream = dir.newDirectoryStream();
+ try {
+ if (!stream.iterator().hasNext())
+ throw new RuntimeException(testSrc + " is empty");
+ } finally {
+ stream.close();
+ }
+
+ // Install security manager with the given policy file
+ System.setProperty("java.security.policy",
+ dir.resolve(policyFile).toString());
+ System.setSecurityManager(new SecurityManager());
+
+ // Walk the source tree
+ CountingVisitor visitor = new CountingVisitor();
+ SecurityException exception = null;
+ try {
+ Files.walkFileTree(dir, visitor);
+ } catch (SecurityException se) {
+ exception = se;
+ }
+
+ // Check result
+ switch (expectedResult) {
+ case PASS:
+ if (exception != null) {
+ exception.printStackTrace();
+ throw new RuntimeException("SecurityException not expected");
+ }
+ if (visitor.count() == 0)
+ throw new RuntimeException("No files visited");
+ break;
+ case FAIL:
+ if (exception == null)
+ throw new RuntimeException("SecurityException expected");
+ if (visitor.count() > 0)
+ throw new RuntimeException("Files were visited");
+ break;
+ case TOP_ONLY:
+ if (exception != null) {
+ exception.printStackTrace();
+ throw new RuntimeException("SecurityException not expected");
+ }
+ if (visitor.count() == 0)
+ throw new RuntimeException("Starting file not visited");
+ if (visitor.count() > 1)
+ throw new RuntimeException("More than starting file visited");
+ break;
+ default:
+ throw new RuntimeException("Should not get here");
+ }
+ }
+
+ static enum ExpectedResult {
+ PASS,
+ FAIL,
+ TOP_ONLY;
+ }
+
+ static class CountingVisitor extends SimpleFileVisitor<Path> {
+ private int count;
+
+ int count() {
+ return count;
+ }
+
+ @Override
+ public FileVisitResult preVisitDirectory(Path dir) {
+ System.out.println(dir);
+ count++;
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
+ System.out.println(file);
+ count++;
+ return FileVisitResult.CONTINUE;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/denyAll.policy Wed Sep 16 09:23:50 2009 -0700
@@ -0,0 +1,3 @@
+// policy file that does not grant any permissions
+grant {
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/grantAll.policy Wed Sep 16 09:23:50 2009 -0700
@@ -0,0 +1,5 @@
+// policy file that grants read access to source directory and all descendants
+grant {
+ permission java.io.FilePermission "${test.src}", "read";
+ permission java.io.FilePermission "${test.src}${file.separator}-", "read";
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/grantTopOnly.policy Wed Sep 16 09:23:50 2009 -0700
@@ -0,0 +1,4 @@
+// policy file that grants read access to source directory
+grant {
+ permission java.io.FilePermission "${test.src}", "read";
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/6842838/CreateBadJar.java Wed Sep 16 09:23:50 2009 -0700
@@ -0,0 +1,168 @@
+/*
+ * 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.
+ *
+ * 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.
+ */
+
+/*
+ * Borrowing significantly from Martin Buchholz's CorruptedZipFiles.java
+ *
+ * Needed a way of testing the checks for corrupt zip/jar entry in
+ * inflate_file from file j2se/src/share/bin/parse_manifest.c
+ * and running them with the 64-bit launcher. e.g.
+ * sparcv9/bin/java -jar badjar.jar
+ *
+ * Run from a script driver Test6842838.sh as we want to specifically run
+ * bin/sparcv9/java, the 64-bit launcher.
+ *
+ * So this program will create a zip file and damage it in the way
+ * required to tickle this bug.
+ *
+ * It will cause a buffer overrun: but that will not always crash.
+ * Use libumem preloaded by the script driver in order to
+ * abort quickly when the overrun happens. That makes the test
+ * Solaris-specific.
+ */
+
+import java.util.*;
+import java.util.zip.*;
+import java.io.*;
+import static java.lang.System.*;
+import static java.util.zip.ZipFile.*;
+
+public class CreateBadJar {
+
+public static void main(String [] arguments) {
+
+ if (arguments.length != 2) {
+ throw new RuntimeException("Arguments: jarfilename entryname");
+ }
+ String outFile = arguments[0];
+ String entryName = arguments[1];
+
+ try {
+ // If the named file doesn't exist, create it.
+ // If it does, we are expecting it to contain the named entry, for
+ // alteration.
+ if (!new File(outFile).exists()) {
+ System.out.println("Creating file " + outFile);
+
+ // Create the requested zip/jar file.
+ ZipOutputStream zos = null;
+ zos = new ZipOutputStream(
+ new FileOutputStream(outFile));
+
+ ZipEntry e = new ZipEntry(entryName);
+ zos.putNextEntry(e);
+ for (int j=0; j<50000; j++) {
+ zos.write((int)'a');
+ }
+ zos.closeEntry();
+ zos.close();
+ zos = null;
+ }
+
+ // Read it.
+ int len = (int)(new File(outFile).length());
+ byte[] good = new byte[len];
+ FileInputStream fis = new FileInputStream(outFile);
+ fis.read(good);
+ fis.close();
+ fis = null;
+
+ int endpos = len - ENDHDR;
+ int cenpos = u16(good, endpos+ENDOFF);
+ if (u32(good, cenpos) != CENSIG) throw new RuntimeException("Where's CENSIG?");
+
+ byte[] bad;
+ bad = good.clone();
+
+ // Corrupt it...
+ int pos = findInCEN(bad, cenpos, entryName);
+
+ // What bad stuff are we doing to it?
+ // Store a 32-bit -1 in uncomp size.
+ bad[pos+0x18]=(byte)0xff;
+ bad[pos+0x19]=(byte)0xff;
+ bad[pos+0x1a]=(byte)0xff;
+ bad[pos+0x1b]=(byte)0xff;
+
+ // Bad work complete, delete the original.
+ new File(outFile).delete();
+
+ // Write it.
+ FileOutputStream fos = new FileOutputStream(outFile);
+ fos.write(bad);
+ fos.close();
+ fos = null;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+}
+
+ /*
+ * Scan Central Directory File Headers looking for the named entry.
+ */
+
+ static int findInCEN(byte[] bytes, int cenpos, String entryName) {
+ int pos = cenpos;
+ int nextPos = 0;
+ String filename = null;
+ do {
+ if (nextPos != 0) {
+ pos = nextPos;
+ }
+ System.out.println("entry at pos = " + pos);
+ if (u32(bytes, pos) != CENSIG) throw new RuntimeException ("entry not found in CEN or premature end...");
+
+ int csize = u32(bytes, pos+0x14); // +0x14 1 dword csize
+ int uncompsize = u32(bytes, pos+0x18); // +0x18 1 dword uncomp size
+ int filenameLength = u16(bytes, pos+0x1c); // +0x1c 1 word length of filename
+ int extraLength = u16(bytes, pos+0x1e); // +0x1e 1 world length of extra field
+ int commentLength = u16(bytes, pos+0x20); // +0x20 1 world length of file comment
+ filename = new String(bytes, pos+0x2e, filenameLength); // +0x2e chars of filename
+ int offset = u32(bytes, pos+0x2a); // +0x2a chars of filename
+
+ System.out.println("filename = " + filename + "\ncsize = " + csize +
+ " uncomp.size = " + uncompsize +" file offset = " + offset);
+ nextPos = pos + 0x2e + filenameLength + extraLength + commentLength;
+
+ } while (!filename.equals(entryName));
+
+ System.out.println("entry found at pos = " + pos);
+ return pos;
+ }
+
+ static int u8(byte[] data, int offset) {
+ return data[offset]&0xff;
+ }
+
+ static int u16(byte[] data, int offset) {
+ return u8(data,offset) + (u8(data,offset+1)<<8);
+ }
+
+ static int u32(byte[] data, int offset) {
+ return u16(data,offset) + (u16(data,offset+2)<<16);
+ }
+
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/6842838/Test6842838.sh Wed Sep 16 09:23:50 2009 -0700
@@ -0,0 +1,75 @@
+#!/bin/sh -x
+
+#
+# @test @(#)Test6842838.sh
+# @bug 6842838
+# @summary Test 6842838 64-bit launcher failure due to corrupt jar
+# @run shell Test6842838.sh
+#
+
+#
+# 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.
+#
+# 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.
+#
+
+if [ "${TESTSRC}" = "" ]
+then TESTSRC=.
+fi
+
+if [ "${TESTJAVA}" = "" ]
+then
+ PARENT=`dirname \`which java\``
+ TESTJAVA=`dirname ${PARENT}`
+ echo "TESTJAVA not set, selecting " ${TESTJAVA}
+ echo "If this is incorrect, try setting the variable manually."
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+ echo "TESTCLASSES not set. Test cannot execute. Failed."
+ exit 1
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ SunOS )
+ NULL=/dev/null
+ PS=":"
+ FS="/"
+ JAVA_EXE=${TESTJAVA}${FS}bin${FS}sparcv9${FS}java
+ ;;
+ * )
+ echo "Only testing on sparcv9 (use libumem to reliably catch buffer overrun)"
+ exit 0;
+ ;;
+esac
+
+BADFILE=newbadjar.jar
+
+${JAVA_EXE} -version
+rm -f ${BADFILE}
+${TESTJAVA}/bin/javac CreateBadJar.java
+${JAVA_EXE} CreateBadJar ${BADFILE} "META-INF/MANIFEST.MF"
+LD_PRELOAD=/lib/64/libumem.so ${JAVA_EXE} -jar ${BADFILE} > test.out 2>&1
+
+grep "Invalid or corrupt jarfile" test.out
+exit $?