From f7b598496d40200f6bab01a8fdac27060a6111c3 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Tue, 30 Jun 2009 11:11:10 +0100 Subject: [PATCH 01/15] 6843003: Windows Server 2008 R2 system recognition Reviewed-by: ohair, sherman --- .../windows/native/java/lang/java_props_md.c | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/jdk/src/windows/native/java/lang/java_props_md.c b/jdk/src/windows/native/java/lang/java_props_md.c index b15a9bafac0..4ab139ad307 100644 --- a/jdk/src/windows/native/java/lang/java_props_md.c +++ b/jdk/src/windows/native/java/lang/java_props_md.c @@ -714,10 +714,10 @@ GetJavaProperties(JNIEnv* env) * Windows XP 64 bit 5 2 * where ((&ver.wServicePackMinor) + 2) = 1 * and si.wProcessorArchitecture = 9 - * Windows Vista family 6 0 - * Windows 2008 6 0 - * where ((&ver.wServicePackMinor) + 2) = 1 - * Windows 7 6 1 + * Windows Vista family 6 0 (VER_NT_WORKSTATION) + * Windows Server 2008 6 0 (!VER_NT_WORKSTATION) + * Windows 7 6 1 (VER_NT_WORKSTATION) + * Windows Server 2008 R2 6 1 (!VER_NT_WORKSTATION) * * This mapping will presumably be augmented as new Windows * versions are released. @@ -768,14 +768,7 @@ GetJavaProperties(JNIEnv* env) } } else if (ver.dwMajorVersion == 6) { /* - * From MSDN OSVERSIONINFOEX documentation: - * - * "Because the version numbers for Windows Server 2008 - * and Windows Vista are identical, you must also test - * whether the wProductType member is VER_NT_WORKSTATION. - * If wProductType is VER_NT_WORKSTATION, the operating - * system is Windows Vista or 7; otherwise, it is Windows - * Server 2008." + * See table in MSDN OSVERSIONINFOEX documentation. */ if (ver.wProductType == VER_NT_WORKSTATION) { switch (ver.dwMinorVersion) { @@ -784,7 +777,11 @@ GetJavaProperties(JNIEnv* env) default: sprops.os_name = "Windows NT (unknown)"; } } else { - sprops.os_name = "Windows Server 2008"; + switch (ver.dwMinorVersion) { + case 0: sprops.os_name = "Windows Server 2008"; break; + case 1: sprops.os_name = "Windows Server 2008 R2"; break; + default: sprops.os_name = "Windows NT (unknown)"; + } } } else { sprops.os_name = "Windows NT (unknown)"; From 5363b41a3e61cd88a565c1568508c9598b239131 Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Fri, 3 Jul 2009 11:13:42 +0800 Subject: [PATCH 02/15] 6853793: OutOfMemoryError in sun.security.provider.certpath.OCSPChecker.check Allocate memory dynamically, keep reading until EOF. Reviewed-by: weijun --- .../provider/certpath/OCSPChecker.java | 23 ++++++++---- .../security/timestamp/HttpTimestamper.java | 35 ++++++++++++------- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java index 35ed85def19..04e0649d8ff 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -351,18 +351,27 @@ class OCSPChecker extends PKIXCertPathChecker { } in = con.getInputStream(); + byte[] response = null; + int total = 0; int contentLength = con.getContentLength(); - if (contentLength == -1) { + if (contentLength != -1) { + response = new byte[contentLength]; + } else { + response = new byte[2048]; contentLength = Integer.MAX_VALUE; } - byte[] response = new byte[contentLength]; - int total = 0; - int count = 0; - while (count != -1 && total < contentLength) { - count = in.read(response, total, response.length - total); + 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); diff --git a/jdk/src/share/classes/sun/security/timestamp/HttpTimestamper.java b/jdk/src/share/classes/sun/security/timestamp/HttpTimestamper.java index 690f13a2a0f..bb735141159 100644 --- a/jdk/src/share/classes/sun/security/timestamp/HttpTimestamper.java +++ b/jdk/src/share/classes/sun/security/timestamp/HttpTimestamper.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ import java.net.URL; import java.net.HttpURLConnection; import java.util.Iterator; import java.util.Set; +import java.util.Arrays; import sun.security.pkcs.*; @@ -137,23 +138,33 @@ public class HttpTimestamper implements Timestamper { } System.out.println(); } - int contentLength = connection.getContentLength(); - if (contentLength == -1) { - contentLength = Integer.MAX_VALUE; - } verifyMimeType(connection.getContentType()); - replyBuffer = new byte[contentLength]; int total = 0; - int count = 0; - while (count != -1 && total < contentLength) { - count = input.read(replyBuffer, total, - replyBuffer.length - total); - total += count; + int contentLength = connection.getContentLength(); + if (contentLength != -1) { + replyBuffer = new byte[contentLength]; + } else { + replyBuffer = new byte[2048]; + contentLength = Integer.MAX_VALUE; } + + while (total < contentLength) { + int count = input.read(replyBuffer, total, + replyBuffer.length - total); + if (count < 0) + break; + + total += count; + if (total >= replyBuffer.length && total < contentLength) { + replyBuffer = Arrays.copyOf(replyBuffer, total * 2); + } + } + replyBuffer = Arrays.copyOf(replyBuffer, total); + if (DEBUG) { System.out.println("received timestamp response (length=" + - replyBuffer.length + ")"); + total + ")"); } } finally { if (input != null) { From 839196d14e119c182b745f417b48d4816d3d4d48 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Fri, 3 Jul 2009 07:24:43 -0700 Subject: [PATCH 03/15] 6857287: (file) Clarifications for symbolic link related javadoc Fix up jsr203 file javadoc related to symbolic links Reviewed-by: alanb --- .../classes/java/nio/file/LinkPermission.java | 2 +- .../java/nio/file/NotLinkException.java | 2 +- jdk/src/share/classes/java/nio/file/Path.java | 79 ++++++++++--------- .../java/nio/file/SecureDirectoryStream.java | 11 +-- .../java/nio/file/attribute/Attributes.java | 10 +-- .../file/attribute/BasicFileAttributes.java | 4 +- 6 files changed, 55 insertions(+), 53 deletions(-) diff --git a/jdk/src/share/classes/java/nio/file/LinkPermission.java b/jdk/src/share/classes/java/nio/file/LinkPermission.java index 01949114761..a318903365a 100644 --- a/jdk/src/share/classes/java/nio/file/LinkPermission.java +++ b/jdk/src/share/classes/java/nio/file/LinkPermission.java @@ -46,7 +46,7 @@ import java.security.BasicPermission; * known as creating a link, or hard link. * Extreme care should be taken when granting this permission. It allows * linking to any file or directory in the file system thus allowing the - * attacker to access to all files. + * attacker access to all files. * * * symbolic diff --git a/jdk/src/share/classes/java/nio/file/NotLinkException.java b/jdk/src/share/classes/java/nio/file/NotLinkException.java index bdc1fc354ad..fafdeee6cc6 100644 --- a/jdk/src/share/classes/java/nio/file/NotLinkException.java +++ b/jdk/src/share/classes/java/nio/file/NotLinkException.java @@ -27,7 +27,7 @@ package java.nio.file; /** * Checked exception thrown when a file system operation fails because a file - * is not a link. + * is not a symbolic link. * * @since 1.7 */ diff --git a/jdk/src/share/classes/java/nio/file/Path.java b/jdk/src/share/classes/java/nio/file/Path.java index e00c96144d9..113a7c58067 100644 --- a/jdk/src/share/classes/java/nio/file/Path.java +++ b/jdk/src/share/classes/java/nio/file/Path.java @@ -91,8 +91,8 @@ import java.util.Set; * iterate over the entries in the directory.

*
  • Files can be {@link #copyTo(Path,CopyOption[]) copied} or * {@link #moveTo(Path,CopyOption[]) moved}.

  • - *
  • Symbolic-links may be {@link #createSymbolicLink created}, or the - * target of a link may be {@link #readSymbolicLink read}.

  • + *
  • Symbolic links may be {@link #createSymbolicLink created}, or the + * target of a symbolic link may be {@link #readSymbolicLink read}.

  • *
  • The {@link #toRealPath real} path of an existing file may be * obtained.

  • * @@ -403,12 +403,12 @@ public abstract class Path * p.relativize(p.resolve(q)).equals(q) * * - *

    When symbolic-links are supported, then whether the resulting path, + *

    When symbolic links are supported, then whether the resulting path, * when resolved against this path, yields a path that can be used to locate * the {@link #isSameFile same} file as {@code other} is implementation * dependent. For example, if this path is {@code "/a/b"} and the given * path is {@code "/a/x"} then the resulting relative path may be {@code - * "../x"}. If {@code "b"} is a symbolic-link then is implementation + * "../x"}. If {@code "b"} is a symbolic link then is implementation * dependent if {@code "a/b/../x"} would locate the same file as {@code "/a/x"}. * * @param other @@ -430,8 +430,8 @@ public abstract class Path * *

    An implementation may require to examine the file to determine if the * file is a directory. Consequently this method may not be atomic with respect - * to other file system operations. If the file is a symbolic-link then the - * link is deleted and not the final target of the link. + * to other file system operations. If the file is a symbolic link then the + * symbolic link itself, not the final target of the link, is deleted. * *

    If the file is a directory then the directory must be empty. In some * implementations a directory has entries for special files or links that @@ -459,11 +459,11 @@ public abstract class Path /** * Deletes the file located by this path, if it exists. * - *

    As with the {@link #delete delete()} method, an implementation - * may require to examine the file to determine if the file is a directory. + *

    As with the {@link #delete delete()} method, an implementation may + * need to examine the file to determine if the file is a directory. * Consequently this method may not be atomic with respect to other file - * system operations. If the file is a symbolic-link then the link is - * deleted and not the final target of the link. + * system operations. If the file is a symbolic link, then the symbolic + * link itself, not the final target of the link, is deleted. * *

    If the file is a directory then the directory must be empty. In some * implementations a directory has entries for special files or links that @@ -507,7 +507,7 @@ public abstract class Path * create symbolic links, in which case this method may throw {@code IOException}. * * @param target - * the target of the link + * the target of the symbolic link * @param attrs * the array of attributes to set atomically when creating the * symbolic link @@ -573,9 +573,9 @@ public abstract class Path * Reads the target of a symbolic link (optional operation). * *

    If the file system supports symbolic - * links then this method is used read the target of the link, failing - * if the file is not a link. The target of the link need not exist. The - * returned {@code Path} object will be associated with the same file + * links then this method is used to read the target of the link, failing + * if the file is not a symbolic link. The target of the link need not exist. + * The returned {@code Path} object will be associated with the same file * system as this {@code Path}. * * @return a {@code Path} object representing the target of the link @@ -584,7 +584,7 @@ public abstract class Path * if the implementation does not support symbolic links * @throws NotLinkException * if the target could otherwise not be read because the file - * is not a link (optional specific exception) + * is not a symbolic link (optional specific exception) * @throws IOException * if an I/O error occurs * @throws SecurityException @@ -724,8 +724,8 @@ public abstract class Path * exists, except if the source and target are the {@link #isSameFile same} * file, in which case this method has no effect. File attributes are not * required to be copied to the target file. If symbolic links are supported, - * and the file is a link, then the final target of the link is copied. If - * the file is a directory then it creates an empty directory in the target + * and the file is a symbolic link, then the final target of the link is copied. + * If the file is a directory then it creates an empty directory in the target * location (entries in the directory are not copied). This method can be * used with the {@link Files#walkFileTree Files.walkFileTree} utility * method to copy a directory and all entries in the directory, or an entire @@ -740,8 +740,8 @@ public abstract class Path * {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} * If the target file exists, then the target file is replaced if it * is not a non-empty directory. If the target file exists and is a - * symbolic-link then the symbolic-link is replaced (not the target of - * the link. + * symbolic link, then the symbolic link itself, not the target of + * the link, is replaced. * * * {@link StandardCopyOption#COPY_ATTRIBUTES COPY_ATTRIBUTES} @@ -755,11 +755,11 @@ public abstract class Path * * * {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} - * Symbolic-links are not followed. If the file, located by this path, - * is a symbolic-link then the link is copied rather than the target of - * the link. It is implementation specific if file attributes can be - * copied to the new link. In other words, the {@code COPY_ATTRIBUTES} - * option may be ignored when copying a link. + * Symbolic links are not followed. If the file, located by this path, + * is a symbolic link, then the symbolic link itself, not the target of + * the link, is copied. It is implementation specific if file attributes + * can be copied to the new link. In other words, the {@code + * COPY_ATTRIBUTES} option may be ignored when copying a symbolic link. * * * @@ -807,18 +807,19 @@ public abstract class Path *

    By default, this method attempts to move the file to the target * location, failing if the target file exists except if the source and * target are the {@link #isSameFile same} file, in which case this method - * has no effect. If the file is a symbolic link then the link is moved and - * not the target of the link. This method may be invoked to move an empty - * directory. In some implementations a directory has entries for special - * files or links that are created when the directory is created. In such - * implementations a directory is considered empty when only the special - * entries exist. When invoked to move a directory that is not empty then the - * directory is moved if it does not require moving the entries in the directory. - * For example, renaming a directory on the same {@link FileStore} will usually - * not require moving the entries in the directory. When moving a directory - * requires that its entries be moved then this method fails (by throwing - * an {@code IOException}). To move a file tree may involve copying - * rather than moving directories and this can be done using the {@link + * has no effect. If the file is a symbolic link then the symbolic link + * itself, not the target of the link, is moved. This method may be + * invoked to move an empty directory. In some implementations a directory + * has entries for special files or links that are created when the + * directory is created. In such implementations a directory is considered + * empty when only the special entries exist. When invoked to move a + * directory that is not empty then the directory is moved if it does not + * require moving the entries in the directory. For example, renaming a + * directory on the same {@link FileStore} will usually not require moving + * the entries in the directory. When moving a directory requires that its + * entries be moved then this method fails (by throwing an {@code + * IOException}). To move a file tree may involve copying rather + * than moving directories and this can be done using the {@link * #copyTo copyTo} method in conjunction with the {@link * Files#walkFileTree Files.walkFileTree} utility method. * @@ -831,8 +832,8 @@ public abstract class Path * {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} * If the target file exists, then the target file is replaced if it * is not a non-empty directory. If the target file exists and is a - * symbolic-link then the symbolic-link is replaced and not the target of - * the link. + * symbolic link, then the symbolic link itself, not the target of + * the link, is replaced. * * * {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} @@ -1495,7 +1496,7 @@ public abstract class Path * *

    Where a file is registered with a watch service by means of a symbolic * link then it is implementation specific if the watch continues to depend - * on the existence of the link after it is registered. + * on the existence of the symbolic link after it is registered. * * @param watcher * the watch service to which this object is to be registered diff --git a/jdk/src/share/classes/java/nio/file/SecureDirectoryStream.java b/jdk/src/share/classes/java/nio/file/SecureDirectoryStream.java index 9655695d301..9667a3cf5ce 100644 --- a/jdk/src/share/classes/java/nio/file/SecureDirectoryStream.java +++ b/jdk/src/share/classes/java/nio/file/SecureDirectoryStream.java @@ -166,12 +166,13 @@ public abstract class SecureDirectoryStream /** * Deletes a file. * - *

    Unlike the {@link Path#delete delete()} method, this method - * does not first examine the file to determine if the file is a directory. + *

    Unlike the {@link Path#delete delete()} method, this method does + * not first examine the file to determine if the file is a directory. * Whether a directory is deleted by this method is system dependent and - * therefore not specified. If the file is a symbolic-link then the link is - * deleted (not the final target of the link). When the parameter is a - * relative path then the file to delete is relative to this open directory. + * therefore not specified. If the file is a symbolic link, then the link + * itself, not the final target of the link, is deleted. When the + * parameter is a relative path then the file to delete is relative to + * this open directory. * * @param path * the path of the file to delete diff --git a/jdk/src/share/classes/java/nio/file/attribute/Attributes.java b/jdk/src/share/classes/java/nio/file/attribute/Attributes.java index 3ffa6389b43..cfcbf44a708 100644 --- a/jdk/src/share/classes/java/nio/file/attribute/Attributes.java +++ b/jdk/src/share/classes/java/nio/file/attribute/Attributes.java @@ -48,9 +48,9 @@ public final class Attributes { * symbolic links are followed and the file attributes of the final target * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS * NOFOLLOW_LINKS} is present then symbolic links are not followed and so - * the method returns the file attributes of the symbolic link. This option - * should be used where there is a need to determine if a file is a - * symbolic link: + * the method returns the file attributes of the symbolic link itself. + * This option should be used where there is a need to determine if a + * file is a symbolic link: *

          *    boolean isSymbolicLink = Attributes.readBasicFileAttributes(file, NOFOLLOW_LINKS).isSymbolicLink();
          * 
    @@ -98,7 +98,7 @@ public final class Attributes { * symbolic links are followed and the file attributes of the final target * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS * NOFOLLOW_LINKS} is present then symbolic links are not followed and so - * the method returns the file attributes of the symbolic link. + * the method returns the file attributes of the symbolic link itself. * * @param file * A file reference that locates the file @@ -145,7 +145,7 @@ public final class Attributes { * symbolic links are followed and the file attributes of the final target * of the link are read. If the option {@link LinkOption#NOFOLLOW_LINKS * NOFOLLOW_LINKS} is present then symbolic links are not followed and so - * the method returns the file attributes of the symbolic link. + * the method returns the file attributes of the symbolic link itself. * * @param file * A file reference that locates the file diff --git a/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java b/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java index 6fb3bbf7ee9..4e45711292a 100644 --- a/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java +++ b/jdk/src/share/classes/java/nio/file/attribute/BasicFileAttributes.java @@ -81,13 +81,13 @@ public interface BasicFileAttributes { boolean isDirectory(); /** - * Tells whether the file is a symbolic-link. + * Tells whether the file is a symbolic link. */ boolean isSymbolicLink(); /** * Tells whether the file is something other than a regular file, directory, - * or link. + * or symbolic link. */ boolean isOther(); From d8a3c0970652cd914ae4d1ce945f5ff86f15435a Mon Sep 17 00:00:00 2001 From: Jean-Christophe Collet Date: Mon, 6 Jul 2009 15:13:48 +0200 Subject: [PATCH 04/15] 6856856: NPE in HTTP protocol handler logging Fixed the NPE and Moved the java.util.logging dependency to a single class and used reflection to make it a soft one. Reviewed-by: chegar --- .../classes/sun/net/www/http/HttpCapture.java | 72 +++++++++++++++++++ .../classes/sun/net/www/http/HttpClient.java | 10 +-- .../www/protocol/http/HttpLogFormatter.java | 3 +- .../www/protocol/http/HttpURLConnection.java | 65 ++++++++--------- 4 files changed, 105 insertions(+), 45 deletions(-) diff --git a/jdk/src/share/classes/sun/net/www/http/HttpCapture.java b/jdk/src/share/classes/sun/net/www/http/HttpCapture.java index 873c0dcc398..78debed415f 100644 --- a/jdk/src/share/classes/sun/net/www/http/HttpCapture.java +++ b/jdk/src/share/classes/sun/net/www/http/HttpCapture.java @@ -25,6 +25,8 @@ package sun.net.www.http; import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; @@ -60,6 +62,76 @@ public class HttpCapture { private static boolean initialized = false; private static volatile ArrayList patterns = null; private static volatile ArrayList capFiles = null; + /* Logging is done in an ugly way so that it does not require the presence + * the java.util.logging package. If the Logger class is not available, then + * logging is turned off. This is for helping the modularization effort. + */ + private static Object logger = null; + private static boolean logging = false; + + static { + Class cl; + try { + cl = Class.forName("java.util.logging.Logger"); + } catch (ClassNotFoundException ex) { + cl = null; + } + if (cl != null) { + try { + Method m = cl.getMethod("getLogger", String.class); + logger = m.invoke(null, "sun.net.www.protocol.http.HttpURLConnection"); + logging = true; + } catch (NoSuchMethodException noSuchMethodException) { + } catch (SecurityException securityException) { + } catch (IllegalAccessException illegalAccessException) { + } catch (IllegalArgumentException illegalArgumentException) { + } catch (InvocationTargetException invocationTargetException) { + } + } + } + + public static void fine(String s) { + if (logging) { + ((Logger)logger).fine(s); + } + } + + public static void finer(String s) { + if (logging) { + ((Logger)logger).finer(s); + } + } + + public static void finest(String s) { + if (logging) { + ((Logger)logger).finest(s); + } + } + + public static void severe(String s) { + if (logging) { + ((Logger)logger).finest(s); + } + } + + public static void info(String s) { + if (logging) { + ((Logger)logger).info(s); + } + } + + public static void warning(String s) { + if (logging) { + ((Logger)logger).warning(s); + } + } + + public static boolean isLoggable(String level) { + if (!logging) { + return false; + } + return ((Logger)logger).isLoggable(Level.parse(level)); + } private static synchronized void init() { initialized = true; diff --git a/jdk/src/share/classes/sun/net/www/http/HttpClient.java b/jdk/src/share/classes/sun/net/www/http/HttpClient.java index f170ff1cca0..c4ff7552c18 100644 --- a/jdk/src/share/classes/sun/net/www/http/HttpClient.java +++ b/jdk/src/share/classes/sun/net/www/http/HttpClient.java @@ -28,8 +28,6 @@ package sun.net.www.http; import java.io.*; import java.net.*; import java.util.Locale; -import java.util.logging.Level; -import java.util.logging.Logger; import sun.net.NetworkClient; import sun.net.ProgressSource; import sun.net.www.MessageHeader; @@ -66,10 +64,6 @@ public class HttpClient extends NetworkClient { /** Default port number for http daemons. REMIND: make these private */ static final int httpPortNumber = 80; - // Use same logger as HttpURLConnection since we want to combine both event - // streams into one single HTTP log - private static Logger logger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection"); - /** return default port number (subclasses may override) */ protected int getDefaultPort () { return httpPortNumber; } @@ -810,8 +804,8 @@ public class HttpClient extends NetworkClient { if (isKeepingAlive()) { // Wrap KeepAliveStream if keep alive is enabled. - if (logger.isLoggable(Level.FINEST)) { - logger.finest("KeepAlive stream used: " + url); + if (HttpCapture.isLoggable("FINEST")) { + HttpCapture.finest("KeepAlive stream used: " + url); } serverInput = new KeepAliveStream(serverInput, pi, cl, this); failedOnce = false; diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpLogFormatter.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpLogFormatter.java index 0163d42eda0..97b9be64ed1 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpLogFormatter.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpLogFormatter.java @@ -49,8 +49,7 @@ public class HttpLogFormatter extends java.util.logging.SimpleFormatter { @Override public String format(LogRecord record) { - if (!"sun.net.www.protocol.http.HttpURLConnection".equalsIgnoreCase(record.getSourceClassName()) - && !"sun.net.www.http.HttpClient".equalsIgnoreCase(record.getSourceClassName())) { + if (!"sun.net.www.http.HttpCapture".equalsIgnoreCase(record.getSourceClassName())) { // Don't change format for stuff that doesn't concern us return super.format(record); } diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index afd35f0d72e..accd8295503 100644 --- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -51,14 +51,13 @@ import java.util.List; import java.util.Locale; import java.util.StringTokenizer; import java.util.Iterator; -import java.util.logging.Level; -import java.util.logging.Logger; import sun.net.*; import sun.net.www.*; import sun.net.www.http.HttpClient; import sun.net.www.http.PosterOutputStream; import sun.net.www.http.ChunkedInputStream; import sun.net.www.http.ChunkedOutputStream; +import sun.net.www.http.HttpCapture; import java.text.SimpleDateFormat; import java.util.TimeZone; import java.net.MalformedURLException; @@ -71,8 +70,6 @@ import java.nio.ByteBuffer; public class HttpURLConnection extends java.net.HttpURLConnection { - private static Logger logger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection"); - static String HTTP_CONNECT = "CONNECT"; static final String version; @@ -304,14 +301,14 @@ public class HttpURLConnection extends java.net.HttpURLConnection { return java.security.AccessController.doPrivileged( new java.security.PrivilegedAction() { public PasswordAuthentication run() { - if (logger.isLoggable(Level.FINEST)) { - logger.finest("Requesting Authentication: host =" + host + " url = " + url); + if (HttpCapture.isLoggable("FINEST")) { + HttpCapture.finest("Requesting Authentication: host =" + host + " url = " + url); } PasswordAuthentication pass = Authenticator.requestPasswordAuthentication( host, addr, port, protocol, prompt, scheme, url, authType); - if (pass != null && logger.isLoggable(Level.FINEST)) { - logger.finest("Authentication returned: " + pass.toString()); + if (HttpCapture.isLoggable("FINEST")) { + HttpCapture.finest("Authentication returned: " + (pass != null ? pass.toString() : "null")); } return pass; } @@ -466,8 +463,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { setRequests=true; } - if (logger.isLoggable(Level.FINE)) { - logger.fine(requests.toString()); + if (HttpCapture.isLoggable("FINE")) { + HttpCapture.fine(requests.toString()); } http.writeRequests(requests, poster); if (ps.checkError()) { @@ -723,11 +720,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection { && !(cachedResponse instanceof SecureCacheResponse)) { cachedResponse = null; } - if (logger.isLoggable(Level.FINEST)) { - logger.finest("Cache Request for " + uri + " / " + getRequestMethod()); - if (cachedResponse != null) { - logger.finest("From cache: "+cachedResponse.toString()); - } + if (HttpCapture.isLoggable("FINEST")) { + HttpCapture.finest("Cache Request for " + uri + " / " + getRequestMethod()); + HttpCapture.finest("From cache: " + (cachedResponse != null ? cachedResponse.toString() : "null")); } if (cachedResponse != null) { cachedHeaders = mapToMessageHeader(cachedResponse.getHeaders()); @@ -766,8 +761,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { }); if (sel != null) { URI uri = sun.net.www.ParseUtil.toURI(url); - if (logger.isLoggable(Level.FINEST)) { - logger.finest("ProxySelector Request for " + uri); + if (HttpCapture.isLoggable("FINEST")) { + HttpCapture.finest("ProxySelector Request for " + uri); } Iterator it = sel.select(uri).iterator(); Proxy p; @@ -783,9 +778,9 @@ public class HttpURLConnection extends java.net.HttpURLConnection { http = getNewHttpClient(url, p, connectTimeout, false); http.setReadTimeout(readTimeout); } - if (logger.isLoggable(Level.FINEST)) { + if (HttpCapture.isLoggable("FINEST")) { if (p != null) { - logger.finest("Proxy used: " + p.toString()); + HttpCapture.finest("Proxy used: " + p.toString()); } } break; @@ -1015,15 +1010,15 @@ public class HttpURLConnection extends java.net.HttpURLConnection { URI uri = ParseUtil.toURI(url); if (uri != null) { - if (logger.isLoggable(Level.FINEST)) { - logger.finest("CookieHandler request for " + uri); + if (HttpCapture.isLoggable("FINEST")) { + HttpCapture.finest("CookieHandler request for " + uri); } Map> cookies = cookieHandler.get( uri, requests.getHeaders(EXCLUDE_HEADERS)); if (!cookies.isEmpty()) { - if (logger.isLoggable(Level.FINEST)) { - logger.finest("Cookies retrieved: " + cookies.toString()); + if (HttpCapture.isLoggable("FINEST")) { + HttpCapture.finest("Cookies retrieved: " + cookies.toString()); } for (Map.Entry> entry : cookies.entrySet()) { @@ -1154,8 +1149,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { writeRequests(); } http.parseHTTP(responses, pi, this); - if (logger.isLoggable(Level.FINE)) { - logger.fine(responses.toString()); + if (HttpCapture.isLoggable("FINE")) { + HttpCapture.fine(responses.toString()); } inputStream = http.getInputStream(); @@ -1599,8 +1594,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { http.parseHTTP(responses, null, this); /* Log the response to the CONNECT */ - if (logger.isLoggable(Level.FINE)) { - logger.fine(responses.toString()); + if (HttpCapture.isLoggable("FINE")) { + HttpCapture.fine(responses.toString()); } statusLine = responses.getValue(0); @@ -1727,8 +1722,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { setPreemptiveProxyAuthentication(requests); /* Log the CONNECT request */ - if (logger.isLoggable(Level.FINE)) { - logger.fine(requests.toString()); + if (HttpCapture.isLoggable("FINE")) { + HttpCapture.fine(requests.toString()); } http.writeRequests(requests, null); @@ -1872,8 +1867,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } } - if (logger.isLoggable(Level.FINER)) { - logger.finer("Proxy Authentication for " + authhdr.toString() +" returned " + ret.toString()); + if (HttpCapture.isLoggable("FINER")) { + HttpCapture.finer("Proxy Authentication for " + authhdr.toString() +" returned " + (ret != null ? ret.toString() : "null")); } return ret; } @@ -2002,8 +1997,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { } } } - if (logger.isLoggable(Level.FINER)) { - logger.finer("Server Authentication for " + authhdr.toString() +" returned " + ret.toString()); + if (HttpCapture.isLoggable("FINER")) { + HttpCapture.finer("Server Authentication for " + authhdr.toString() +" returned " + (ret != null ? ret.toString() : "null")); } return ret; } @@ -2078,8 +2073,8 @@ public class HttpURLConnection extends java.net.HttpURLConnection { if (streaming()) { throw new HttpRetryException (RETRY_MSG3, stat, loc); } - if (logger.isLoggable(Level.FINE)) { - logger.fine("Redirected from " + url + " to " + locUrl); + if (HttpCapture.isLoggable("FINE")) { + HttpCapture.fine("Redirected from " + url + " to " + locUrl); } // clear out old response headers!!!! From cab876d8d1dea4bb41278315342d50db85f65da9 Mon Sep 17 00:00:00 2001 From: Martin Buchholz Date: Mon, 6 Jul 2009 11:30:40 -0700 Subject: [PATCH 05/15] 6854795: Miscellaneous improvements to "jar" Cleanup of jar/Main.java (Initial patch by tobyr@google.com, additional review by jeremymanson@google.com, ulf.zibis@gmx.de) Reviewed-by: sherman, alanb --- jdk/src/share/classes/sun/tools/jar/Main.java | 349 +++++++++++------- jdk/test/tools/jar/index/MetaInf.java | 75 +++- 2 files changed, 263 insertions(+), 161 deletions(-) diff --git a/jdk/src/share/classes/sun/tools/jar/Main.java b/jdk/src/share/classes/sun/tools/jar/Main.java index ecd76d6e800..99f60f94c7a 100644 --- a/jdk/src/share/classes/sun/tools/jar/Main.java +++ b/jdk/src/share/classes/sun/tools/jar/Main.java @@ -26,12 +26,16 @@ package sun.tools.jar; import java.io.*; +import java.nio.file.Path; import java.util.*; import java.util.zip.*; import java.util.jar.*; import java.util.jar.Manifest; import java.text.MessageFormat; import sun.misc.JarIndex; +import static sun.misc.JarIndex.INDEX_NAME; +import static java.util.jar.JarFile.MANIFEST_NAME; +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; /** * This class implements a simple utility for creating files in the JAR @@ -58,7 +62,6 @@ class Main { // Directories specified by "-C" operation. Set paths = new HashSet(); - CRC32 crc32 = new CRC32(); /* * cflag: create * uflag: update @@ -71,10 +74,8 @@ class Main { */ boolean cflag, uflag, xflag, tflag, vflag, flag0, Mflag, iflag; - static final String MANIFEST = JarFile.MANIFEST_NAME; static final String MANIFEST_DIR = "META-INF/"; static final String VERSION = "1.0"; - static final String INDEX = JarIndex.INDEX_NAME; private static ResourceBundle rsrc; @@ -126,9 +127,21 @@ class Main { this.program = program; } + /** + * Creates a new empty temporary file in the same directory as the + * specified file. A variant of File.createTempFile. + */ + private static File createTempFileInSameDirectoryAs(File file) + throws IOException { + File dir = file.getParentFile(); + if (dir == null) + dir = new File("."); + return File.createTempFile("jartmp", null, dir); + } + private boolean ok; - /* + /** * Starts main program with the specified arguments. */ public synchronized boolean run(String args[]) { @@ -161,7 +174,7 @@ class Main { } addVersion(manifest); addCreatedBy(manifest); - if (isAmbigousMainClass(manifest)) { + if (isAmbiguousMainClass(manifest)) { if (in != null) { in.close(); } @@ -195,9 +208,7 @@ class Main { FileOutputStream out; if (fname != null) { inputFile = new File(fname); - String path = inputFile.getParent(); - tmpFile = File.createTempFile("tmp", null, - new File((path == null) ? "." : path)); + tmpFile = createTempFileInSameDirectoryAs(inputFile); in = new FileInputStream(inputFile); out = new FileOutputStream(tmpFile); } else { @@ -208,7 +219,8 @@ class Main { InputStream manifest = (!Mflag && (mname != null)) ? (new FileInputStream(mname)) : null; expand(null, files, true); - boolean updateOk = update(in, new BufferedOutputStream(out), manifest, null); + boolean updateOk = update(in, new BufferedOutputStream(out), + manifest, null); if (ok) { ok = updateOk; } @@ -270,8 +282,8 @@ class Main { return ok; } - /* - * Parse command line arguments. + /** + * Parses command line arguments. */ boolean parseArgs(String args[]) { /* Preprocess and expand @file arguments */ @@ -405,7 +417,7 @@ class Main { return true; } - /* + /** * Expands list of files to process into full list of all files that * can be found by recursively descending directories. */ @@ -442,7 +454,7 @@ class Main { } } - /* + /** * Creates a new JAR file. */ void create(OutputStream out, Manifest manifest) @@ -461,7 +473,7 @@ class Main { e.setSize(0); e.setCrc(0); zos.putNextEntry(e); - e = new ZipEntry(MANIFEST); + e = new ZipEntry(MANIFEST_NAME); e.setTime(System.currentTimeMillis()); if (flag0) { crc32Manifest(e, manifest); @@ -476,8 +488,32 @@ class Main { zos.close(); } - /* - * update an existing jar file. + private char toUpperCaseASCII(char c) { + return (c < 'a' || c > 'z') ? c : (char) (c + 'A' - 'a'); + } + + /** + * Compares two strings for equality, ignoring case. The second + * argument must contain only upper-case ASCII characters. + * We don't want case comparison to be locale-dependent (else we + * have the notorious "turkish i bug"). + */ + private boolean equalsIgnoreCase(String s, String upper) { + assert upper.toUpperCase(java.util.Locale.ENGLISH).equals(upper); + int len; + if ((len = s.length()) != upper.length()) + return false; + for (int i = 0; i < len; i++) { + char c1 = s.charAt(i); + char c2 = upper.charAt(i); + if (c1 != c2 && toUpperCaseASCII(c1) != c2) + return false; + } + return true; + } + + /** + * Updates an existing jar file. */ boolean update(InputStream in, OutputStream out, InputStream newManifest, @@ -487,8 +523,6 @@ class Main { ZipOutputStream zos = new JarOutputStream(out); ZipEntry e = null; boolean foundManifest = false; - byte[] buf = new byte[1024]; - int n = 0; boolean updateOk = true; if (jarIndex != null) { @@ -499,10 +533,9 @@ class Main { while ((e = zis.getNextEntry()) != null) { String name = e.getName(); - boolean isManifestEntry = name.toUpperCase( - java.util.Locale.ENGLISH). - equals(MANIFEST); - if ((name.toUpperCase().equals(INDEX) && jarIndex != null) + boolean isManifestEntry = equalsIgnoreCase(name, MANIFEST_NAME); + + if ((jarIndex != null && equalsIgnoreCase(name, INDEX_NAME)) || (Mflag && isManifestEntry)) { continue; } else if (isManifestEntry && ((newManifest != null) || @@ -513,9 +546,9 @@ class Main { // might need it below, and we can't re-read the same data // twice. FileInputStream fis = new FileInputStream(mname); - boolean ambigous = isAmbigousMainClass(new Manifest(fis)); + boolean ambiguous = isAmbiguousMainClass(new Manifest(fis)); fis.close(); - if (ambigous) { + if (ambiguous) { return false; } } @@ -539,9 +572,7 @@ class Main { e2.setCrc(e.getCrc()); } zos.putNextEntry(e2); - while ((n = zis.read(buf, 0, buf.length)) != -1) { - zos.write(buf, 0, n); - } + copy(zis, zos); } else { // replace with the new files File f = entryMap.get(name); addFile(zos, f); @@ -558,7 +589,7 @@ class Main { if (!foundManifest) { if (newManifest != null) { Manifest m = new Manifest(newManifest); - updateOk = !isAmbigousMainClass(m); + updateOk = !isAmbiguousMainClass(m); if (updateOk) { updateManifest(m, zos); } @@ -575,23 +606,16 @@ class Main { private void addIndex(JarIndex index, ZipOutputStream zos) throws IOException { - ZipEntry e = new ZipEntry(INDEX); + ZipEntry e = new ZipEntry(INDEX_NAME); e.setTime(System.currentTimeMillis()); if (flag0) { - e.setMethod(ZipEntry.STORED); - File ifile = File.createTempFile("index", null, new File(".")); - BufferedOutputStream bos = new BufferedOutputStream - (new FileOutputStream(ifile)); - index.write(bos); - crc32File(e, ifile); - bos.close(); - ifile.delete(); + CRC32OutputStream os = new CRC32OutputStream(); + index.write(os); + os.updateEntry(e); } zos.putNextEntry(e); index.write(zos); - if (vflag) { - // output(getMsg("out.update.manifest")); - } + zos.closeEntry(); } private void updateManifest(Manifest m, ZipOutputStream zos) @@ -602,10 +626,9 @@ class Main { if (ename != null) { addMainClass(m, ename); } - ZipEntry e = new ZipEntry(MANIFEST); + ZipEntry e = new ZipEntry(MANIFEST_NAME); e.setTime(System.currentTimeMillis()); if (flag0) { - e.setMethod(ZipEntry.STORED); crc32Manifest(e, m); } zos.putNextEntry(e); @@ -620,7 +643,8 @@ class Main { name = name.replace(File.separatorChar, '/'); String matchPath = ""; for (String path : paths) { - if (name.startsWith(path) && (path.length() > matchPath.length())) { + if (name.startsWith(path) + && (path.length() > matchPath.length())) { matchPath = path; } } @@ -658,7 +682,7 @@ class Main { global.put(Attributes.Name.MAIN_CLASS, mainApp); } - private boolean isAmbigousMainClass(Manifest m) { + private boolean isAmbiguousMainClass(Manifest m) { if (ename != null) { Attributes global = m.getMainAttributes(); if ((global.get(Attributes.Name.MAIN_CLASS) != null)) { @@ -670,7 +694,7 @@ class Main { return false; } - /* + /** * Adds a new file entry to the ZIP output stream. */ void addFile(ZipOutputStream zos, File file) throws IOException { @@ -684,7 +708,7 @@ class Main { if (name.equals("") || name.equals(".") || name.equals(zname)) { return; - } else if ((name.equals(MANIFEST_DIR) || name.equals(MANIFEST)) + } else if ((name.equals(MANIFEST_DIR) || name.equals(MANIFEST_NAME)) && !Mflag) { if (vflag) { output(formatMsg("out.ignore.entry", name)); @@ -704,19 +728,11 @@ class Main { e.setSize(0); e.setCrc(0); } else if (flag0) { - e.setSize(size); - e.setMethod(ZipEntry.STORED); crc32File(e, file); } zos.putNextEntry(e); if (!isDir) { - byte[] buf = new byte[8192]; - int len; - InputStream is = new BufferedInputStream(new FileInputStream(file)); - while ((len = is.read(buf, 0, buf.length)) != -1) { - zos.write(buf, 0, len); - } - is.close(); + copy(file, zos); } zos.closeEntry(); /* report how much compression occurred. */ @@ -737,39 +753,83 @@ class Main { } } - /* - * compute the crc32 of a file. This is necessary when the ZipOutputStream - * is in STORED mode. + /** + * A buffer for use only by copy(InputStream, OutputStream). + * Not as clean as allocating a new buffer as needed by copy, + * but significantly more efficient. */ - private void crc32Manifest(ZipEntry e, Manifest m) throws IOException { - crc32.reset(); - CRC32OutputStream os = new CRC32OutputStream(crc32); - m.write(os); - e.setSize((long) os.n); - e.setCrc(crc32.getValue()); + private byte[] copyBuf = new byte[8192]; + + /** + * Copies all bytes from the input stream to the output stream. + * Does not close or flush either stream. + * + * @param from the input stream to read from + * @param to the output stream to write to + * @throws IOException if an I/O error occurs + */ + private void copy(InputStream from, OutputStream to) throws IOException { + int n; + while ((n = from.read(copyBuf)) != -1) + to.write(copyBuf, 0, n); } - /* - * compute the crc32 of a file. This is necessary when the ZipOutputStream - * is in STORED mode. + /** + * Copies all bytes from the input file to the output stream. + * Does not close or flush the output stream. + * + * @param from the input file to read from + * @param to the output stream to write to + * @throws IOException if an I/O error occurs + */ + private void copy(File from, OutputStream to) throws IOException { + InputStream in = new FileInputStream(from); + try { + copy(in, to); + } finally { + in.close(); + } + } + + /** + * Copies all bytes from the input stream to the output file. + * Does not close the input stream. + * + * @param from the input stream to read from + * @param to the output file to write to + * @throws IOException if an I/O error occurs + */ + private void copy(InputStream from, File to) throws IOException { + OutputStream out = new FileOutputStream(to); + try { + copy(from, out); + } finally { + out.close(); + } + } + + /** + * Computes the crc32 of a Manifest. This is necessary when the + * ZipOutputStream is in STORED mode. + */ + private void crc32Manifest(ZipEntry e, Manifest m) throws IOException { + CRC32OutputStream os = new CRC32OutputStream(); + m.write(os); + os.updateEntry(e); + } + + /** + * Computes the crc32 of a File. This is necessary when the + * ZipOutputStream is in STORED mode. */ private void crc32File(ZipEntry e, File f) throws IOException { - InputStream is = new BufferedInputStream(new FileInputStream(f)); - byte[] buf = new byte[8192]; - crc32.reset(); - int r = 0; - int nread = 0; - long len = f.length(); - while ((r = is.read(buf)) != -1) { - nread += r; - crc32.update(buf, 0, r); - } - is.close(); - if (nread != (int) len) { + CRC32OutputStream os = new CRC32OutputStream(); + copy(f, os); + if (os.n != f.length()) { throw new JarException(formatMsg( "error.incorrect.length", f.getPath())); } - e.setCrc(crc32.getValue()); + os.updateEntry(e); } void replaceFSC(String files[]) { @@ -780,6 +840,7 @@ class Main { } } + @SuppressWarnings("serial") Set newDirSet() { return new HashSet() { public boolean add(ZipEntry e) { @@ -797,7 +858,7 @@ class Main { } } - /* + /** * Extracts specified entries from JAR file. */ void extract(InputStream in, String files[]) throws IOException { @@ -827,7 +888,7 @@ class Main { updateLastModifiedTime(dirs); } - /* + /** * Extracts specified entries from JAR file, via ZipFile. */ void extract(String fname, String files[]) throws IOException { @@ -853,7 +914,7 @@ class Main { updateLastModifiedTime(dirs); } - /* + /** * Extracts next entry from JAR file, creating directories as needed. If * the entry is for a directory which doesn't exist prior to this * invocation, returns that entry, otherwise returns null. @@ -888,19 +949,13 @@ class Main { "error.create.dir", d.getPath())); } } - OutputStream os = new FileOutputStream(f); - byte[] b = new byte[8192]; - int len; try { - while ((len = is.read(b, 0, b.length)) != -1) { - os.write(b, 0, len); - } + copy(is, f); } finally { if (is instanceof ZipInputStream) ((ZipInputStream)is).closeEntry(); else is.close(); - os.close(); } if (vflag) { if (e.getMethod() == ZipEntry.DEFLATED) { @@ -919,7 +974,7 @@ class Main { return rc; } - /* + /** * Lists contents of JAR file. */ void list(InputStream in, String files[]) throws IOException { @@ -937,7 +992,7 @@ class Main { } } - /* + /** * Lists contents of JAR file, via ZipFile. */ void list(String fname, String files[]) throws IOException { @@ -950,32 +1005,38 @@ class Main { } /** - * Output the class index table to the INDEX.LIST file of the + * Outputs the class index table to the INDEX.LIST file of the * root jar file. */ void dumpIndex(String rootjar, JarIndex index) throws IOException { - File scratchFile = File.createTempFile("scratch", null, new File(".")); File jarFile = new File(rootjar); - boolean updateOk = update(new FileInputStream(jarFile), - new FileOutputStream(scratchFile), - null, index); - jarFile.delete(); - if (!scratchFile.renameTo(jarFile)) { - scratchFile.delete(); - throw new IOException(getMsg("error.write.file")); + Path jarPath = jarFile.toPath(); + Path tmpPath = createTempFileInSameDirectoryAs(jarFile).toPath(); + try { + if (update(jarPath.newInputStream(), + tmpPath.newOutputStream(), + null, index)) { + try { + tmpPath.moveTo(jarPath, REPLACE_EXISTING); + } catch (IOException e) { + throw new IOException(getMsg("error.write.file"), e); + } + } + } finally { + tmpPath.deleteIfExists(); } - scratchFile.delete(); } - private Hashtable jarTable = new Hashtable(); - /* - * Generate the transitive closure of the Class-Path attribute for + private HashSet jarPaths = new HashSet(); + + /** + * Generates the transitive closure of the Class-Path attribute for * the specified jar file. */ - Vector getJarPath(String jar) throws IOException { - Vector files = new Vector(); + List getJarPath(String jar) throws IOException { + List files = new ArrayList(); files.add(jar); - jarTable.put(jar, jar); + jarPaths.add(jar); // take out the current path String path = jar.substring(0, Math.max(0, jar.lastIndexOf('/') + 1)); @@ -998,7 +1059,7 @@ class Main { if (!ajar.endsWith("/")) { // it is a jar file ajar = path.concat(ajar); /* check on cyclic dependency */ - if (jarTable.get(ajar) == null) { + if (! jarPaths.contains(ajar)) { files.addAll(getJarPath(ajar)); } } @@ -1012,10 +1073,10 @@ class Main { } /** - * Generate class index file for the specified root jar file. + * Generates class index file for the specified root jar file. */ void genIndex(String rootjar, String[] files) throws IOException { - Vector jars = getJarPath(rootjar); + List jars = getJarPath(rootjar); int njars = jars.size(); String[] jarfiles; @@ -1027,12 +1088,12 @@ class Main { } njars = jars.size(); } - jarfiles = (String[])jars.toArray(new String[njars]); + jarfiles = jars.toArray(new String[njars]); JarIndex index = new JarIndex(jarfiles); dumpIndex(rootjar, index); } - /* + /** * Prints entry information, if requested. */ void printEntry(ZipEntry e, String[] files) throws IOException { @@ -1049,7 +1110,7 @@ class Main { } } - /* + /** * Prints entry information. */ void printEntry(ZipEntry e) throws IOException { @@ -1067,21 +1128,21 @@ class Main { } } - /* - * Print usage message and die. + /** + * Prints usage message. */ void usageError() { error(getMsg("usage")); } - /* + /** * A fatal exception has been caught. No recovery possible */ void fatalError(Exception e) { e.printStackTrace(); } - /* + /** * A fatal condition has been detected; message is "s". * No recovery possible */ @@ -1103,39 +1164,43 @@ class Main { err.println(s); } - /* + /** * Main routine to start program. */ public static void main(String args[]) { Main jartool = new Main(System.out, System.err, "jar"); System.exit(jartool.run(args) ? 0 : 1); } -} -/* - * an OutputStream that doesn't send its output anywhere, (but could). - * It's here to find the CRC32 of a manifest, necessary for STORED only - * mode in ZIP. - */ -final class CRC32OutputStream extends java.io.OutputStream { - CRC32 crc; - int n = 0; - CRC32OutputStream(CRC32 crc) { - this.crc = crc; - } + /** + * An OutputStream that doesn't send its output anywhere, (but could). + * It's here to find the CRC32 of an input file, necessary for STORED + * mode in ZIP. + */ + private static class CRC32OutputStream extends java.io.OutputStream { + final CRC32 crc = new CRC32(); + long n = 0; - public void write(int r) throws IOException { - crc.update(r); - n++; - } + CRC32OutputStream() {} - public void write(byte[] b) throws IOException { - crc.update(b, 0, b.length); - n += b.length; - } + public void write(int r) throws IOException { + crc.update(r); + n++; + } - public void write(byte[] b, int off, int len) throws IOException { - crc.update(b, off, len); - n += len - off; + public void write(byte[] b, int off, int len) throws IOException { + crc.update(b, off, len); + n += len; + } + + /** + * Updates a ZipEntry which describes the data read by this + * output stream, in STORED mode. + */ + public void updateEntry(ZipEntry e) { + e.setMethod(ZipEntry.STORED); + e.setSize(n); + e.setCrc(crc.getValue()); + } } } diff --git a/jdk/test/tools/jar/index/MetaInf.java b/jdk/test/tools/jar/index/MetaInf.java index dae74836938..9e05a8d4fb4 100644 --- a/jdk/test/tools/jar/index/MetaInf.java +++ b/jdk/test/tools/jar/index/MetaInf.java @@ -23,13 +23,15 @@ /* * @test - * @bug 4408526 + * @bug 4408526 6854795 * @summary Index the non-meta files in META-INF, such as META-INF/services. */ import java.io.*; +import java.util.Arrays; import java.util.jar.*; import sun.tools.jar.Main; +import java.util.zip.ZipFile; public class MetaInf { @@ -39,29 +41,51 @@ public class MetaInf { static String contents = System.getProperty("test.src") + File.separatorChar + "jarcontents"; - // Options passed to "jar" command. - static String[] jarArgs1 = new String[] { - "cf", jarName, "-C", contents, SERVICES - }; - static String[] jarArgs2 = new String[] { - "i", jarName - }; + static void run(String ... args) { + if (! new Main(System.out, System.err, "jar").run(args)) + throw new Error("jar failed: args=" + Arrays.toString(args)); + } - public static void main(String[] args) throws IOException { + static void copy(File from, File to) throws IOException { + FileInputStream in = new FileInputStream(from); + FileOutputStream out = new FileOutputStream(to); + try { + byte[] buf = new byte[8192]; + int n; + while ((n = in.read(buf)) != -1) + out.write(buf, 0, n); + } finally { + in.close(); + out.close(); + } + } + + static boolean contains(File jarFile, String entryName) + throws IOException { + return new ZipFile(jarFile).getEntry(entryName) != null; + } + + static void checkContains(File jarFile, String entryName) + throws IOException { + if (! contains(jarFile, entryName)) + throw new Error(String.format("expected jar %s to contain %s", + jarFile, entryName)); + } + + static void testIndex(String jarName) throws IOException { + System.err.printf("jarName=%s%n", jarName); + + File jar = new File(jarName); // Create a jar to be indexed. - Main jarTool = new Main(System.out, System.err, "jar"); - if (!jarTool.run(jarArgs1)) { - throw new Error("Could not create jar file."); + run("cf", jarName, "-C", contents, SERVICES); + + for (int i = 0; i < 2; i++) { + run("i", jarName); + checkContains(jar, INDEX); + checkContains(jar, SERVICES); } - // Index the jar. - jarTool = new Main(System.out, System.err, "jar"); - if (!jarTool.run(jarArgs2)) { - throw new Error("Could not index jar file."); - } - - // Read the index. Verify that META-INF/services is indexed. JarFile f = new JarFile(jarName); BufferedReader index = new BufferedReader( @@ -75,4 +99,17 @@ public class MetaInf { } throw new Error(SERVICES + " not indexed."); } + + public static void main(String[] args) throws IOException { + testIndex("a.jar"); // a path with parent == null + testIndex("./a.zip"); // a path with parent != null + + // Try indexing a jar in the default temp directory. + File tmpFile = File.createTempFile("MetaInf", null, null); + try { + testIndex(tmpFile.getPath()); + } finally { + tmpFile.delete(); + } + } } From 21aa3652d44605eb6a91fcfddc1d206398295503 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Tue, 7 Jul 2009 16:12:34 -0700 Subject: [PATCH 06/15] 6857803: Missing links to exceptions in javadoc for Class.getGeneric{Superclass, Interfaces} Reviewed-by: chegar --- jdk/src/share/classes/java/lang/Class.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index 4ba497c64cf..ddf57631790 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -627,7 +627,7 @@ public final * * @return an array of {@code TypeVariable} objects that represent * the type variables declared by this generic declaration - * @throws GenericSignatureFormatError if the generic + * @throws java.lang.reflect.GenericSignatureFormatError if the generic * signature of this generic declaration does not conform to * the format specified in the Java Virtual Machine Specification, * 3rd edition @@ -673,12 +673,12 @@ public final * {@code Class} object representing the {@code Object} class is * returned. * - * @throws GenericSignatureFormatError if the generic + * @throws java.lang.reflect.GenericSignatureFormatError if the generic * class signature does not conform to the format specified in the * Java Virtual Machine Specification, 3rd edition * @throws TypeNotPresentException if the generic superclass * refers to a non-existent type declaration - * @throws MalformedParameterizedTypeException if the + * @throws java.lang.reflect.MalformedParameterizedTypeException if the * generic superclass refers to a parameterized type that cannot be * instantiated for any reason * @return the superclass of the class represented by this object @@ -795,14 +795,14 @@ public final *

    If this object represents a primitive type or void, the * method returns an array of length 0. * - * @throws GenericSignatureFormatError + * @throws java.lang.reflect.GenericSignatureFormatError * if the generic class signature does not conform to the format * specified in the Java Virtual Machine Specification, 3rd edition * @throws TypeNotPresentException if any of the generic * superinterfaces refers to a non-existent type declaration - * @throws MalformedParameterizedTypeException if any of the - * generic superinterfaces refer to a parameterized type that cannot - * be instantiated for any reason + * @throws java.lang.reflect.MalformedParameterizedTypeException + * if any of the generic superinterfaces refer to a parameterized + * type that cannot be instantiated for any reason * @return an array of interfaces implemented by this class * @since 1.5 */ From 96a8d1a9f8805de2786eee08b3352b49a6dacb16 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 8 Jul 2009 12:07:16 +0800 Subject: [PATCH 07/15] 6857802: GSS getRemainingInitLifetime method returns milliseconds not seconds Reviewed-by: xuelei --- .../jgss/krb5/Krb5InitCredential.java | 2 +- .../security/krb5/auto/LifeTimeInSeconds.java | 50 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 jdk/test/sun/security/krb5/auto/LifeTimeInSeconds.java diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java index 1aac87223e1..4718f57e7d3 100644 --- a/jdk/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java +++ b/jdk/src/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java @@ -238,7 +238,7 @@ public class Krb5InitCredential retVal = (int)(getEndTime().getTime() - (new Date().getTime())); - return retVal; + return retVal/1000; } /** diff --git a/jdk/test/sun/security/krb5/auto/LifeTimeInSeconds.java b/jdk/test/sun/security/krb5/auto/LifeTimeInSeconds.java new file mode 100644 index 00000000000..2d20fc415bb --- /dev/null +++ b/jdk/test/sun/security/krb5/auto/LifeTimeInSeconds.java @@ -0,0 +1,50 @@ +/* + * 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 6857802 + * @summary GSS getRemainingInitLifetime method returns milliseconds not seconds + */ +import org.ietf.jgss.GSSCredential; +import org.ietf.jgss.GSSManager; + +public class LifeTimeInSeconds { + public static void main(String[] args) throws Exception { + new OneKDC(null).writeJAASConf(); + System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); + + GSSManager gm = GSSManager.getInstance(); + GSSCredential cred = gm.createCredential(GSSCredential.INITIATE_AND_ACCEPT); + int time = cred.getRemainingLifetime(); + int time2 = cred.getRemainingInitLifetime(null); + // The test KDC issues a TGT with a default lifetime of 11 hours + int elevenhrs = 11*3600; + if (time > elevenhrs+60 || time < elevenhrs-60) { + throw new Exception("getRemainingLifetime returns wrong value."); + } + if (time2 > elevenhrs+60 || time2 < elevenhrs-60) { + throw new Exception("getRemainingInitLifetime returns wrong value."); + } + } +} From 9148ed61cfd3c9f22826249ea3639e90e23c73ab Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Wed, 8 Jul 2009 12:07:43 +0800 Subject: [PATCH 08/15] 6857795: krb5.conf ignored if system properties on realm and kdc are provided Reviewed-by: xuelei --- .../classes/sun/security/krb5/Config.java | 35 ++++--- jdk/test/sun/security/krb5/ConfPlusProp.java | 94 +++++++++++++++++++ jdk/test/sun/security/krb5/confplusprop.conf | 11 +++ jdk/test/sun/security/krb5/confplusprop2.conf | 7 ++ 4 files changed, 133 insertions(+), 14 deletions(-) create mode 100644 jdk/test/sun/security/krb5/ConfPlusProp.java create mode 100644 jdk/test/sun/security/krb5/confplusprop.conf create mode 100644 jdk/test/sun/security/krb5/confplusprop2.conf diff --git a/jdk/src/share/classes/sun/security/krb5/Config.java b/jdk/src/share/classes/sun/security/krb5/Config.java index e036776f53e..8adcba81f53 100644 --- a/jdk/src/share/classes/sun/security/krb5/Config.java +++ b/jdk/src/share/classes/sun/security/krb5/Config.java @@ -123,7 +123,7 @@ public class Config { java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction ("java.security.krb5.kdc")); - defaultRealm = + defaultRealm = java.security.AccessController.doPrivileged( new sun.security.action.GetPropertyAction ("java.security.krb5.realm")); @@ -134,6 +134,16 @@ public class Config { "java.security.krb5.realm both must be set or " + "neither must be set."); } + + // Read the Kerberos configuration file + try { + Vector configFile; + configFile = loadConfigFile(); + stanzaTable = parseStanzaTable(configFile); + } catch (IOException ioe) { + // No krb5.conf, no problem. We'll use DNS etc. + } + if (kdchost != null) { /* * If configuration information is only specified by @@ -141,22 +151,19 @@ public class Config { * java.security.krb5.realm, we put both in the hashtable * under [libdefaults]. */ - Hashtable kdcs = new Hashtable (); + if (stanzaTable == null) { + stanzaTable = new Hashtable (); + } + Hashtable kdcs = + (Hashtable)stanzaTable.get("libdefaults"); + if (kdcs == null) { + kdcs = new Hashtable (); + stanzaTable.put("libdefaults", kdcs); + } kdcs.put("default_realm", defaultRealm); // The user can specify a list of kdc hosts separated by ":" kdchost = kdchost.replace(':', ' '); kdcs.put("kdc", kdchost); - stanzaTable = new Hashtable (); - stanzaTable.put("libdefaults", kdcs); - } else { - // Read the Kerberos configuration file - try { - Vector configFile; - configFile = loadConfigFile(); - stanzaTable = parseStanzaTable(configFile); - } catch (IOException ioe) { - // No krb5.conf, no problem. We'll use DNS etc. - } } } @@ -294,7 +301,7 @@ public class Config { * hashtable. */ if (name.equalsIgnoreCase("kdc") && - (!section.equalsIgnoreCase("libdefaults")) && + (section.equalsIgnoreCase(getDefault("default_realm", "libdefaults"))) && (java.security.AccessController.doPrivileged( new sun.security.action. GetPropertyAction("java.security.krb5.kdc")) != null)) { diff --git a/jdk/test/sun/security/krb5/ConfPlusProp.java b/jdk/test/sun/security/krb5/ConfPlusProp.java new file mode 100644 index 00000000000..b1ea2ca5e75 --- /dev/null +++ b/jdk/test/sun/security/krb5/ConfPlusProp.java @@ -0,0 +1,94 @@ +/* + * 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 6857795 + * @summary krb5.conf ignored if system properties on realm and kdc are provided + */ + +import sun.security.krb5.Config; +import sun.security.krb5.KrbException; + +public class ConfPlusProp { + public static void main(String[] args) throws Exception { + System.setProperty("java.security.krb5.realm", "R2"); + System.setProperty("java.security.krb5.kdc", "k2"); + + // Point to a file with existing default_realm + System.setProperty("java.security.krb5.conf", + System.getProperty("test.src", ".") +"/confplusprop.conf"); + Config config = Config.getInstance(); + + if (!config.getDefaultRealm().equals("R2")) { + throw new Exception("Default realm error"); + } + if (!config.getKDCList("R1").equals("k1")) { + throw new Exception("R1 kdc error"); + } + if (!config.getKDCList("R2").equals("k2")) { + throw new Exception("R2 kdc error"); + } + if (!config.getDefault("forwardable", "libdefaults").equals("well")) { + throw new Exception("Extra config error"); + } + + // Point to a file with no libdefaults + System.setProperty("java.security.krb5.conf", + System.getProperty("test.src", ".") +"/confplusprop2.conf"); + Config.refresh(); + + config = Config.getInstance(); + + if (!config.getDefaultRealm().equals("R2")) { + throw new Exception("Default realm error again"); + } + if (!config.getKDCList("R1").equals("k12")) { + throw new Exception("R1 kdc error"); + } + if (!config.getKDCList("R2").equals("k2")) { + throw new Exception("R2 kdc error"); + } + + // Point to a non-existing file + System.setProperty("java.security.krb5.conf", "i-am-not-a file"); + Config.refresh(); + + config = Config.getInstance(); + + if (!config.getDefaultRealm().equals("R2")) { + throw new Exception("Default realm error"); + } + try { + config.getKDCList("R1"); + throw new Exception("R1 is nowhere"); + } catch (KrbException ke) { + // OK + } + if (!config.getKDCList("R2").equals("k2")) { + throw new Exception("R2 kdc error"); + } + if (config.getDefault("forwardable", "libdefaults") != null) { + throw new Exception("Extra config error"); + } + } +} diff --git a/jdk/test/sun/security/krb5/confplusprop.conf b/jdk/test/sun/security/krb5/confplusprop.conf new file mode 100644 index 00000000000..80c925b14cd --- /dev/null +++ b/jdk/test/sun/security/krb5/confplusprop.conf @@ -0,0 +1,11 @@ +[libdefaults] +default_realm = R1 +forwardable = well + +[realms] +R1 = { + kdc = k1 +} +R2 = { + kdc = old +} diff --git a/jdk/test/sun/security/krb5/confplusprop2.conf b/jdk/test/sun/security/krb5/confplusprop2.conf new file mode 100644 index 00000000000..df00eccbccf --- /dev/null +++ b/jdk/test/sun/security/krb5/confplusprop2.conf @@ -0,0 +1,7 @@ +[realms] +R1 = { + kdc = k12 +} +R2 = { + kdc = old +} From 529e9065c2026ba0d359af78d1b8f0c6d0596371 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Wed, 8 Jul 2009 09:11:24 -0700 Subject: [PATCH 09/15] 6858127: Missing -DNDEBUG on Linux and Windows native code compiles Reviewed-by: tbell, dcubed --- jdk/make/common/Defs-linux.gmk | 2 +- jdk/make/common/Defs-windows.gmk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/make/common/Defs-linux.gmk b/jdk/make/common/Defs-linux.gmk index 672affde32b..424eaf0a7db 100644 --- a/jdk/make/common/Defs-linux.gmk +++ b/jdk/make/common/Defs-linux.gmk @@ -193,7 +193,7 @@ ifeq ($(ARCH_DATA_MODEL), 64) CPPFLAGS_COMMON += -D_LP64=1 endif -CPPFLAGS_OPT = +CPPFLAGS_OPT = -DNDEBUG CPPFLAGS_DBG = -DDEBUG ifneq ($(PRODUCT), java) CPPFLAGS_DBG += -DLOGGING diff --git a/jdk/make/common/Defs-windows.gmk b/jdk/make/common/Defs-windows.gmk index 00b8ea71e2a..0c220107df2 100644 --- a/jdk/make/common/Defs-windows.gmk +++ b/jdk/make/common/Defs-windows.gmk @@ -363,7 +363,7 @@ ifeq ($(COMPILER_WARNINGS_FATAL),true) CFLAGS_COMMON += -WX endif -CPPFLAGS_OPT = +CPPFLAGS_OPT = -DNDEBUG CPPFLAGS_DBG = -DDEBUG -DLOGGING CXXFLAGS_COMMON = $(CFLAGS_COMMON) From 64697c3e7ac7741b9b62373bcca0fcb5a08e730d Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Wed, 8 Jul 2009 09:12:17 -0700 Subject: [PATCH 10/15] 6855551: java -Xrunhprof crashes when running with classes compiled with targed=7 Reviewed-by: tbell, dcubed --- jdk/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c | 4 ++-- jdk/test/demo/jvmti/hprof/HelloWorld.java | 2 +- jdk/test/demo/jvmti/hprof/StackMapTableTest.java | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/jdk/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c b/jdk/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c index 6d43d9baa90..d241e80dafa 100644 --- a/jdk/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c +++ b/jdk/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c @@ -263,8 +263,8 @@ assert_error(CrwClassImage *ci, const char *condition, (void)sprintf(buf, "CRW ASSERTION FAILURE: %s (%s:%s:%d)", condition, - ci->name==0?"?":ci->name, - mi->name==0?"?":mi->name, + ci->name==NULL?"?":ci->name, + (mi==NULL||mi->name==NULL)?"?":mi->name, byte_code_offset); fatal_error(ci, buf, file, line); } diff --git a/jdk/test/demo/jvmti/hprof/HelloWorld.java b/jdk/test/demo/jvmti/hprof/HelloWorld.java index e349bbd08e9..ae8ec5c1482 100644 --- a/jdk/test/demo/jvmti/hprof/HelloWorld.java +++ b/jdk/test/demo/jvmti/hprof/HelloWorld.java @@ -24,7 +24,7 @@ /* HelloWorld: * - * Sample target appluication for HPROF tests + * Sample target application for HPROF tests * */ diff --git a/jdk/test/demo/jvmti/hprof/StackMapTableTest.java b/jdk/test/demo/jvmti/hprof/StackMapTableTest.java index a34614dfccb..0acc6fe61dc 100644 --- a/jdk/test/demo/jvmti/hprof/StackMapTableTest.java +++ b/jdk/test/demo/jvmti/hprof/StackMapTableTest.java @@ -23,11 +23,11 @@ /* @test - * @bug 6266289 6299047 + * @bug 6266289 6299047 6855180 6855551 * @summary Test jvmti hprof and java_crw_demo with StackMapTable attributes * * @compile ../DemoRun.java - * @compile -source 1.6 -g:lines HelloWorld.java + * @compile -source 7 -g:lines HelloWorld.java * @build StackMapTableTest * @run main StackMapTableTest HelloWorld */ From 40a7ea7c9c6ded29c0774c04f561698f5c163e43 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Thu, 9 Jul 2009 12:31:30 -0700 Subject: [PATCH 11/15] 6628737: Specification of wrapper class valueOf static factories should require caching Reviewed-by: mr --- jdk/src/share/classes/java/lang/Byte.java | 4 ++-- jdk/src/share/classes/java/lang/Character.java | 4 ++++ jdk/src/share/classes/java/lang/Integer.java | 3 +++ jdk/src/share/classes/java/lang/Long.java | 5 +++++ jdk/src/share/classes/java/lang/Short.java | 3 +++ 5 files changed, 17 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/java/lang/Byte.java b/jdk/src/share/classes/java/lang/Byte.java index 2bb6480c539..ba7486377d6 100644 --- a/jdk/src/share/classes/java/lang/Byte.java +++ b/jdk/src/share/classes/java/lang/Byte.java @@ -90,8 +90,8 @@ public final class Byte extends Number implements Comparable { * If a new {@code Byte} instance is not required, this method * should generally be used in preference to the constructor * {@link #Byte(byte)}, as this method is likely to yield - * significantly better space and time performance by caching - * frequently requested values. + * significantly better space and time performance since + * all byte values are cached. * * @param b a byte value. * @return a {@code Byte} instance representing {@code b}. diff --git a/jdk/src/share/classes/java/lang/Character.java b/jdk/src/share/classes/java/lang/Character.java index e33052ee170..9b9c938fa1e 100644 --- a/jdk/src/share/classes/java/lang/Character.java +++ b/jdk/src/share/classes/java/lang/Character.java @@ -2571,6 +2571,10 @@ class Character extends Object implements java.io.Serializable, ComparableCharacter instance representing c. * @since 1.5 diff --git a/jdk/src/share/classes/java/lang/Integer.java b/jdk/src/share/classes/java/lang/Integer.java index 50863dd7e9f..da35d2f7a4e 100644 --- a/jdk/src/share/classes/java/lang/Integer.java +++ b/jdk/src/share/classes/java/lang/Integer.java @@ -638,6 +638,9 @@ public final class Integer extends Number implements Comparable { * to yield significantly better space and time performance by * caching frequently requested values. * + * This method will always cache values in the range -128 to 127, + * inclusive, and may cache other values outside of this range. + * * @param i an {@code int} value. * @return an {@code Integer} instance representing {@code i}. * @since 1.5 diff --git a/jdk/src/share/classes/java/lang/Long.java b/jdk/src/share/classes/java/lang/Long.java index c632d5df2d9..a2fe09c959d 100644 --- a/jdk/src/share/classes/java/lang/Long.java +++ b/jdk/src/share/classes/java/lang/Long.java @@ -560,6 +560,11 @@ public final class Long extends Number implements Comparable { * significantly better space and time performance by caching * frequently requested values. * + * Note that unlike the {@linkplain Integer#valueOf(int) + * corresponding method} in the {@code Integer} class, this method + * is not required to cache values within a particular + * range. + * * @param l a long value. * @return a {@code Long} instance representing {@code l}. * @since 1.5 diff --git a/jdk/src/share/classes/java/lang/Short.java b/jdk/src/share/classes/java/lang/Short.java index 8abbf65d61a..a5d72120dfb 100644 --- a/jdk/src/share/classes/java/lang/Short.java +++ b/jdk/src/share/classes/java/lang/Short.java @@ -219,6 +219,9 @@ public final class Short extends Number implements Comparable { * significantly better space and time performance by caching * frequently requested values. * + * This method will always cache values in the range -128 to 127, + * inclusive, and may cache other values outside of this range. + * * @param s a short value. * @return a {@code Short} instance representing {@code s}. * @since 1.5 From 5ba2fd7d33d98a75b94044fcdc0b099bd9d74ba3 Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Fri, 10 Jul 2009 17:27:13 +0800 Subject: [PATCH 12/15] 6852744: PIT b61: PKI test suite fails because self signed certificates are beingrejected Make the builder aware of SKID/AKID, break the internal circular dependences Reviewed-by: mullan --- .../certpath/DistributionPointFetcher.java | 96 ++++- .../provider/certpath/ForwardBuilder.java | 176 +++++++- .../selfIssued/DisableRevocation.java | 260 ++++++++++++ .../selfIssued/KeyUsageMatters.java | 303 ++++++++++++++ .../cert/CertPathBuilder/selfIssued/README | 382 ++++++++++++++++++ .../selfIssued/StatusLoopDependency.java | 309 ++++++++++++++ .../CertPathBuilder/selfIssued/generate.sh | 221 ++++++++++ .../CertPathBuilder/selfIssued/openssl.cnf | 205 ++++++++++ 8 files changed, 1940 insertions(+), 12 deletions(-) create mode 100644 jdk/test/java/security/cert/CertPathBuilder/selfIssued/DisableRevocation.java create mode 100644 jdk/test/java/security/cert/CertPathBuilder/selfIssued/KeyUsageMatters.java create mode 100644 jdk/test/java/security/cert/CertPathBuilder/selfIssued/README create mode 100644 jdk/test/java/security/cert/CertPathBuilder/selfIssued/StatusLoopDependency.java create mode 100644 jdk/test/java/security/cert/CertPathBuilder/selfIssued/generate.sh create mode 100644 jdk/test/java/security/cert/CertPathBuilder/selfIssued/openssl.cnf diff --git a/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java b/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java index 34f26f64a0f..39ee1f1dad6 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-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 @@ -34,6 +34,7 @@ import javax.security.auth.x500.X500Principal; import sun.security.action.GetPropertyAction; import sun.security.util.Debug; +import sun.security.util.DerOutputStream; import sun.security.x509.*; /** @@ -333,7 +334,15 @@ class DistributionPointFetcher { if (match == false) { return false; } - indirectCRL = true; + + // we accept the case that a CRL issuer provide status + // information for itself. + if (ForwardBuilder.issues(certImpl, crlImpl, provider)) { + // reset the public key used to verify the CRL's signature + prevKey = certImpl.getPublicKey(); + } else { + indirectCRL = true; + } } else if (crlIssuer.equals(certIssuer) == false) { if (debug != null) { debug.println("crl issuer does not equal cert issuer"); @@ -347,7 +356,14 @@ class DistributionPointFetcher { PKIXExtensions.AuthorityKey_Id.toString()); if (!Arrays.equals(certAKID, crlAKID)) { - indirectCRL = true; + // we accept the case that a CRL issuer provide status + // information for itself. + if (ForwardBuilder.issues(certImpl, crlImpl, provider)) { + // reset the public key used to verify the CRL's signature + prevKey = certImpl.getPublicKey(); + } else { + indirectCRL = true; + } } } @@ -542,10 +558,80 @@ class DistributionPointFetcher { certSel.setSubject(crlIssuer.asX500Principal()); boolean[] crlSign = {false,false,false,false,false,false,true}; certSel.setKeyUsage(crlSign); + + // Currently by default, forward builder does not enable + // subject/authority key identifier identifying for target + // certificate, instead, it only compares the CRL issuer and + // the target certificate subject. If the certificate of the + // delegated CRL issuer is a self-issued certificate, the + // builder is unable to find the proper CRL issuer by issuer + // name only, there is a potential dead loop on finding the + // proper issuer. It is of great help to narrow the target + // scope down to aware of authority key identifiers in the + // selector, for the purposes of breaking the dead loop. + AuthorityKeyIdentifierExtension akidext = + crlImpl.getAuthKeyIdExtension(); + if (akidext != null) { + KeyIdentifier akid = (KeyIdentifier)akidext.get(akidext.KEY_ID); + if (akid != null) { + DerOutputStream derout = new DerOutputStream(); + derout.putOctetString(akid.getIdentifier()); + certSel.setSubjectKeyIdentifier(derout.toByteArray()); + } + + SerialNumber asn = + (SerialNumber)akidext.get(akidext.SERIAL_NUMBER); + if (asn != null) { + certSel.setSerialNumber(asn.getNumber()); + } + // the subject criterion will be set by builder automatically. + } + + // by far, we have validated the previous certificate, we can + // trust it during validating the CRL issuer. + // Except the performance improvement, another benefit is to break + // the dead loop while looking for the issuer back and forth + // between the delegated self-issued certificate and its issuer. + Set trustAnchors = new HashSet(); + if (anchor != null) { + trustAnchors.add(anchor); + } + + if (prevKey != null) { + // if the previous key is of the anchor, don't bother to + // duplicate the trust. + boolean duplicated = false; + PublicKey publicKey = prevKey; + X500Principal principal = certImpl.getIssuerX500Principal(); + + if (anchor != null) { + X509Certificate trustedCert = anchor.getTrustedCert(); + X500Principal trustedPrincipal; + PublicKey trustedPublicKey; + if (trustedCert != null) { + trustedPrincipal = trustedCert.getSubjectX500Principal(); + trustedPublicKey = trustedCert.getPublicKey(); + } else { + trustedPrincipal = anchor.getCA(); + trustedPublicKey = anchor.getCAPublicKey(); + } + + if (principal.equals(trustedPrincipal) && + publicKey.equals(trustedPublicKey)) { + duplicated = true; + } + } + + if (!duplicated) { + TrustAnchor temporary = + new TrustAnchor(principal, publicKey, null); + trustAnchors.add(temporary); + } + } + PKIXBuilderParameters params = null; try { - params = new PKIXBuilderParameters - (Collections.singleton(anchor), certSel); + params = new PKIXBuilderParameters(trustAnchors, certSel); } catch (InvalidAlgorithmParameterException iape) { throw new CRLException(iape); } diff --git a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java index d8713cdcac4..393a7663c91 100644 --- a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java +++ b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import java.util.*; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; +import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertPathValidatorException; import java.security.cert.PKIXReason; @@ -43,12 +44,22 @@ import java.security.cert.X509CertSelector; import javax.security.auth.x500.X500Principal; import sun.security.util.Debug; +import sun.security.util.DerOutputStream; import sun.security.x509.AccessDescription; import sun.security.x509.AuthorityInfoAccessExtension; import sun.security.x509.PKIXExtensions; import sun.security.x509.PolicyMappingsExtension; import sun.security.x509.X500Name; import sun.security.x509.X509CertImpl; +import sun.security.x509.X509CRLImpl; +import sun.security.x509.AuthorityKeyIdentifierExtension; +import sun.security.x509.KeyIdentifier; +import sun.security.x509.SubjectKeyIdentifierExtension; +import sun.security.x509.SerialNumber; +import sun.security.x509.GeneralNames; +import sun.security.x509.GeneralName; +import sun.security.x509.GeneralNameInterface; +import java.math.BigInteger; /** * This class represents a forward builder, which is able to retrieve @@ -237,7 +248,7 @@ class ForwardBuilder extends Builder { } else { if (caSelector == null) { - caSelector = new X509CertSelector(); + caSelector = new AdaptableX509CertSelector(); /* * Match on certificate validity date. @@ -269,6 +280,29 @@ class ForwardBuilder extends Builder { * at least as many CA certs that have already been traversed */ caSelector.setBasicConstraints(currentState.traversedCACerts); + + /* + * Facilitate certification path construction with authority + * key identifier and subject key identifier. + */ + AuthorityKeyIdentifierExtension akidext = + currentState.cert.getAuthorityKeyIdentifierExtension(); + if (akidext != null) { + KeyIdentifier akid = (KeyIdentifier)akidext.get(akidext.KEY_ID); + if (akid != null) { + DerOutputStream derout = new DerOutputStream(); + derout.putOctetString(akid.getIdentifier()); + caSelector.setSubjectKeyIdentifier(derout.toByteArray()); + } + + SerialNumber asn = + (SerialNumber)akidext.get(akidext.SERIAL_NUMBER); + if (asn != null) { + caSelector.setSerialNumber(asn.getNumber()); + } + // the subject criterion was set previously. + } + sel = caSelector; } @@ -817,13 +851,25 @@ class ForwardBuilder extends Builder { } else { continue; } - } + } else { + X500Principal principal = anchor.getCA(); + java.security.PublicKey publicKey = anchor.getCAPublicKey(); - X500Principal trustedCAName = anchor.getCA(); + if (principal != null && publicKey != null && + principal.equals(cert.getSubjectX500Principal())) { + if (publicKey.equals(cert.getPublicKey())) { + // the cert itself is a trust anchor + this.trustAnchor = anchor; + return true; + } + // else, it is a self-issued certificate of the anchor + } - /* Check subject/issuer name chaining */ - if (!trustedCAName.equals(cert.getIssuerX500Principal())) { - continue; + // Check subject/issuer name chaining + if (principal == null || + !principal.equals(cert.getIssuerX500Principal())) { + continue; + } } /* Check revocation if it is enabled */ @@ -890,4 +936,120 @@ class ForwardBuilder extends Builder { void removeFinalCertFromPath(LinkedList certPathList) { certPathList.removeFirst(); } + + /** Verifies whether a CRL is issued by a certain certificate + * + * @param cert the certificate + * @param crl the CRL to be verified + * @param provider the name of the signature provider + */ + static boolean issues(X509CertImpl cert, X509CRLImpl crl, String provider) + throws IOException { + + boolean kidmatched = false; + + // check certificate's key usage + boolean[] usages = cert.getKeyUsage(); + if (usages != null && !usages[6]) { + return false; + } + + // check certificate's SKID and CRL's AKID + AuthorityKeyIdentifierExtension akidext = crl.getAuthKeyIdExtension(); + if (akidext != null) { + // the highest priority, matching KID + KeyIdentifier akid = (KeyIdentifier)akidext.get(akidext.KEY_ID); + if (akid != null) { + SubjectKeyIdentifierExtension skidext = + cert.getSubjectKeyIdentifierExtension(); + if (skidext != null) { + KeyIdentifier skid = + (KeyIdentifier)skidext.get(skidext.KEY_ID); + if (!akid.equals(skid)) { + return false; + } + + kidmatched = true; + } + // conservatively, in case of X509 V1 certificate, + // does return false here if no SKID extension. + } + + // the medium priority, matching issuer name/serial number + SerialNumber asn = (SerialNumber)akidext.get(akidext.SERIAL_NUMBER); + GeneralNames anames = (GeneralNames)akidext.get(akidext.AUTH_NAME); + if (asn != null && anames != null) { + X500Name subject = (X500Name)cert.getSubjectDN(); + BigInteger serial = cert.getSerialNumber(); + + if (serial != null && subject != null) { + if (serial.equals(asn.getNumber())) { + return false; + } + + for (GeneralName name : anames.names()) { + GeneralNameInterface gni = name.getName(); + if (subject.equals(gni)) { + return true; + } + } + } + + return false; + } + + if (kidmatched) { + return true; + } + } + + // the last priority, verify the CRL signature with the cert. + X500Principal crlIssuer = crl.getIssuerX500Principal(); + X500Principal certSubject = cert.getSubjectX500Principal(); + if (certSubject != null && certSubject.equals(crlIssuer)) { + try { + crl.verify(cert.getPublicKey(), provider); + return true; + } catch (Exception e) { + // ignore all exceptions. + } + } + + return false; + } + + /** + * An adaptable X509 certificate selector for forward certification path + * building. + */ + private static class AdaptableX509CertSelector extends X509CertSelector { + public AdaptableX509CertSelector() { + super(); + } + + /** + * Decides whether a Certificate should be selected. + * + * For the purpose of compatibility, when a certificate is of + * version 1 and version 2, or the certificate does not include + * a subject key identifier extension, the selection criterion + * of subjectKeyIdentifier will be disabled. + * + * @Override + */ + public boolean match(Certificate cert) { + if (!(cert instanceof X509Certificate)) { + return false; + } + X509Certificate xcert = (X509Certificate)cert; + + if (xcert.getVersion() < 3 || + xcert.getExtensionValue("2.5.29.14") == null) { + // disable the subjectKeyIdentifier criterion + setSubjectKeyIdentifier(null); + } + + return super.match(cert); + } + } } diff --git a/jdk/test/java/security/cert/CertPathBuilder/selfIssued/DisableRevocation.java b/jdk/test/java/security/cert/CertPathBuilder/selfIssued/DisableRevocation.java new file mode 100644 index 00000000000..236ec77a4ab --- /dev/null +++ b/jdk/test/java/security/cert/CertPathBuilder/selfIssued/DisableRevocation.java @@ -0,0 +1,260 @@ +/* + * 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 6852744 + * @summary PIT b61: PKI test suite fails because self signed certificates + * are being rejected + * @run main/othervm DisableRevocation subca + * @run main/othervm DisableRevocation subci + * @run main/othervm DisableRevocation alice + * @author Xuelei Fan + */ + +import java.io.*; +import java.net.SocketException; +import java.util.*; +import java.security.Security; +import java.security.cert.*; +import java.security.cert.CertPathValidatorException.BasicReason; +import sun.security.util.DerInputStream; + +/** + * A test case helps to ensure that a certification path building process is + * able to identify a self-issued certificate from its issuer when disable + * revocation checking. + */ +public final class DisableRevocation { + + // the trust anchor + static String selfSignedCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICPjCCAaegAwIBAgIBADANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA2MjgxMzMyMThaFw0zMDA2MDgxMzMyMTha\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB\n" + + "AQUAA4GNADCBiQKBgQDInJhXi0655bPXAVkz1n5I6fAcZejzPnOPuwq3hU3OxFw8\n" + + "81Uf6o9oKI1h4w4XAD8u1cUNOgiX+wPwojronlp68bIfO6FVhNf287pLtLhNJo+7\n" + + "m6Qxw3ymFvEKy+PVj20CHSggdKHxUa4MBZBmHMFNBuxfYmjwzn+yTMmCCXOvSwID\n" + + "AQABo4GJMIGGMB0GA1UdDgQWBBSQ52Dpau+gtL+Kc31dusYnKj16ZTBHBgNVHSME\n" + + "QDA+gBSQ52Dpau+gtL+Kc31dusYnKj16ZaEjpCEwHzELMAkGA1UEBhMCVVMxEDAO\n" + + "BgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYw\n" + + "DQYJKoZIhvcNAQEEBQADgYEAjBt6ea65HCqbGsS2rs/HhlGusYXtThRVC5vwXSey\n" + + "ZFYwSgukuq1KDzckqZFu1meNImEwdZjwxdN0e2p/nVREPC42rZliSj6V1ThayKXj\n" + + "DWEZW1U5aR8T+3NYfDrdKcJGx4Hzfz0qKz1j4ssV1M9ptJxYYv4y2Da+592IN1S9\n" + + "v/E=\n" + + "-----END CERTIFICATE-----"; + + // the sub-ca + static String subCaCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICUDCCAbmgAwIBAgIBAzANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA2MjgxMzMyMjRaFw0yOTAzMTUxMzMyMjRa\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPFv24SK78VI0gWlyIrq/X\n" + + "srl1431K5hJJxMYZtaQunyPmrYg3oI9KvKFykxnR0N4XDPaIi75p9dXGppVu80BA\n" + + "+csvIPBwlBQoNmKDQWTziDOqfK4tE+IMuL/Y7pxnH6CDMY7VGpvatty2zcmH+m/v\n" + + "E/n+HPyeELJQT2rT/3T+7wIDAQABo4GJMIGGMB0GA1UdDgQWBBRidC8Dt3dBzYES\n" + + "KpR2tR560sZ0+zBHBgNVHSMEQDA+gBSQ52Dpau+gtL+Kc31dusYnKj16ZaEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEEBQADgYEAMeMKqrMr5d3eTQsv\n" + + "MYOD15Dl3THQGLAa4ad5Eyq5/1eUeEOpztzCgDfi0iPD8YCubIEVasBTSqTiGXqb\n" + + "RpGuPHOwwfWvHrTeHSludiFBAUiKj7aEV+oQa0FBn4U4TT8HA62HQ93FhzTDI3jP\n" + + "iil34GktVl6gfMKGzUEW/Dh8OM4=\n" + + "-----END CERTIFICATE-----"; + + // a delegated CRL issuer, it's a self-issued certificate of trust anchor + static String topCrlIssuerCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICPjCCAaegAwIBAgIBAjANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA2MjgxMzMyMjNaFw0yOTAzMTUxMzMyMjNa\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB\n" + + "AQUAA4GNADCBiQKBgQC99u93trf+WmpfiqunJy/P31ej1l4rESxft2JSGNjKuLFN\n" + + "/BO3SAugGJSkCARAwXjB0c8eeXhXWhVVWdNpbKepRJTxrjDfnFIavLgtUvmFwn/3\n" + + "hPXe+RQeA8+AJ99Y+o+10kY8JAZLa2j93C2FdmwOjUbo8aIz85yhbiV1tEDjLwID\n" + + "AQABo4GJMIGGMB0GA1UdDgQWBBSyFyA3XWLbdL6W6hksmBn7RKsQmDBHBgNVHSME\n" + + "QDA+gBSQ52Dpau+gtL+Kc31dusYnKj16ZaEjpCEwHzELMAkGA1UEBhMCVVMxEDAO\n" + + "BgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYw\n" + + "DQYJKoZIhvcNAQEEBQADgYEAHTm8aRTeakgCfEBCgSWK9wvMW1c18ANGMm8OFDBk\n" + + "xabVy9BT0MVFHlaneh89oIxTZN0FMTpg21GZMAvIzhEt7DGdO7HLsW7JniN7/OZ0\n" + + "rACmpK5frmZrLS03zUm8c+rTbazNfYLoZVG3/mDZbKIi+4y8IGnFcgLVsHsYoBNP\n" + + "G0c=\n" + + "-----END CERTIFICATE-----"; + + // a delegated CRL issuer, it's a self-issued certificate of sub-ca + static String subCrlIssuerCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICUDCCAbmgAwIBAgIBBDANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA2MjgxMzMyMjdaFw0yOTAzMTUxMzMyMjda\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+8AcLJtGAVUWvv3ifcyQw\n" + + "OGqwzcPrBw/XCs6vTMlcdtFzcH1M+Z3/QHN9+5VT1gqeTIZ+b8g9005Og3XKy/HX\n" + + "obXZeLv20VZsr+jm52ySghEYOVCTJ9OyFOAp5adp6nf0cA66Feh3LsmVhpTEcDOG\n" + + "GnyntQm0DBYxRoOT/GBlvQIDAQABo4GJMIGGMB0GA1UdDgQWBBSRWhMuZLQoHSDN\n" + + "xhxr+vdDmfAY8jBHBgNVHSMEQDA+gBSQ52Dpau+gtL+Kc31dusYnKj16ZaEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEEBQADgYEAMIDZLdOLFiPyS1bh\n" + + "Ch4eUYHT+K1WG93skbga3kVYg3GSe+gctwkKwKK13bwfi8zc7wwz6MtmQwEYhppc\n" + + "pKKKEwi5QirBCP54rihLCvRQaj6ZqUJ6VP+zPAqHYMDbzlBbHtVF/1lQUP30I6SV\n" + + "Fu987DvLmZ2GuQA9FKJsnlD9pbU=\n" + + "-----END CERTIFICATE-----"; + + // the target EE certificate + static String targetCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICNzCCAaCgAwIBAgIBAjANBgkqhkiG9w0BAQQFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA2MjgxMzMy\n" + + "MzBaFw0yOTAzMTUxMzMyMzBaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG\n" + + "9w0BAQEFAAOBjQAwgYkCgYEA7wnsvR4XEOfVznf40l8ClLod+7L0y2/+smVV+GM/\n" + + "T1/QF/stajAJxXNy08gK00WKZ6ruTHhR9vh/Z6+EQM2RZDCpU0A7LPa3kLE/XTmS\n" + + "1MLDu8ntkdlpURpvhdDWem+rl2HU5oZgzV8Jkcov9vXuSjqEDfr45FlPuV40T8+7\n" + + "cxsCAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSBwsAhi6Z1kriOs3ty\n" + + "uSIujv9a3DAfBgNVHSMEGDAWgBRidC8Dt3dBzYESKpR2tR560sZ0+zANBgkqhkiG\n" + + "9w0BAQQFAAOBgQDEiBqd5AMy2SQopFaS3dYkzj8MHlwtbCSoNVYkOfDnewcatrbk\n" + + "yFcp6FX++PMdOQFHWvvnDdkCUAzZQp8kCkF9tGLVLBtOK7XxQ1us1LZym7kOPzsd\n" + + "G93Dcf0U1JRO77juc61Br5paAy8Bok18Y/MeG7uKgB2MAEJYKhGKbCrfMw==\n" + + "-----END CERTIFICATE-----"; + + private static Set generateTrustAnchors() + throws CertificateException { + // generate certificate from cert string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + ByteArrayInputStream is = + new ByteArrayInputStream(selfSignedCertStr.getBytes()); + Certificate selfSignedCert = cf.generateCertificate(is); + + // generate a trust anchor + TrustAnchor anchor = + new TrustAnchor((X509Certificate)selfSignedCert, null); + + return Collections.singleton(anchor); + } + + private static CertStore generateCertificateStore() throws Exception { + Collection entries = new HashSet(); + + // generate certificate from certificate string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + ByteArrayInputStream is; + + is = new ByteArrayInputStream(targetCertStr.getBytes()); + Certificate cert = cf.generateCertificate(is); + entries.add(cert); + + is = new ByteArrayInputStream(subCaCertStr.getBytes()); + cert = cf.generateCertificate(is); + entries.add(cert); + + is = new ByteArrayInputStream(selfSignedCertStr.getBytes()); + cert = cf.generateCertificate(is); + entries.add(cert); + + is = new ByteArrayInputStream(topCrlIssuerCertStr.getBytes()); + cert = cf.generateCertificate(is); + entries.add(cert); + + is = new ByteArrayInputStream(subCrlIssuerCertStr.getBytes()); + cert = cf.generateCertificate(is); + entries.add(cert); + + return CertStore.getInstance("Collection", + new CollectionCertStoreParameters(entries)); + } + + private static X509CertSelector generateSelector(String name) + throws Exception { + X509CertSelector selector = new X509CertSelector(); + + // generate certificate from certificate string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + ByteArrayInputStream is = null; + if (name.equals("subca")) { + is = new ByteArrayInputStream(subCaCertStr.getBytes()); + } else if (name.equals("subci")) { + is = new ByteArrayInputStream(subCrlIssuerCertStr.getBytes()); + } else { + is = new ByteArrayInputStream(targetCertStr.getBytes()); + } + + X509Certificate target = (X509Certificate)cf.generateCertificate(is); + byte[] extVal = target.getExtensionValue("2.5.29.14"); + if (extVal != null) { + DerInputStream in = new DerInputStream(extVal); + byte[] subjectKID = in.getOctetString(); + selector.setSubjectKeyIdentifier(subjectKID); + } else { + // unlikely to happen. + throw new Exception("unexpected certificate: no SKID extension"); + } + + return selector; + } + + private static boolean match(String name, Certificate cert) + throws Exception { + X509CertSelector selector = new X509CertSelector(); + + // generate certificate from certificate string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + ByteArrayInputStream is = null; + if (name.equals("subca")) { + is = new ByteArrayInputStream(subCaCertStr.getBytes()); + } else if (name.equals("subci")) { + is = new ByteArrayInputStream(subCrlIssuerCertStr.getBytes()); + } else { + is = new ByteArrayInputStream(targetCertStr.getBytes()); + } + X509Certificate target = (X509Certificate)cf.generateCertificate(is); + + return target.equals(cert); + } + + + public static void main(String[] args) throws Exception { + CertPathBuilder builder = CertPathBuilder.getInstance("PKIX"); + + X509CertSelector selector = generateSelector(args[0]); + + Set anchors = generateTrustAnchors(); + CertStore certs = generateCertificateStore(); + + + PKIXBuilderParameters params = + new PKIXBuilderParameters(anchors, selector); + params.addCertStore(certs); + params.setRevocationEnabled(false); + params.setDate(new Date(109, 7, 1)); // 2009-07-01 + Security.setProperty("ocsp.enable", "false"); + System.setProperty("com.sun.security.enableCRLDP", "false"); + + PKIXCertPathBuilderResult result = + (PKIXCertPathBuilderResult)builder.build(params); + + if (!match(args[0], result.getCertPath().getCertificates().get(0))) { + throw new Exception("unexpected certificate"); + } + } +} diff --git a/jdk/test/java/security/cert/CertPathBuilder/selfIssued/KeyUsageMatters.java b/jdk/test/java/security/cert/CertPathBuilder/selfIssued/KeyUsageMatters.java new file mode 100644 index 00000000000..af977c3d8d2 --- /dev/null +++ b/jdk/test/java/security/cert/CertPathBuilder/selfIssued/KeyUsageMatters.java @@ -0,0 +1,303 @@ +/* + * 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 6852744 + * @summary PIT b61: PKI test suite fails because self signed certificates + * are being rejected + * @run main/othervm KeyUsageMatters subca + * @run main/othervm KeyUsageMatters subci + * @run main/othervm KeyUsageMatters alice + * @author Xuelei Fan + */ + +import java.io.*; +import java.net.SocketException; +import java.util.*; +import java.security.Security; +import java.security.cert.*; +import java.security.cert.CertPathValidatorException.BasicReason; +import sun.security.util.DerInputStream; + +/** + * KeyUsage extension plays a important rule during looking for the issuer + * of a certificate or CRL. A certificate issuer should have the keyCertSign + * bit set, and a CRL issuer should have the cRLSign bit set. + * + * Sometime, a delegated CRL issuer would also have the keyCertSign bit set, + * as would be troublesome to find the proper CRL issuer during certificate + * path build if the delegated CRL issuer is a self-issued certificate, for + * it is hard to identify it from its issuer by the "issuer" field only. + * + * The fix of 6852744 should addresses above issue, and allow a delegated CRL + * issuer to have keyCertSign bit set. + * + * In the test case, the delegated CRL issuers have cRLSign bit set only, and + * the CAs have the keyCertSign bit set only, it is expected to work before + * and after the bug fix of 6852744. + */ +public final class KeyUsageMatters { + + // the trust anchor + static String selfSignedCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICPjCCAaegAwIBAgIBADANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA0MjcwMjI0MzJaFw0zMDA0MDcwMjI0MzJa\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB\n" + + "AQUAA4GNADCBiQKBgQC4OTag24sTxL2tXTNuvpmUEtdxrYAZoFsslFQ60T+WD9wQ\n" + + "Jeiw87FSPsR2vxRuv0j8DNm2a4h7LNNIFcLurfNldbz5pvgZ7VqdbbUMPE9qP85n\n" + + "jgDl4woyRTSUeRI4A7O0CO6NpES21dtbdhroWQrEkHxpnrDPxsxrz5gf2m3gqwID\n" + + "AQABo4GJMIGGMB0GA1UdDgQWBBSCJd0hpl5PdAD9IZS+Hzng4lXLGzBHBgNVHSME\n" + + "QDA+gBSCJd0hpl5PdAD9IZS+Hzng4lXLG6EjpCEwHzELMAkGA1UEBhMCVVMxEDAO\n" + + "BgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAgQw\n" + + "DQYJKoZIhvcNAQEEBQADgYEAluy6HIjWcq009lTLmhp+Np6dxU78pInBK8RZkza0\n" + + "484qGaxFGD3UGyZkI5uWmsH2XuMbuox5khfIq6781gmkPBHXBIEtJN8eLusOHEye\n" + + "iE8h7WI+N3qa6Pj56WionMrioqC/3X+b06o147bbhx8U0vkYv/HyPaITOFfMXTdz\n" + + "Vjw=\n" + + "-----END CERTIFICATE-----"; + + // the sub-ca + static String subCaCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICUDCCAbmgAwIBAgIBAzANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA0MjcwMjI0MzRaFw0yOTAxMTIwMjI0MzRa\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCiAJnAQW2ad3ZMKUhSJVZj\n" + + "8pBqxTcHSTwAVguQkDglsN/OIwUpvR5Jgp3lpRWUEt6idEp0FZzORpvtjt3pr5MG\n" + + "Eg2CDptekC5BSPS+fIAIKlncB3HwOiFFhH6b3wTydDCdEd2fvsi4QMOSVrIYMeA8\n" + + "P/mCz6kRhfUQPE0CMmOUewIDAQABo4GJMIGGMB0GA1UdDgQWBBT0/nNP8WpyxmYr\n" + + "IBp4tN8y08jw2jBHBgNVHSMEQDA+gBSCJd0hpl5PdAD9IZS+Hzng4lXLG6EjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQEEBQADgYEAS9PzI6B39R/U9fRj\n" + + "UExzN1FXNP5awnAPtiv34kSCL6n6MryqkfG+8aaAOdZsSjmTylNFaF7cW/Xp1VBF\n" + + "hq0bg/SbEAbK7+UwL8GSC3crhULHLbh+1iFdVTEwxCw5YmB8ji3BaZ/WKW/PkjCZ\n" + + "7cXP6VDeZMG6oRQ4hbOcixoFPXo=\n" + + "-----END CERTIFICATE-----"; + + // a delegated CRL issuer, it's a self-issued certificate of trust anchor + static String topCrlIssuerCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICKzCCAZSgAwIBAgIBAjANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA0MjcwMjI0MzNaFw0yOTAxMTIwMjI0MzNa\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB\n" + + "AQUAA4GNADCBiQKBgQDMJeBMBybHykI/YpwUJ4O9euqDSLb1kpWpceBS8TVqvgBC\n" + + "SgUJWtFZL0i6bdvF6mMdlbuBkGzhXqHiVAi96/zRLbUC9F8SMEJ6MuD+YhQ0ZFTQ\n" + + "atKy8zf8O9XzztelLJ26Gqb7QPV133WY3haAqHtCXOhEKkCN16NOYNC37DTaJwID\n" + + "AQABo3cwdTAdBgNVHQ4EFgQULXSWzXzUOIpOJpzbSCpW42IJUugwRwYDVR0jBEAw\n" + + "PoAUgiXdIaZeT3QA/SGUvh854OJVyxuhI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYD\n" + + "VQQKEwdFeGFtcGxlggEAMAsGA1UdDwQEAwIBAjANBgkqhkiG9w0BAQQFAAOBgQAY\n" + + "eMnf5AHSNlyUlzXk8o2S0h4gCuvKX6C3kFfKuZcWvFAbx4yQOWLS2s15/nzR4+AP\n" + + "FGX3lgJjROyAh7fGedTQK+NFWwkM2ag1g3hXktnlnT1qHohi0w31nVBJxXEDO/Ck\n" + + "uJTpJGt8XxxbFaw5v7cHy7XuTAeU/sekvjEiNHW00Q==\n" + + "-----END CERTIFICATE-----"; + + // a delegated CRL issuer, it's a self-issued certificate of sub-ca + static String subCrlIssuerCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICPTCCAaagAwIBAgIBBDANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA0MjcwMjI0MzRaFw0yOTAxMTIwMjI0MzRa\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDWUtDQx2MB/7arDiquMJyd\n" + + "LWwSg6p8sg5z6wKrC1v47MT4DBhFX+0RUgTMUdQgYpgxGpczn+6y4zfV76064S0N\n" + + "4L/IQ+SunTW1w4yRGjB+xkyyJmWAqijG1nr+Dgkv5nxPI+9Er5lHcoVWVMEcvvRm\n" + + "6jIBQdldVlSgv+VgUnFm5wIDAQABo3cwdTAdBgNVHQ4EFgQUkV3Qqtk7gIot9n60\n" + + "jX6dloxrfMEwRwYDVR0jBEAwPoAUgiXdIaZeT3QA/SGUvh854OJVyxuhI6QhMB8x\n" + + "CzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlggEAMAsGA1UdDwQEAwIBAjAN\n" + + "BgkqhkiG9w0BAQQFAAOBgQADu4GM8EdmIKhC7FRvk5jF90zfvZ38wbXBzCjKI4jX\n" + + "QJrhne1bfyeNNm5c1w+VKidT+XzBzBGH7ZqYzoZmzRIfcbLKX2brEBKiukeeAyL3\n" + + "bctQtbp19tX+uu2dQberD188AAysKTkHcJUV+rRsTwVJ9vcYKxoRxKk8DhH7ZS3M\n" + + "rg==\n" + + "-----END CERTIFICATE-----"; + + // the target EE certificate + static String targetCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICNzCCAaCgAwIBAgIBAjANBgkqhkiG9w0BAQQFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA0MjcwMjI0\n" + + "MzZaFw0yOTAxMTIwMjI0MzZaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG\n" + + "9w0BAQEFAAOBjQAwgYkCgYEAvYSaU3oiE4Pxp/aUIXwMqOwSiWkZ+O3aTu13hRtK\n" + + "ZyR+Wtj63IuvaigAC4uC+zBypF93ThjwCzVR2qKDQaQzV8CLleO96gStt7Y+i3G2\n" + + "V3IUGgrVCqeK7N6nNYu0wW84sibcPqG/TIy0UoaQMqgB21xtRF+1DUVlFh4Z89X/\n" + + "pskCAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSynMEdcal/e9TmvlNE\n" + + "4suXGA4+hjAfBgNVHSMEGDAWgBT0/nNP8WpyxmYrIBp4tN8y08jw2jANBgkqhkiG\n" + + "9w0BAQQFAAOBgQB/jru7E/+piSmUwByw5qbZsoQZVcgR97pd2TErNJpJMAX2oIHR\n" + + "wJH6w4NuYs27+fEAX7wK4whc6EUH/w1SI6o28F2rG6HqYQPPZ2E2WqwbBQL9nYE3\n" + + "Vfzu/G9axTUQXFbf90h80UErA+mZVxqc2xtymLuH0YEaMZImtRZ2MXHfXg==\n" + + "-----END CERTIFICATE-----"; + + // CRL issued by the delegated CRL issuer, topCrlIssuerCertStr + static String topCrlStr = + "-----BEGIN X509 CRL-----\n" + + "MIIBGzCBhQIBATANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQMA4GA1UE\n" + + "ChMHRXhhbXBsZRcNMDkwNDI3MDIzODA0WhcNMjgwNjI2MDIzODA0WjAiMCACAQUX\n" + + "DTA5MDQyNzAyMzgwMFowDDAKBgNVHRUEAwoBBKAOMAwwCgYDVR0UBAMCAQIwDQYJ\n" + + "KoZIhvcNAQEEBQADgYEAoarfzXEtw3ZDi4f9U8eSvRIipHSyxOrJC7HR/hM5VhmY\n" + + "CErChny6x9lBVg9s57tfD/P9PSzBLusCcHwHMAbMOEcTltVVKUWZnnbumpywlYyg\n" + + "oKLrE9+yCOkYUOpiRlz43/3vkEL5hjIKMcDSZnPKBZi1h16Yj2hPe9GMibNip54=\n" + + "-----END X509 CRL-----"; + + // CRL issued by the delegated CRL issuer, subCrlIssuerCertStr + static String subCrlStr = + "-----BEGIN X509 CRL-----\n" + + "MIIBLTCBlwIBATANBgkqhkiG9w0BAQQFADAxMQswCQYDVQQGEwJVUzEQMA4GA1UE\n" + + "ChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMRcNMDkwNDI3MDIzODA0WhcNMjgw\n" + + "NjI2MDIzODA0WjAiMCACAQQXDTA5MDQyNzAyMzgwMVowDDAKBgNVHRUEAwoBBKAO\n" + + "MAwwCgYDVR0UBAMCAQIwDQYJKoZIhvcNAQEEBQADgYEAeS+POqYEIHIIJcsLxuUr\n" + + "aJFzQ/ujH0QmnyMNEL3Uavyq4VQuAahF+w6aTPb5UBzms0uX8NAvD2vNoUJvmJOX\n" + + "nGKuq4Q1DFj82E7/9d25nXdWGOmFvFCRVO+St2Xe5n8CJuZNBiz388FDSIOiFSCa\n" + + "ARGr6Qu68MYGtLMC6ZqP3u0=\n" + + "-----END X509 CRL-----"; + + private static Set generateTrustAnchors() + throws CertificateException { + // generate certificate from cert string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + ByteArrayInputStream is = + new ByteArrayInputStream(selfSignedCertStr.getBytes()); + Certificate selfSignedCert = cf.generateCertificate(is); + + // generate a trust anchor + TrustAnchor anchor = + new TrustAnchor((X509Certificate)selfSignedCert, null); + + return Collections.singleton(anchor); + } + + private static CertStore generateCertificateStore() throws Exception { + Collection entries = new HashSet(); + + // generate certificate from certificate string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + ByteArrayInputStream is; + + is = new ByteArrayInputStream(targetCertStr.getBytes()); + Certificate cert = cf.generateCertificate(is); + entries.add(cert); + + is = new ByteArrayInputStream(subCaCertStr.getBytes()); + cert = cf.generateCertificate(is); + entries.add(cert); + + is = new ByteArrayInputStream(selfSignedCertStr.getBytes()); + cert = cf.generateCertificate(is); + entries.add(cert); + + is = new ByteArrayInputStream(topCrlIssuerCertStr.getBytes()); + cert = cf.generateCertificate(is); + entries.add(cert); + + is = new ByteArrayInputStream(subCrlIssuerCertStr.getBytes()); + cert = cf.generateCertificate(is); + entries.add(cert); + + // generate CRL from CRL string + is = new ByteArrayInputStream(topCrlStr.getBytes()); + Collection mixes = cf.generateCRLs(is); + entries.addAll(mixes); + + is = new ByteArrayInputStream(subCrlStr.getBytes()); + mixes = cf.generateCRLs(is); + entries.addAll(mixes); + + return CertStore.getInstance("Collection", + new CollectionCertStoreParameters(entries)); + } + + private static X509CertSelector generateSelector(String name) + throws Exception { + X509CertSelector selector = new X509CertSelector(); + + // generate certificate from certificate string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + ByteArrayInputStream is = null; + if (name.equals("subca")) { + is = new ByteArrayInputStream(subCaCertStr.getBytes()); + } else if (name.equals("subci")) { + is = new ByteArrayInputStream(subCrlIssuerCertStr.getBytes()); + } else { + is = new ByteArrayInputStream(targetCertStr.getBytes()); + } + + X509Certificate target = (X509Certificate)cf.generateCertificate(is); + byte[] extVal = target.getExtensionValue("2.5.29.14"); + if (extVal != null) { + DerInputStream in = new DerInputStream(extVal); + byte[] subjectKID = in.getOctetString(); + selector.setSubjectKeyIdentifier(subjectKID); + } else { + // unlikely to happen. + throw new Exception("unexpected certificate: no SKID extension"); + } + + return selector; + } + + private static boolean match(String name, Certificate cert) + throws Exception { + X509CertSelector selector = new X509CertSelector(); + + // generate certificate from certificate string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + ByteArrayInputStream is = null; + if (name.equals("subca")) { + is = new ByteArrayInputStream(subCaCertStr.getBytes()); + } else if (name.equals("subci")) { + is = new ByteArrayInputStream(subCrlIssuerCertStr.getBytes()); + } else { + is = new ByteArrayInputStream(targetCertStr.getBytes()); + } + X509Certificate target = (X509Certificate)cf.generateCertificate(is); + + return target.equals(cert); + } + + + public static void main(String[] args) throws Exception { + CertPathBuilder builder = CertPathBuilder.getInstance("PKIX"); + + X509CertSelector selector = generateSelector(args[0]); + + Set anchors = generateTrustAnchors(); + CertStore certs = generateCertificateStore(); + + + PKIXBuilderParameters params = + new PKIXBuilderParameters(anchors, selector); + params.addCertStore(certs); + params.setRevocationEnabled(true); + params.setDate(new Date(109, 5, 1)); // 2009-05-01 + Security.setProperty("ocsp.enable", "false"); + System.setProperty("com.sun.security.enableCRLDP", "true"); + + PKIXCertPathBuilderResult result = + (PKIXCertPathBuilderResult)builder.build(params); + + if (!match(args[0], result.getCertPath().getCertificates().get(0))) { + throw new Exception("unexpected certificate"); + } + } +} diff --git a/jdk/test/java/security/cert/CertPathBuilder/selfIssued/README b/jdk/test/java/security/cert/CertPathBuilder/selfIssued/README new file mode 100644 index 00000000000..b0c1d6e0255 --- /dev/null +++ b/jdk/test/java/security/cert/CertPathBuilder/selfIssued/README @@ -0,0 +1,382 @@ +/* + * 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. + */ + + Certificates and CRLs + +The certificates and CRLs used by KeyUsageMatters.java are copied from +test/java/security/cert/CertPathValidator/indirectCRL. + +Here lists the local generated certificates and CRLs used in the test cases. + +The generate.sh depends on openssl, and it should be run under ksh. The +script will create many directories and files, please run it in a +directory outside of JDK workspace. + +1. root certifiate and key +-----BEGIN CERTIFICATE----- +MIICPjCCAaegAwIBAgIBADANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA2MjgxMzMyMThaFw0zMDA2MDgxMzMyMTha +MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQDInJhXi0655bPXAVkz1n5I6fAcZejzPnOPuwq3hU3OxFw8 +81Uf6o9oKI1h4w4XAD8u1cUNOgiX+wPwojronlp68bIfO6FVhNf287pLtLhNJo+7 +m6Qxw3ymFvEKy+PVj20CHSggdKHxUa4MBZBmHMFNBuxfYmjwzn+yTMmCCXOvSwID +AQABo4GJMIGGMB0GA1UdDgQWBBSQ52Dpau+gtL+Kc31dusYnKj16ZTBHBgNVHSME +QDA+gBSQ52Dpau+gtL+Kc31dusYnKj16ZaEjpCEwHzELMAkGA1UEBhMCVVMxEDAO +BgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYw +DQYJKoZIhvcNAQEEBQADgYEAjBt6ea65HCqbGsS2rs/HhlGusYXtThRVC5vwXSey +ZFYwSgukuq1KDzckqZFu1meNImEwdZjwxdN0e2p/nVREPC42rZliSj6V1ThayKXj +DWEZW1U5aR8T+3NYfDrdKcJGx4Hzfz0qKz1j4ssV1M9ptJxYYv4y2Da+592IN1S9 +v/E= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,46F13CECA9B38323 + +AVNWPH7jiPyJVq9KfL3IlGVCwD41KVapg12yJR2t/WWlLaKr19/0oWNvimcrd040 +txFKvcFO9TFLxmaco33+actCoL0K/XbrCBICThZLybzcFTuYFMum8eqL61avQgBe +Kt4CCjcupWLzKWkKTMV/bP6nPnPUSB9U8QeGwutjJYnLDi0TuYx8YSqZo/36vM98 +r3OvtcSA5XEN4guxxHusZJnhbclVb/Z1WtLVb4v2d5yBtPM2p3R0hK17L4Dnusjl +n56z6Z0AIYmfAggM/Fpge2uT3D/5n//l1lZRNoSvsX5UZipKswZKLpvx7IJ+AqgA +UO9lcmNLGnIXME3IS3smd83wPi7nxH3NCYWHbGAKLm6mkFMs5LOhofUMOBS3Rxmm +2RjCGtuzDxBPKveo9/Y80B//6sEce2gdi7fCKgWwtR4VFuJd0hWODD6CarK3edHH +rUG62Kt2aqiI/y/NLEbfHCHbyM37c9/OzS5Zy695dDl22r5EirVFsVgejQR1JGtP +ANdc6kkkJW+s6GiqimShssMTp1x0L8twT/+wEa38LafiaPKk4OweleBuyz7k2FxA +Rr2u9IOvGU3eKAeH8HSFWvaNE9S2lYFPiWWZ6O/LzVvnb847+gungQ7SPRzOkt4k +L4PtHIoKmLWFr5tzML1Q8wiaKcTWMb5LZbRbo+2XYGoIpilxkBBuhX7cMJFwOHEf +YJJRixBI97doPsnIQ3GkA8xY+INzQ4LWNQbnEtS7L7t26NA9tDlg4ILU/UfMoQIp +Ol4EZY1U7gD8BeMwo2vX3x/WA+a7R2N95klBFNqn9jSkm6a5yoeCZw== +-----END RSA PRIVATE KEY----- + + +2. root crl issuer and key +-----BEGIN CERTIFICATE----- +MIICPjCCAaegAwIBAgIBAjANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA2MjgxMzMyMjNaFw0yOTAzMTUxMzMyMjNa +MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQC99u93trf+WmpfiqunJy/P31ej1l4rESxft2JSGNjKuLFN +/BO3SAugGJSkCARAwXjB0c8eeXhXWhVVWdNpbKepRJTxrjDfnFIavLgtUvmFwn/3 +hPXe+RQeA8+AJ99Y+o+10kY8JAZLa2j93C2FdmwOjUbo8aIz85yhbiV1tEDjLwID +AQABo4GJMIGGMB0GA1UdDgQWBBSyFyA3XWLbdL6W6hksmBn7RKsQmDBHBgNVHSME +QDA+gBSQ52Dpau+gtL+Kc31dusYnKj16ZaEjpCEwHzELMAkGA1UEBhMCVVMxEDAO +BgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYw +DQYJKoZIhvcNAQEEBQADgYEAHTm8aRTeakgCfEBCgSWK9wvMW1c18ANGMm8OFDBk +xabVy9BT0MVFHlaneh89oIxTZN0FMTpg21GZMAvIzhEt7DGdO7HLsW7JniN7/OZ0 +rACmpK5frmZrLS03zUm8c+rTbazNfYLoZVG3/mDZbKIi+4y8IGnFcgLVsHsYoBNP +G0c= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,3881A5676C1AD5E5 + +KgaAtGlIQXVnsoifcd1oTi4hS1J+InHISFcZepI1h1hrU9KVAJAlwD1GIeM2qAkG +P1ABsA0TE0yRJpd3qHih2IPtD42osfc3HmNTw17nh4Trd3ESilrs4w/rrH8e6bR5 +WlqG0OKsw8x57t44m9yX94+pP3tdPaJwnFk5M7pDCO44IZskmy10S0NHBn7wMwM/ +mqlZ15mK6YZTwOuLzpdSDJqYPLiv77KpfeiqSN++ISXoNhIcNYHRVyErAS/DcBlx +mbrmBaGexhuagQYqVikEDIvg8kBDWD92EjOFbz94Z6eTvliauJ/+E1/Ffefe2cN5 +LaVwuUsiyW9GjarWwBJDFrXesTikklshC9V35j/ACHVdh5CuO8FGfVijIwlbZ14N +xKWJdSlZlJgEjkwUlWfi1KmrFrob+yK20fGMWr3oY1rTKWZdYkrqnnKEYcMQV/TH +XNY77D5idJ3FLtvJyziqIFuohdatQsu6xFP5UEOeUi6OhptJDjjS+zDhiBlL4cqA +klThzvuycxjZT+5xno0f8GEnZkQNcC6xxPoP6vstNMKLz1rI1CVUSXZBHc5nfMaF +m75rrLbvf6F2NLUspaNXnW8TUMHxcu8nNCnM4/u6hkqebQo/N8X1/v1HImsewwWO +P5uJwqmqfuRz0vZyMKAk3FzQIfrjJouxDfkNV2YHM9VP/grPlDgzmgiN0+6bCbn+ +RW2K8kvkSFZehQ1Ygdst9KYH3NEcEYVYY9pH1N1xRNAylcIDJNwrFwf9vfwjt9/q +AVsyDxUBT/KVCcqr15LNNq9HmmcP6IZZMRjdyf2BR+/cobxxDRZq1Q== +-----END RSA PRIVATE KEY----- + + +3. root CRL issued by root crl issuer. +-----BEGIN X509 CRL----- +MIIBGzCBhQIBATANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQMA4GA1UE +ChMHRXhhbXBsZRcNMDkwNjI4MTMzMjM4WhcNMjgwODI3MTMzMjM4WjAiMCACAQUX +DTA5MDYyODEzMzIzN1owDDAKBgNVHRUEAwoBBKAOMAwwCgYDVR0UBAMCAQEwDQYJ +KoZIhvcNAQEEBQADgYEAVUIeu2x7ZwsliafoCBOg+u8Q4S/VFfTe/SQnRyTM3/V1 +v+Vn5Acc7eo8Rh4AHcnFFbLNk38n6lllov/CaVR0IPZ6hnrNHVa7VYkNlRAwV2aN +GUUhkMMOLVLnN25UOrN9J637SHmRE6pB+TRMaEQ73V7UNlWxuSMK4KofWen0A34= +-----END X509 CRL----- + + +4. subca certificate and key +-----BEGIN CERTIFICATE----- +MIICUDCCAbmgAwIBAgIBAzANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA2MjgxMzMyMjRaFw0yOTAzMTUxMzMyMjRa +MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz +cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPFv24SK78VI0gWlyIrq/X +srl1431K5hJJxMYZtaQunyPmrYg3oI9KvKFykxnR0N4XDPaIi75p9dXGppVu80BA ++csvIPBwlBQoNmKDQWTziDOqfK4tE+IMuL/Y7pxnH6CDMY7VGpvatty2zcmH+m/v +E/n+HPyeELJQT2rT/3T+7wIDAQABo4GJMIGGMB0GA1UdDgQWBBRidC8Dt3dBzYES +KpR2tR560sZ0+zBHBgNVHSMEQDA+gBSQ52Dpau+gtL+Kc31dusYnKj16ZaEjpCEw +HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEEBQADgYEAMeMKqrMr5d3eTQsv +MYOD15Dl3THQGLAa4ad5Eyq5/1eUeEOpztzCgDfi0iPD8YCubIEVasBTSqTiGXqb +RpGuPHOwwfWvHrTeHSludiFBAUiKj7aEV+oQa0FBn4U4TT8HA62HQ93FhzTDI3jP +iil34GktVl6gfMKGzUEW/Dh8OM4= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,35408AD3018F0049 + +4t6WfpFNqpOr47Wc/OAt8+KZK0+WX7d3nlJn47W+QN7AkPfBlLBpcQJkImhP4/eh +aJyk8fPOdUhT/4rgc5ORuKk4d9boD36KK5Iz/+/oNBxzuld6TybVb+Hvw41cIZTW +CtkvADQpR8XWbPre+3ZH2eAKoTeWX0xR7pYg1JsFk9vxee6U82iqsAYRdUOdot8D +9zdDbbeaLWs78UbZkxFtuXREuyNVX880Q17t8qszJL2KmmtMQpUvxTlW04Ope1Ug +uIuOxeannzpKRD+37fj+oacM3GRqVFOP47/NVaziOexDBn4b5nlW6OMro6t0qiHt +1GLJcw1oLXoFe8ycexfzYWUiHymSz5Vh3wIflsQY+Ik6dopL+fpk2cVD0bncKJlf +Ie9PvL04RwannRjgtPl9X05tzcgeyznp2Ix1/rsriZQQpdPTLGA6w6kUhQeK6TwT +eX7pXn3iLTGK+VoHRfbxBQR2Fvq1nRJbvsmJFhPOcJU5CYSaDPGGdA6NorbdVgbc +14DlkhzojhEpZ7DaUeFNUXUMlQOR5UUTZB+wL3zQoY/FzHci3JD1Gj4NlbC9mMEg +ncWZcpZWOnP2kHSz2o/UOxQM80gerukI7NOr020iJ+ZZRb/gyAAzLPnD+mCZ7/e2 +JJ3x6yHOtVA6WzZiQH1d9/bm79rtcWaRH83X/idG1lHuKXQJFAaw5f7Z2n2/yuF1 +9pZf7el1M7UoBf74oc68klAl46f4inroy8anAtc/qjSTXUYQrNvKZsWU9AZVS7oH +iEuYMVW4KiZh3SHsIg5TZdMbdVYtZpcTsl/Kh6XuY0o0Xsi+rTK5AA== +-----END RSA PRIVATE KEY----- + + +5. crl issuer of subca, the certificate and key +-----BEGIN CERTIFICATE----- +MIICUDCCAbmgAwIBAgIBBDANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA2MjgxMzMyMjdaFw0yOTAzMTUxMzMyMjda +MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz +cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+8AcLJtGAVUWvv3ifcyQw +OGqwzcPrBw/XCs6vTMlcdtFzcH1M+Z3/QHN9+5VT1gqeTIZ+b8g9005Og3XKy/HX +obXZeLv20VZsr+jm52ySghEYOVCTJ9OyFOAp5adp6nf0cA66Feh3LsmVhpTEcDOG +GnyntQm0DBYxRoOT/GBlvQIDAQABo4GJMIGGMB0GA1UdDgQWBBSRWhMuZLQoHSDN +xhxr+vdDmfAY8jBHBgNVHSMEQDA+gBSQ52Dpau+gtL+Kc31dusYnKj16ZaEjpCEw +HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEEBQADgYEAMIDZLdOLFiPyS1bh +Ch4eUYHT+K1WG93skbga3kVYg3GSe+gctwkKwKK13bwfi8zc7wwz6MtmQwEYhppc +pKKKEwi5QirBCP54rihLCvRQaj6ZqUJ6VP+zPAqHYMDbzlBbHtVF/1lQUP30I6SV +Fu987DvLmZ2GuQA9FKJsnlD9pbU= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,4CD10EAA24AF8C25 + +6pTRc9jsn6CJ2EMYhuGX3aWrDThhacnqdtsKIqUzX8Ga7Jz9kq6HseTRlqPkzBfb +rCl+eVIkgugrPbf93375mP/ozY8LkEgD9TRAL1uXqha2N6TRLC2ozQJQSoIc441e +UZ9XkB6tPGRfPNvi1xE0WTP7bjOUkvkPU9wM9QFuBW6B7mRf3tG2nqkFiTpY6nz8 +5X5+h9jafcCvMwYhfJm0JFTGWmX4WJWubs8QeYndvIriDDw2zpVNcno45sClSQCb +YVekMLgGlKPmNGub5iRfXsozykE3jbMnXRokxrvzk20jjo0XYPVGfCRe9IhJh8Ud +iCG/kPaJspbUkUlKXfvIOdp2pnoDFZI5hbfc75YrFYJ8x8dwRYBUl6yRtBkw5Yo/ +VQDuNq3d7YpxiGxVTwFox6HQ5+rs6jwSGzOilgOCxPSs41fYcdAlogNqLzjvhn+e +0GU1XTVyMJbO0Ae6Sgm4PmxU7QM2bdzESuZWbYRFbH2ywwmoR8SahB3ICBhuIA/l +lsCrBbq+jL/K2IL1VXBKuaKBN1ShKUPZD/ABWNv4uENNg2AFq1XQ6kvTU8Glfhd9 +tyK8YnJ0ViY4VLGhdf0s2eEPmbfxOv0HCW0sz/57eASoQSTJTdVApYopWHBOwaNq +8qQUEPDMTKaPNqCjA2m/NwGrLPHhU0d5dHmp+9gTbCTmWy4sVenhBPbOy6wvFpNA +F+35tJVaZQOOurm/KC2dLOYkKyAvqnB7D2q4zducpWkiyCweg7uYL14Mo5JQmGuq +2DwfRiMxdqqoqHFKEOxsoAMrKSwJlYojUknfz/LEaqxtMePQtNwhjw== +-----END RSA PRIVATE KEY----- + + +6. CLR issued by subca CRL issuer +-----BEGIN X509 CRL----- +MIIBLTCBlwIBATANBgkqhkiG9w0BAQQFADAxMQswCQYDVQQGEwJVUzEQMA4GA1UE +ChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMRcNMDkwNjI4MTMzMjQzWhcNMjgw +ODI3MTMzMjQzWjAiMCACAQQXDTA5MDYyODEzMzIzOFowDDAKBgNVHRUEAwoBBKAO +MAwwCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQEEBQADgYEACQZEf6ydb3fKTMPJ8DBO +oo630MsrT3P0x0AC4+aQOueCBaGpNqW/H379uZxXAad7yr+aXUBwaeBMYVKUbwOe +5TrN5QWPe2eCkU+MSQvh1SHASDDMH4jhWFMRdO3aPMDKKPlO/Q3s0G72eD7Zo5dr +N9AvUXxGxU4DruoJuFPcrCI= +-----END X509 CRL----- + + +7. dumca certificate and key +-----BEGIN CERTIFICATE----- +MIICUDCCAbmgAwIBAgIBBTANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA2MjgxMzMyMjhaFw0yOTAzMTUxMzMyMjha +MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz +cy1EMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDeWn+ulgls9+dK3KzzfC1b +a9RMSf+gjv/Olw5386Vw6pJOVngR11RytWJoLiKbjYPyGhP1cms2FoUKuAEO31gD +3AoUCa+nXgaMLiDtmdC5ATqVv3Oap5aNgAqq0mxMxOylKgcUhfuH2icEnfBtHzEe +ST11S69zQr5GGfa/XslbDQIDAQABo4GJMIGGMB0GA1UdDgQWBBRCmXIsp4G3iP7Z +Qv4gS19W8W/cLzBHBgNVHSMEQDA+gBSQ52Dpau+gtL+Kc31dusYnKj16ZaEjpCEw +HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEEBQADgYEAkRiLpJesXyNQ34ZP +Oc4d0gvCl4pyNHx5gsV0yHtxP7oYoIa7Bw4setplQ9Y2YcH5xuXK84xvAby9csWp +cod1QOkFzZfb9qj10PXfD8bMoLOyrZfr5nsNAl2scvOtnM1TFL/ll5/S2PVcPthx +Z5t128UNQYMu93OmVjZANL5L6Jw= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,11485599004D2482 + +R+TgUoQo1Ksqpnwh1B1x3u7jxd1qJsfG5st7WJaeJzSY3v+ZnmTS4O008eKgw6Z1 +eGJevsNW8Z8ButjChzlesCm+90jpKpOqA6MlvzeknAxtGdEfe8rUEytfNOorjJTy +1Mu9T8Tlk6tmmmXNTDX1lQytYaHA4e4VVEbYGNceMNcPonT1Y0SyebJwtfd4XKkG +Ty40kMnb+qrFr1ZxVRG+LWKDR/bS0S2K2zY6Ha45d8yoYZlgLZ7yVAlrp0T0PF4B +UWvSyNK9VOBLrvqXSofK5gNGkR/C63x8FU2V25ISicBQBXLNo9OgIsbrryHF330T +2TxhnOpFU1AwgTSfp4Fy/Htkvgo7/jmFRa3r4xelTdEUKvRrwaZeMjg0fT+24529 +8o8MMOF0YWNtIDNUVRFg9/DgAsD/LoXbOGc/E2ryJdq1D4N914s4m/D5Sox27iu4 +3op/dt+WMoA0g/YbjhWn2cAfWcH9P8p8/n/FUO8APmGI3aHbtOhJQ8qwxcalp6kO +fICWsW4ygWtdpnyJWzAY0Udtsl8mglTppGTl59OYZmlDQTLhJ1hWiXLeNKj0pGPz +bAJ5jGQN8zXAk83j019rI5WveAdWp+w1XRGvmPxLL3heojHrkutuYLQ0LOcFwNvg +OqmPvZneRBoy6Yshp0XyYy+qioxDm+Vd/NV1/aCWgQXJA3vFqUg3AURLFHHTh+7h +fa3DDCLtdg/wJkRtOWjFhq0hgx5sb9zVv8HCuMERbZJbWwDOfSrHJwXj4KaTHVqY +OWfBE9vzeAxRpdpe69SZWYg3tyu7uSf6a5Rp55iMI3kjuQMCanvsNA== +-----END RSA PRIVATE KEY----- + + +8. crl issuer for dumca, the certificate and key +-----BEGIN CERTIFICATE----- +MIICUDCCAbmgAwIBAgIBBjANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA2MjgxMzMyMjlaFw0yOTAzMTUxMzMyMjla +MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz +cy1EMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDF7NjUUWji4pPmFg3qx4HB +kjtInwe7i2lPjRUN0ZwTcWob2RaD1+fhc7seeNmnypjERTa9TXF5cs2PgSHWNISC +QbQpbobOUcSsV/6Lr0kvrHJuVowcX13VsApGSJavVs2oJqUiFGNpnch8yR/pMHJf +hsd/Go+nUXMOl2xN31DMFQIDAQABo4GJMIGGMB0GA1UdDgQWBBS1XVE2CYKHgO7t +1koYVTu2w7xgNTBHBgNVHSMEQDA+gBSQ52Dpau+gtL+Kc31dusYnKj16ZaEjpCEw +HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEEBQADgYEAHYraYtdetZFOiTUR +dhvUi556el1WT25O8pF21YAzRI7KI4yzl6deD29DtcIPiBc8H1A4U6OhwXSQsqTd +taOHHdZxnU+m078mb231OPVvo48uZwpnX35g/qItW+Nb/dIEb08537oQKoGgL0hV +sKZPWod70JBkJabDuUirorhlk4A= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,1E0E5983F90A10E0 + +KdPTRmJjeKXFTgdVIgP0eu+m0evwVD2QFMkT3pPI9HELRxtkgIQzjK8F0KIHK9vi +Ur0CMgJkX0zs2v7HIG7jvfQ2fREidRTk1g3xCjHXVbpwjWN2dbo+mR0J2zzxNILy +mSs13PlDPdV81Vkn1WkMY0lhdrEpR6senQ4KIiMJTMsWZabG3lyFM6d7ag7CDVC+ +jnsUFg2XW5dYP/kb09p14+CdiQwruNVeVEWhWPG1pAjl7hXCEM5ssz9fNk6Gyh2X +OXB2mMysqTkt+qB+OIqLKj3NTUs2ovVQZnaCaynsnMYTcIEFmv3lC0gJHYAZtBXf +IkySb+VaB7wmk1CI1+texDU8+B2sq7wmqX0SLY7dMwkbxP1kydn9U5i4Gqmdxpw5 +4+jn7dB6oKfVFlXIZTZzhmN44cIdai48qVmse1BRDxUdfmlgd9C2W1mw4N60BXbt +DeNr8ua5UtcUOXBGJk6VEJapDU/dnnANhVR4R48Y9t+g1qlhwHB4zbSrAIJ5Rsbg +6pvdt7BQmFXtm4flZbf21Lr8awWkNFdc/k/3uXA6xemgsFNxPZXlpXO26KpIP+nz +lt9Q82WxIkzE+BvO+qd5wMqQ/GC/ztO8GJeGdRIo6un7KkNKs2AZDoCELo2lO53B +EBWHeABtJpB1Fw3lW3iJn0A6YbYzK1omztoNMkesBIi0QI5L/e0tq4Mp+LUjLm+Y +ywdrofTiYTu8R7mgS1b5q3eFtwUR9MZuKJGvhsBcSfS41vH2hDezYHg8vW55UIE3 +h7EhOUnTkHY43OKZnmXHwh3pTEmHv1TfMpeaktiU/w0= +-----END RSA PRIVATE KEY----- + +9. end entity certificate issued by subca, Alice +-----BEGIN CERTIFICATE----- +MIICNzCCAaCgAwIBAgIBAjANBgkqhkiG9w0BAQQFADAxMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA2MjgxMzMy +MzBaFw0yOTAzMTUxMzMyMzBaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt +cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEA7wnsvR4XEOfVznf40l8ClLod+7L0y2/+smVV+GM/ +T1/QF/stajAJxXNy08gK00WKZ6ruTHhR9vh/Z6+EQM2RZDCpU0A7LPa3kLE/XTmS +1MLDu8ntkdlpURpvhdDWem+rl2HU5oZgzV8Jkcov9vXuSjqEDfr45FlPuV40T8+7 +cxsCAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSBwsAhi6Z1kriOs3ty +uSIujv9a3DAfBgNVHSMEGDAWgBRidC8Dt3dBzYESKpR2tR560sZ0+zANBgkqhkiG +9w0BAQQFAAOBgQDEiBqd5AMy2SQopFaS3dYkzj8MHlwtbCSoNVYkOfDnewcatrbk +yFcp6FX++PMdOQFHWvvnDdkCUAzZQp8kCkF9tGLVLBtOK7XxQ1us1LZym7kOPzsd +G93Dcf0U1JRO77juc61Br5paAy8Bok18Y/MeG7uKgB2MAEJYKhGKbCrfMw== +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,9E29E1901B338431 + +796Bj4/MwwHdy6+yZQcq3pS12EZPlEm7qsCCTl787y+DYEnnj+9W4WX4+1zWsUGV +1+39oe/KOUfi5O9ytMuKiroIrklmkskWHDoW6sr4VcDprnLYL+75AhTfgpOtY+gK +q+++N7P2o9V6YF7PiGxaBqGy/3bt0nTu0sjctfzbo4g0PniiId9sus2Y+iRHKebJ +r9V0b0jB8USuIsZ+4IQJFZ+/zeKuqqqPM/4v5VKNUahER8oykhRd4L9UactnVH5t +dsfowtHmOmKE6ObJX3m+HgJMvauMMf7zJVdqJquU2vy0bUk9ufCrA7t5ws7JDRzd +SG5gt7EVQzd5x/yXsQdKbDew5mXsYPB8vz4moTgj4YJU+m6k0t1PH00pz7LUrDHl +E8ZAmXIKLEBIih1AWkdASR/YZsfB3URIC8mLyDSZJN5iEVJxl/JWm6pbJlP3Xn3J +fraVEXP6uerf29CNhizq520AfGdsSqga6atdx6PXBVm67V0TZ+zmBMUQJrWmJUUC +NFGAac+M58lYX9uwsrO9x/x6GSZvhQQu1kfD1m8DHN3IV5m3uHxsEvhmuHaqFEMJ +uH336HbqWYENXwZfDHZvOU1o2FejsLZ7QmFjB72iAxhVNQt53pCXed2gF/bERGSn +qi0PsYtjyzfEUefqlVRSWVulbQfGwkvl8dX9s6BxmOG1q0BzlDu+cQLYXPS+XOww +H8GgkGp6XTd04qT/qCm8gcuxAvdkYkj2zgAIKaqeJ53S3Ua9lrIKnA3L3btiEG5F +JTYutSdRqB4liukkB1TciiDVSmOisszjrMHhRRYPfgeLfnRFdX9U9g== +-----END RSA PRIVATE KEY----- + +10. end entity certificate issued by subca, Bob +-----BEGIN CERTIFICATE----- +MIICNTCCAZ6gAwIBAgIBAzANBgkqhkiG9w0BAQQFADAxMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA2MjgxMzMy +MzVaFw0yOTAzMTUxMzMyMzVaMD8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt +cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQwwCgYDVQQDEwNCb2IwgZ8wDQYJKoZIhvcN +AQEBBQADgY0AMIGJAoGBALLrxd3DpXuH7yiAoyi/Rc1F7WsyyeNE1Ra2ymHpcee/ +3sbldekcgPl6lGQF/JJ5ARBbfeDtaf6ZtAK3j6aXqxVFxDKKu86r96v74gWJB7Vv +CHcUPvmE/EGESq3VNFI998DbmvqICLC97nFLUIrKWDH1rRFZjjkmouln40UxQXvV +AgMBAAGjTzBNMAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUTXz1J2viNSKvRHIRVhD6 +cJE4lgYwHwYDVR0jBBgwFoAUYnQvA7d3Qc2BEiqUdrUeetLGdPswDQYJKoZIhvcN +AQEEBQADgYEApsKyLf4FbXb26KsQrxgFn/w0d/7ck4cE8a6oXQqi5OLheNSWfD3S +fgD1dR28mGmhBiyOkdLmrhA1+6BuEr4FsuyLgrFnEqKL0ZhVhiqvwKLGqvasWxfU +Edaw4WXvRcfRWXfgjtwB6PSj/3nqGKSGRPif/OFIjO6UqHwEM7JEWO4= +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,4A820975D251613F + +GseD8MIztC0oYMxwpxeBO4/YPs9ZFFjgncXXcy+1oYZdlEsrS1xw87unjeHigL8m +QPIn8Guv3DiOsBdvweuMAgPPaA1zlophPClbGZMk7BB3T2acEfjBQH1DZz7kd7Bf +OmI2DrqcEg1yDi7l7YutBuTQPiy3nj3d7pbScuFd5YVMu6yH0YpS7JsPvviabFk2 +eYVlkaiejtQwV+4rUb7sH/0iyqX2uqvnpnGAwVzGp+tfSOl71SByz240nOODBRgY +3Uvxkrw6XhCBAayJE0t7rkPMEe1KgZaGO2IU2jsJJbyHVjvNPSugdbsT28prZHN1 +5M1J1NSOssq/kAq6S3f9sC5j7OzP7oUlx8uMUUSaz09/Ttq22tUoqmTue2IqqxAt +lDaeR8duHP5VV1wWnDsW/XaVYlBFQ4eFPJcXqmWsNAkDQVJp327GrcT6ngevP8fD +BcIxyX6J0rETPruAE+1+PAGjqy+C+oB0ssyZvKcjzdajHcNxSlRpCuOO2ekDvNPO +h+mVukNpHCEBsh3jYmk3z9i7VPLCM0BI+vheJ1TbM+homWP6bXyTQxtLfaKzXZJH +jRJ+zGTMBNJoPVKkou03uXFpT6hdWr9nYwbMT6G9hmC0If3wEl8nRjDKbmyMS29B +p3im1kPxVJA0DjhghC+7tACy42ffw6KZPALwaVDKHGeitrQBc3xTGfrjOGQOTTcm +hZ8icYCY0cjl5KQ2kq2GpXa2zQMujNV/Oj7D4sE0xcASMRXl3tst77R/j0eowx1M +niCTRphxx4iTPkieIbjWWeFTpVmSzUBrm4hSw3tiRapVWf6Zo3aAIg== +-----END RSA PRIVATE KEY----- + +11. end entity certificate issued by subca, Susan +-----BEGIN CERTIFICATE----- +MIICNzCCAaCgAwIBAgIBBDANBgkqhkiG9w0BAQQFADAxMQswCQYDVQQGEwJVUzEQ +MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA2MjgxMzMy +MzZaFw0yOTAzMTUxMzMyMzZaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt +cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVTdXNhbjCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEAr2u6mdjqAVtfcgPze+9OUFZu3pi+HqoNBoygm2gq +qRAe+FVNSUeNAMQesQBo/eB0F1Iv/BjnYJ/7pYMLaf90MLoYr0Q5vNKYlBdcyUee +Jn1WmfN2Qk+UoUaiM4HAKHNJnZk13vWpZW54mcW1q09oj0oMjAZtaZsqpY6CtW6/ ++J8CAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBQVK9naug5W9pQlBqD2 +fVaCXooa1TAfBgNVHSMEGDAWgBRidC8Dt3dBzYESKpR2tR560sZ0+zANBgkqhkiG +9w0BAQQFAAOBgQDKYoM8EbP78ucjtsdvw4ywyo21hhSeP9PmRnNz/U3F9sQATmn+ +QBl6sBsrmbML2yrhkM1ctZTVUVp0S72fAbLgVjNk86p/CF+a2tmi0+lJh1aR7zQi +opt+68Nec2/52kgWi64ruF7YITmGHBxS/RDooFbscZbdrPgcow/Jw+5HnQ== +-----END CERTIFICATE----- + +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,9025CDB2AB43B0DE + +q4hvYnqkhDSDCsbXfxtMjPvzT38ql5wscOsGwDM/xMANSyPk9h/aqAxvB8G+8v6E +63x9Q5jRi2YY6z2sOpvu0utu7Xn6KA/H1YrpYFURTEjBbK2Qd41vPQ/NYcIO3nQd +PR2Qm3kpNumBSZomyNfJk9oegGxfw+P0af2GIb6YqmTDot+LLCLwpqxrGyQQ1LYp +zc4A9D/b19Y0eD+TU9S2KEYszvfUo7RBxRFSZ6QN1rT2SEa7IJN9wb6TvgeB2lRB +Ds90tmLtkbuwLTZre+aqbM8mU40+RI9GHh+mPw0Qz55Kw2CUe+PnGsLQnOTm7p/I +mLiPTNMJKvwaR18Z88IE9UwL0zE/ND7vZfrhqTn9bHRnzHU4NtBCBsS8zloI+rXZ +EIWKMDyzMH3wpbNYq/AemSvvUz1wGOxit5TjG2QwwCNt8hPLl0Es6Q5aWdAPPrLM +EfX/6gL7bLTHNyLPz/U32o0H4hz5J7FQ7SuYUPLI3ybiPC2qL11jbtrZMesAYEAX +mvRnqO+6dPEpwGmKz8kUj2mC8X8FPKCCiy4kbc8NjLTMao+/vOgD+wBuIePaC3yE +vpuZrsUSFZWRJ824sDMmmZFoi2DKsp1zqCV1kXozaPGigaOxtkdp890nBcGkPijQ +8F+jCGwSFda6UfuJHCQ/eJB+8LQUWa8u1TeJ9zo98oD2OBfQ5maZU0Vfv1EXvwbp +pz2R6HXFaPrQDeGO0xVzD453AbY/fZCGnhIwrEYvPAbwpIKde397MP66gYFMNFhA +IaMimFnBv7IHL08Ka0KtqbVhLpEKWFpZ6LsOnyispeB4KF0md+lpGg== +-----END RSA PRIVATE KEY----- diff --git a/jdk/test/java/security/cert/CertPathBuilder/selfIssued/StatusLoopDependency.java b/jdk/test/java/security/cert/CertPathBuilder/selfIssued/StatusLoopDependency.java new file mode 100644 index 00000000000..ed0cf53ace1 --- /dev/null +++ b/jdk/test/java/security/cert/CertPathBuilder/selfIssued/StatusLoopDependency.java @@ -0,0 +1,309 @@ +/* + * 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 6852744 + * @summary PIT b61: PKI test suite fails because self signed certificates + * are being rejected + * @run main/othervm StatusLoopDependency subca + * @run main/othervm StatusLoopDependency subci + * @run main/othervm StatusLoopDependency alice + * @author Xuelei Fan + */ + +import java.io.*; +import java.net.SocketException; +import java.util.*; +import java.security.Security; +import java.security.cert.*; +import java.security.cert.CertPathValidatorException.BasicReason; +import sun.security.util.DerInputStream; + +/** + * KeyUsage extension plays a important rule during looking for the issuer + * of a certificate or CRL. A certificate issuer should have the keyCertSign + * bit set, and a CRL issuer should have the cRLSign bit set. + * + * Sometime, a delegated CRL issuer would also have the keyCertSign bit set, + * as would be troublesome to find the proper CRL issuer during certificate + * path build if the delegated CRL issuer is a self-issued certificate, for + * it is hard to identify it from its issuer by the "issuer" field only. + * + * In the test case, the delegated CRL issuers have keyCertSign bit set, and + * the CAs have the cRLSign bit set also. If we cannot identify the delegated + * CRL issuer from its issuer, there is a potential loop to find the correct + * CRL. + * + * And when revocation enabled, needs to check the status of the delegated + * CRL issuers. If the delegated CRL issuer issues itself status, there is + * a potential loop to verify the CRL and check the status of delegated CRL + * issuer. + * + * The fix of 6852744 should addresses above issues. + */ +public final class StatusLoopDependency { + + // the trust anchor + static String selfSignedCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICPjCCAaegAwIBAgIBADANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA2MjgxMzMyMThaFw0zMDA2MDgxMzMyMTha\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB\n" + + "AQUAA4GNADCBiQKBgQDInJhXi0655bPXAVkz1n5I6fAcZejzPnOPuwq3hU3OxFw8\n" + + "81Uf6o9oKI1h4w4XAD8u1cUNOgiX+wPwojronlp68bIfO6FVhNf287pLtLhNJo+7\n" + + "m6Qxw3ymFvEKy+PVj20CHSggdKHxUa4MBZBmHMFNBuxfYmjwzn+yTMmCCXOvSwID\n" + + "AQABo4GJMIGGMB0GA1UdDgQWBBSQ52Dpau+gtL+Kc31dusYnKj16ZTBHBgNVHSME\n" + + "QDA+gBSQ52Dpau+gtL+Kc31dusYnKj16ZaEjpCEwHzELMAkGA1UEBhMCVVMxEDAO\n" + + "BgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYw\n" + + "DQYJKoZIhvcNAQEEBQADgYEAjBt6ea65HCqbGsS2rs/HhlGusYXtThRVC5vwXSey\n" + + "ZFYwSgukuq1KDzckqZFu1meNImEwdZjwxdN0e2p/nVREPC42rZliSj6V1ThayKXj\n" + + "DWEZW1U5aR8T+3NYfDrdKcJGx4Hzfz0qKz1j4ssV1M9ptJxYYv4y2Da+592IN1S9\n" + + "v/E=\n" + + "-----END CERTIFICATE-----"; + + // the sub-ca + static String subCaCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICUDCCAbmgAwIBAgIBAzANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA2MjgxMzMyMjRaFw0yOTAzMTUxMzMyMjRa\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPFv24SK78VI0gWlyIrq/X\n" + + "srl1431K5hJJxMYZtaQunyPmrYg3oI9KvKFykxnR0N4XDPaIi75p9dXGppVu80BA\n" + + "+csvIPBwlBQoNmKDQWTziDOqfK4tE+IMuL/Y7pxnH6CDMY7VGpvatty2zcmH+m/v\n" + + "E/n+HPyeELJQT2rT/3T+7wIDAQABo4GJMIGGMB0GA1UdDgQWBBRidC8Dt3dBzYES\n" + + "KpR2tR560sZ0+zBHBgNVHSMEQDA+gBSQ52Dpau+gtL+Kc31dusYnKj16ZaEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEEBQADgYEAMeMKqrMr5d3eTQsv\n" + + "MYOD15Dl3THQGLAa4ad5Eyq5/1eUeEOpztzCgDfi0iPD8YCubIEVasBTSqTiGXqb\n" + + "RpGuPHOwwfWvHrTeHSludiFBAUiKj7aEV+oQa0FBn4U4TT8HA62HQ93FhzTDI3jP\n" + + "iil34GktVl6gfMKGzUEW/Dh8OM4=\n" + + "-----END CERTIFICATE-----"; + + // a delegated CRL issuer, it's a self-issued certificate of trust anchor + static String topCrlIssuerCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICPjCCAaegAwIBAgIBAjANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA2MjgxMzMyMjNaFw0yOTAzMTUxMzMyMjNa\n" + + "MB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMIGfMA0GCSqGSIb3DQEB\n" + + "AQUAA4GNADCBiQKBgQC99u93trf+WmpfiqunJy/P31ej1l4rESxft2JSGNjKuLFN\n" + + "/BO3SAugGJSkCARAwXjB0c8eeXhXWhVVWdNpbKepRJTxrjDfnFIavLgtUvmFwn/3\n" + + "hPXe+RQeA8+AJ99Y+o+10kY8JAZLa2j93C2FdmwOjUbo8aIz85yhbiV1tEDjLwID\n" + + "AQABo4GJMIGGMB0GA1UdDgQWBBSyFyA3XWLbdL6W6hksmBn7RKsQmDBHBgNVHSME\n" + + "QDA+gBSQ52Dpau+gtL+Kc31dusYnKj16ZaEjpCEwHzELMAkGA1UEBhMCVVMxEDAO\n" + + "BgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYw\n" + + "DQYJKoZIhvcNAQEEBQADgYEAHTm8aRTeakgCfEBCgSWK9wvMW1c18ANGMm8OFDBk\n" + + "xabVy9BT0MVFHlaneh89oIxTZN0FMTpg21GZMAvIzhEt7DGdO7HLsW7JniN7/OZ0\n" + + "rACmpK5frmZrLS03zUm8c+rTbazNfYLoZVG3/mDZbKIi+4y8IGnFcgLVsHsYoBNP\n" + + "G0c=\n" + + "-----END CERTIFICATE-----"; + + // a delegated CRL issuer, it's a self-issued certificate of sub-ca + static String subCrlIssuerCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICUDCCAbmgAwIBAgIBBDANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTAeFw0wOTA2MjgxMzMyMjdaFw0yOTAzMTUxMzMyMjda\n" + + "MDExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFtcGxlMRAwDgYDVQQLEwdDbGFz\n" + + "cy0xMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+8AcLJtGAVUWvv3ifcyQw\n" + + "OGqwzcPrBw/XCs6vTMlcdtFzcH1M+Z3/QHN9+5VT1gqeTIZ+b8g9005Og3XKy/HX\n" + + "obXZeLv20VZsr+jm52ySghEYOVCTJ9OyFOAp5adp6nf0cA66Feh3LsmVhpTEcDOG\n" + + "GnyntQm0DBYxRoOT/GBlvQIDAQABo4GJMIGGMB0GA1UdDgQWBBSRWhMuZLQoHSDN\n" + + "xhxr+vdDmfAY8jBHBgNVHSMEQDA+gBSQ52Dpau+gtL+Kc31dusYnKj16ZaEjpCEw\n" + + "HzELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0V4YW1wbGWCAQAwDwYDVR0TAQH/BAUw\n" + + "AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEEBQADgYEAMIDZLdOLFiPyS1bh\n" + + "Ch4eUYHT+K1WG93skbga3kVYg3GSe+gctwkKwKK13bwfi8zc7wwz6MtmQwEYhppc\n" + + "pKKKEwi5QirBCP54rihLCvRQaj6ZqUJ6VP+zPAqHYMDbzlBbHtVF/1lQUP30I6SV\n" + + "Fu987DvLmZ2GuQA9FKJsnlD9pbU=\n" + + "-----END CERTIFICATE-----"; + + // the target EE certificate + static String targetCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIICNzCCAaCgAwIBAgIBAjANBgkqhkiG9w0BAQQFADAxMQswCQYDVQQGEwJVUzEQ\n" + + "MA4GA1UEChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMTAeFw0wOTA2MjgxMzMy\n" + + "MzBaFw0yOTAzMTUxMzMyMzBaMEExCzAJBgNVBAYTAlVTMRAwDgYDVQQKEwdFeGFt\n" + + "cGxlMRAwDgYDVQQLEwdDbGFzcy0xMQ4wDAYDVQQDEwVBbGljZTCBnzANBgkqhkiG\n" + + "9w0BAQEFAAOBjQAwgYkCgYEA7wnsvR4XEOfVznf40l8ClLod+7L0y2/+smVV+GM/\n" + + "T1/QF/stajAJxXNy08gK00WKZ6ruTHhR9vh/Z6+EQM2RZDCpU0A7LPa3kLE/XTmS\n" + + "1MLDu8ntkdlpURpvhdDWem+rl2HU5oZgzV8Jkcov9vXuSjqEDfr45FlPuV40T8+7\n" + + "cxsCAwEAAaNPME0wCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBSBwsAhi6Z1kriOs3ty\n" + + "uSIujv9a3DAfBgNVHSMEGDAWgBRidC8Dt3dBzYESKpR2tR560sZ0+zANBgkqhkiG\n" + + "9w0BAQQFAAOBgQDEiBqd5AMy2SQopFaS3dYkzj8MHlwtbCSoNVYkOfDnewcatrbk\n" + + "yFcp6FX++PMdOQFHWvvnDdkCUAzZQp8kCkF9tGLVLBtOK7XxQ1us1LZym7kOPzsd\n" + + "G93Dcf0U1JRO77juc61Br5paAy8Bok18Y/MeG7uKgB2MAEJYKhGKbCrfMw==\n" + + "-----END CERTIFICATE-----"; + + // CRL issued by the delegated CRL issuer, topCrlIssuerCertStr + static String topCrlStr = + "-----BEGIN X509 CRL-----\n" + + "MIIBGzCBhQIBATANBgkqhkiG9w0BAQQFADAfMQswCQYDVQQGEwJVUzEQMA4GA1UE\n" + + "ChMHRXhhbXBsZRcNMDkwNjI4MTMzMjM4WhcNMjgwODI3MTMzMjM4WjAiMCACAQUX\n" + + "DTA5MDYyODEzMzIzN1owDDAKBgNVHRUEAwoBBKAOMAwwCgYDVR0UBAMCAQEwDQYJ\n" + + "KoZIhvcNAQEEBQADgYEAVUIeu2x7ZwsliafoCBOg+u8Q4S/VFfTe/SQnRyTM3/V1\n" + + "v+Vn5Acc7eo8Rh4AHcnFFbLNk38n6lllov/CaVR0IPZ6hnrNHVa7VYkNlRAwV2aN\n" + + "GUUhkMMOLVLnN25UOrN9J637SHmRE6pB+TRMaEQ73V7UNlWxuSMK4KofWen0A34=\n" + + "-----END X509 CRL-----"; + + // CRL issued by the delegated CRL issuer, subCrlIssuerCertStr + static String subCrlStr = + "-----BEGIN X509 CRL-----\n" + + "MIIBLTCBlwIBATANBgkqhkiG9w0BAQQFADAxMQswCQYDVQQGEwJVUzEQMA4GA1UE\n" + + "ChMHRXhhbXBsZTEQMA4GA1UECxMHQ2xhc3MtMRcNMDkwNjI4MTMzMjQzWhcNMjgw\n" + + "ODI3MTMzMjQzWjAiMCACAQQXDTA5MDYyODEzMzIzOFowDDAKBgNVHRUEAwoBBKAO\n" + + "MAwwCgYDVR0UBAMCAQEwDQYJKoZIhvcNAQEEBQADgYEACQZEf6ydb3fKTMPJ8DBO\n" + + "oo630MsrT3P0x0AC4+aQOueCBaGpNqW/H379uZxXAad7yr+aXUBwaeBMYVKUbwOe\n" + + "5TrN5QWPe2eCkU+MSQvh1SHASDDMH4jhWFMRdO3aPMDKKPlO/Q3s0G72eD7Zo5dr\n" + + "N9AvUXxGxU4DruoJuFPcrCI=\n" + + "-----END X509 CRL-----"; + + private static Set generateTrustAnchors() + throws CertificateException { + // generate certificate from cert string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + ByteArrayInputStream is = + new ByteArrayInputStream(selfSignedCertStr.getBytes()); + Certificate selfSignedCert = cf.generateCertificate(is); + + // generate a trust anchor + TrustAnchor anchor = + new TrustAnchor((X509Certificate)selfSignedCert, null); + + return Collections.singleton(anchor); + } + + private static CertStore generateCertificateStore() throws Exception { + Collection entries = new HashSet(); + + // generate certificate from certificate string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + + ByteArrayInputStream is; + + is = new ByteArrayInputStream(targetCertStr.getBytes()); + Certificate cert = cf.generateCertificate(is); + entries.add(cert); + + is = new ByteArrayInputStream(subCaCertStr.getBytes()); + cert = cf.generateCertificate(is); + entries.add(cert); + + is = new ByteArrayInputStream(selfSignedCertStr.getBytes()); + cert = cf.generateCertificate(is); + entries.add(cert); + + is = new ByteArrayInputStream(topCrlIssuerCertStr.getBytes()); + cert = cf.generateCertificate(is); + entries.add(cert); + + is = new ByteArrayInputStream(subCrlIssuerCertStr.getBytes()); + cert = cf.generateCertificate(is); + entries.add(cert); + + // generate CRL from CRL string + is = new ByteArrayInputStream(topCrlStr.getBytes()); + Collection mixes = cf.generateCRLs(is); + entries.addAll(mixes); + + is = new ByteArrayInputStream(subCrlStr.getBytes()); + mixes = cf.generateCRLs(is); + entries.addAll(mixes); + + return CertStore.getInstance("Collection", + new CollectionCertStoreParameters(entries)); + } + + private static X509CertSelector generateSelector(String name) + throws Exception { + X509CertSelector selector = new X509CertSelector(); + + // generate certificate from certificate string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + ByteArrayInputStream is = null; + if (name.equals("subca")) { + is = new ByteArrayInputStream(subCaCertStr.getBytes()); + } else if (name.equals("subci")) { + is = new ByteArrayInputStream(subCrlIssuerCertStr.getBytes()); + } else { + is = new ByteArrayInputStream(targetCertStr.getBytes()); + } + + X509Certificate target = (X509Certificate)cf.generateCertificate(is); + byte[] extVal = target.getExtensionValue("2.5.29.14"); + if (extVal != null) { + DerInputStream in = new DerInputStream(extVal); + byte[] subjectKID = in.getOctetString(); + selector.setSubjectKeyIdentifier(subjectKID); + } else { + // unlikely to happen. + throw new Exception("unexpected certificate: no SKID extension"); + } + + return selector; + } + + private static boolean match(String name, Certificate cert) + throws Exception { + X509CertSelector selector = new X509CertSelector(); + + // generate certificate from certificate string + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + ByteArrayInputStream is = null; + if (name.equals("subca")) { + is = new ByteArrayInputStream(subCaCertStr.getBytes()); + } else if (name.equals("subci")) { + is = new ByteArrayInputStream(subCrlIssuerCertStr.getBytes()); + } else { + is = new ByteArrayInputStream(targetCertStr.getBytes()); + } + X509Certificate target = (X509Certificate)cf.generateCertificate(is); + + return target.equals(cert); + } + + + public static void main(String[] args) throws Exception { + CertPathBuilder builder = CertPathBuilder.getInstance("PKIX"); + + X509CertSelector selector = generateSelector(args[0]); + + Set anchors = generateTrustAnchors(); + CertStore certs = generateCertificateStore(); + + + PKIXBuilderParameters params = + new PKIXBuilderParameters(anchors, selector); + params.addCertStore(certs); + params.setRevocationEnabled(true); + params.setDate(new Date(109, 7, 1)); // 2009-07-01 + Security.setProperty("ocsp.enable", "false"); + System.setProperty("com.sun.security.enableCRLDP", "true"); + + PKIXCertPathBuilderResult result = + (PKIXCertPathBuilderResult)builder.build(params); + + if (!match(args[0], result.getCertPath().getCertificates().get(0))) { + throw new Exception("unexpected certificate"); + } + } +} diff --git a/jdk/test/java/security/cert/CertPathBuilder/selfIssued/generate.sh b/jdk/test/java/security/cert/CertPathBuilder/selfIssued/generate.sh new file mode 100644 index 00000000000..06429d63ffa --- /dev/null +++ b/jdk/test/java/security/cert/CertPathBuilder/selfIssued/generate.sh @@ -0,0 +1,221 @@ +# +# 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. +# + +#!/bin/ksh +# +# needs ksh to run the script. + +# generate a self-signed root certificate +if [ ! -f root/root_cert.pem ]; then + if [ ! -d root ]; then + mkdir root + fi + + openssl req -x509 -newkey rsa:1024 -keyout root/root_key.pem \ + -out root/root_cert.pem -subj "/C=US/O=Example" \ + -config openssl.cnf -reqexts cert_issuer -days 7650 \ + -passin pass:passphrase -passout pass:passphrase +fi + +# generate a sele-issued root crl issuer certificate +if [ ! -f root/top_crlissuer_cert.pem ]; then + if [ ! -d root ]; then + mkdir root + fi + + openssl req -newkey rsa:1024 -keyout root/top_crlissuer_key.pem \ + -out root/top_crlissuer_req.pem -subj "/C=US/O=Example" -days 7650 \ + -passin pass:passphrase -passout pass:passphrase + + openssl x509 -req -in root/top_crlissuer_req.pem -extfile openssl.cnf \ + -extensions crl_issuer -CA root/root_cert.pem \ + -CAkey root/root_key.pem -out root/top_crlissuer_cert.pem \ + -CAcreateserial -CAserial root/root_cert.srl -days 7200 \ + -passin pass:passphrase +fi + +# generate subca cert issuer and crl iuuser certificates +if [ ! -f subca/subca_cert.pem ]; then + if [ ! -d subca ]; then + mkdir subca + fi + + openssl req -newkey rsa:1024 -keyout subca/subca_key.pem \ + -out subca/subca_req.pem -subj "/C=US/O=Example/OU=Class-1" \ + -days 7650 -passin pass:passphrase -passout pass:passphrase + + openssl x509 -req -in subca/subca_req.pem -extfile openssl.cnf \ + -extensions cert_issuer -CA root/root_cert.pem \ + -CAkey root/root_key.pem -out subca/subca_cert.pem -CAcreateserial \ + -CAserial root/root_cert.srl -days 7200 -passin pass:passphrase + + openssl req -newkey rsa:1024 -keyout subca/subca_crlissuer_key.pem \ + -out subca/subca_crlissuer_req.pem -subj "/C=US/O=Example/OU=Class-1" \ + -days 7650 -passin pass:passphrase -passout pass:passphrase + + openssl x509 -req -in subca/subca_crlissuer_req.pem -extfile openssl.cnf \ + -extensions crl_issuer -CA root/root_cert.pem \ + -CAkey root/root_key.pem -out subca/subca_crlissuer_cert.pem \ + -CAcreateserial -CAserial root/root_cert.srl -days 7200 \ + -passin pass:passphrase +fi + +# generate dumca cert issuer and crl iuuser certificates +if [ ! -f dumca/dumca_cert.pem ]; then + if [ ! -d sumca ]; then + mkdir dumca + fi + + openssl req -newkey rsa:1024 -keyout dumca/dumca_key.pem \ + -out dumca/dumca_req.pem -subj "/C=US/O=Example/OU=Class-D" \ + -days 7650 -passin pass:passphrase -passout pass:passphrase + + openssl x509 -req -in dumca/dumca_req.pem -extfile openssl.cnf \ + -extensions cert_issuer -CA root/root_cert.pem \ + -CAkey root/root_key.pem -out dumca/dumca_cert.pem \ + -CAcreateserial -CAserial root/root_cert.srl -days 7200 \ + -passin pass:passphrase + + openssl req -newkey rsa:1024 -keyout dumca/dumca_crlissuer_key.pem \ + -out dumca/dumca_crlissuer_req.pem -subj "/C=US/O=Example/OU=Class-D" \ + -days 7650 -passin pass:passphrase -passout pass:passphrase + + openssl x509 -req -in dumca/dumca_crlissuer_req.pem \ + -extfile openssl.cnf -extensions crl_issuer -CA root/root_cert.pem \ + -CAkey root/root_key.pem -out dumca/dumca_crlissuer_cert.pem \ + -CAcreateserial -CAserial root/root_cert.srl -days 7200 \ + -passin pass:passphrase +fi + +# generate certifiacte for Alice +if [ ! -f subca/alice/alice_cert.pem ]; then + if [ ! -d subca/alice ]; then + mkdir -p subca/alice + fi + + openssl req -newkey rsa:1024 -keyout subca/alice/alice_key.pem \ + -out subca/alice/alice_req.pem \ + -subj "/C=US/O=Example/OU=Class-1/CN=Alice" -days 7650 \ + -passin pass:passphrase -passout pass:passphrase + + openssl x509 -req -in subca/alice/alice_req.pem \ + -extfile openssl.cnf -extensions ee_of_subca \ + -CA subca/subca_cert.pem -CAkey subca/subca_key.pem \ + -out subca/alice/alice_cert.pem -CAcreateserial \ + -CAserial subca/subca_cert.srl -days 7200 -passin pass:passphrase +fi + +# generate certifiacte for Bob +if [ ! -f subca/bob/bob_cert.pem ]; then + if [ ! -d subca/bob ]; then + mkdir -p subca/bob + fi + + openssl req -newkey rsa:1024 -keyout subca/bob/bob_key.pem \ + -out subca/bob/bob_req.pem \ + -subj "/C=US/O=Example/OU=Class-1/CN=Bob" -days 7650 \ + -passin pass:passphrase -passout pass:passphrase + + openssl x509 -req -in subca/bob/bob_req.pem \ + -extfile openssl.cnf -extensions ee_of_subca \ + -CA subca/subca_cert.pem -CAkey subca/subca_key.pem \ + -out subca/bob/bob_cert.pem -CAcreateserial \ + -CAserial subca/subca_cert.srl -days 7200 -passin pass:passphrase +fi + +# generate certifiacte for Susan +if [ ! -f subca/susan/susan_cert.pem ]; then + if [ ! -d subca/susan ]; then + mkdir -p subca/susan + fi + + openssl req -newkey rsa:1024 -keyout subca/susan/susan_key.pem \ + -out subca/susan/susan_req.pem \ + -subj "/C=US/O=Example/OU=Class-1/CN=Susan" -days 7650 \ + -passin pass:passphrase -passout pass:passphrase + + openssl x509 -req -in subca/susan/susan_req.pem -extfile openssl.cnf \ + -extensions ee_of_subca -CA subca/subca_cert.pem \ + -CAkey subca/subca_key.pem -out subca/susan/susan_cert.pem \ + -CAcreateserial -CAserial subca/subca_cert.srl -days 7200 \ + -passin pass:passphrase +fi + + +# generate the top CRL +if [ ! -f root/top_crl.pem ]; then + if [ ! -d root ]; then + mkdir root + fi + + if [ ! -f root/index.txt ]; then + touch root/index.txt + echo 00 > root/crlnumber + fi + + openssl ca -gencrl -config openssl.cnf -name ca_top -crldays 7000 \ + -crl_reason superseded -keyfile root/top_crlissuer_key.pem \ + -cert root/top_crlissuer_cert.pem -out root/top_crl.pem \ + -passin pass:passphrase +fi + +# revoke dumca +openssl ca -revoke dumca/dumca_cert.pem -config openssl.cnf \ + -name ca_top -crl_reason superseded \ + -keyfile root/top_crlissuer_key.pem -cert root/top_crlissuer_cert.pem \ + -passin pass:passphrase + +openssl ca -gencrl -config openssl.cnf -name ca_top -crldays 7000 \ + -crl_reason superseded -keyfile root/top_crlissuer_key.pem \ + -cert root/top_crlissuer_cert.pem -out root/top_crl.pem \ + -passin pass:passphrase + +# revoke for subca +if [ ! -f subca/subca_crl.pem ]; then + if [ ! -d subca ]; then + mkdir subca + fi + + if [ ! -f subca/index.txt ]; then + touch subca/index.txt + echo 00 > subca/crlnumber + fi + + openssl ca -gencrl -config openssl.cnf -name ca_subca -crldays 7000 \ + -crl_reason superseded -keyfile subca/subca_crlissuer_key.pem \ + -cert subca/subca_crlissuer_cert.pem -out subca/subca_crl.pem \ + -passin pass:passphrase +fi + +# revoke susan +openssl ca -revoke subca/susan/susan_cert.pem -config openssl.cnf \ + -name ca_subca -crl_reason superseded \ + -keyfile subca/subca_crlissuer_key.pem \ + -cert subca/subca_crlissuer_cert.pem -passin pass:passphrase + +openssl ca -gencrl -config openssl.cnf -name ca_subca -crldays 7000 \ + -crl_reason superseded -keyfile subca/subca_crlissuer_key.pem \ + -cert subca/subca_crlissuer_cert.pem -out subca/subca_crl.pem \ + -passin pass:passphrase diff --git a/jdk/test/java/security/cert/CertPathBuilder/selfIssued/openssl.cnf b/jdk/test/java/security/cert/CertPathBuilder/selfIssued/openssl.cnf new file mode 100644 index 00000000000..f9fca998b72 --- /dev/null +++ b/jdk/test/java/security/cert/CertPathBuilder/selfIssued/openssl.cnf @@ -0,0 +1,205 @@ +# +# 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. +# + +# +# OpenSSL configuration file. +# + +HOME = . +RANDFILE = $ENV::HOME/.rnd + +[ ca ] +default_ca = CA_default + +[ CA_default ] +dir = ./top +certs = $dir/certs +crl_dir = $dir/crl +database = $dir/index.txt +unique_subject = no +new_certs_dir = $dir/newcerts +certificate = $dir/cacert.pem +serial = $dir/serial +crlnumber = $dir/crlnumber +crl = $dir/crl.pem +private_key = $dir/private/cakey.pem +RANDFILE = $dir/private/.rand +x509_extensions = v3_ca + +name_opt = ca_default +cert_opt = ca_default + +default_days = 7650 +default_crl_days = 30 +default_md = sha1 +preserve = no + +policy = policy_anything + +[ ca_top ] +dir = ./root +certs = $dir/certs +crl_dir = $dir/crl +database = $dir/index.txt +unique_subject = no +new_certs_dir = $dir/newcerts +certificate = $dir/cacert.pem +serial = $dir/serial +crlnumber = $dir/crlnumber +crl = $dir/crl.pem +private_key = $dir/private/cakey.pem +RANDFILE = $dir/private/.rand + +x509_extensions = v3_ca + +name_opt = ca_default +cert_opt = ca_default + +default_days = 7650 +default_crl_days = 30 +default_md = sha1 +preserve = no + +policy = policy_anything + +[ ca_subca ] +dir = ./subca +certs = $dir/certs +crl_dir = $dir/crl +database = $dir/index.txt +unique_subject = no +new_certs_dir = $dir/newcerts + +certificate = $dir/cacert.pem +serial = $dir/serial +crlnumber = $dir/crlnumber +crl = $dir/crl.pem +private_key = $dir/private/cakey.pem +RANDFILE = $dir/private/.rand + +x509_extensions = usr_cert + +name_opt = ca_default +cert_opt = ca_default + +default_days = 7650 +default_crl_days = 30 +default_md = sha1 +preserve = no + +policy = policy_anything + +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +[ req ] +default_bits = 1024 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca + +string_mask = nombstr + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = NO +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = A-State + +localityName = Locality Name (eg, city) + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = Internet Widgits Pty Ltd + +organizationalUnitName = Organizational Unit Name (eg, section) + +commonName = Common Name (eg, YOUR name) +commonName_max = 64 + +emailAddress = Email Address +emailAddress_max = 64 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 +unstructuredName = An optional company name + +[ usr_cert ] +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer + +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectAltName = email:example@openjdk.net, RID:1.2.3.4:true + +[ v3_ca ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always +basicConstraints = critical,CA:true +keyUsage = keyCertSign, cRLSign + +[ cert_issuer ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always +basicConstraints = critical,CA:true +keyUsage = keyCertSign, cRLSign + +[ crl_issuer ] +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always +basicConstraints = critical,CA:true +keyUsage = keyCertSign, cRLSign + + +[ crl_ext ] +authorityKeyIdentifier = keyid:always,issuer:always + +[ ee_of_subca ] +keyUsage = nonRepudiation, digitalSignature, keyEncipherment, keyAgreement + +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer From 1b9d35f50c366a761ef753f55662bb3d43502d1b Mon Sep 17 00:00:00 2001 From: Matthew Flaschen Date: Sat, 11 Jul 2009 16:43:08 +0100 Subject: [PATCH 13/15] 6562614: Compiler warnings for gettimeofday in Inet4/Inet6AddressImpl.c Add missing header to remove compiler warnings. Reviewed-by: martin --- jdk/src/solaris/native/java/net/Inet4AddressImpl.c | 1 + jdk/src/solaris/native/java/net/Inet6AddressImpl.c | 1 + 2 files changed, 2 insertions(+) diff --git a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c index 9e3cca486db..4e43c9d5a3a 100644 --- a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c +++ b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c @@ -24,6 +24,7 @@ */ #include +#include #include #include #include diff --git a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c index 5ecedbc6c4f..246585abcc3 100644 --- a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c +++ b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c @@ -24,6 +24,7 @@ */ #include +#include #include #include #include From cbb1a71a104f7b0166c211bf2eb10cd305b8771a Mon Sep 17 00:00:00 2001 From: Xue-Lei Andrew Fan Date: Mon, 13 Jul 2009 23:01:03 +0800 Subject: [PATCH 14/15] 6453837: PartialCompositeContext.allEmpty is buggy Reviewed-by: weijun --- .../com/sun/jndi/toolkit/ctx/PartialCompositeContext.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/share/classes/com/sun/jndi/toolkit/ctx/PartialCompositeContext.java b/jdk/src/share/classes/com/sun/jndi/toolkit/ctx/PartialCompositeContext.java index 5e7e0e3adce..c7bfcfaae4c 100644 --- a/jdk/src/share/classes/com/sun/jndi/toolkit/ctx/PartialCompositeContext.java +++ b/jdk/src/share/classes/com/sun/jndi/toolkit/ctx/PartialCompositeContext.java @@ -493,9 +493,9 @@ public abstract class PartialCompositeContext implements Context, Resolver { * Tests whether a name contains a nonempty component. */ protected static boolean allEmpty(Name name) { - Enumeration enum_ = name.getAll(); + Enumeration enum_ = name.getAll(); while (enum_.hasMoreElements()) { - if (!enum_.equals("")) { + if (!enum_.nextElement().isEmpty()) { return false; } } From fa45d4b2e5bfebd0d1b42e29d599cd7b6fe6abb1 Mon Sep 17 00:00:00 2001 From: Valerie Peng Date: Mon, 13 Jul 2009 15:14:17 -0700 Subject: [PATCH 15/15] 6832540: IllegalArgumentException in ClassLoader.definePackage when classes are loaded in parallel Modified to handle race condition for parallel-capable classloaders by re-trying/re-verifying package Reviewed-by: alanb --- .../classes/java/net/URLClassLoader.java | 64 ++++++++++++------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/jdk/src/share/classes/java/net/URLClassLoader.java b/jdk/src/share/classes/java/net/URLClassLoader.java index 601601a5652..22be20b7ecd 100644 --- a/jdk/src/share/classes/java/net/URLClassLoader.java +++ b/jdk/src/share/classes/java/net/URLClassLoader.java @@ -305,6 +305,35 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { } } + /* + * Retrieve the package using the specified package name. + * If non-null, verify the package using the specified code + * source and manifest. + */ + private Package getAndVerifyPackage(String pkgname, + Manifest man, URL url) { + Package pkg = getPackage(pkgname); + if (pkg != null) { + // Package found, so check package sealing. + if (pkg.isSealed()) { + // Verify that code source URL is the same. + if (!pkg.isSealed(url)) { + throw new SecurityException( + "sealing violation: package " + pkgname + " is sealed"); + } + } else { + // Make sure we are not attempting to seal the package + // at this code source URL. + if ((man != null) && isSealed(pkgname, man)) { + throw new SecurityException( + "sealing violation: can't seal package " + pkgname + + ": already loaded"); + } + } + } + return pkg; + } + /* * Defines a Class using the class bytes obtained from the specified * Resource. The resulting Class must be resolved before it can be @@ -316,32 +345,23 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { if (i != -1) { String pkgname = name.substring(0, i); // Check if package already loaded. - Package pkg = getPackage(pkgname); Manifest man = res.getManifest(); - if (pkg != null) { - // Package found, so check package sealing. - if (pkg.isSealed()) { - // Verify that code source URL is the same. - if (!pkg.isSealed(url)) { - throw new SecurityException( - "sealing violation: package " + pkgname + " is sealed"); + if (getAndVerifyPackage(pkgname, man, url) == null) { + try { + if (man != null) { + definePackage(pkgname, man, url); + } else { + definePackage(pkgname, null, null, null, null, null, null, null); } - - } else { - // Make sure we are not attempting to seal the package - // at this code source URL. - if ((man != null) && isSealed(pkgname, man)) { - throw new SecurityException( - "sealing violation: can't seal package " + pkgname + - ": already loaded"); + } catch (IllegalArgumentException iae) { + // parallel-capable class loaders: re-verify in case of a + // race condition + if (getAndVerifyPackage(pkgname, man, url) == null) { + // Should never happen + throw new AssertionError("Cannot find package " + + pkgname); } } - } else { - if (man != null) { - definePackage(pkgname, man, url); - } else { - definePackage(pkgname, null, null, null, null, null, null, null); - } } } // Now read the class bytes and define the class