diff --git a/src/share/classes/sun/security/provider/certpath/OCSPResponse.java b/src/share/classes/sun/security/provider/certpath/OCSPResponse.java index 20bac34f2ccfaa6b098730c466b92703f21961a1..62cd4288ed00f1a58dd65dc80c6fca51ce326564 100644 --- a/src/share/classes/sun/security/provider/certpath/OCSPResponse.java +++ b/src/share/classes/sun/security/provider/certpath/OCSPResponse.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 @@ -28,8 +28,6 @@ package sun.security.provider.certpath; 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 @@ class OCSPResponse { // 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 @@ class OCSPResponse { // 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 keyPurposes = cert.getExtendedKeyUsage(); @@ -360,6 +358,43 @@ class OCSPResponse { "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 @@ class OCSPResponse { } 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"); } } diff --git a/src/share/classes/sun/security/x509/OCSPNoCheckExtension.java b/src/share/classes/sun/security/x509/OCSPNoCheckExtension.java new file mode 100644 index 0000000000000000000000000000000000000000..b721439d5c9fb064e4a913b651ba9290a9ed926a --- /dev/null +++ b/src/share/classes/sun/security/x509/OCSPNoCheckExtension.java @@ -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. + *

+ * 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. + *

+ * id-pkix-ocsp-nocheck OBJECT IDENTIFIER ::= { id-pkix-ocsp 5 }
+ * 
+ * + * @author Xuelei Fan + * @see Extension + * @see CertAttrSet + */ +public class OCSPNoCheckExtension extends Extension + implements CertAttrSet { + + /** + * 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 getElements() { + return (new AttributeNameEnumeration()).elements(); + } + + /** + * Return the name of this attribute. + */ + public String getName() { + return NAME; + } +} diff --git a/src/share/classes/sun/security/x509/OIDMap.java b/src/share/classes/sun/security/x509/OIDMap.java index bb7cffef3439d345c24172a4385ebbf4784cf46a..f52fab3eeef81352047a89f0228ed91f8032356b 100644 --- a/src/share/classes/sun/security/x509/OIDMap.java +++ b/src/share/classes/sun/security/x509/OIDMap.java @@ -100,6 +100,8 @@ public class OIDMap { 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 @@ public class OIDMap { "sun.security.x509.DeltaCRLIndicatorExtension"); addInternal(FRESHEST_CRL, PKIXExtensions.FreshestCRL_Id, "sun.security.x509.FreshestCRLExtension"); + addInternal(OCSPNOCHECK, PKIXExtensions.OCSPNoCheck_Id, + "sun.security.x509.OCSPNoCheckExtension"); } /** diff --git a/src/share/classes/sun/security/x509/PKIXExtensions.java b/src/share/classes/sun/security/x509/PKIXExtensions.java index 78177944c08bfbe1376111531156bd41860289a2..f140c548551465135e6dd4fd57d1fcc1e8a95467 100644 --- a/src/share/classes/sun/security/x509/PKIXExtensions.java +++ b/src/share/classes/sun/security/x509/PKIXExtensions.java @@ -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 @@ public class PKIXExtensions { 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 class PKIXExtensions { */ 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 @@ public class PKIXExtensions { SubjectInfoAccess_Id = ObjectIdentifier.newInternal(SubjectInfoAccess_data); FreshestCRL_Id = ObjectIdentifier.newInternal(FreshestCRL_data); + OCSPNoCheck_Id = ObjectIdentifier.newInternal(OCSPNoCheck_data); } }