6798714: OCSPResponse class has to check the validity of signing certificate for OCSP response
Summary: checking validity and ocsp-nocheck extension.
Reviewed-by: mullan, vinnie
--- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java Fri Mar 13 09:21:13 2009 +0800
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java Fri Mar 13 12:59:25 2009 +0800
@@ -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
@@ -28,8 +28,6 @@
import java.io.*;
import java.math.BigInteger;
import java.security.*;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateFactory;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CRLReason;
import java.security.cert.X509Certificate;
@@ -335,7 +333,7 @@
// Check whether the cert returned by the responder is trusted
if (x509Certs != null && x509Certs[0] != null) {
- X509Certificate cert = x509Certs[0];
+ X509CertImpl cert = x509Certs[0];
// First check if the cert matches the responder cert which
// was set locally.
@@ -344,8 +342,8 @@
// Next check if the cert was issued by the responder cert
// which was set locally.
- } else if (cert.getIssuerDN().equals(
- responderCert.getSubjectDN())) {
+ } else if (cert.getIssuerX500Principal().equals(
+ responderCert.getSubjectX500Principal())) {
// Check for the OCSPSigning key purpose
List<String> keyPurposes = cert.getExtendedKeyUsage();
@@ -360,6 +358,43 @@
"OCSP responses");
}
+ // check the validity
+ try {
+ Date dateCheckedAgainst = params.getDate();
+ if (dateCheckedAgainst == null) {
+ cert.checkValidity();
+ } else {
+ cert.checkValidity(dateCheckedAgainst);
+ }
+ } catch (GeneralSecurityException e) {
+ if (DEBUG != null) {
+ DEBUG.println("Responder's certificate is not " +
+ "within the validity period.");
+ }
+ throw new CertPathValidatorException(
+ "Responder's certificate not within the " +
+ "validity period");
+ }
+
+ // check for revocation
+ //
+ // A CA may specify that an OCSP client can trust a
+ // responder for the lifetime of the responder's
+ // certificate. The CA does so by including the
+ // extension id-pkix-ocsp-nocheck.
+ //
+ Extension noCheck =
+ cert.getExtension(PKIXExtensions.OCSPNoCheck_Id);
+ if (noCheck != null) {
+ if (DEBUG != null) {
+ DEBUG.println("Responder's certificate includes " +
+ "the extension id-pkix-ocsp-nocheck.");
+ }
+ } else {
+ // we should do the revocating checking of the
+ // authorized responder in a future update.
+ }
+
// verify the signature
try {
cert.verify(responderCert.getPublicKey());
@@ -369,6 +404,14 @@
} catch (GeneralSecurityException e) {
responderCert = null;
}
+ } else {
+ if (DEBUG != null) {
+ DEBUG.println("Responder's certificate is not " +
+ "authorized to sign OCSP responses.");
+ }
+ throw new CertPathValidatorException(
+ "Responder's certificate not authorized to sign " +
+ "OCSP responses");
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/security/x509/OCSPNoCheckExtension.java Fri Mar 13 12:59:25 2009 +0800
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.security.x509;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Enumeration;
+
+import sun.security.util.*;
+
+/**
+ * Represent the OCSP NoCheck Extension from RFC2560.
+ * <p>
+ * A CA may specify that an OCSP client can trust a responder for the
+ * lifetime of the responder's certificate. The CA does so by including
+ * the extension id-pkix-ocsp-nocheck. This SHOULD be a non-critical
+ * extension. The value of the extension should be NULL. CAs issuing
+ * such a certificate should realized that a compromise of the
+ * responder's key, is as serious as the compromise of a CA key used to
+ * sign CRLs, at least for the validity period of this certificate. CA's
+ * may choose to issue this type of certificate with a very short
+ * lifetime and renew it frequently.
+ * <pre>
+ * id-pkix-ocsp-nocheck OBJECT IDENTIFIER ::= { id-pkix-ocsp 5 }
+ * </pre>
+ *
+ * @author Xuelei Fan
+ * @see Extension
+ * @see CertAttrSet
+ */
+public class OCSPNoCheckExtension extends Extension
+ implements CertAttrSet<String> {
+
+ /**
+ * Identifier for this attribute, to be used with the
+ * get, set, delete methods of Certificate, x509 type.
+ */
+ public static final String IDENT =
+ "x509.info.extensions.OCSPNoCheck";
+ /**
+ * Attribute names.
+ */
+ public static final String NAME = "OCSPNoCheck";
+
+ /**
+ * Create a OCSPNoCheckExtension
+ */
+ public OCSPNoCheckExtension() throws IOException {
+ this.extensionId = PKIXExtensions.OCSPNoCheck_Id;
+ this.critical = false;
+ this.extensionValue = new byte[0];
+ }
+
+ /**
+ * Create the extension from the passed DER encoded value.
+ *
+ * @param critical true if the extension is to be treated as critical.
+ * @param value an array of DER encoded bytes of the actual value.
+ * @exception IOException on error.
+ */
+ public OCSPNoCheckExtension(Boolean critical, Object value)
+ throws IOException {
+
+ this.extensionId = PKIXExtensions.OCSPNoCheck_Id;
+ this.critical = critical.booleanValue();
+
+ // the value should be null, just ignore it here.
+ this.extensionValue = new byte[0];
+ }
+
+ /**
+ * Set the attribute value.
+ */
+ public void set(String name, Object obj) throws IOException {
+ throw new IOException("No attribute is allowed by " +
+ "CertAttrSet:OCSPNoCheckExtension.");
+ }
+
+ /**
+ * Get the attribute value.
+ */
+ public Object get(String name) throws IOException {
+ throw new IOException("No attribute is allowed by " +
+ "CertAttrSet:OCSPNoCheckExtension.");
+ }
+
+ /**
+ * Delete the attribute value.
+ */
+ public void delete(String name) throws IOException {
+ throw new IOException("No attribute is allowed by " +
+ "CertAttrSet:OCSPNoCheckExtension.");
+ }
+
+ /**
+ * Return an enumeration of names of attributes existing within this
+ * attribute.
+ */
+ public Enumeration<String> getElements() {
+ return (new AttributeNameEnumeration()).elements();
+ }
+
+ /**
+ * Return the name of this attribute.
+ */
+ public String getName() {
+ return NAME;
+ }
+}
--- a/jdk/src/share/classes/sun/security/x509/OIDMap.java Fri Mar 13 09:21:13 2009 +0800
+++ b/jdk/src/share/classes/sun/security/x509/OIDMap.java Fri Mar 13 12:59:25 2009 +0800
@@ -100,6 +100,8 @@
DeltaCRLIndicatorExtension.NAME;
private static final String FRESHEST_CRL = ROOT + "." +
FreshestCRLExtension.NAME;
+ private static final String OCSPNOCHECK = ROOT + "." +
+ OCSPNoCheckExtension.NAME;
private static final int NetscapeCertType_data[] =
{ 2, 16, 840, 1, 113730, 1, 1 };
@@ -161,6 +163,8 @@
"sun.security.x509.DeltaCRLIndicatorExtension");
addInternal(FRESHEST_CRL, PKIXExtensions.FreshestCRL_Id,
"sun.security.x509.FreshestCRLExtension");
+ addInternal(OCSPNOCHECK, PKIXExtensions.OCSPNoCheck_Id,
+ "sun.security.x509.OCSPNoCheckExtension");
}
/**
--- a/jdk/src/share/classes/sun/security/x509/PKIXExtensions.java Fri Mar 13 09:21:13 2009 +0800
+++ b/jdk/src/share/classes/sun/security/x509/PKIXExtensions.java Fri Mar 13 12:59:25 2009 +0800
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-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
@@ -74,6 +74,8 @@
private static final int AuthInfoAccess_data [] = { 1, 3, 6, 1, 5, 5, 7, 1, 1};
private static final int SubjectInfoAccess_data [] = { 1, 3, 6, 1, 5, 5, 7, 1, 11};
private static final int FreshestCRL_data [] = { 2, 5, 29, 46 };
+ private static final int OCSPNoCheck_data [] = { 1, 3, 6, 1, 5, 5, 7,
+ 48, 1, 5};
/**
* Identifies the particular public key used to sign the certificate.
@@ -216,6 +218,12 @@
*/
public static final ObjectIdentifier FreshestCRL_Id;
+ /**
+ * Identifies the OCSP client can trust the responder for the
+ * lifetime of the responder's certificate.
+ */
+ public static final ObjectIdentifier OCSPNoCheck_Id;
+
static {
AuthorityKey_Id = ObjectIdentifier.newInternal(AuthorityKey_data);
SubjectKey_Id = ObjectIdentifier.newInternal(SubjectKey_data);
@@ -257,5 +265,6 @@
SubjectInfoAccess_Id =
ObjectIdentifier.newInternal(SubjectInfoAccess_data);
FreshestCRL_Id = ObjectIdentifier.newInternal(FreshestCRL_data);
+ OCSPNoCheck_Id = ObjectIdentifier.newInternal(OCSPNoCheck_data);
}
}