Merge
This commit is contained in:
commit
b43c00d17d
@ -454,6 +454,8 @@ JAVA_JAVA_java = \
|
|||||||
sun/misc/JavaLangAccess.java \
|
sun/misc/JavaLangAccess.java \
|
||||||
sun/misc/JavaIOAccess.java \
|
sun/misc/JavaIOAccess.java \
|
||||||
sun/misc/JavaIOFileDescriptorAccess.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)
|
FILES_java = $(JAVA_JAVA_java)
|
||||||
|
@ -187,9 +187,6 @@ void InitLauncher(jboolean javaw);
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
typedef jclass (JNICALL FindClassFromBootLoader_t(JNIEnv *env,
|
typedef jclass (JNICALL FindClassFromBootLoader_t(JNIEnv *env,
|
||||||
const char *name,
|
const char *name));
|
||||||
jboolean init,
|
|
||||||
jobject loader,
|
|
||||||
jboolean throwError));
|
|
||||||
jclass FindBootStrapClass(JNIEnv *env, const char *classname);
|
jclass FindBootStrapClass(JNIEnv *env, const char *classname);
|
||||||
#endif /* _JAVA_H_ */
|
#endif /* _JAVA_H_ */
|
||||||
|
@ -59,7 +59,7 @@ inflate_file(int fd, zentry *entry, int *size_out)
|
|||||||
char *out;
|
char *out;
|
||||||
z_stream zs;
|
z_stream zs;
|
||||||
|
|
||||||
if (entry->csize == 0xffffffff || entry->isize == 0xffffffff)
|
if (entry->csize == (size_t) -1 || entry->isize == (size_t) -1 )
|
||||||
return (NULL);
|
return (NULL);
|
||||||
if (lseek(fd, entry->offset, SEEK_SET) < (off_t)0)
|
if (lseek(fd, entry->offset, SEEK_SET) < (off_t)0)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
@ -133,7 +133,7 @@ public class JdbcRowSetResourceBundle implements Serializable {
|
|||||||
* This method returns an enumerated handle of the keys
|
* This method returns an enumerated handle of the keys
|
||||||
* which correspond to values translated to various locales.
|
* 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.
|
* corresponding locales.
|
||||||
*/
|
*/
|
||||||
public Enumeration getKeys() {
|
public Enumeration getKeys() {
|
||||||
@ -146,7 +146,7 @@ public class JdbcRowSetResourceBundle implements Serializable {
|
|||||||
* returns the corresponding value reading it
|
* returns the corresponding value reading it
|
||||||
* from the Resource Bundle loaded earlier.
|
* from the Resource Bundle loaded earlier.
|
||||||
*
|
*
|
||||||
* @returns value in locale specific language
|
* @return value in locale specific language
|
||||||
* according to the key passed.
|
* according to the key passed.
|
||||||
*/
|
*/
|
||||||
public Object handleGetObject(String key) {
|
public Object handleGetObject(String key) {
|
||||||
|
@ -3737,7 +3737,6 @@ public class JoinRowSetImpl extends WebRowSetImpl implements JoinRowSet {
|
|||||||
* Returns a result set containing the original value of the current
|
* Returns a result set containing the original value of the current
|
||||||
* row only.
|
* row only.
|
||||||
*
|
*
|
||||||
* @return the original result set of the row
|
|
||||||
* @throws SQLException if there is no current row
|
* @throws SQLException if there is no current row
|
||||||
* @see #setOriginalRow
|
* @see #setOriginalRow
|
||||||
*/
|
*/
|
||||||
|
@ -46,6 +46,17 @@ import javax.sql.rowset.spi.*;
|
|||||||
*/
|
*/
|
||||||
public class WebRowSetXmlReader implements XmlReader, Serializable {
|
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
|
* Parses the given <code>WebRowSet</code> object, getting its input from
|
||||||
* the given <code>java.io.Reader</code> object. The parser will send
|
* the given <code>java.io.Reader</code> object. The parser will send
|
||||||
@ -69,17 +80,6 @@ public class WebRowSetXmlReader implements XmlReader, Serializable {
|
|||||||
* reader for the given rowset
|
* reader for the given rowset
|
||||||
* @see XmlReaderContentHandler
|
* @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 {
|
public void readXML(WebRowSet caller, java.io.Reader reader) throws SQLException {
|
||||||
try {
|
try {
|
||||||
// Crimson Parser(as in J2SE 1.4.1 is NOT able to handle
|
// Crimson Parser(as in J2SE 1.4.1 is NOT able to handle
|
||||||
|
@ -565,8 +565,9 @@ public final
|
|||||||
* represented by this object.
|
* represented by this object.
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
String name = this.name;
|
||||||
if (name == null)
|
if (name == null)
|
||||||
name = getName0();
|
this.name = name = getName0();
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,16 +380,28 @@ public abstract class ClassLoader {
|
|||||||
// First, check if the class has already been loaded
|
// First, check if the class has already been loaded
|
||||||
Class c = findLoadedClass(name);
|
Class c = findLoadedClass(name);
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
|
long t0 = System.nanoTime();
|
||||||
try {
|
try {
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
c = parent.loadClass(name, false);
|
c = parent.loadClass(name, false);
|
||||||
} else {
|
} else {
|
||||||
c = findBootstrapClass0(name);
|
c = findBootstrapClassOrNull(name);
|
||||||
}
|
}
|
||||||
} catch (ClassNotFoundException e) {
|
} 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
|
// If still not found, then invoke findClass in order
|
||||||
// to find the class.
|
// to find the class.
|
||||||
|
long t1 = System.nanoTime();
|
||||||
c = findClass(name);
|
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) {
|
if (resolve) {
|
||||||
@ -1008,22 +1020,29 @@ public abstract class ClassLoader {
|
|||||||
if (system == null) {
|
if (system == null) {
|
||||||
if (!checkName(name))
|
if (!checkName(name))
|
||||||
throw new ClassNotFoundException(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);
|
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();
|
check();
|
||||||
if (!checkName(name))
|
if (!checkName(name)) return null;
|
||||||
throw new ClassNotFoundException(name);
|
|
||||||
return findBootstrapClass(name);
|
return findBootstrapClass(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private native Class findBootstrapClass(String name)
|
// return null if not found
|
||||||
throws ClassNotFoundException;
|
private native Class findBootstrapClass(String name);
|
||||||
|
|
||||||
// Check to make sure the class loader has been initialized.
|
// Check to make sure the class loader has been initialized.
|
||||||
private void check() {
|
private void check() {
|
||||||
|
@ -340,6 +340,7 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
|
|||||||
* used.
|
* used.
|
||||||
*/
|
*/
|
||||||
private Class defineClass(String name, Resource res) throws IOException {
|
private Class defineClass(String name, Resource res) throws IOException {
|
||||||
|
long t0 = System.nanoTime();
|
||||||
int i = name.lastIndexOf('.');
|
int i = name.lastIndexOf('.');
|
||||||
URL url = res.getCodeSourceURL();
|
URL url = res.getCodeSourceURL();
|
||||||
if (i != -1) {
|
if (i != -1) {
|
||||||
@ -370,12 +371,14 @@ public class URLClassLoader extends SecureClassLoader implements Closeable {
|
|||||||
// Use (direct) ByteBuffer:
|
// Use (direct) ByteBuffer:
|
||||||
CodeSigner[] signers = res.getCodeSigners();
|
CodeSigner[] signers = res.getCodeSigners();
|
||||||
CodeSource cs = new CodeSource(url, signers);
|
CodeSource cs = new CodeSource(url, signers);
|
||||||
|
sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
|
||||||
return defineClass(name, bb, cs);
|
return defineClass(name, bb, cs);
|
||||||
} else {
|
} else {
|
||||||
byte[] b = res.getBytes();
|
byte[] b = res.getBytes();
|
||||||
// must read certificates AFTER reading bytes.
|
// must read certificates AFTER reading bytes.
|
||||||
CodeSigner[] signers = res.getCodeSigners();
|
CodeSigner[] signers = res.getCodeSigners();
|
||||||
CodeSource cs = new CodeSource(url, signers);
|
CodeSource cs = new CodeSource(url, signers);
|
||||||
|
sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
|
||||||
return defineClass(name, b, 0, b.length, cs);
|
return defineClass(name, b, 0, b.length, cs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,12 @@ class FileTreeWalker {
|
|||||||
private final boolean detectCycles;
|
private final boolean detectCycles;
|
||||||
private final LinkOption[] linkOptions;
|
private final LinkOption[] linkOptions;
|
||||||
private final FileVisitor<? super Path> visitor;
|
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 fl = false;
|
||||||
boolean dc = false;
|
boolean dc = false;
|
||||||
for (FileVisitOption option: options) {
|
for (FileVisitOption option: options) {
|
||||||
@ -58,18 +62,15 @@ class FileTreeWalker {
|
|||||||
this.linkOptions = (fl) ? new LinkOption[0] :
|
this.linkOptions = (fl) ? new LinkOption[0] :
|
||||||
new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
|
new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
|
||||||
this.visitor = visitor;
|
this.visitor = visitor;
|
||||||
|
this.maxDepth = maxDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Walk file tree starting at the given file
|
* Walk file tree starting at the given file
|
||||||
*/
|
*/
|
||||||
void walk(Path start, int maxDepth) {
|
void walk(Path start) {
|
||||||
// don't use attributes of starting file as they may be stale
|
|
||||||
if (start instanceof BasicFileAttributesHolder) {
|
|
||||||
((BasicFileAttributesHolder)start).invalidate();
|
|
||||||
}
|
|
||||||
FileVisitResult result = walk(start,
|
FileVisitResult result = walk(start,
|
||||||
maxDepth,
|
0,
|
||||||
new ArrayList<AncestorDirectory>());
|
new ArrayList<AncestorDirectory>());
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
throw new NullPointerException("Visitor returned 'null'");
|
throw new NullPointerException("Visitor returned 'null'");
|
||||||
@ -89,12 +90,15 @@ class FileTreeWalker {
|
|||||||
List<AncestorDirectory> ancestors)
|
List<AncestorDirectory> ancestors)
|
||||||
{
|
{
|
||||||
// depth check
|
// depth check
|
||||||
if (depth-- < 0)
|
if (depth > maxDepth)
|
||||||
return FileVisitResult.CONTINUE;
|
return FileVisitResult.CONTINUE;
|
||||||
|
|
||||||
// if attributes are cached then use them if possible
|
// if attributes are cached then use them if possible
|
||||||
BasicFileAttributes attrs = null;
|
BasicFileAttributes attrs = null;
|
||||||
if (file instanceof BasicFileAttributesHolder) {
|
if ((depth > 0) &&
|
||||||
|
(file instanceof BasicFileAttributesHolder) &&
|
||||||
|
(System.getSecurityManager() == null))
|
||||||
|
{
|
||||||
BasicFileAttributes cached = ((BasicFileAttributesHolder)file).get();
|
BasicFileAttributes cached = ((BasicFileAttributesHolder)file).get();
|
||||||
if (!followLinks || !cached.isSymbolicLink())
|
if (!followLinks || !cached.isSymbolicLink())
|
||||||
attrs = cached;
|
attrs = cached;
|
||||||
@ -120,6 +124,10 @@ class FileTreeWalker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SecurityException x) {
|
} 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;
|
return FileVisitResult.CONTINUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,7 +204,7 @@ class FileTreeWalker {
|
|||||||
try {
|
try {
|
||||||
for (Path entry: stream) {
|
for (Path entry: stream) {
|
||||||
inAction = true;
|
inAction = true;
|
||||||
result = walk(entry, depth, ancestors);
|
result = walk(entry, depth+1, ancestors);
|
||||||
inAction = false;
|
inAction = false;
|
||||||
|
|
||||||
// returning null will cause NPE to be thrown
|
// returning null will cause NPE to be thrown
|
||||||
|
@ -223,7 +223,7 @@ public final class Files {
|
|||||||
{
|
{
|
||||||
if (maxDepth < 0)
|
if (maxDepth < 0)
|
||||||
throw new IllegalArgumentException("'maxDepth' is negative");
|
throw new IllegalArgumentException("'maxDepth' is negative");
|
||||||
new FileTreeWalker(options, visitor).walk(start, maxDepth);
|
new FileTreeWalker(options, visitor, maxDepth).walk(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,7 +28,7 @@ package java.util.logging;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* ErrorManager objects can be attached to Handlers to process
|
* 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>
|
* <p>
|
||||||
* When processing logging output, if a Handler encounters problems
|
* When processing logging output, if a Handler encounters problems
|
||||||
* then rather than throwing an Exception back to the issuer of
|
* then rather than throwing an Exception back to the issuer of
|
||||||
@ -72,7 +72,7 @@ public class ErrorManager {
|
|||||||
/**
|
/**
|
||||||
* The error method is called when a Handler failure occurs.
|
* The error method is called when a Handler failure occurs.
|
||||||
* <p>
|
* <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
|
* behavior in this base class is that the first call is
|
||||||
* reported to System.err, and subsequent calls are ignored.
|
* reported to System.err, and subsequent calls are ignored.
|
||||||
*
|
*
|
||||||
|
@ -39,7 +39,7 @@ import java.security.*;
|
|||||||
* For a rotating set of files, as each file reaches a given size
|
* For a rotating set of files, as each file reaches a given size
|
||||||
* limit, it is closed, rotated out, and a new file opened.
|
* limit, it is closed, rotated out, and a new file opened.
|
||||||
* Successively older files are named by adding "0", "1", "2",
|
* Successively older files are named by adding "0", "1", "2",
|
||||||
* etc into the base filename.
|
* etc. into the base filename.
|
||||||
* <p>
|
* <p>
|
||||||
* By default buffering is enabled in the IO libraries but each log
|
* By default buffering is enabled in the IO libraries but each log
|
||||||
* record is flushed out when it is complete.
|
* record is flushed out when it is complete.
|
||||||
@ -391,7 +391,7 @@ public class FileHandler extends StreamHandler {
|
|||||||
// Generate a lock file name from the "unique" int.
|
// Generate a lock file name from the "unique" int.
|
||||||
lockFileName = generate(pattern, 0, unique).toString() + ".lck";
|
lockFileName = generate(pattern, 0, unique).toString() + ".lck";
|
||||||
// Now try to lock that filename.
|
// 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
|
// between processes (and not within a process), we first check
|
||||||
// if we ourself already have the file locked.
|
// if we ourself already have the file locked.
|
||||||
synchronized(locks) {
|
synchronized(locks) {
|
||||||
|
@ -52,7 +52,7 @@ public abstract class Formatter {
|
|||||||
* Format the given log record and return the formatted string.
|
* Format the given log record and return the formatted string.
|
||||||
* <p>
|
* <p>
|
||||||
* The resulting formatted String will normally include a
|
* 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}
|
* It is recommended to use the {@link Formatter#formatMessage}
|
||||||
* convenience method to localize and format the message field.
|
* convenience method to localize and format the message field.
|
||||||
*
|
*
|
||||||
@ -66,7 +66,7 @@ public abstract class Formatter {
|
|||||||
* Return the header string for a set of formatted records.
|
* Return the header string for a set of formatted records.
|
||||||
* <p>
|
* <p>
|
||||||
* This base class returns an empty string, but this may be
|
* 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)
|
* @param h The target handler (can be null)
|
||||||
* @return header string
|
* @return header string
|
||||||
@ -79,7 +79,7 @@ public abstract class Formatter {
|
|||||||
* Return the tail string for a set of formatted records.
|
* Return the tail string for a set of formatted records.
|
||||||
* <p>
|
* <p>
|
||||||
* This base class returns an empty string, but this may be
|
* 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)
|
* @param h The target handler (can be null)
|
||||||
* @return tail string
|
* @return tail string
|
||||||
|
@ -274,7 +274,7 @@ public abstract class Handler {
|
|||||||
* <tt>Level</tt> and whether it satisfies any <tt>Filter</tt>. It also
|
* <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
|
* may make other <tt>Handler</tt> specific checks that might prevent a
|
||||||
* handler from logging the <tt>LogRecord</tt>. It will return false if
|
* 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>
|
* <p>
|
||||||
* @param record a <tt>LogRecord</tt>
|
* @param record a <tt>LogRecord</tt>
|
||||||
* @return true if the <tt>LogRecord</tt> would be logged.
|
* @return true if the <tt>LogRecord</tt> would be logged.
|
||||||
|
@ -110,7 +110,7 @@ public class Level implements java.io.Serializable {
|
|||||||
* Typically INFO messages will be written to the console
|
* Typically INFO messages will be written to the console
|
||||||
* or its equivalent. So the INFO level should only be
|
* or its equivalent. So the INFO level should only be
|
||||||
* used for reasonably significant messages that will
|
* 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>.
|
* This level is initialized to <CODE>800</CODE>.
|
||||||
*/
|
*/
|
||||||
public static final Level INFO = new Level("INFO", 800, defaultBundle);
|
public static final Level INFO = new Level("INFO", 800, defaultBundle);
|
||||||
@ -245,6 +245,8 @@ public class Level implements java.io.Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns a string representation of this Level.
|
||||||
|
*
|
||||||
* @return the non-localized name of the Level, for example "INFO".
|
* @return the non-localized name of the Level, for example "INFO".
|
||||||
*/
|
*/
|
||||||
public final String toString() {
|
public final String toString() {
|
||||||
@ -299,14 +301,14 @@ public class Level implements java.io.Serializable {
|
|||||||
* @throws IllegalArgumentException if the value is not valid.
|
* @throws IllegalArgumentException if the value is not valid.
|
||||||
* Valid values are integers between <CODE>Integer.MIN_VALUE</CODE>
|
* Valid values are integers between <CODE>Integer.MIN_VALUE</CODE>
|
||||||
* and <CODE>Integer.MAX_VALUE</CODE>, and all known level names.
|
* 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
|
* <CODE>FINER</CODE>, <CODE>FINEST</CODE>), or created by this class with
|
||||||
* appropriate package access, or new levels defined or created
|
* appropriate package access, or new levels defined or created
|
||||||
* by subclasses.
|
* by subclasses.
|
||||||
*
|
*
|
||||||
* @return The parsed value. Passing an integer that corresponds to a known name
|
* @return The parsed value. Passing an integer that corresponds to a known name
|
||||||
* (eg 700) will return the associated name (eg <CODE>CONFIG</CODE>).
|
* (e.g., 700) will return the associated name (e.g., <CODE>CONFIG</CODE>).
|
||||||
* Passing an integer that does not (eg 1) will return a new level name
|
* Passing an integer that does not (e.g., 1) will return a new level name
|
||||||
* initialized to that value.
|
* initialized to that value.
|
||||||
*/
|
*/
|
||||||
public static synchronized Level parse(String name) throws IllegalArgumentException {
|
public static synchronized Level parse(String name) throws IllegalArgumentException {
|
||||||
|
@ -188,7 +188,7 @@ public class LogRecord implements java.io.Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the source Logger name's
|
* Get the source Logger's name.
|
||||||
*
|
*
|
||||||
* @return source logger name (may be null)
|
* @return source logger name (may be null)
|
||||||
*/
|
*/
|
||||||
@ -197,7 +197,7 @@ public class LogRecord implements java.io.Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the source Logger name.
|
* Set the source Logger's name.
|
||||||
*
|
*
|
||||||
* @param name the source logger name (may be null)
|
* @param name the source logger name (may be null)
|
||||||
*/
|
*/
|
||||||
|
@ -66,7 +66,7 @@ import java.lang.ref.WeakReference;
|
|||||||
* effective level from its parent.
|
* effective level from its parent.
|
||||||
* <p>
|
* <p>
|
||||||
* On each logging call the Logger initially performs a cheap
|
* 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
|
* effective log level of the logger. If the request level is
|
||||||
* lower than the log level, the logging call returns immediately.
|
* lower than the log level, the logging call returns immediately.
|
||||||
* <p>
|
* <p>
|
||||||
@ -230,7 +230,7 @@ public class Logger {
|
|||||||
* Protected method to construct a logger for a named subsystem.
|
* Protected method to construct a logger for a named subsystem.
|
||||||
* <p>
|
* <p>
|
||||||
* The logger will be initially configured with a null Level
|
* 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
|
* @param name A name for the logger. This should
|
||||||
* be a dot-separated name and should normally
|
* be a dot-separated name and should normally
|
||||||
@ -240,7 +240,7 @@ public class Logger {
|
|||||||
* @param resourceBundleName name of ResourceBundle to be used for localizing
|
* @param resourceBundleName name of ResourceBundle to be used for localizing
|
||||||
* messages for this logger. May be null if none
|
* messages for this logger. May be null if none
|
||||||
* of the messages require localization.
|
* 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.
|
* no corresponding resource can be found.
|
||||||
*/
|
*/
|
||||||
protected Logger(String name, String resourceBundleName) {
|
protected Logger(String name, String resourceBundleName) {
|
||||||
@ -285,7 +285,7 @@ public class Logger {
|
|||||||
* <p>
|
* <p>
|
||||||
* If a new logger is created its log level will be configured
|
* If a new logger is created its log level will be configured
|
||||||
* based on the LogManager configuration and it will 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.
|
* be registered in the LogManager global namespace.
|
||||||
*
|
*
|
||||||
* @param name A name for the logger. This should
|
* @param name A name for the logger. This should
|
||||||
@ -308,7 +308,7 @@ public class Logger {
|
|||||||
* <p>
|
* <p>
|
||||||
* If a new logger is created its log level will be configured
|
* If a new logger is created its log level will be configured
|
||||||
* based on the LogManager and it will configured to also send logging
|
* 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.
|
* the LogManager global namespace.
|
||||||
* <p>
|
* <p>
|
||||||
* If the named Logger already exists and does not yet have a
|
* If the named Logger already exists and does not yet have a
|
||||||
@ -326,7 +326,8 @@ public class Logger {
|
|||||||
* messages for this logger. May be <CODE>null</CODE> if none of
|
* messages for this logger. May be <CODE>null</CODE> if none of
|
||||||
* the messages require localization.
|
* the messages require localization.
|
||||||
* @return a suitable Logger
|
* @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
|
* @throws IllegalArgumentException if the Logger already exists and uses
|
||||||
* a different resource bundle name.
|
* a different resource bundle name.
|
||||||
* @throws NullPointerException if the name is null.
|
* @throws NullPointerException if the name is null.
|
||||||
@ -395,7 +396,8 @@ public class Logger {
|
|||||||
* messages for this logger.
|
* messages for this logger.
|
||||||
* May be null if none of the messages require localization.
|
* May be null if none of the messages require localization.
|
||||||
* @return a newly created private Logger
|
* @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) {
|
public static synchronized Logger getAnonymousLogger(String resourceBundleName) {
|
||||||
LogManager manager = LogManager.getLogManager();
|
LogManager manager = LogManager.getLogManager();
|
||||||
@ -514,7 +516,7 @@ public class Logger {
|
|||||||
* level then the given message is forwarded to all the
|
* level then the given message is forwarded to all the
|
||||||
* registered output Handler objects.
|
* registered output Handler objects.
|
||||||
* <p>
|
* <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 msg The string message (or a key in the message catalog)
|
||||||
*/
|
*/
|
||||||
public void log(Level level, String msg) {
|
public void log(Level level, String msg) {
|
||||||
@ -532,7 +534,7 @@ public class Logger {
|
|||||||
* level then a corresponding LogRecord is created and forwarded
|
* level then a corresponding LogRecord is created and forwarded
|
||||||
* to all the registered output Handler objects.
|
* to all the registered output Handler objects.
|
||||||
* <p>
|
* <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 msg The string message (or a key in the message catalog)
|
||||||
* @param param1 parameter to the message
|
* @param param1 parameter to the message
|
||||||
*/
|
*/
|
||||||
@ -553,7 +555,7 @@ public class Logger {
|
|||||||
* level then a corresponding LogRecord is created and forwarded
|
* level then a corresponding LogRecord is created and forwarded
|
||||||
* to all the registered output Handler objects.
|
* to all the registered output Handler objects.
|
||||||
* <p>
|
* <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 msg The string message (or a key in the message catalog)
|
||||||
* @param params array of parameters to the message
|
* @param params array of parameters to the message
|
||||||
*/
|
*/
|
||||||
@ -578,7 +580,7 @@ public class Logger {
|
|||||||
* processed specially by output Formatters and is not treated
|
* processed specially by output Formatters and is not treated
|
||||||
* as a formatting parameter to the LogRecord message property.
|
* as a formatting parameter to the LogRecord message property.
|
||||||
* <p>
|
* <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 msg The string message (or a key in the message catalog)
|
||||||
* @param thrown Throwable associated with log message.
|
* @param thrown Throwable associated with log message.
|
||||||
*/
|
*/
|
||||||
@ -603,7 +605,7 @@ public class Logger {
|
|||||||
* level then the given message is forwarded to all the
|
* level then the given message is forwarded to all the
|
||||||
* registered output Handler objects.
|
* registered output Handler objects.
|
||||||
* <p>
|
* <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 sourceClass name of class that issued the logging request
|
||||||
* @param sourceMethod name of method 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)
|
* @param msg The string message (or a key in the message catalog)
|
||||||
@ -626,7 +628,7 @@ public class Logger {
|
|||||||
* level then a corresponding LogRecord is created and forwarded
|
* level then a corresponding LogRecord is created and forwarded
|
||||||
* to all the registered output Handler objects.
|
* to all the registered output Handler objects.
|
||||||
* <p>
|
* <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 sourceClass name of class that issued the logging request
|
||||||
* @param sourceMethod name of method 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)
|
* @param msg The string message (or a key in the message catalog)
|
||||||
@ -653,7 +655,7 @@ public class Logger {
|
|||||||
* level then a corresponding LogRecord is created and forwarded
|
* level then a corresponding LogRecord is created and forwarded
|
||||||
* to all the registered output Handler objects.
|
* to all the registered output Handler objects.
|
||||||
* <p>
|
* <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 sourceClass name of class that issued the logging request
|
||||||
* @param sourceMethod name of method 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)
|
* @param msg The string message (or a key in the message catalog)
|
||||||
@ -684,7 +686,7 @@ public class Logger {
|
|||||||
* processed specially by output Formatters and is not treated
|
* processed specially by output Formatters and is not treated
|
||||||
* as a formatting parameter to the LogRecord message property.
|
* as a formatting parameter to the LogRecord message property.
|
||||||
* <p>
|
* <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 sourceClass name of class that issued the logging request
|
||||||
* @param sourceMethod name of method 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)
|
* @param msg The string message (or a key in the message catalog)
|
||||||
@ -731,7 +733,7 @@ public class Logger {
|
|||||||
* resource bundle name is null, or an empty String or invalid
|
* resource bundle name is null, or an empty String or invalid
|
||||||
* then the msg string is not localized.
|
* then the msg string is not localized.
|
||||||
* <p>
|
* <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 sourceClass name of class that issued the logging request
|
||||||
* @param sourceMethod name of method that issued the logging request
|
* @param sourceMethod name of method that issued the logging request
|
||||||
* @param bundleName name of resource bundle to localize msg,
|
* @param bundleName name of resource bundle to localize msg,
|
||||||
@ -762,7 +764,7 @@ public class Logger {
|
|||||||
* resource bundle name is null, or an empty String or invalid
|
* resource bundle name is null, or an empty String or invalid
|
||||||
* then the msg string is not localized.
|
* then the msg string is not localized.
|
||||||
* <p>
|
* <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 sourceClass name of class that issued the logging request
|
||||||
* @param sourceMethod name of method that issued the logging request
|
* @param sourceMethod name of method that issued the logging request
|
||||||
* @param bundleName name of resource bundle to localize msg,
|
* @param bundleName name of resource bundle to localize msg,
|
||||||
@ -795,7 +797,7 @@ public class Logger {
|
|||||||
* resource bundle name is null, or an empty String or invalid
|
* resource bundle name is null, or an empty String or invalid
|
||||||
* then the msg string is not localized.
|
* then the msg string is not localized.
|
||||||
* <p>
|
* <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 sourceClass name of class that issued the logging request
|
||||||
* @param sourceMethod name of method that issued the logging request
|
* @param sourceMethod name of method that issued the logging request
|
||||||
* @param bundleName name of resource bundle to localize msg,
|
* @param bundleName name of resource bundle to localize msg,
|
||||||
@ -832,7 +834,7 @@ public class Logger {
|
|||||||
* processed specially by output Formatters and is not treated
|
* processed specially by output Formatters and is not treated
|
||||||
* as a formatting parameter to the LogRecord message property.
|
* as a formatting parameter to the LogRecord message property.
|
||||||
* <p>
|
* <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 sourceClass name of class that issued the logging request
|
||||||
* @param sourceMethod name of method that issued the logging request
|
* @param sourceMethod name of method that issued the logging request
|
||||||
* @param bundleName name of resource bundle to localize msg,
|
* @param bundleName name of resource bundle to localize msg,
|
||||||
@ -1214,7 +1216,7 @@ public class Logger {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify whether or not this logger should send its output
|
* 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
|
* also be written to the parent's Handlers, and potentially
|
||||||
* to its parent, recursively up the namespace.
|
* to its parent, recursively up the namespace.
|
||||||
*
|
*
|
||||||
|
@ -105,8 +105,8 @@ public interface LoggingMXBean extends PlatformManagedObject {
|
|||||||
*
|
*
|
||||||
* @param loggerName The name of the <tt>Logger</tt> to be set.
|
* @param loggerName The name of the <tt>Logger</tt> to be set.
|
||||||
* Must be non-null.
|
* Must be non-null.
|
||||||
* @param levelName The name of the level to set the specified logger to,
|
* @param levelName The name of the level to set on the specified logger,
|
||||||
* or <tt>null</tt> if to set the level to inherit
|
* or <tt>null</tt> if setting the level to inherit
|
||||||
* from its nearest ancestor.
|
* from its nearest ancestor.
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if the specified logger
|
* @throws IllegalArgumentException if the specified logger
|
||||||
|
@ -136,7 +136,7 @@ public class MemoryHandler extends Handler {
|
|||||||
* @param size the number of log records to buffer (must be greater than zero)
|
* @param size the number of log records to buffer (must be greater than zero)
|
||||||
* @param pushLevel message level to push on
|
* @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) {
|
public MemoryHandler(Handler target, int size, Level pushLevel) {
|
||||||
if (target == null || pushLevel == null) {
|
if (target == null || pushLevel == null) {
|
||||||
@ -258,7 +258,7 @@ public class MemoryHandler extends Handler {
|
|||||||
* This method checks if the <tt>LogRecord</tt> has an appropriate level and
|
* 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>
|
* 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
|
* 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>
|
* <p>
|
||||||
* @param record a <tt>LogRecord</tt>
|
* @param record a <tt>LogRecord</tt>
|
||||||
* @return true if the <tt>LogRecord</tt> would be logged.
|
* @return true if the <tt>LogRecord</tt> would be logged.
|
||||||
|
@ -220,7 +220,7 @@ public class StreamHandler extends Handler {
|
|||||||
* <p>
|
* <p>
|
||||||
* This method checks if the <tt>LogRecord</tt> has an appropriate level and
|
* 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
|
* 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>
|
* <p>
|
||||||
* @param record a <tt>LogRecord</tt>
|
* @param record a <tt>LogRecord</tt>
|
||||||
* @return true if the <tt>LogRecord</tt> would be logged.
|
* @return true if the <tt>LogRecord</tt> would be logged.
|
||||||
|
@ -253,14 +253,10 @@ class ZipEntry implements ZipConstants, Cloneable {
|
|||||||
* the first 0xFFFF bytes are output to the ZIP file entry.
|
* the first 0xFFFF bytes are output to the ZIP file entry.
|
||||||
*
|
*
|
||||||
* @param comment the comment string
|
* @param comment the comment string
|
||||||
* @exception IllegalArgumentException if the length of the specified
|
*
|
||||||
* comment string is greater than 0xFFFF bytes
|
|
||||||
* @see #getComment()
|
* @see #getComment()
|
||||||
*/
|
*/
|
||||||
public void setComment(String comment) {
|
public void setComment(String comment) {
|
||||||
if (comment != null && comment.length() > 0xffff) {
|
|
||||||
throw new IllegalArgumentException("invalid entry comment length");
|
|
||||||
}
|
|
||||||
this.comment = comment;
|
this.comment = comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +195,10 @@ class ZipFile implements ZipConstants, Closeable {
|
|||||||
if (charset == null)
|
if (charset == null)
|
||||||
throw new NullPointerException("charset is null");
|
throw new NullPointerException("charset is null");
|
||||||
this.zc = ZipCoder.get(charset);
|
this.zc = ZipCoder.get(charset);
|
||||||
|
long t0 = System.nanoTime();
|
||||||
jzfile = open(name, mode, file.lastModified());
|
jzfile = open(name, mode, file.lastModified());
|
||||||
|
sun.misc.PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0);
|
||||||
|
sun.misc.PerfCounter.getZipFileCount().increment();
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.total = getTotal(jzfile);
|
this.total = getTotal(jzfile);
|
||||||
}
|
}
|
||||||
|
@ -168,8 +168,8 @@ import javax.sql.rowset.serial.*;
|
|||||||
* The majority of methods for setting placeholder parameters take two parameters,
|
* The majority of methods for setting placeholder parameters take two parameters,
|
||||||
* with the first parameter
|
* with the first parameter
|
||||||
* indicating which placeholder parameter is to be set, and the second 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>,
|
* giving the value to be set. Methods such as <code>setInt</code>,
|
||||||
* <code>getString</code>, <code>getBoolean</code>, and <code>getLong</code> fall into
|
* <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
|
* 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
|
* <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
|
* element in the array is an <code>Object</code> instance representing the
|
||||||
@ -3259,9 +3259,9 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* @param x the parameter value
|
* @param x the parameter value
|
||||||
* @exception SQLException if a database access error occurs or
|
* @exception SQLException if a database access error occurs or
|
||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @see #getBoolean
|
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setBoolean(String parameterName, boolean x) throws SQLException{
|
public void setBoolean(String parameterName, boolean x) throws SQLException{
|
||||||
@ -3281,7 +3281,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getByte
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setByte(String parameterName, byte x) throws SQLException{
|
public void setByte(String parameterName, byte x) throws SQLException{
|
||||||
@ -3301,7 +3301,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getShort
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setShort(String parameterName, short x) throws SQLException{
|
public void setShort(String parameterName, short x) throws SQLException{
|
||||||
@ -3320,7 +3320,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getInt
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setInt(String parameterName, int x) throws SQLException{
|
public void setInt(String parameterName, int x) throws SQLException{
|
||||||
@ -3339,7 +3339,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getLong
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setLong(String parameterName, long x) throws SQLException{
|
public void setLong(String parameterName, long x) throws SQLException{
|
||||||
@ -3358,7 +3358,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getFloat
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setFloat(String parameterName, float x) throws SQLException{
|
public void setFloat(String parameterName, float x) throws SQLException{
|
||||||
@ -3377,7 +3377,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getDouble
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setDouble(String parameterName, double x) throws SQLException{
|
public void setDouble(String parameterName, double x) throws SQLException{
|
||||||
@ -3398,7 +3398,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getBigDecimal
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{
|
public void setBigDecimal(String parameterName, BigDecimal x) throws SQLException{
|
||||||
@ -3421,7 +3421,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getString
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setString(String parameterName, String x) throws SQLException{
|
public void setString(String parameterName, String x) throws SQLException{
|
||||||
@ -3443,7 +3443,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getBytes
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setBytes(String parameterName, byte x[]) throws SQLException{
|
public void setBytes(String parameterName, byte x[]) throws SQLException{
|
||||||
@ -3464,7 +3464,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getTimestamp
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setTimestamp(String parameterName, java.sql.Timestamp x)
|
public void setTimestamp(String parameterName, java.sql.Timestamp x)
|
||||||
@ -3712,7 +3712,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* or <code>STRUCT</code> data type and the JDBC driver does not support
|
* or <code>STRUCT</code> data type and the JDBC driver does not support
|
||||||
* this data type
|
* this data type
|
||||||
* @see Types
|
* @see Types
|
||||||
* @see #getObject
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setObject(String parameterName, Object x, int targetSqlType, int scale)
|
public void setObject(String parameterName, Object x, int targetSqlType, int scale)
|
||||||
@ -3740,7 +3740,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
|
* <code>REF</code>, <code>ROWID</code>, <code>SQLXML</code>
|
||||||
* or <code>STRUCT</code> data type and the JDBC driver does not support
|
* or <code>STRUCT</code> data type and the JDBC driver does not support
|
||||||
* this data type
|
* this data type
|
||||||
* @see #getObject
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setObject(String parameterName, Object x, int targetSqlType)
|
public void setObject(String parameterName, Object x, int targetSqlType)
|
||||||
@ -3782,7 +3782,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* <code>Object</code> parameter is ambiguous
|
* <code>Object</code> parameter is ambiguous
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getObject
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setObject(String parameterName, Object x) throws SQLException{
|
public void setObject(String parameterName, Object x) throws SQLException{
|
||||||
@ -4064,7 +4064,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getDate
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setDate(String parameterName, java.sql.Date x)
|
public void setDate(String parameterName, java.sql.Date x)
|
||||||
@ -4091,7 +4091,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getDate
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setDate(String parameterName, java.sql.Date x, Calendar cal)
|
public void setDate(String parameterName, java.sql.Date x, Calendar cal)
|
||||||
@ -4111,7 +4111,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getTime
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setTime(String parameterName, java.sql.Time x)
|
public void setTime(String parameterName, java.sql.Time x)
|
||||||
@ -4138,7 +4138,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getTime
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setTime(String parameterName, java.sql.Time x, Calendar cal)
|
public void setTime(String parameterName, java.sql.Time x, Calendar cal)
|
||||||
@ -4165,7 +4165,7 @@ public static final int ASCII_STREAM_PARAM = 2;
|
|||||||
* this method is called on a closed <code>CallableStatement</code>
|
* this method is called on a closed <code>CallableStatement</code>
|
||||||
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
|
||||||
* this method
|
* this method
|
||||||
* @see #getTimestamp
|
* @see #getParams
|
||||||
* @since 1.4
|
* @since 1.4
|
||||||
*/
|
*/
|
||||||
public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal)
|
public void setTimestamp(String parameterName, java.sql.Timestamp x, Calendar cal)
|
||||||
|
191
jdk/src/share/classes/sun/misc/PerfCounter.java
Normal file
191
jdk/src/share/classes/sun/misc/PerfCounter.java
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,12 +26,14 @@
|
|||||||
package sun.security.provider.certpath;
|
package sun.security.provider.certpath;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.security.AccessController;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.cert.*;
|
import java.security.cert.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import javax.security.auth.x500.X500Principal;
|
import javax.security.auth.x500.X500Principal;
|
||||||
|
|
||||||
|
import sun.security.action.GetBooleanAction;
|
||||||
import sun.security.util.Debug;
|
import sun.security.util.Debug;
|
||||||
import sun.security.x509.GeneralNames;
|
import sun.security.x509.GeneralNames;
|
||||||
import sun.security.x509.GeneralNameInterface;
|
import sun.security.x509.GeneralNameInterface;
|
||||||
@ -64,9 +66,8 @@ public abstract class Builder {
|
|||||||
* Authority Information Access extension shall be enabled. Currently
|
* Authority Information Access extension shall be enabled. Currently
|
||||||
* disabled by default for compatibility reasons.
|
* disabled by default for compatibility reasons.
|
||||||
*/
|
*/
|
||||||
final static boolean USE_AIA =
|
final static boolean USE_AIA = AccessController.doPrivileged
|
||||||
DistributionPointFetcher.getBooleanProperty
|
(new GetBooleanAction("com.sun.security.enableAIAcaIssuers"));
|
||||||
("com.sun.security.enableAIAcaIssuers", false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the builder with the input parameters.
|
* Initialize the builder with the input parameters.
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,9 +25,11 @@
|
|||||||
|
|
||||||
package sun.security.provider.certpath;
|
package sun.security.provider.certpath;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import sun.misc.HexDumpEncoder;
|
import sun.misc.HexDumpEncoder;
|
||||||
import sun.security.x509.*;
|
import sun.security.x509.*;
|
||||||
@ -54,21 +56,28 @@ import sun.security.util.*;
|
|||||||
public class CertId {
|
public class CertId {
|
||||||
|
|
||||||
private static final boolean debug = false;
|
private static final boolean debug = false;
|
||||||
private AlgorithmId hashAlgId;
|
private static final AlgorithmId SHA1_ALGID
|
||||||
private byte[] issuerNameHash;
|
= new AlgorithmId(AlgorithmId.SHA_oid);
|
||||||
private byte[] issuerKeyHash;
|
private final AlgorithmId hashAlgId;
|
||||||
private SerialNumber certSerialNumber;
|
private final byte[] issuerNameHash;
|
||||||
|
private final byte[] issuerKeyHash;
|
||||||
|
private final SerialNumber certSerialNumber;
|
||||||
private int myhash = -1; // hashcode for this CertId
|
private int myhash = -1; // hashcode for this CertId
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a CertId. The hash algorithm used is SHA-1.
|
* Creates a CertId. The hash algorithm used is SHA-1.
|
||||||
*/
|
*/
|
||||||
public CertId(X509CertImpl issuerCert, SerialNumber serialNumber)
|
public CertId(X509Certificate issuerCert, SerialNumber serialNumber)
|
||||||
throws Exception {
|
throws IOException {
|
||||||
|
|
||||||
// compute issuerNameHash
|
// compute issuerNameHash
|
||||||
MessageDigest md = MessageDigest.getInstance("SHA1");
|
MessageDigest md = null;
|
||||||
hashAlgId = AlgorithmId.get("SHA1");
|
try {
|
||||||
|
md = MessageDigest.getInstance("SHA1");
|
||||||
|
} catch (NoSuchAlgorithmException nsae) {
|
||||||
|
throw new IOException("Unable to create CertId", nsae);
|
||||||
|
}
|
||||||
|
hashAlgId = SHA1_ALGID;
|
||||||
md.update(issuerCert.getSubjectX500Principal().getEncoded());
|
md.update(issuerCert.getSubjectX500Principal().getEncoded());
|
||||||
issuerNameHash = md.digest();
|
issuerNameHash = md.digest();
|
||||||
|
|
||||||
@ -90,6 +99,7 @@ public class CertId {
|
|||||||
encoder.encode(issuerNameHash));
|
encoder.encode(issuerNameHash));
|
||||||
System.out.println("issuerKeyHash is " +
|
System.out.println("issuerKeyHash is " +
|
||||||
encoder.encode(issuerKeyHash));
|
encoder.encode(issuerKeyHash));
|
||||||
|
System.out.println("SerialNumber is " + serialNumber.getNumber());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +107,6 @@ public class CertId {
|
|||||||
* Creates a CertId from its ASN.1 DER encoding.
|
* Creates a CertId from its ASN.1 DER encoding.
|
||||||
*/
|
*/
|
||||||
public CertId(DerInputStream derIn) throws IOException {
|
public CertId(DerInputStream derIn) throws IOException {
|
||||||
|
|
||||||
hashAlgId = AlgorithmId.parse(derIn.getDerValue());
|
hashAlgId = AlgorithmId.parse(derIn.getDerValue());
|
||||||
issuerNameHash = derIn.getOctetString();
|
issuerNameHash = derIn.getOctetString();
|
||||||
issuerKeyHash = derIn.getOctetString();
|
issuerKeyHash = derIn.getOctetString();
|
||||||
@ -157,7 +166,7 @@ public class CertId {
|
|||||||
*
|
*
|
||||||
* @return the hashcode value.
|
* @return the hashcode value.
|
||||||
*/
|
*/
|
||||||
public int hashCode() {
|
@Override public int hashCode() {
|
||||||
if (myhash == -1) {
|
if (myhash == -1) {
|
||||||
myhash = hashAlgId.hashCode();
|
myhash = hashAlgId.hashCode();
|
||||||
for (int i = 0; i < issuerNameHash.length; i++) {
|
for (int i = 0; i < issuerNameHash.length; i++) {
|
||||||
@ -180,8 +189,7 @@ public class CertId {
|
|||||||
* @param other the object to test for equality with this object.
|
* @param other the object to test for equality with this object.
|
||||||
* @return true if the objects are considered equal, false otherwise.
|
* @return true if the objects are considered equal, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean equals(Object other) {
|
@Override public boolean equals(Object other) {
|
||||||
|
|
||||||
if (this == other) {
|
if (this == other) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -203,7 +211,7 @@ public class CertId {
|
|||||||
/**
|
/**
|
||||||
* Create a string representation of the CertId.
|
* Create a string representation of the CertId.
|
||||||
*/
|
*/
|
||||||
public String toString() {
|
@Override public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("CertId \n");
|
sb.append("CertId \n");
|
||||||
sb.append("Algorithm: " + hashAlgId.toString() +"\n");
|
sb.append("Algorithm: " + hashAlgId.toString() +"\n");
|
||||||
|
@ -80,6 +80,7 @@ class CrlRevocationChecker extends PKIXCertPathChecker {
|
|||||||
{ false, false, false, false, false, false, true };
|
{ false, false, false, false, false, false, true };
|
||||||
private static final boolean[] ALL_REASONS =
|
private static final boolean[] ALL_REASONS =
|
||||||
{true, true, true, true, true, true, true, true, true};
|
{true, true, true, true, true, true, true, true, true};
|
||||||
|
private boolean mOnlyEECert = false;
|
||||||
|
|
||||||
// Maximum clock skew in milliseconds (15 minutes) allowed when checking
|
// Maximum clock skew in milliseconds (15 minutes) allowed when checking
|
||||||
// validity of CRLs
|
// validity of CRLs
|
||||||
@ -114,6 +115,12 @@ class CrlRevocationChecker extends PKIXCertPathChecker {
|
|||||||
CrlRevocationChecker(TrustAnchor anchor, PKIXParameters params,
|
CrlRevocationChecker(TrustAnchor anchor, PKIXParameters params,
|
||||||
Collection<X509Certificate> certs) throws CertPathValidatorException
|
Collection<X509Certificate> certs) throws CertPathValidatorException
|
||||||
{
|
{
|
||||||
|
this(anchor, params, certs, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
CrlRevocationChecker(TrustAnchor anchor, PKIXParameters params,
|
||||||
|
Collection<X509Certificate> certs, boolean onlyEECert)
|
||||||
|
throws CertPathValidatorException {
|
||||||
mAnchor = anchor;
|
mAnchor = anchor;
|
||||||
mParams = params;
|
mParams = params;
|
||||||
mStores = new ArrayList<CertStore>(params.getCertStores());
|
mStores = new ArrayList<CertStore>(params.getCertStores());
|
||||||
@ -133,6 +140,7 @@ class CrlRevocationChecker extends PKIXCertPathChecker {
|
|||||||
}
|
}
|
||||||
Date testDate = params.getDate();
|
Date testDate = params.getDate();
|
||||||
mCurrentTime = (testDate != null ? testDate : new Date());
|
mCurrentTime = (testDate != null ? testDate : new Date());
|
||||||
|
mOnlyEECert = onlyEECert;
|
||||||
init(false);
|
init(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,6 +272,13 @@ class CrlRevocationChecker extends PKIXCertPathChecker {
|
|||||||
" ---checking " + msg + "...");
|
" ---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
|
// reject circular dependencies - RFC 3280 is not explicit on how
|
||||||
// to handle this, so we feel it is safest to reject them until
|
// to handle this, so we feel it is safest to reject them until
|
||||||
// the issue is resolved in the PKIX WG.
|
// the issue is resolved in the PKIX WG.
|
||||||
|
@ -32,7 +32,7 @@ import java.security.*;
|
|||||||
import java.security.cert.*;
|
import java.security.cert.*;
|
||||||
import javax.security.auth.x500.X500Principal;
|
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.Debug;
|
||||||
import sun.security.util.DerOutputStream;
|
import sun.security.util.DerOutputStream;
|
||||||
import sun.security.x509.*;
|
import sun.security.x509.*;
|
||||||
@ -62,28 +62,8 @@ class DistributionPointFetcher {
|
|||||||
* extension shall be enabled. Currently disabled by default for
|
* extension shall be enabled. Currently disabled by default for
|
||||||
* compatibility and legal reasons.
|
* compatibility and legal reasons.
|
||||||
*/
|
*/
|
||||||
private final static boolean USE_CRLDP =
|
private final static boolean USE_CRLDP = AccessController.doPrivileged
|
||||||
getBooleanProperty("com.sun.security.enableCRLDP", false);
|
(new GetBooleanAction("com.sun.security.enableCRLDP"));
|
||||||
|
|
||||||
/**
|
|
||||||
* 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'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// singleton instance
|
// singleton instance
|
||||||
private static final DistributionPointFetcher INSTANCE =
|
private static final DistributionPointFetcher INSTANCE =
|
||||||
|
@ -82,6 +82,7 @@ class ForwardBuilder extends Builder {
|
|||||||
TrustAnchor trustAnchor;
|
TrustAnchor trustAnchor;
|
||||||
private Comparator<X509Certificate> comparator;
|
private Comparator<X509Certificate> comparator;
|
||||||
private boolean searchAllCertStores = true;
|
private boolean searchAllCertStores = true;
|
||||||
|
private boolean onlyEECert = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the builder with the input parameters.
|
* Initialize the builder with the input parameters.
|
||||||
@ -89,7 +90,8 @@ class ForwardBuilder extends Builder {
|
|||||||
* @param params the parameter set used to build a certification path
|
* @param params the parameter set used to build a certification path
|
||||||
*/
|
*/
|
||||||
ForwardBuilder(PKIXBuilderParameters buildParams,
|
ForwardBuilder(PKIXBuilderParameters buildParams,
|
||||||
X500Principal targetSubjectDN, boolean searchAllCertStores)
|
X500Principal targetSubjectDN, boolean searchAllCertStores,
|
||||||
|
boolean onlyEECert)
|
||||||
{
|
{
|
||||||
super(buildParams, targetSubjectDN);
|
super(buildParams, targetSubjectDN);
|
||||||
|
|
||||||
@ -108,6 +110,7 @@ class ForwardBuilder extends Builder {
|
|||||||
}
|
}
|
||||||
comparator = new PKIXCertComparator(trustedSubjectDNs);
|
comparator = new PKIXCertComparator(trustedSubjectDNs);
|
||||||
this.searchAllCertStores = searchAllCertStores;
|
this.searchAllCertStores = searchAllCertStores;
|
||||||
|
this.onlyEECert = onlyEECert;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -875,8 +878,8 @@ class ForwardBuilder extends Builder {
|
|||||||
/* Check revocation if it is enabled */
|
/* Check revocation if it is enabled */
|
||||||
if (buildParams.isRevocationEnabled()) {
|
if (buildParams.isRevocationEnabled()) {
|
||||||
try {
|
try {
|
||||||
CrlRevocationChecker crlChecker =
|
CrlRevocationChecker crlChecker = new CrlRevocationChecker
|
||||||
new CrlRevocationChecker(anchor, buildParams);
|
(anchor, buildParams, null, onlyEECert);
|
||||||
crlChecker.check(cert, anchor.getCAPublicKey(), true);
|
crlChecker.check(cert, anchor.getCAPublicKey(), true);
|
||||||
} catch (CertPathValidatorException cpve) {
|
} catch (CertPathValidatorException cpve) {
|
||||||
if (debug != null) {
|
if (debug != null) {
|
||||||
|
329
jdk/src/share/classes/sun/security/provider/certpath/OCSP.java
Normal file
329
jdk/src/share/classes/sun/security/provider/certpath/OCSP.java
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -25,19 +25,20 @@
|
|||||||
|
|
||||||
package sun.security.provider.certpath;
|
package sun.security.provider.certpath;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.Principal;
|
|
||||||
import java.security.PrivilegedAction;
|
import java.security.PrivilegedAction;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.security.cert.*;
|
import java.security.cert.*;
|
||||||
import java.security.cert.CertPathValidatorException.BasicReason;
|
import java.security.cert.CertPathValidatorException.BasicReason;
|
||||||
import java.net.*;
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import javax.security.auth.x500.X500Principal;
|
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.*;
|
import sun.security.x509.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -50,27 +51,18 @@ import sun.security.x509.*;
|
|||||||
*/
|
*/
|
||||||
class OCSPChecker extends PKIXCertPathChecker {
|
class OCSPChecker extends PKIXCertPathChecker {
|
||||||
|
|
||||||
public static final String OCSP_ENABLE_PROP = "ocsp.enable";
|
static final String OCSP_ENABLE_PROP = "ocsp.enable";
|
||||||
public static final String OCSP_URL_PROP = "ocsp.responderURL";
|
static final String OCSP_URL_PROP = "ocsp.responderURL";
|
||||||
public static final String OCSP_CERT_SUBJECT_PROP =
|
static final String OCSP_CERT_SUBJECT_PROP =
|
||||||
"ocsp.responderCertSubjectName";
|
"ocsp.responderCertSubjectName";
|
||||||
public static final String OCSP_CERT_ISSUER_PROP =
|
static final String OCSP_CERT_ISSUER_PROP = "ocsp.responderCertIssuerName";
|
||||||
"ocsp.responderCertIssuerName";
|
static final String OCSP_CERT_NUMBER_PROP =
|
||||||
public static final String OCSP_CERT_NUMBER_PROP =
|
|
||||||
"ocsp.responderCertSerialNumber";
|
"ocsp.responderCertSerialNumber";
|
||||||
|
|
||||||
private static final String HEX_DIGITS = "0123456789ABCDEFabcdef";
|
private static final String HEX_DIGITS = "0123456789ABCDEFabcdef";
|
||||||
private static final Debug DEBUG = Debug.getInstance("certpath");
|
private static final Debug DEBUG = Debug.getInstance("certpath");
|
||||||
private static final boolean dump = false;
|
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 int remainingCerts;
|
||||||
|
|
||||||
private X509Certificate[] certs;
|
private X509Certificate[] certs;
|
||||||
@ -79,19 +71,26 @@ class OCSPChecker extends PKIXCertPathChecker {
|
|||||||
|
|
||||||
private PKIXParameters pkixParams;
|
private PKIXParameters pkixParams;
|
||||||
|
|
||||||
|
private boolean onlyEECert = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Constructor
|
* Default Constructor
|
||||||
*
|
*
|
||||||
* @param certPath the X509 certification path
|
* @param certPath the X509 certification path
|
||||||
* @param pkixParams the input PKIX parameter set
|
* @param pkixParams the input PKIX parameter set
|
||||||
* @exception CertPathValidatorException Exception thrown if cert path
|
* @throws CertPathValidatorException if OCSPChecker can not be created
|
||||||
* does not validate.
|
|
||||||
*/
|
*/
|
||||||
OCSPChecker(CertPath certPath, PKIXParameters pkixParams)
|
OCSPChecker(CertPath certPath, PKIXParameters pkixParams)
|
||||||
throws CertPathValidatorException {
|
throws CertPathValidatorException {
|
||||||
|
this(certPath, pkixParams, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
OCSPChecker(CertPath certPath, PKIXParameters pkixParams, boolean onlyEECert)
|
||||||
|
throws CertPathValidatorException {
|
||||||
|
|
||||||
this.cp = certPath;
|
this.cp = certPath;
|
||||||
this.pkixParams = pkixParams;
|
this.pkixParams = pkixParams;
|
||||||
|
this.onlyEECert = onlyEECert;
|
||||||
List<? extends Certificate> tmp = cp.getCertificates();
|
List<? extends Certificate> tmp = cp.getCertificates();
|
||||||
certs = tmp.toArray(new X509Certificate[tmp.size()]);
|
certs = tmp.toArray(new X509Certificate[tmp.size()]);
|
||||||
init(false);
|
init(false);
|
||||||
@ -101,6 +100,7 @@ class OCSPChecker extends PKIXCertPathChecker {
|
|||||||
* Initializes the internal state of the checker from parameters
|
* Initializes the internal state of the checker from parameters
|
||||||
* specified in the constructor
|
* specified in the constructor
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void init(boolean forward) throws CertPathValidatorException {
|
public void init(boolean forward) throws CertPathValidatorException {
|
||||||
if (!forward) {
|
if (!forward) {
|
||||||
remainingCerts = certs.length + 1;
|
remainingCerts = certs.length + 1;
|
||||||
@ -110,11 +110,11 @@ class OCSPChecker extends PKIXCertPathChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isForwardCheckingSupported() {
|
@Override public boolean isForwardCheckingSupported() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getSupportedExtensions() {
|
@Override public Set<String> getSupportedExtensions() {
|
||||||
return Collections.<String>emptySet();
|
return Collections.<String>emptySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,26 +127,26 @@ class OCSPChecker extends PKIXCertPathChecker {
|
|||||||
* @exception CertPathValidatorException Exception is thrown if the
|
* @exception CertPathValidatorException Exception is thrown if the
|
||||||
* certificate has been revoked.
|
* certificate has been revoked.
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public void check(Certificate cert, Collection<String> unresolvedCritExts)
|
public void check(Certificate cert, Collection<String> unresolvedCritExts)
|
||||||
throws CertPathValidatorException {
|
throws CertPathValidatorException {
|
||||||
|
|
||||||
InputStream in = null;
|
|
||||||
OutputStream out = null;
|
|
||||||
|
|
||||||
// Decrement the certificate counter
|
// Decrement the certificate counter
|
||||||
remainingCerts--;
|
remainingCerts--;
|
||||||
|
|
||||||
|
X509CertImpl currCertImpl = null;
|
||||||
try {
|
try {
|
||||||
X509Certificate responderCert = null;
|
currCertImpl = X509CertImpl.toImpl((X509Certificate)cert);
|
||||||
boolean seekResponderCert = false;
|
} catch (CertificateException ce) {
|
||||||
X500Principal responderSubjectName = null;
|
throw new CertPathValidatorException(ce);
|
||||||
X500Principal responderIssuerName = null;
|
}
|
||||||
BigInteger responderSerialNumber = null;
|
|
||||||
|
|
||||||
boolean seekIssuerCert = true;
|
if (onlyEECert && currCertImpl.getBasicConstraints() != -1) {
|
||||||
X509CertImpl issuerCertImpl = null;
|
if (DEBUG != null) {
|
||||||
X509CertImpl currCertImpl =
|
DEBUG.println("Skipping revocation check, not end entity cert");
|
||||||
X509CertImpl.toImpl((X509Certificate)cert);
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OCSP security property values, in the following order:
|
* OCSP security property values, in the following order:
|
||||||
@ -155,22 +155,24 @@ class OCSPChecker extends PKIXCertPathChecker {
|
|||||||
* 3. ocsp.responderCertIssuerName
|
* 3. ocsp.responderCertIssuerName
|
||||||
* 4. ocsp.responderCertSerialNumber
|
* 4. ocsp.responderCertSerialNumber
|
||||||
*/
|
*/
|
||||||
|
// should cache these properties to avoid calling every time?
|
||||||
String[] properties = getOCSPProperties();
|
String[] properties = getOCSPProperties();
|
||||||
|
|
||||||
// Check whether OCSP is feasible before seeking cert information
|
// Check whether OCSP is feasible before seeking cert information
|
||||||
URL url = getOCSPServerURL(currCertImpl, properties);
|
URI uri = getOCSPServerURI(currCertImpl, properties[0]);
|
||||||
|
|
||||||
// When responder's subject name is set then the issuer/serial
|
// When responder's subject name is set then the issuer/serial
|
||||||
// properties are ignored
|
// properties are ignored
|
||||||
|
X500Principal responderSubjectName = null;
|
||||||
|
X500Principal responderIssuerName = null;
|
||||||
|
BigInteger responderSerialNumber = null;
|
||||||
if (properties[1] != null) {
|
if (properties[1] != null) {
|
||||||
responderSubjectName = new X500Principal(properties[1]);
|
responderSubjectName = new X500Principal(properties[1]);
|
||||||
|
|
||||||
} else if (properties[2] != null && properties[3] != null) {
|
} else if (properties[2] != null && properties[3] != null) {
|
||||||
responderIssuerName = new X500Principal(properties[2]);
|
responderIssuerName = new X500Principal(properties[2]);
|
||||||
// remove colon or space separators
|
// remove colon or space separators
|
||||||
String value = stripOutSeparators(properties[3]);
|
String value = stripOutSeparators(properties[3]);
|
||||||
responderSerialNumber = new BigInteger(value, 16);
|
responderSerialNumber = new BigInteger(value, 16);
|
||||||
|
|
||||||
} else if (properties[2] != null || properties[3] != null) {
|
} else if (properties[2] != null || properties[3] != null) {
|
||||||
throw new CertPathValidatorException(
|
throw new CertPathValidatorException(
|
||||||
"Must specify both ocsp.responderCertIssuerName and " +
|
"Must specify both ocsp.responderCertIssuerName and " +
|
||||||
@ -180,20 +182,24 @@ class OCSPChecker extends PKIXCertPathChecker {
|
|||||||
// If the OCSP responder cert properties are set then the
|
// If the OCSP responder cert properties are set then the
|
||||||
// identified cert must be located in the trust anchors or
|
// identified cert must be located in the trust anchors or
|
||||||
// in the cert stores.
|
// in the cert stores.
|
||||||
|
boolean seekResponderCert = false;
|
||||||
if (responderSubjectName != null || responderIssuerName != null) {
|
if (responderSubjectName != null || responderIssuerName != null) {
|
||||||
seekResponderCert = true;
|
seekResponderCert = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the issuer certificate to the next cert in the chain
|
// Set the issuer certificate to the next cert in the chain
|
||||||
// (unless we're processing the final cert).
|
// (unless we're processing the final cert).
|
||||||
|
X509Certificate issuerCert = null;
|
||||||
|
boolean seekIssuerCert = true;
|
||||||
|
X509Certificate responderCert = null;
|
||||||
if (remainingCerts < certs.length) {
|
if (remainingCerts < certs.length) {
|
||||||
issuerCertImpl = X509CertImpl.toImpl(certs[remainingCerts]);
|
issuerCert = certs[remainingCerts];
|
||||||
seekIssuerCert = false; // done
|
seekIssuerCert = false; // done
|
||||||
|
|
||||||
// By default, the OCSP responder's cert is the same as the
|
// By default, the OCSP responder's cert is the same as the
|
||||||
// issuer of the cert being validated.
|
// issuer of the cert being validated.
|
||||||
if (!seekResponderCert) {
|
if (!seekResponderCert) {
|
||||||
responderCert = certs[remainingCerts];
|
responderCert = issuerCert;
|
||||||
if (DEBUG != null) {
|
if (DEBUG != null) {
|
||||||
DEBUG.println("Responder's certificate is the same " +
|
DEBUG.println("Responder's certificate is the same " +
|
||||||
"as the issuer of the certificate being validated");
|
"as the issuer of the certificate being validated");
|
||||||
@ -212,7 +218,8 @@ class OCSPChecker extends PKIXCertPathChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Extract the anchor certs
|
// Extract the anchor certs
|
||||||
Iterator anchors = pkixParams.getTrustAnchors().iterator();
|
Iterator<TrustAnchor> anchors
|
||||||
|
= pkixParams.getTrustAnchors().iterator();
|
||||||
if (!anchors.hasNext()) {
|
if (!anchors.hasNext()) {
|
||||||
throw new CertPathValidatorException(
|
throw new CertPathValidatorException(
|
||||||
"Must specify at least one trust anchor");
|
"Must specify at least one trust anchor");
|
||||||
@ -220,25 +227,23 @@ class OCSPChecker extends PKIXCertPathChecker {
|
|||||||
|
|
||||||
X500Principal certIssuerName =
|
X500Principal certIssuerName =
|
||||||
currCertImpl.getIssuerX500Principal();
|
currCertImpl.getIssuerX500Principal();
|
||||||
while (anchors.hasNext() &&
|
while (anchors.hasNext() && (seekIssuerCert || seekResponderCert)) {
|
||||||
(seekIssuerCert || seekResponderCert)) {
|
|
||||||
|
|
||||||
TrustAnchor anchor = (TrustAnchor)anchors.next();
|
TrustAnchor anchor = anchors.next();
|
||||||
X509Certificate anchorCert = anchor.getTrustedCert();
|
X509Certificate anchorCert = anchor.getTrustedCert();
|
||||||
X500Principal anchorSubjectName =
|
X500Principal anchorSubjectName =
|
||||||
anchorCert.getSubjectX500Principal();
|
anchorCert.getSubjectX500Principal();
|
||||||
|
|
||||||
if (dump) {
|
if (dump) {
|
||||||
System.out.println("Issuer DN is " + certIssuerName);
|
System.out.println("Issuer DN is " + certIssuerName);
|
||||||
System.out.println("Subject DN is " +
|
System.out.println("Subject DN is " + anchorSubjectName);
|
||||||
anchorSubjectName);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if anchor cert is the issuer cert
|
// Check if anchor cert is the issuer cert
|
||||||
if (seekIssuerCert &&
|
if (seekIssuerCert &&
|
||||||
certIssuerName.equals(anchorSubjectName)) {
|
certIssuerName.equals(anchorSubjectName)) {
|
||||||
|
|
||||||
issuerCertImpl = X509CertImpl.toImpl(anchorCert);
|
issuerCert = anchorCert;
|
||||||
seekIssuerCert = false; // done
|
seekIssuerCert = false; // done
|
||||||
|
|
||||||
// By default, the OCSP responder's cert is the same as
|
// By default, the OCSP responder's cert is the same as
|
||||||
@ -272,10 +277,9 @@ class OCSPChecker extends PKIXCertPathChecker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (issuerCertImpl == null) {
|
if (issuerCert == null) {
|
||||||
throw new CertPathValidatorException(
|
throw new CertPathValidatorException(
|
||||||
"No trusted certificate for " +
|
"No trusted certificate for " + currCertImpl.getIssuerDN());
|
||||||
currCertImpl.getIssuerDN());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check cert stores if responder cert has not yet been found
|
// Check cert stores if responder cert has not yet been found
|
||||||
@ -287,18 +291,26 @@ class OCSPChecker extends PKIXCertPathChecker {
|
|||||||
X509CertSelector filter = null;
|
X509CertSelector filter = null;
|
||||||
if (responderSubjectName != null) {
|
if (responderSubjectName != null) {
|
||||||
filter = new X509CertSelector();
|
filter = new X509CertSelector();
|
||||||
filter.setSubject(responderSubjectName.getName());
|
filter.setSubject(responderSubjectName);
|
||||||
} else if (responderIssuerName != null &&
|
} else if (responderIssuerName != null &&
|
||||||
responderSerialNumber != null) {
|
responderSerialNumber != null) {
|
||||||
filter = new X509CertSelector();
|
filter = new X509CertSelector();
|
||||||
filter.setIssuer(responderIssuerName.getName());
|
filter.setIssuer(responderIssuerName);
|
||||||
filter.setSerialNumber(responderSerialNumber);
|
filter.setSerialNumber(responderSerialNumber);
|
||||||
}
|
}
|
||||||
if (filter != null) {
|
if (filter != null) {
|
||||||
List<CertStore> certStores = pkixParams.getCertStores();
|
List<CertStore> certStores = pkixParams.getCertStores();
|
||||||
for (CertStore certStore : certStores) {
|
for (CertStore certStore : certStores) {
|
||||||
Iterator i =
|
Iterator i = null;
|
||||||
certStore.getCertificates(filter).iterator();
|
try {
|
||||||
|
i = certStore.getCertificates(filter).iterator();
|
||||||
|
} catch (CertStoreException cse) {
|
||||||
|
// ignore and try next certStore
|
||||||
|
if (DEBUG != null) {
|
||||||
|
DEBUG.println("CertStore exception:" + cse);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (i.hasNext()) {
|
if (i.hasNext()) {
|
||||||
responderCert = (X509Certificate) i.next();
|
responderCert = (X509Certificate) i.next();
|
||||||
seekResponderCert = false; // done
|
seekResponderCert = false; // done
|
||||||
@ -316,112 +328,33 @@ class OCSPChecker extends PKIXCertPathChecker {
|
|||||||
"(set using the OCSP security properties).");
|
"(set using the OCSP security properties).");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct an OCSP Request
|
CertId certId = null;
|
||||||
OCSPRequest ocspRequest =
|
OCSPResponse response = null;
|
||||||
new OCSPRequest(currCertImpl, issuerCertImpl);
|
try {
|
||||||
|
certId = new CertId
|
||||||
// Use the URL to the OCSP service that was created earlier
|
(issuerCert, currCertImpl.getSerialNumberObject());
|
||||||
HttpURLConnection con = (HttpURLConnection)url.openConnection();
|
response = OCSP.check(Collections.singletonList(certId), uri,
|
||||||
if (DEBUG != null) {
|
responderCert, pkixParams.getDate());
|
||||||
DEBUG.println("connecting to OCSP service at: " + url);
|
} catch (IOException ioe) {
|
||||||
|
// should allow this to pass if network failures are acceptable
|
||||||
|
throw new CertPathValidatorException
|
||||||
|
("Unable to send OCSP request", ioe);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indicate that both input and output will be performed,
|
RevocationStatus rs = (RevocationStatus) response.getSingleResponse(certId);
|
||||||
// that the method is POST, and that the content length is
|
RevocationStatus.CertStatus certStatus = rs.getCertStatus();
|
||||||
// the length of the byte array
|
if (certStatus == RevocationStatus.CertStatus.REVOKED) {
|
||||||
|
|
||||||
con.setDoOutput(true);
|
|
||||||
con.setDoInput(true);
|
|
||||||
con.setRequestMethod("POST");
|
|
||||||
con.setRequestProperty("Content-type", "application/ocsp-request");
|
|
||||||
byte[] bytes = ocspRequest.encodeBytes();
|
|
||||||
CertId certId = ocspRequest.getCertId();
|
|
||||||
|
|
||||||
con.setRequestProperty("Content-length",
|
|
||||||
String.valueOf(bytes.length));
|
|
||||||
out = con.getOutputStream();
|
|
||||||
out.write(bytes);
|
|
||||||
out.flush();
|
|
||||||
|
|
||||||
// Check the response
|
|
||||||
if (DEBUG != null &&
|
|
||||||
con.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
|
||||||
DEBUG.println("Received HTTP error: " + con.getResponseCode() +
|
|
||||||
" - " + con.getResponseMessage());
|
|
||||||
}
|
|
||||||
in = con.getInputStream();
|
|
||||||
|
|
||||||
byte[] response = null;
|
|
||||||
int total = 0;
|
|
||||||
int contentLength = con.getContentLength();
|
|
||||||
if (contentLength != -1) {
|
|
||||||
response = new byte[contentLength];
|
|
||||||
} else {
|
|
||||||
response = new byte[2048];
|
|
||||||
contentLength = Integer.MAX_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (total < contentLength) {
|
|
||||||
int count = in.read(response, total, response.length - total);
|
|
||||||
if (count < 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
total += count;
|
|
||||||
if (total >= response.length && total < contentLength) {
|
|
||||||
response = Arrays.copyOf(response, total * 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
response = Arrays.copyOf(response, total);
|
|
||||||
|
|
||||||
OCSPResponse ocspResponse = new OCSPResponse(response, pkixParams,
|
|
||||||
responderCert);
|
|
||||||
// Check that response applies to the cert that was supplied
|
|
||||||
if (! certId.equals(ocspResponse.getCertId())) {
|
|
||||||
throw new CertPathValidatorException(
|
|
||||||
"Certificate in the OCSP response does not match the " +
|
|
||||||
"certificate supplied in the OCSP request.");
|
|
||||||
}
|
|
||||||
SerialNumber serialNumber = currCertImpl.getSerialNumberObject();
|
|
||||||
int certOCSPStatus = ocspResponse.getCertStatus(serialNumber);
|
|
||||||
|
|
||||||
if (DEBUG != null) {
|
|
||||||
DEBUG.println("Status of certificate (with serial number " +
|
|
||||||
serialNumber.getNumber() + ") is: " +
|
|
||||||
OCSPResponse.certStatusToText(certOCSPStatus));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (certOCSPStatus == OCSPResponse.CERT_STATUS_REVOKED) {
|
|
||||||
Throwable t = new CertificateRevokedException(
|
Throwable t = new CertificateRevokedException(
|
||||||
ocspResponse.getRevocationTime(),
|
rs.getRevocationTime(), rs.getRevocationReason(),
|
||||||
ocspResponse.getRevocationReason(),
|
|
||||||
responderCert.getSubjectX500Principal(),
|
responderCert.getSubjectX500Principal(),
|
||||||
ocspResponse.getSingleExtensions());
|
rs.getSingleExtensions());
|
||||||
throw new CertPathValidatorException(t.getMessage(), t,
|
throw new CertPathValidatorException(t.getMessage(), t,
|
||||||
null, -1, BasicReason.REVOKED);
|
null, -1, BasicReason.REVOKED);
|
||||||
|
} else if (certStatus == RevocationStatus.CertStatus.UNKNOWN) {
|
||||||
} else if (certOCSPStatus == OCSPResponse.CERT_STATUS_UNKNOWN) {
|
|
||||||
throw new CertPathValidatorException(
|
throw new CertPathValidatorException(
|
||||||
"Certificate's revocation status is unknown", null, cp,
|
"Certificate's revocation status is unknown", null, cp,
|
||||||
remainingCerts, BasicReason.UNDETERMINED_REVOCATION_STATUS);
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -431,20 +364,18 @@ class OCSPChecker extends PKIXCertPathChecker {
|
|||||||
* 3. ocsp.responderCertIssuerName
|
* 3. ocsp.responderCertIssuerName
|
||||||
* 4. ocsp.responderCertSerialNumber
|
* 4. ocsp.responderCertSerialNumber
|
||||||
*/
|
*/
|
||||||
private static URL getOCSPServerURL(X509CertImpl currCertImpl,
|
private static URI getOCSPServerURI(X509CertImpl currCertImpl,
|
||||||
String[] properties)
|
String responderURL) throws CertPathValidatorException {
|
||||||
throws CertificateParsingException, CertPathValidatorException {
|
|
||||||
|
|
||||||
if (properties[0] != null) {
|
if (responderURL != null) {
|
||||||
try {
|
try {
|
||||||
return new URL(properties[0]);
|
return new URI(responderURL);
|
||||||
} catch (java.net.MalformedURLException e) {
|
} catch (URISyntaxException e) {
|
||||||
throw new CertPathValidatorException(e);
|
throw new CertPathValidatorException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Examine the certificate's AuthorityInfoAccess extension
|
// Examine the certificate's AuthorityInfoAccess extension
|
||||||
|
|
||||||
AuthorityInfoAccessExtension aia =
|
AuthorityInfoAccessExtension aia =
|
||||||
currCertImpl.getAuthorityInfoAccessExtension();
|
currCertImpl.getAuthorityInfoAccessExtension();
|
||||||
if (aia == null) {
|
if (aia == null) {
|
||||||
@ -459,13 +390,8 @@ class OCSPChecker extends PKIXCertPathChecker {
|
|||||||
|
|
||||||
GeneralName generalName = description.getAccessLocation();
|
GeneralName generalName = description.getAccessLocation();
|
||||||
if (generalName.getType() == GeneralNameInterface.NAME_URI) {
|
if (generalName.getType() == GeneralNameInterface.NAME_URI) {
|
||||||
try {
|
|
||||||
URIName uri = (URIName) generalName.getName();
|
URIName uri = (URIName) generalName.getName();
|
||||||
return (new URL(uri.getName()));
|
return uri.getURI();
|
||||||
|
|
||||||
} catch (java.net.MalformedURLException e) {
|
|
||||||
throw new CertPathValidatorException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,9 +26,9 @@
|
|||||||
package sun.security.provider.certpath;
|
package sun.security.provider.certpath;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.cert.CertPathValidatorException;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import sun.misc.HexDumpEncoder;
|
import sun.misc.HexDumpEncoder;
|
||||||
import sun.security.x509.*;
|
|
||||||
import sun.security.util.*;
|
import sun.security.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,47 +77,33 @@ class OCSPRequest {
|
|||||||
private static final Debug debug = Debug.getInstance("certpath");
|
private static final Debug debug = Debug.getInstance("certpath");
|
||||||
private static final boolean dump = false;
|
private static final boolean dump = false;
|
||||||
|
|
||||||
// Serial number of the certificates to be checked for revocation
|
// List of request CertIds
|
||||||
private SerialNumber serialNumber;
|
private final List<CertId> certIds;
|
||||||
|
|
||||||
// Issuer's certificate (for computing certId hash values)
|
|
||||||
private X509CertImpl issuerCert;
|
|
||||||
|
|
||||||
// CertId of the certificate to be checked
|
|
||||||
private CertId certId = null;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constructs an OCSPRequest. This constructor is used
|
* Constructs an OCSPRequest. This constructor is used
|
||||||
* to construct an unsigned OCSP Request for a single user cert.
|
* to construct an unsigned OCSP Request for a single user cert.
|
||||||
*/
|
*/
|
||||||
// used by OCSPChecker
|
OCSPRequest(CertId certId) {
|
||||||
OCSPRequest(X509CertImpl userCert, X509CertImpl issuerCert)
|
this.certIds = Collections.singletonList(certId);
|
||||||
throws CertPathValidatorException {
|
}
|
||||||
|
|
||||||
if (issuerCert == null) {
|
OCSPRequest(List<CertId> certIds) {
|
||||||
throw new CertPathValidatorException("Null IssuerCertificate");
|
this.certIds = certIds;
|
||||||
}
|
|
||||||
this.issuerCert = issuerCert;
|
|
||||||
serialNumber = userCert.getSerialNumberObject();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// used by OCSPChecker
|
|
||||||
byte[] encodeBytes() throws IOException {
|
byte[] encodeBytes() throws IOException {
|
||||||
|
|
||||||
// encode tbsRequest
|
// encode tbsRequest
|
||||||
DerOutputStream tmp = new DerOutputStream();
|
DerOutputStream tmp = new DerOutputStream();
|
||||||
DerOutputStream derSingleReqList = new DerOutputStream();
|
DerOutputStream requestsOut = new DerOutputStream();
|
||||||
SingleRequest singleRequest = null;
|
for (CertId certId : certIds) {
|
||||||
|
DerOutputStream certIdOut = new DerOutputStream();
|
||||||
try {
|
certId.encode(certIdOut);
|
||||||
singleRequest = new SingleRequest(issuerCert, serialNumber);
|
requestsOut.write(DerValue.tag_Sequence, certIdOut);
|
||||||
} catch (Exception e) {
|
|
||||||
throw new IOException("Error encoding OCSP request");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
certId = singleRequest.getCertId();
|
tmp.write(DerValue.tag_Sequence, requestsOut);
|
||||||
singleRequest.encode(derSingleReqList);
|
|
||||||
tmp.write(DerValue.tag_Sequence, derSingleReqList);
|
|
||||||
// No extensions supported
|
// No extensions supported
|
||||||
DerOutputStream tbsRequest = new DerOutputStream();
|
DerOutputStream tbsRequest = new DerOutputStream();
|
||||||
tbsRequest.write(DerValue.tag_Sequence, tmp);
|
tbsRequest.write(DerValue.tag_Sequence, tmp);
|
||||||
@ -134,31 +120,10 @@ class OCSPRequest {
|
|||||||
System.out.println(hexEnc.encode(bytes));
|
System.out.println(hexEnc.encode(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
return(bytes);
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// used by OCSPChecker
|
List<CertId> getCertIds() {
|
||||||
CertId getCertId() {
|
return certIds;
|
||||||
return certId;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class SingleRequest {
|
|
||||||
private CertId certId;
|
|
||||||
|
|
||||||
// No extensions are set
|
|
||||||
|
|
||||||
private SingleRequest(X509CertImpl cert, SerialNumber serialNo) throws Exception {
|
|
||||||
certId = new CertId(cert, serialNo);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void encode(DerOutputStream out) throws IOException {
|
|
||||||
DerOutputStream tmp = new DerOutputStream();
|
|
||||||
certId.encode(tmp);
|
|
||||||
out.write(DerValue.tag_Sequence, tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
private CertId getCertId() {
|
|
||||||
return certId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,17 +28,16 @@ package sun.security.provider.certpath;
|
|||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.CertificateParsingException;
|
||||||
import java.security.cert.CertPathValidatorException;
|
import java.security.cert.CertPathValidatorException;
|
||||||
import java.security.cert.CRLReason;
|
import java.security.cert.CRLReason;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.security.cert.PKIXParameters;
|
import java.util.Collections;
|
||||||
import javax.security.auth.x500.X500Principal;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import sun.misc.HexDumpEncoder;
|
import sun.misc.HexDumpEncoder;
|
||||||
import sun.security.x509.*;
|
import sun.security.x509.*;
|
||||||
import sun.security.util.*;
|
import sun.security.util.*;
|
||||||
@ -113,32 +112,29 @@ import sun.security.util.*;
|
|||||||
* @author Ram Marti
|
* @author Ram Marti
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class OCSPResponse {
|
public final class OCSPResponse {
|
||||||
|
|
||||||
// Certificate status CHOICE
|
public enum ResponseStatus {
|
||||||
public static final int CERT_STATUS_GOOD = 0;
|
SUCCESSFUL, // Response has valid confirmations
|
||||||
public static final int CERT_STATUS_REVOKED = 1;
|
MALFORMED_REQUEST, // Illegal confirmation request
|
||||||
public static final int CERT_STATUS_UNKNOWN = 2;
|
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 Debug DEBUG = Debug.getInstance("certpath");
|
||||||
private static final boolean dump = false;
|
private static final boolean dump = false;
|
||||||
private static final ObjectIdentifier OCSP_BASIC_RESPONSE_OID;
|
private static final ObjectIdentifier OCSP_BASIC_RESPONSE_OID =
|
||||||
private static final ObjectIdentifier OCSP_NONCE_EXTENSION_OID;
|
ObjectIdentifier.newInternal(new int[] { 1, 3, 6, 1, 5, 5, 7, 48, 1, 1});
|
||||||
static {
|
private static final ObjectIdentifier OCSP_NONCE_EXTENSION_OID =
|
||||||
ObjectIdentifier tmp1 = null;
|
ObjectIdentifier.newInternal(new int[] { 1, 3, 6, 1, 5, 5, 7, 48, 1, 2});
|
||||||
ObjectIdentifier tmp2 = null;
|
|
||||||
try {
|
|
||||||
tmp1 = new ObjectIdentifier("1.3.6.1.5.5.7.48.1.1");
|
|
||||||
tmp2 = new ObjectIdentifier("1.3.6.1.5.5.7.48.1.2");
|
|
||||||
} catch (Exception e) {
|
|
||||||
// should not happen; log and exit
|
|
||||||
}
|
|
||||||
OCSP_BASIC_RESPONSE_OID = tmp1;
|
|
||||||
OCSP_NONCE_EXTENSION_OID = tmp2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// OCSP response status code
|
private static final int CERT_STATUS_GOOD = 0;
|
||||||
private static final int OCSP_RESPONSE_OK = 0;
|
private static final int CERT_STATUS_REVOKED = 1;
|
||||||
|
private static final int CERT_STATUS_UNKNOWN = 2;
|
||||||
|
|
||||||
// ResponderID CHOICE tags
|
// ResponderID CHOICE tags
|
||||||
private static final int NAME_TAG = 1;
|
private static final int NAME_TAG = 1;
|
||||||
@ -147,7 +143,8 @@ class OCSPResponse {
|
|||||||
// Object identifier for the OCSPSigning key purpose
|
// 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 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
|
// Maximum clock skew in milliseconds (15 minutes) allowed when checking
|
||||||
// validity of OCSP responses
|
// validity of OCSP responses
|
||||||
@ -159,20 +156,10 @@ class OCSPResponse {
|
|||||||
/*
|
/*
|
||||||
* Create an OCSP response from its ASN.1 DER encoding.
|
* Create an OCSP response from its ASN.1 DER encoding.
|
||||||
*/
|
*/
|
||||||
// used by OCSPChecker
|
OCSPResponse(byte[] bytes, Date dateCheckedAgainst,
|
||||||
OCSPResponse(byte[] bytes, PKIXParameters params,
|
|
||||||
X509Certificate responderCert)
|
X509Certificate responderCert)
|
||||||
throws IOException, CertPathValidatorException {
|
throws IOException, CertPathValidatorException {
|
||||||
|
|
||||||
try {
|
|
||||||
int responseStatus;
|
|
||||||
ObjectIdentifier responseType;
|
|
||||||
int version;
|
|
||||||
CertificateIssuerName responderName = null;
|
|
||||||
Date producedAtDate;
|
|
||||||
AlgorithmId sigAlgId;
|
|
||||||
byte[] ocspNonce;
|
|
||||||
|
|
||||||
// OCSPResponse
|
// OCSPResponse
|
||||||
if (dump) {
|
if (dump) {
|
||||||
HexDumpEncoder hexEnc = new HexDumpEncoder();
|
HexDumpEncoder hexEnc = new HexDumpEncoder();
|
||||||
@ -187,15 +174,20 @@ class OCSPResponse {
|
|||||||
DerInputStream derIn = der.getData();
|
DerInputStream derIn = der.getData();
|
||||||
|
|
||||||
// responseStatus
|
// responseStatus
|
||||||
responseStatus = derIn.getEnumerated();
|
int status = derIn.getEnumerated();
|
||||||
if (DEBUG != null) {
|
if (status >= 0 && status < rsvalues.length) {
|
||||||
DEBUG.println("OCSP response: " +
|
responseStatus = rsvalues[status];
|
||||||
responseToText(responseStatus));
|
} else {
|
||||||
|
// unspecified responseStatus
|
||||||
|
throw new IOException("Unknown OCSPResponse status: " + status);
|
||||||
}
|
}
|
||||||
if (responseStatus != OCSP_RESPONSE_OK) {
|
if (DEBUG != null) {
|
||||||
throw new CertPathValidatorException(
|
DEBUG.println("OCSP response status: " + responseStatus);
|
||||||
"OCSP Response Failure: " +
|
}
|
||||||
responseToText(responseStatus));
|
if (responseStatus != ResponseStatus.SUCCESSFUL) {
|
||||||
|
// no need to continue, responseBytes are not set.
|
||||||
|
singleResponseMap = Collections.emptyMap();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// responseBytes
|
// responseBytes
|
||||||
@ -203,7 +195,7 @@ class OCSPResponse {
|
|||||||
if (!der.isContextSpecific((byte)0)) {
|
if (!der.isContextSpecific((byte)0)) {
|
||||||
throw new IOException("Bad encoding in responseBytes element " +
|
throw new IOException("Bad encoding in responseBytes element " +
|
||||||
"of OCSP response: expected ASN.1 context specific tag 0.");
|
"of OCSP response: expected ASN.1 context specific tag 0.");
|
||||||
};
|
}
|
||||||
DerValue tmp = der.data.getDerValue();
|
DerValue tmp = der.data.getDerValue();
|
||||||
if (tmp.tag != DerValue.tag_Sequence) {
|
if (tmp.tag != DerValue.tag_Sequence) {
|
||||||
throw new IOException("Bad encoding in responseBytes element " +
|
throw new IOException("Bad encoding in responseBytes element " +
|
||||||
@ -212,7 +204,7 @@ class OCSPResponse {
|
|||||||
|
|
||||||
// responseType
|
// responseType
|
||||||
derIn = tmp.data;
|
derIn = tmp.data;
|
||||||
responseType = derIn.getOID();
|
ObjectIdentifier responseType = derIn.getOID();
|
||||||
if (responseType.equals(OCSP_BASIC_RESPONSE_OID)) {
|
if (responseType.equals(OCSP_BASIC_RESPONSE_OID)) {
|
||||||
if (DEBUG != null) {
|
if (DEBUG != null) {
|
||||||
DEBUG.println("OCSP response type: basic");
|
DEBUG.println("OCSP response type: basic");
|
||||||
@ -230,6 +222,10 @@ class OCSPResponse {
|
|||||||
new DerInputStream(derIn.getOctetString());
|
new DerInputStream(derIn.getOctetString());
|
||||||
|
|
||||||
DerValue[] seqTmp = basicOCSPResponse.getSequence(2);
|
DerValue[] seqTmp = basicOCSPResponse.getSequence(2);
|
||||||
|
if (seqTmp.length < 3) {
|
||||||
|
throw new IOException("Unexpected BasicOCSPResponse value");
|
||||||
|
}
|
||||||
|
|
||||||
DerValue responseData = seqTmp[0];
|
DerValue responseData = seqTmp[0];
|
||||||
|
|
||||||
// Need the DER encoded ResponseData to verify the signature later
|
// Need the DER encoded ResponseData to verify the signature later
|
||||||
@ -249,7 +245,7 @@ class OCSPResponse {
|
|||||||
if (seq.isConstructed() && seq.isContextSpecific()) {
|
if (seq.isConstructed() && seq.isContextSpecific()) {
|
||||||
//System.out.println ("version is available");
|
//System.out.println ("version is available");
|
||||||
seq = seq.data.getDerValue();
|
seq = seq.data.getDerValue();
|
||||||
version = seq.getInteger();
|
int version = seq.getInteger();
|
||||||
if (seq.data.available() != 0) {
|
if (seq.data.available() != 0) {
|
||||||
throw new IOException("Bad encoding in version " +
|
throw new IOException("Bad encoding in version " +
|
||||||
" element of OCSP response: bad format");
|
" element of OCSP response: bad format");
|
||||||
@ -261,56 +257,66 @@ class OCSPResponse {
|
|||||||
// responderID
|
// responderID
|
||||||
short tag = (byte)(seq.tag & 0x1f);
|
short tag = (byte)(seq.tag & 0x1f);
|
||||||
if (tag == NAME_TAG) {
|
if (tag == NAME_TAG) {
|
||||||
responderName = new CertificateIssuerName(seq.getData());
|
|
||||||
if (DEBUG != null) {
|
if (DEBUG != null) {
|
||||||
|
X500Name responderName = new X500Name(seq.getData());
|
||||||
DEBUG.println("OCSP Responder name: " + responderName);
|
DEBUG.println("OCSP Responder name: " + responderName);
|
||||||
}
|
}
|
||||||
} else if (tag == KEY_TAG) {
|
} else if (tag == KEY_TAG) {
|
||||||
// Ignore, for now
|
// Ignore, for now
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("Bad encoding in responderID element " +
|
throw new IOException("Bad encoding in responderID element of " +
|
||||||
"of OCSP response: expected ASN.1 context specific tag 0 " +
|
"OCSP response: expected ASN.1 context specific tag 0 or 1");
|
||||||
"or 1");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// producedAt
|
// producedAt
|
||||||
seq = seqDerIn.getDerValue();
|
seq = seqDerIn.getDerValue();
|
||||||
producedAtDate = seq.getGeneralizedTime();
|
if (DEBUG != null) {
|
||||||
|
Date producedAtDate = seq.getGeneralizedTime();
|
||||||
|
DEBUG.println("OCSP response produced at: " + producedAtDate);
|
||||||
|
}
|
||||||
|
|
||||||
// responses
|
// responses
|
||||||
DerValue[] singleResponseDer = seqDerIn.getSequence(1);
|
DerValue[] singleResponseDer = seqDerIn.getSequence(1);
|
||||||
// Examine only the first response
|
singleResponseMap
|
||||||
singleResponse = new SingleResponse(singleResponseDer[0]);
|
= new HashMap<CertId, SingleResponse>(singleResponseDer.length);
|
||||||
|
if (DEBUG != null) {
|
||||||
|
DEBUG.println("OCSP number of SingleResponses: "
|
||||||
|
+ singleResponseDer.length);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < singleResponseDer.length; i++) {
|
||||||
|
SingleResponse singleResponse
|
||||||
|
= new SingleResponse(singleResponseDer[i]);
|
||||||
|
singleResponseMap.put(singleResponse.getCertId(), singleResponse);
|
||||||
|
}
|
||||||
|
|
||||||
// responseExtensions
|
// responseExtensions
|
||||||
if (seqDerIn.available() > 0) {
|
if (seqDerIn.available() > 0) {
|
||||||
seq = seqDerIn.getDerValue();
|
seq = seqDerIn.getDerValue();
|
||||||
if (seq.isContextSpecific((byte)1)) {
|
if (seq.isContextSpecific((byte)1)) {
|
||||||
DerValue[] responseExtDer = seq.data.getSequence(3);
|
DerValue[] responseExtDer = seq.data.getSequence(3);
|
||||||
Extension[] responseExtension =
|
|
||||||
new Extension[responseExtDer.length];
|
|
||||||
for (int i = 0; i < responseExtDer.length; i++) {
|
for (int i = 0; i < responseExtDer.length; i++) {
|
||||||
responseExtension[i] = new Extension(responseExtDer[i]);
|
Extension responseExtension
|
||||||
|
= new Extension(responseExtDer[i]);
|
||||||
if (DEBUG != null) {
|
if (DEBUG != null) {
|
||||||
DEBUG.println("OCSP extension: " +
|
DEBUG.println("OCSP extension: " + responseExtension);
|
||||||
responseExtension[i]);
|
|
||||||
}
|
}
|
||||||
if ((responseExtension[i].getExtensionId()).equals(
|
if (responseExtension.getExtensionId().equals(
|
||||||
OCSP_NONCE_EXTENSION_OID)) {
|
OCSP_NONCE_EXTENSION_OID)) {
|
||||||
|
/*
|
||||||
ocspNonce =
|
ocspNonce =
|
||||||
responseExtension[i].getExtensionValue();
|
responseExtension[i].getExtensionValue();
|
||||||
|
*/
|
||||||
} else if (responseExtension[i].isCritical()) {
|
} else if (responseExtension.isCritical()) {
|
||||||
throw new IOException(
|
throw new IOException(
|
||||||
"Unsupported OCSP critical extension: " +
|
"Unsupported OCSP critical extension: " +
|
||||||
responseExtension[i].getExtensionId());
|
responseExtension.getExtensionId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// signatureAlgorithmId
|
// signatureAlgorithmId
|
||||||
sigAlgId = AlgorithmId.parse(seqTmp[1]);
|
AlgorithmId sigAlgId = AlgorithmId.parse(seqTmp[1]);
|
||||||
|
|
||||||
// signature
|
// signature
|
||||||
byte[] signature = seqTmp[2].getBitString();
|
byte[] signature = seqTmp[2].getBitString();
|
||||||
@ -321,14 +327,18 @@ class OCSPResponse {
|
|||||||
// certs are available
|
// certs are available
|
||||||
DerValue seqCert = seqTmp[3];
|
DerValue seqCert = seqTmp[3];
|
||||||
if (!seqCert.isContextSpecific((byte)0)) {
|
if (!seqCert.isContextSpecific((byte)0)) {
|
||||||
throw new IOException("Bad encoding in certs element " +
|
throw new IOException("Bad encoding in certs element of " +
|
||||||
"of OCSP response: expected ASN.1 context specific tag 0.");
|
"OCSP response: expected ASN.1 context specific tag 0.");
|
||||||
}
|
}
|
||||||
DerValue[] certs = (seqCert.getData()).getSequence(3);
|
DerValue[] certs = seqCert.getData().getSequence(3);
|
||||||
x509Certs = new X509CertImpl[certs.length];
|
x509Certs = new X509CertImpl[certs.length];
|
||||||
|
try {
|
||||||
for (int i = 0; i < certs.length; i++) {
|
for (int i = 0; i < certs.length; i++) {
|
||||||
x509Certs[i] = new X509CertImpl(certs[i].toByteArray());
|
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
|
// Check whether the cert returned by the responder is trusted
|
||||||
@ -346,34 +356,32 @@ class OCSPResponse {
|
|||||||
responderCert.getSubjectX500Principal())) {
|
responderCert.getSubjectX500Principal())) {
|
||||||
|
|
||||||
// Check for the OCSPSigning key purpose
|
// Check for the OCSPSigning key purpose
|
||||||
|
try {
|
||||||
List<String> keyPurposes = cert.getExtendedKeyUsage();
|
List<String> keyPurposes = cert.getExtendedKeyUsage();
|
||||||
if (keyPurposes == null ||
|
if (keyPurposes == null ||
|
||||||
!keyPurposes.contains(KP_OCSP_SIGNING_OID)) {
|
!keyPurposes.contains(KP_OCSP_SIGNING_OID)) {
|
||||||
if (DEBUG != null) {
|
|
||||||
DEBUG.println("Responder's certificate is not " +
|
|
||||||
"valid for signing OCSP responses.");
|
|
||||||
}
|
|
||||||
throw new CertPathValidatorException(
|
throw new CertPathValidatorException(
|
||||||
"Responder's certificate not valid for signing " +
|
"Responder's certificate not valid for signing " +
|
||||||
"OCSP responses");
|
"OCSP responses");
|
||||||
}
|
}
|
||||||
|
} catch (CertificateParsingException cpe) {
|
||||||
|
// assume cert is not valid for signing
|
||||||
|
throw new CertPathValidatorException(
|
||||||
|
"Responder's certificate not valid for signing " +
|
||||||
|
"OCSP responses", cpe);
|
||||||
|
}
|
||||||
|
|
||||||
// check the validity
|
// check the validity
|
||||||
try {
|
try {
|
||||||
Date dateCheckedAgainst = params.getDate();
|
|
||||||
if (dateCheckedAgainst == null) {
|
if (dateCheckedAgainst == null) {
|
||||||
cert.checkValidity();
|
cert.checkValidity();
|
||||||
} else {
|
} else {
|
||||||
cert.checkValidity(dateCheckedAgainst);
|
cert.checkValidity(dateCheckedAgainst);
|
||||||
}
|
}
|
||||||
} catch (GeneralSecurityException e) {
|
} catch (GeneralSecurityException e) {
|
||||||
if (DEBUG != null) {
|
|
||||||
DEBUG.println("Responder's certificate is not " +
|
|
||||||
"within the validity period.");
|
|
||||||
}
|
|
||||||
throw new CertPathValidatorException(
|
throw new CertPathValidatorException(
|
||||||
"Responder's certificate not within the " +
|
"Responder's certificate not within the " +
|
||||||
"validity period");
|
"validity period", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for revocation
|
// check for revocation
|
||||||
@ -391,7 +399,7 @@ class OCSPResponse {
|
|||||||
"the extension id-pkix-ocsp-nocheck.");
|
"the extension id-pkix-ocsp-nocheck.");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// we should do the revocating checking of the
|
// we should do the revocation checking of the
|
||||||
// authorized responder in a future update.
|
// authorized responder in a future update.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,12 +413,8 @@ class OCSPResponse {
|
|||||||
responderCert = null;
|
responderCert = null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (DEBUG != null) {
|
|
||||||
DEBUG.println("Responder's certificate is not " +
|
|
||||||
"authorized to sign OCSP responses.");
|
|
||||||
}
|
|
||||||
throw new CertPathValidatorException(
|
throw new CertPathValidatorException(
|
||||||
"Responder's certificate not authorized to sign " +
|
"Responder's certificate is not authorized to sign " +
|
||||||
"OCSP responses");
|
"OCSP responses");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -418,30 +422,23 @@ class OCSPResponse {
|
|||||||
// Confirm that the signed response was generated using the public
|
// Confirm that the signed response was generated using the public
|
||||||
// key from the trusted responder cert
|
// key from the trusted responder cert
|
||||||
if (responderCert != null) {
|
if (responderCert != null) {
|
||||||
|
|
||||||
if (!verifyResponse(responseDataDer, responderCert,
|
if (!verifyResponse(responseDataDer, responderCert,
|
||||||
sigAlgId, signature, params)) {
|
sigAlgId, signature)) {
|
||||||
if (DEBUG != null) {
|
|
||||||
DEBUG.println("Error verifying OCSP Responder's " +
|
|
||||||
"signature");
|
|
||||||
}
|
|
||||||
throw new CertPathValidatorException(
|
throw new CertPathValidatorException(
|
||||||
"Error verifying OCSP Responder's signature");
|
"Error verifying OCSP Responder's signature");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Need responder's cert in order to verify the signature
|
// 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(
|
throw new CertPathValidatorException(
|
||||||
"Unable to verify OCSP Responder's signature");
|
"Unable to verify OCSP Responder's signature");
|
||||||
}
|
}
|
||||||
} catch (CertPathValidatorException cpve) {
|
|
||||||
throw cpve;
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new CertPathValidatorException(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the OCSP ResponseStatus.
|
||||||
|
*/
|
||||||
|
ResponseStatus getResponseStatus() {
|
||||||
|
return responseStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -449,11 +446,10 @@ class OCSPResponse {
|
|||||||
* The responder's cert is implicitly trusted.
|
* The responder's cert is implicitly trusted.
|
||||||
*/
|
*/
|
||||||
private boolean verifyResponse(byte[] responseData, X509Certificate cert,
|
private boolean verifyResponse(byte[] responseData, X509Certificate cert,
|
||||||
AlgorithmId sigAlgId, byte[] signBytes, PKIXParameters params)
|
AlgorithmId sigAlgId, byte[] signBytes)
|
||||||
throws SignatureException {
|
throws CertPathValidatorException {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
Signature respSignature = Signature.getInstance(sigAlgId.getName());
|
Signature respSignature = Signature.getInstance(sigAlgId.getName());
|
||||||
respSignature.initVerify(cert);
|
respSignature.initVerify(cert);
|
||||||
respSignature.update(responseData);
|
respSignature.update(responseData);
|
||||||
@ -472,92 +468,33 @@ class OCSPResponse {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (InvalidKeyException ike) {
|
} catch (InvalidKeyException ike) {
|
||||||
throw new SignatureException(ike);
|
throw new CertPathValidatorException(ike);
|
||||||
|
|
||||||
} catch (NoSuchAlgorithmException nsae) {
|
} catch (NoSuchAlgorithmException nsae) {
|
||||||
throw new SignatureException(nsae);
|
throw new CertPathValidatorException(nsae);
|
||||||
|
} catch (SignatureException se) {
|
||||||
|
throw new CertPathValidatorException(se);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Return the revocation status code for a given certificate.
|
* Returns the SingleResponse of the specified CertId, or null if
|
||||||
|
* there is no response for that CertId.
|
||||||
*/
|
*/
|
||||||
// used by OCSPChecker
|
SingleResponse getSingleResponse(CertId certId) {
|
||||||
int getCertStatus(SerialNumber sn) {
|
return singleResponseMap.get(certId);
|
||||||
// ignore serial number for now; if we support multiple
|
|
||||||
// requests/responses then it will be used
|
|
||||||
return singleResponse.getStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// used by OCSPChecker
|
|
||||||
CertId getCertId() {
|
|
||||||
return singleResponse.getCertId();
|
|
||||||
}
|
|
||||||
|
|
||||||
Date getRevocationTime() {
|
|
||||||
return singleResponse.getRevocationTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
CRLReason getRevocationReason() {
|
|
||||||
return singleResponse.getRevocationReason();
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, java.security.cert.Extension> getSingleExtensions() {
|
|
||||||
return singleResponse.getSingleExtensions();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Map an OCSP response status code to a string.
|
|
||||||
*/
|
|
||||||
static private String responseToText(int status) {
|
|
||||||
switch (status) {
|
|
||||||
case 0:
|
|
||||||
return "Successful";
|
|
||||||
case 1:
|
|
||||||
return "Malformed request";
|
|
||||||
case 2:
|
|
||||||
return "Internal error";
|
|
||||||
case 3:
|
|
||||||
return "Try again later";
|
|
||||||
case 4:
|
|
||||||
return "Unused status code";
|
|
||||||
case 5:
|
|
||||||
return "Request must be signed";
|
|
||||||
case 6:
|
|
||||||
return "Request is unauthorized";
|
|
||||||
default:
|
|
||||||
return ("Unknown status code: " + status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Map a certificate's revocation status code to a string.
|
|
||||||
*/
|
|
||||||
// used by OCSPChecker
|
|
||||||
static String certStatusToText(int certStatus) {
|
|
||||||
switch (certStatus) {
|
|
||||||
case 0:
|
|
||||||
return "Good";
|
|
||||||
case 1:
|
|
||||||
return "Revoked";
|
|
||||||
case 2:
|
|
||||||
return "Unknown";
|
|
||||||
default:
|
|
||||||
return ("Unknown certificate status code: " + certStatus);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A class representing a single OCSP response.
|
* A class representing a single OCSP response.
|
||||||
*/
|
*/
|
||||||
private class SingleResponse {
|
final static class SingleResponse implements OCSP.RevocationStatus {
|
||||||
private CertId certId;
|
private final CertId certId;
|
||||||
private int certStatus;
|
private final CertStatus certStatus;
|
||||||
private Date thisUpdate;
|
private final Date thisUpdate;
|
||||||
private Date nextUpdate;
|
private final Date nextUpdate;
|
||||||
private Date revocationTime;
|
private final Date revocationTime;
|
||||||
private CRLReason revocationReason = CRLReason.UNSPECIFIED;
|
private final CRLReason revocationReason;
|
||||||
private HashMap<String, java.security.cert.Extension> singleExtensions;
|
private final Map<String, java.security.cert.Extension> singleExtensions;
|
||||||
|
|
||||||
private SingleResponse(DerValue der) throws IOException {
|
private SingleResponse(DerValue der) throws IOException {
|
||||||
if (der.tag != DerValue.tag_Sequence) {
|
if (der.tag != DerValue.tag_Sequence) {
|
||||||
@ -568,35 +505,48 @@ class OCSPResponse {
|
|||||||
certId = new CertId(tmp.getDerValue().data);
|
certId = new CertId(tmp.getDerValue().data);
|
||||||
DerValue derVal = tmp.getDerValue();
|
DerValue derVal = tmp.getDerValue();
|
||||||
short tag = (byte)(derVal.tag & 0x1f);
|
short tag = (byte)(derVal.tag & 0x1f);
|
||||||
if (tag == CERT_STATUS_GOOD) {
|
if (tag == CERT_STATUS_REVOKED) {
|
||||||
certStatus = CERT_STATUS_GOOD;
|
certStatus = CertStatus.REVOKED;
|
||||||
} else if (tag == CERT_STATUS_REVOKED) {
|
|
||||||
certStatus = CERT_STATUS_REVOKED;
|
|
||||||
revocationTime = derVal.data.getGeneralizedTime();
|
revocationTime = derVal.data.getGeneralizedTime();
|
||||||
if (derVal.data.available() != 0) {
|
if (derVal.data.available() != 0) {
|
||||||
int reason = derVal.getEnumerated();
|
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 out-of-range just leave as UNSPECIFIED
|
||||||
if (reason >= 0 && reason < values.length) {
|
if (reason >= 0 && reason < values.length) {
|
||||||
revocationReason = values[reason];
|
revocationReason = values[reason];
|
||||||
|
} else {
|
||||||
|
revocationReason = CRLReason.UNSPECIFIED;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
revocationReason = CRLReason.UNSPECIFIED;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
revocationReason = CRLReason.UNSPECIFIED;
|
||||||
}
|
}
|
||||||
// RevokedInfo
|
// RevokedInfo
|
||||||
if (DEBUG != null) {
|
if (DEBUG != null) {
|
||||||
DEBUG.println("Revocation time: " + revocationTime);
|
DEBUG.println("Revocation time: " + revocationTime);
|
||||||
DEBUG.println("Revocation reason: " + revocationReason);
|
DEBUG.println("Revocation reason: " + revocationReason);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
revocationTime = null;
|
||||||
|
revocationReason = CRLReason.UNSPECIFIED;
|
||||||
|
if (tag == CERT_STATUS_GOOD) {
|
||||||
|
certStatus = CertStatus.GOOD;
|
||||||
} else if (tag == CERT_STATUS_UNKNOWN) {
|
} else if (tag == CERT_STATUS_UNKNOWN) {
|
||||||
certStatus = CERT_STATUS_UNKNOWN;
|
certStatus = CertStatus.UNKNOWN;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("Invalid certificate status");
|
throw new IOException("Invalid certificate status");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
thisUpdate = tmp.getGeneralizedTime();
|
thisUpdate = tmp.getGeneralizedTime();
|
||||||
|
|
||||||
if (tmp.available() == 0) {
|
if (tmp.available() == 0) {
|
||||||
// we are done
|
// we are done
|
||||||
|
nextUpdate = null;
|
||||||
} else {
|
} else {
|
||||||
derVal = tmp.getDerValue();
|
derVal = tmp.getDerValue();
|
||||||
tag = (byte)(derVal.tag & 0x1f);
|
tag = (byte)(derVal.tag & 0x1f);
|
||||||
@ -610,6 +560,8 @@ class OCSPResponse {
|
|||||||
derVal = tmp.getDerValue();
|
derVal = tmp.getDerValue();
|
||||||
tag = (byte)(derVal.tag & 0x1f);
|
tag = (byte)(derVal.tag & 0x1f);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
nextUpdate = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// singleExtensions
|
// singleExtensions
|
||||||
@ -627,7 +579,11 @@ class OCSPResponse {
|
|||||||
DEBUG.println("OCSP single extension: " + ext);
|
DEBUG.println("OCSP single extension: " + ext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
singleExtensions = Collections.emptyMap();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
singleExtensions = Collections.emptyMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
@ -657,7 +613,7 @@ class OCSPResponse {
|
|||||||
/*
|
/*
|
||||||
* Return the certificate's revocation status code
|
* Return the certificate's revocation status code
|
||||||
*/
|
*/
|
||||||
private int getStatus() {
|
@Override public CertStatus getCertStatus() {
|
||||||
return certStatus;
|
return certStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -665,28 +621,28 @@ class OCSPResponse {
|
|||||||
return certId;
|
return certId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Date getRevocationTime() {
|
@Override public Date getRevocationTime() {
|
||||||
return revocationTime;
|
return (Date) revocationTime.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
private CRLReason getRevocationReason() {
|
@Override public CRLReason getRevocationReason() {
|
||||||
return revocationReason;
|
return revocationReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, java.security.cert.Extension> getSingleExtensions() {
|
@Override
|
||||||
return singleExtensions;
|
public Map<String, java.security.cert.Extension> getSingleExtensions() {
|
||||||
|
return Collections.unmodifiableMap(singleExtensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a string representation of a single OCSP response.
|
* Construct a string representation of a single OCSP response.
|
||||||
*/
|
*/
|
||||||
public String toString() {
|
@Override public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.append("SingleResponse: \n");
|
sb.append("SingleResponse: \n");
|
||||||
sb.append(certId);
|
sb.append(certId);
|
||||||
sb.append("\nCertStatus: "+ certStatusToText(getCertStatus(null)) +
|
sb.append("\nCertStatus: "+ certStatus + "\n");
|
||||||
"\n");
|
if (certStatus == CertStatus.REVOKED) {
|
||||||
if (certStatus == CERT_STATUS_REVOKED) {
|
|
||||||
sb.append("revocationTime is " + revocationTime + "\n");
|
sb.append("revocationTime is " + revocationTime + "\n");
|
||||||
sb.append("revocationReason is " + revocationReason + "\n");
|
sb.append("revocationReason is " + revocationReason + "\n");
|
||||||
}
|
}
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -28,8 +28,6 @@ package sun.security.provider.certpath;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.PrivilegedAction;
|
|
||||||
import java.security.Security;
|
|
||||||
import java.security.cert.CertPath;
|
import java.security.cert.CertPath;
|
||||||
import java.security.cert.CertPathParameters;
|
import java.security.cert.CertPathParameters;
|
||||||
import java.security.cert.CertPathValidatorException;
|
import java.security.cert.CertPathValidatorException;
|
||||||
@ -49,6 +47,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.security.auth.x500.X500Principal;
|
import javax.security.auth.x500.X500Principal;
|
||||||
|
import sun.security.action.GetBooleanSecurityPropertyAction;
|
||||||
import sun.security.util.Debug;
|
import sun.security.util.Debug;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -67,7 +66,8 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
|
|||||||
private List<PKIXCertPathChecker> userCheckers;
|
private List<PKIXCertPathChecker> userCheckers;
|
||||||
private String sigProvider;
|
private String sigProvider;
|
||||||
private BasicChecker basicChecker;
|
private BasicChecker basicChecker;
|
||||||
private String ocspProperty;
|
private boolean ocspEnabled = false;
|
||||||
|
private boolean onlyEECert = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor.
|
* Default constructor.
|
||||||
@ -253,13 +253,12 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
|
|||||||
|
|
||||||
if (pkixParam.isRevocationEnabled()) {
|
if (pkixParam.isRevocationEnabled()) {
|
||||||
// Examine OCSP security property
|
// Examine OCSP security property
|
||||||
ocspProperty = AccessController.doPrivileged(
|
ocspEnabled = AccessController.doPrivileged(
|
||||||
new PrivilegedAction<String>() {
|
new GetBooleanSecurityPropertyAction
|
||||||
public String run() {
|
(OCSPChecker.OCSP_ENABLE_PROP));
|
||||||
return
|
onlyEECert = AccessController.doPrivileged(
|
||||||
Security.getProperty(OCSPChecker.OCSP_ENABLE_PROP);
|
new GetBooleanSecurityPropertyAction
|
||||||
}
|
("com.sun.security.onlyCheckRevocationOfEECert"));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,15 +300,15 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
|
|||||||
if (pkixParam.isRevocationEnabled()) {
|
if (pkixParam.isRevocationEnabled()) {
|
||||||
|
|
||||||
// Use OCSP if it has been enabled
|
// Use OCSP if it has been enabled
|
||||||
if ("true".equalsIgnoreCase(ocspProperty)) {
|
if (ocspEnabled) {
|
||||||
OCSPChecker ocspChecker =
|
OCSPChecker ocspChecker =
|
||||||
new OCSPChecker(cpOriginal, pkixParam);
|
new OCSPChecker(cpOriginal, pkixParam, onlyEECert);
|
||||||
certPathCheckers.add(ocspChecker);
|
certPathCheckers.add(ocspChecker);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always use CRLs
|
// Always use CRLs
|
||||||
CrlRevocationChecker revocationChecker =
|
CrlRevocationChecker revocationChecker = new
|
||||||
new CrlRevocationChecker(anchor, pkixParam, certList);
|
CrlRevocationChecker(anchor, pkixParam, certList, onlyEECert);
|
||||||
certPathCheckers.add(revocationChecker);
|
certPathCheckers.add(revocationChecker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,6 +26,7 @@
|
|||||||
package sun.security.provider.certpath;
|
package sun.security.provider.certpath;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.security.AccessController;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.InvalidAlgorithmParameterException;
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
@ -44,6 +45,7 @@ import java.util.LinkedList;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.security.auth.x500.X500Principal;
|
import javax.security.auth.x500.X500Principal;
|
||||||
|
|
||||||
|
import sun.security.action.GetBooleanSecurityPropertyAction;
|
||||||
import sun.security.x509.X500Name;
|
import sun.security.x509.X500Name;
|
||||||
import sun.security.x509.PKIXExtensions;
|
import sun.security.x509.PKIXExtensions;
|
||||||
import sun.security.util.Debug;
|
import sun.security.util.Debug;
|
||||||
@ -85,6 +87,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
|
|||||||
private PublicKey finalPublicKey;
|
private PublicKey finalPublicKey;
|
||||||
private X509CertSelector targetSel;
|
private X509CertSelector targetSel;
|
||||||
private List<CertStore> orderedCertStores;
|
private List<CertStore> orderedCertStores;
|
||||||
|
private boolean onlyEECert = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an instance of <code>SunCertPathBuilder</code>.
|
* Create an instance of <code>SunCertPathBuilder</code>.
|
||||||
@ -97,6 +100,9 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
|
|||||||
} catch (CertificateException e) {
|
} catch (CertificateException e) {
|
||||||
throw new CertPathBuilderException(e);
|
throw new CertPathBuilderException(e);
|
||||||
}
|
}
|
||||||
|
onlyEECert = AccessController.doPrivileged(
|
||||||
|
new GetBooleanSecurityPropertyAction
|
||||||
|
("com.sun.security.onlyCheckRevocationOfEECert"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -256,7 +262,6 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Private build reverse method.
|
* Private build reverse method.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
private void buildReverse(List<List<Vertex>> adjacencyList,
|
private void buildReverse(List<List<Vertex>> adjacencyList,
|
||||||
LinkedList<X509Certificate> certPathList) throws Exception
|
LinkedList<X509Certificate> certPathList) throws Exception
|
||||||
@ -296,7 +301,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
|
|||||||
currentState.updateState(anchor);
|
currentState.updateState(anchor);
|
||||||
// init the crl checker
|
// init the crl checker
|
||||||
currentState.crlChecker =
|
currentState.crlChecker =
|
||||||
new CrlRevocationChecker(null, buildParams);
|
new CrlRevocationChecker(null, buildParams, null, onlyEECert);
|
||||||
try {
|
try {
|
||||||
depthFirstSearchReverse(null, currentState,
|
depthFirstSearchReverse(null, currentState,
|
||||||
new ReverseBuilder(buildParams, targetSubjectDN), adjacencyList,
|
new ReverseBuilder(buildParams, targetSubjectDN), adjacencyList,
|
||||||
@ -341,10 +346,12 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
|
|||||||
adjacencyList.add(new LinkedList<Vertex>());
|
adjacencyList.add(new LinkedList<Vertex>());
|
||||||
|
|
||||||
// init the crl checker
|
// init the crl checker
|
||||||
currentState.crlChecker = new CrlRevocationChecker(null, buildParams);
|
currentState.crlChecker
|
||||||
|
= new CrlRevocationChecker(null, buildParams, null, onlyEECert);
|
||||||
|
|
||||||
depthFirstSearchForward(targetSubjectDN, currentState,
|
depthFirstSearchForward(targetSubjectDN, currentState,
|
||||||
new ForwardBuilder(buildParams, targetSubjectDN, searchAllCertStores),
|
new ForwardBuilder
|
||||||
|
(buildParams, targetSubjectDN, searchAllCertStores, onlyEECert),
|
||||||
adjacencyList, certPathList);
|
adjacencyList, certPathList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,8 +493,8 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
|
|||||||
userCheckers.add(mustCheck, basicChecker);
|
userCheckers.add(mustCheck, basicChecker);
|
||||||
mustCheck++;
|
mustCheck++;
|
||||||
if (buildParams.isRevocationEnabled()) {
|
if (buildParams.isRevocationEnabled()) {
|
||||||
userCheckers.add(mustCheck,
|
userCheckers.add(mustCheck, new CrlRevocationChecker
|
||||||
new CrlRevocationChecker(anchor, buildParams));
|
(anchor, buildParams, null, onlyEECert));
|
||||||
mustCheck++;
|
mustCheck++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ public final class AccessDescription {
|
|||||||
} else {
|
} else {
|
||||||
method = accessMethod.toString();
|
method = accessMethod.toString();
|
||||||
}
|
}
|
||||||
return ("accessMethod: " + method +
|
return ("\n accessMethod: " + method +
|
||||||
"\n accessLocation: " + accessLocation.toString() + "\n");
|
"\n accessLocation: " + accessLocation.toString() + "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,14 +72,6 @@ Agent::get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object)
|
|||||||
{
|
{
|
||||||
jvmtiError err;
|
jvmtiError err;
|
||||||
Monitor *m;
|
Monitor *m;
|
||||||
|
|
||||||
/* We use tags to track these, the tag is the Monitor pointer */
|
|
||||||
err = jvmti->RawMonitorEnter(lock); {
|
|
||||||
check_jvmti_error(jvmti, err, "raw monitor enter");
|
|
||||||
|
|
||||||
/* The raw monitor enter/exit protects us from creating two
|
|
||||||
* instances for the same object.
|
|
||||||
*/
|
|
||||||
jlong tag;
|
jlong tag;
|
||||||
|
|
||||||
m = NULL;
|
m = NULL;
|
||||||
@ -90,18 +82,20 @@ Agent::get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object)
|
|||||||
m = (Monitor *)(void *)(ptrdiff_t)tag;
|
m = (Monitor *)(void *)(ptrdiff_t)tag;
|
||||||
if ( m == NULL ) {
|
if ( m == NULL ) {
|
||||||
m = new Monitor(jvmti, env, object);
|
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*/
|
/*LINTED*/
|
||||||
tag = (jlong)(ptrdiff_t)(void *)m;
|
tag = (jlong)(ptrdiff_t)(void *)m;
|
||||||
err = jvmti->SetTag(object, tag);
|
err = jvmti->SetTag(object, tag);
|
||||||
check_jvmti_error(jvmti, err, "set 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");
|
|
||||||
|
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,12 +106,11 @@ Agent::Agent(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
|
|||||||
|
|
||||||
stdout_message("Agent created..\n");
|
stdout_message("Agent created..\n");
|
||||||
stdout_message("VMInit...\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 */
|
/* Start monitor list */
|
||||||
monitor_count = 0;
|
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()
|
Agent::~Agent()
|
||||||
@ -134,9 +127,6 @@ void Agent::vm_death(jvmtiEnv *jvmti, JNIEnv *env)
|
|||||||
delete monitor_list[i];
|
delete monitor_list[i];
|
||||||
}
|
}
|
||||||
free(monitor_list);
|
free(monitor_list);
|
||||||
/* Destroy the Monitor lock to use */
|
|
||||||
err = jvmti->DestroyRawMonitor(lock);
|
|
||||||
check_jvmti_error(jvmti, err, "destroy raw monitor");
|
|
||||||
/* Print death message */
|
/* Print death message */
|
||||||
stdout_message("VMDeath...\n");
|
stdout_message("VMDeath...\n");
|
||||||
}
|
}
|
||||||
@ -218,5 +208,13 @@ void Agent::object_free(jvmtiEnv* jvmti, jlong tag)
|
|||||||
Monitor *m;
|
Monitor *m;
|
||||||
/*LINTED*/
|
/*LINTED*/
|
||||||
m = (Monitor *)(ptrdiff_t)tag;
|
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;
|
delete m;
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,12 @@
|
|||||||
class Agent {
|
class Agent {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
jrawMonitorID lock;
|
enum {
|
||||||
|
initial_monitor_list_size = 64,
|
||||||
|
monitor_list_grow_size = 16
|
||||||
|
};
|
||||||
Monitor **monitor_list;
|
Monitor **monitor_list;
|
||||||
|
unsigned monitor_list_size;
|
||||||
unsigned monitor_count;
|
unsigned monitor_count;
|
||||||
Thread *get_thread(jvmtiEnv *jvmti, JNIEnv *env, jthread thread);
|
Thread *get_thread(jvmtiEnv *jvmti, JNIEnv *env, jthread thread);
|
||||||
Monitor *get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object);
|
Monitor *get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object);
|
||||||
|
@ -73,6 +73,16 @@ Monitor::~Monitor()
|
|||||||
name, contends, waits, timeouts);
|
name, contends, waits, timeouts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Monitor::get_slot()
|
||||||
|
{
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Monitor::set_slot(int aslot)
|
||||||
|
{
|
||||||
|
slot = aslot;
|
||||||
|
}
|
||||||
|
|
||||||
void Monitor::contended()
|
void Monitor::contended()
|
||||||
{
|
{
|
||||||
contends++;
|
contends++;
|
||||||
|
@ -35,6 +35,7 @@ class Monitor {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
char name[64];
|
char name[64];
|
||||||
|
int slot;
|
||||||
unsigned contends;
|
unsigned contends;
|
||||||
unsigned waits;
|
unsigned waits;
|
||||||
unsigned timeouts;
|
unsigned timeouts;
|
||||||
@ -42,6 +43,8 @@ class Monitor {
|
|||||||
public:
|
public:
|
||||||
Monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object);
|
Monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object);
|
||||||
~Monitor();
|
~Monitor();
|
||||||
|
int get_slot();
|
||||||
|
void set_slot(int i);
|
||||||
void contended();
|
void contended();
|
||||||
void waited();
|
void waited();
|
||||||
void timeout();
|
void timeout();
|
||||||
|
@ -374,6 +374,12 @@ JVM_FindPrimitiveClass(JNIEnv *env, const char *utf);
|
|||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
JVM_ResolveClass(JNIEnv *env, jclass cls);
|
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
|
* Find a class from a given class loader. Throw ClassNotFoundException
|
||||||
* or NoClassDefFoundError depending on the value of the last
|
* or NoClassDefFoundError depending on the value of the last
|
||||||
|
@ -237,6 +237,9 @@ Java_java_lang_ClassLoader_resolveClass0(JNIEnv *env, jobject this,
|
|||||||
JVM_ResolveClass(env, cls);
|
JVM_ResolveClass(env, cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns NULL if class not found.
|
||||||
|
*/
|
||||||
JNIEXPORT jclass JNICALL
|
JNIEXPORT jclass JNICALL
|
||||||
Java_java_lang_ClassLoader_findBootstrapClass(JNIEnv *env, jobject loader,
|
Java_java_lang_ClassLoader_findBootstrapClass(JNIEnv *env, jobject loader,
|
||||||
jstring classname)
|
jstring classname)
|
||||||
@ -246,7 +249,6 @@ Java_java_lang_ClassLoader_findBootstrapClass(JNIEnv *env, jobject loader,
|
|||||||
char buf[128];
|
char buf[128];
|
||||||
|
|
||||||
if (classname == NULL) {
|
if (classname == NULL) {
|
||||||
JNU_ThrowClassNotFoundException(env, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,11 +260,10 @@ Java_java_lang_ClassLoader_findBootstrapClass(JNIEnv *env, jobject loader,
|
|||||||
VerifyFixClassname(clname);
|
VerifyFixClassname(clname);
|
||||||
|
|
||||||
if (!VerifyClassname(clname, JNI_TRUE)) { /* expects slashed name */
|
if (!VerifyClassname(clname, JNI_TRUE)) { /* expects slashed name */
|
||||||
JNU_ThrowClassNotFoundException(env, clname);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
cls = JVM_FindClassFromClassLoader(env, clname, JNI_FALSE, 0, JNI_FALSE);
|
cls = JVM_FindClassFromBootLoader(env, clname);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (clname != buf) {
|
if (clname != buf) {
|
||||||
|
@ -1324,12 +1324,12 @@ FindBootStrapClass(JNIEnv *env, const char* classname)
|
|||||||
{
|
{
|
||||||
if (findBootClass == NULL) {
|
if (findBootClass == NULL) {
|
||||||
findBootClass = (FindClassFromBootLoader_t *)dlsym(RTLD_DEFAULT,
|
findBootClass = (FindClassFromBootLoader_t *)dlsym(RTLD_DEFAULT,
|
||||||
"JVM_FindClassFromClassLoader");
|
"JVM_FindClassFromBootLoader");
|
||||||
if (findBootClass == NULL) {
|
if (findBootClass == NULL) {
|
||||||
JLI_ReportErrorMessage(DLL_ERROR4,
|
JLI_ReportErrorMessage(DLL_ERROR4,
|
||||||
"JVM_FindClassFromClassLoader");
|
"JVM_FindClassFromBootLoader");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return findBootClass(env, classname, JNI_FALSE, (jobject)NULL, JNI_FALSE);
|
return findBootClass(env, classname);
|
||||||
}
|
}
|
||||||
|
@ -1093,12 +1093,6 @@ void SetJavaLauncherPlatformProps() {}
|
|||||||
*/
|
*/
|
||||||
static FindClassFromBootLoader_t *findBootClass = NULL;
|
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)
|
jclass FindBootStrapClass(JNIEnv *env, const char *classname)
|
||||||
{
|
{
|
||||||
HMODULE hJvm;
|
HMODULE hJvm;
|
||||||
@ -1108,13 +1102,13 @@ jclass FindBootStrapClass(JNIEnv *env, const char *classname)
|
|||||||
if (hJvm == NULL) return NULL;
|
if (hJvm == NULL) return NULL;
|
||||||
/* need to use the demangled entry point */
|
/* need to use the demangled entry point */
|
||||||
findBootClass = (FindClassFromBootLoader_t *)GetProcAddress(hJvm,
|
findBootClass = (FindClassFromBootLoader_t *)GetProcAddress(hJvm,
|
||||||
JVM_BCLOADER);
|
"JVM_FindClassFromBootLoader");
|
||||||
if (findBootClass == NULL) {
|
if (findBootClass == NULL) {
|
||||||
JLI_ReportErrorMessage(DLL_ERROR4, JVM_BCLOADER);
|
JLI_ReportErrorMessage(DLL_ERROR4, "JVM_FindClassFromBootLoader");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return findBootClass(env, classname, JNI_FALSE, (jobject)NULL, JNI_FALSE);
|
return findBootClass(env, classname);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -67,6 +67,9 @@ public class D3DGraphicsDevice extends Win32GraphicsDevice {
|
|||||||
if (d3dAvailable) {
|
if (d3dAvailable) {
|
||||||
// we don't use pixel formats for the d3d pipeline
|
// we don't use pixel formats for the d3d pipeline
|
||||||
pfDisabled = true;
|
pfDisabled = true;
|
||||||
|
sun.misc.PerfCounter.getD3DAvailable().set(1);
|
||||||
|
} else {
|
||||||
|
sun.misc.PerfCounter.getD3DAvailable().set(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
128
jdk/test/com/sun/jdi/BreakpointWithFullGC.sh
Normal file
128
jdk/test/com/sun/jdi/BreakpointWithFullGC.sh
Normal file
@ -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
|
@ -25,7 +25,7 @@
|
|||||||
* @test
|
* @test
|
||||||
* @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689
|
* @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689
|
||||||
* 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313
|
* 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
|
* @summary Basic tests for Process and Environment Variable code
|
||||||
* @run main/othervm Basic
|
* @run main/othervm Basic
|
||||||
* @author Martin Buchholz
|
* @author Martin Buchholz
|
||||||
@ -302,6 +302,14 @@ public class Basic {
|
|||||||
printUTF8(val == null ? "null" : val);
|
printUTF8(val == null ? "null" : val);
|
||||||
} else if (action.equals("System.getenv()")) {
|
} else if (action.equals("System.getenv()")) {
|
||||||
printUTF8(getenvAsString(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")) {
|
} else if (action.equals("pwd")) {
|
||||||
printUTF8(new File(System.getProperty("user.dir"))
|
printUTF8(new File(System.getProperty("user.dir"))
|
||||||
.getCanonicalPath());
|
.getCanonicalPath());
|
||||||
@ -1472,6 +1480,22 @@ public class Basic {
|
|||||||
}
|
}
|
||||||
} catch (Throwable t) { unexpected(t); }
|
} 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
|
// Windows has tricky semi-case-insensitive semantics
|
||||||
//----------------------------------------------------------------
|
//----------------------------------------------------------------
|
||||||
|
132
jdk/test/java/nio/file/Files/WalkWithSecurity.java
Normal file
132
jdk/test/java/nio/file/Files/WalkWithSecurity.java
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
3
jdk/test/java/nio/file/Files/denyAll.policy
Normal file
3
jdk/test/java/nio/file/Files/denyAll.policy
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// policy file that does not grant any permissions
|
||||||
|
grant {
|
||||||
|
};
|
5
jdk/test/java/nio/file/Files/grantAll.policy
Normal file
5
jdk/test/java/nio/file/Files/grantAll.policy
Normal file
@ -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";
|
||||||
|
};
|
4
jdk/test/java/nio/file/Files/grantTopOnly.policy
Normal file
4
jdk/test/java/nio/file/Files/grantTopOnly.policy
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// policy file that grants read access to source directory
|
||||||
|
grant {
|
||||||
|
permission java.io.FilePermission "${test.src}", "read";
|
||||||
|
};
|
168
jdk/test/tools/launcher/6842838/CreateBadJar.java
Normal file
168
jdk/test/tools/launcher/6842838/CreateBadJar.java
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
75
jdk/test/tools/launcher/6842838/Test6842838.sh
Normal file
75
jdk/test/tools/launcher/6842838/Test6842838.sh
Normal file
@ -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 $?
|
Loading…
x
Reference in New Issue
Block a user