173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root/* 273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. 373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * This code is free software; you can redistribute it and/or modify it 673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * under the terms of the GNU General Public License version 2 only, as 773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * published by the Free Software Foundation. Oracle designates this 873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * particular file as subject to the "Classpath" exception as provided 973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * by Oracle in the LICENSE file that accompanied this code. 1073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 1173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * This code is distributed in the hope that it will be useful, but WITHOUT 1273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * version 2 for more details (a copy is included in the LICENSE file that 1573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * accompanied this code). 1673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 1773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * You should have received a copy of the GNU General Public License version 1873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 2 along with this work; if not, write to the Free Software Foundation, 1973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 2173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * or visit www.oracle.com if you need additional information or have any 2373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * questions. 2473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 2573405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootpackage sun.security.provider.certpath; 2673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 2773405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.io.InputStream; 2873405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.io.IOException; 2973405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.io.OutputStream; 3073405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.net.URI; 3173405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.net.URL; 3273405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.net.HttpURLConnection; 3373405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CertificateException; 3473405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CertPathValidatorException; 3573405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CertPathValidatorException.BasicReason; 3673405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CRLReason; 3773405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.Extension; 3873405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.X509Certificate; 3973405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.Arrays; 4073405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.Collections; 4173405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.Date; 4273405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.List; 4373405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.Map; 4473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 4573405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport static sun.security.provider.certpath.OCSPResponse.*; 4673405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.action.GetIntegerAction; 4773405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.util.Debug; 4873405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.util.ObjectIdentifier; 4973405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.AccessDescription; 5073405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.AuthorityInfoAccessExtension; 5173405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.GeneralName; 5273405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.GeneralNameInterface; 5373405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.URIName; 5473405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.X509CertImpl; 5573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 5673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root/** 5773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * This is a class that checks the revocation status of a certificate(s) using 5873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * OCSP. It is not a PKIXCertPathChecker and therefore can be used outside of 5973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * the CertPathValidator framework. It is useful when you want to 6073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * just check the revocation status of a certificate, and you don't want to 6173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * incur the overhead of validating all of the certificates in the 6273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * associated certificate chain. 6373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 6473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @author Sean Mullan 6573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 6673405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootpublic final class OCSP { 6773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 6873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root static final ObjectIdentifier NONCE_EXTENSION_OID = 6973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ObjectIdentifier.newInternal(new int[]{ 1, 3, 6, 1, 5, 5, 7, 48, 1, 2}); 7073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 7173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private static final Debug debug = Debug.getInstance("certpath"); 7273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 7373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private static final int DEFAULT_CONNECT_TIMEOUT = 15000; 7473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 7573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 7673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Integer value indicating the timeout length, in seconds, to be 7773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * used for the OCSP check. A timeout of zero is interpreted as 7873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * an infinite timeout. 7973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 8073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private static final int CONNECT_TIMEOUT = initializeTimeout(); 8173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 8273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 8373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Initialize the timeout length by getting the OCSP timeout 8473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * system property. If the property has not been set, or if its 8573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * value is negative, set the timeout length to the default. 8673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 8773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private static int initializeTimeout() { 8873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root Integer tmp = java.security.AccessController.doPrivileged( 8973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root new GetIntegerAction("com.sun.security.ocsp.timeout")); 9073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (tmp == null || tmp < 0) { 9173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return DEFAULT_CONNECT_TIMEOUT; 9273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 9373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Convert to milliseconds, as the system property will be 9473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // specified in seconds 9573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return tmp * 1000; 9673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 9773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 9873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root private OCSP() {} 9973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 10073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 10173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Obtains the revocation status of a certificate using OCSP using the most 10273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * common defaults. The OCSP responder URI is retrieved from the 10373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * certificate's AIA extension. The OCSP responder certificate is assumed 10473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * to be the issuer's certificate (or issued by the issuer CA). 10573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 10673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param cert the certificate to be checked 10773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param issuerCert the issuer certificate 10873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @return the RevocationStatus 10973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @throws IOException if there is an exception connecting to or 11073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * communicating with the OCSP responder 11173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @throws CertPathValidatorException if an exception occurs while 11273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * encoding the OCSP Request or validating the OCSP Response 11373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 11473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root public static RevocationStatus check(X509Certificate cert, 11573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509Certificate issuerCert) 11673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throws IOException, CertPathValidatorException { 11773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root CertId certId = null; 11873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root URI responderURI = null; 11973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 12073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509CertImpl certImpl = X509CertImpl.toImpl(cert); 12173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root responderURI = getResponderURI(certImpl); 12273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (responderURI == null) { 12373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new CertPathValidatorException 12473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ("No OCSP Responder URI in certificate"); 12573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 12673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root certId = new CertId(issuerCert, certImpl.getSerialNumberObject()); 12773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (CertificateException | IOException e) { 12873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new CertPathValidatorException 12973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ("Exception while encoding OCSPRequest", e); 13073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 13173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root OCSPResponse ocspResponse = check(Collections.singletonList(certId), 13273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root responderURI, issuerCert, null, null, 13373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root Collections.<Extension>emptyList()); 13473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return (RevocationStatus)ocspResponse.getSingleResponse(certId); 13573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 13673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 13773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 13873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Obtains the revocation status of a certificate using OCSP. 13973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 14073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param cert the certificate to be checked 14173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param issuerCert the issuer certificate 14273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param responderURI the URI of the OCSP responder 14373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param responderCert the OCSP responder's certificate 14473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param date the time the validity of the OCSP responder's certificate 14573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * should be checked against. If null, the current time is used. 14673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @return the RevocationStatus 14773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @throws IOException if there is an exception connecting to or 14873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * communicating with the OCSP responder 14973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @throws CertPathValidatorException if an exception occurs while 15073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * encoding the OCSP Request or validating the OCSP Response 15173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 15273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root public static RevocationStatus check(X509Certificate cert, 15373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509Certificate issuerCert, 15473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root URI responderURI, 15573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509Certificate responderCert, 15673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root Date date) 15773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throws IOException, CertPathValidatorException 15873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root { 15973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return check(cert, issuerCert, responderURI, responderCert, date, 16073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root Collections.<Extension>emptyList()); 16173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 16273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 16373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Called by com.sun.deploy.security.TrustDecider 16473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root public static RevocationStatus check(X509Certificate cert, 16573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509Certificate issuerCert, 16673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root URI responderURI, 16773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509Certificate responderCert, 16873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root Date date, List<Extension> extensions) 16973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throws IOException, CertPathValidatorException 17073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root { 17173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root CertId certId = null; 17273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 17373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509CertImpl certImpl = X509CertImpl.toImpl(cert); 17473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root certId = new CertId(issuerCert, certImpl.getSerialNumberObject()); 17573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (CertificateException | IOException e) { 17673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new CertPathValidatorException 17773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ("Exception while encoding OCSPRequest", e); 17873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 17973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root OCSPResponse ocspResponse = check(Collections.singletonList(certId), 18073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root responderURI, issuerCert, responderCert, date, extensions); 18173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return (RevocationStatus) ocspResponse.getSingleResponse(certId); 18273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 18373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 18473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 18573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Checks the revocation status of a list of certificates using OCSP. 18673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 18773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param certs the CertIds to be checked 18873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param responderURI the URI of the OCSP responder 18973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param issuerCert the issuer's certificate 19073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param responderCert the OCSP responder's certificate 19173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param date the time the validity of the OCSP responder's certificate 19273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * should be checked against. If null, the current time is used. 19373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @return the OCSPResponse 19473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @throws IOException if there is an exception connecting to or 19573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * communicating with the OCSP responder 19673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @throws CertPathValidatorException if an exception occurs while 19773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * encoding the OCSP Request or validating the OCSP Response 19873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 19973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root static OCSPResponse check(List<CertId> certIds, URI responderURI, 20073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509Certificate issuerCert, 20173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root X509Certificate responderCert, Date date, 20273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root List<Extension> extensions) 20373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throws IOException, CertPathValidatorException 20473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root { 20573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root byte[] bytes = null; 20673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root OCSPRequest request = null; 20773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 20873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root request = new OCSPRequest(certIds, extensions); 20973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root bytes = request.encodeBytes(); 21073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (IOException ioe) { 21173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new CertPathValidatorException 21273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ("Exception while encoding OCSPRequest", ioe); 21373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 21473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 21573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root InputStream in = null; 21673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root OutputStream out = null; 21773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root byte[] response = null; 21873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 21973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root URL url = responderURI.toURL(); 22073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null) { 22173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("connecting to OCSP service at: " + url); 22273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 22373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root HttpURLConnection con = (HttpURLConnection)url.openConnection(); 22473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root con.setConnectTimeout(CONNECT_TIMEOUT); 22573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root con.setReadTimeout(CONNECT_TIMEOUT); 22673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root con.setDoOutput(true); 22773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root con.setDoInput(true); 22873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root con.setRequestMethod("POST"); 22973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root con.setRequestProperty 23073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ("Content-type", "application/ocsp-request"); 23173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root con.setRequestProperty 23273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ("Content-length", String.valueOf(bytes.length)); 23373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root out = con.getOutputStream(); 23473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root out.write(bytes); 23573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root out.flush(); 23673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Check the response 23773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (debug != null && 23873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root con.getResponseCode() != HttpURLConnection.HTTP_OK) { 23973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root debug.println("Received HTTP error: " + con.getResponseCode() 24073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root + " - " + con.getResponseMessage()); 24173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 24273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root in = con.getInputStream(); 24373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root int contentLength = con.getContentLength(); 24473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (contentLength == -1) { 24573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root contentLength = Integer.MAX_VALUE; 24673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 24773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root response = new byte[contentLength > 2048 ? 2048 : contentLength]; 24873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root int total = 0; 24973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root while (total < contentLength) { 25073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root int count = in.read(response, total, response.length - total); 25173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (count < 0) 25273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root break; 25373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 25473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root total += count; 25573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (total >= response.length && total < contentLength) { 25673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root response = Arrays.copyOf(response, total * 2); 25773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 25873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 25973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root response = Arrays.copyOf(response, total); 26073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (IOException ioe) { 26173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new CertPathValidatorException( 26273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root "Unable to determine revocation status due to network error", 26373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ioe, null, -1, BasicReason.UNDETERMINED_REVOCATION_STATUS); 26473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } finally { 26573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (in != null) { 26673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 26773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root in.close(); 26873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (IOException ioe) { 26973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw ioe; 27073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 27173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 27273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (out != null) { 27373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 27473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root out.close(); 27573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (IOException ioe) { 27673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw ioe; 27773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 27873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 27973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 28073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 28173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root OCSPResponse ocspResponse = null; 28273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 28373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ocspResponse = new OCSPResponse(response); 28473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (IOException ioe) { 28573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // response decoding exception 28673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root throw new CertPathValidatorException(ioe); 28773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 28873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 28973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // verify the response 29073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root ocspResponse.verify(certIds, issuerCert, responderCert, date, 29173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root request.getNonce()); 29273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 29373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return ocspResponse; 29473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 29573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 29673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 29773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Returns the URI of the OCSP Responder as specified in the 29873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * certificate's Authority Information Access extension, or null if 29973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * not specified. 30073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 30173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @param cert the certificate 30273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @return the URI of the OCSP Responder, or null if not specified 30373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 30473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Called by com.sun.deploy.security.TrustDecider 30573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root public static URI getResponderURI(X509Certificate cert) { 30673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root try { 30773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return getResponderURI(X509CertImpl.toImpl(cert)); 30873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } catch (CertificateException ce) { 30973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // treat this case as if the cert had no extension 31073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return null; 31173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 31273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 31373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 31473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root static URI getResponderURI(X509CertImpl certImpl) { 31573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 31673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root // Examine the certificate's AuthorityInfoAccess extension 31773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root AuthorityInfoAccessExtension aia = 31873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root certImpl.getAuthorityInfoAccessExtension(); 31973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (aia == null) { 32073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return null; 32173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 32273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 32373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root List<AccessDescription> descriptions = aia.getAccessDescriptions(); 32473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root for (AccessDescription description : descriptions) { 32573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (description.getAccessMethod().equals((Object) 32673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root AccessDescription.Ad_OCSP_Id)) { 32773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 32873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root GeneralName generalName = description.getAccessLocation(); 32973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root if (generalName.getType() == GeneralNameInterface.NAME_URI) { 33073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root URIName uri = (URIName) generalName.getName(); 33173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return uri.getURI(); 33273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 33373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 33473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 33573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root return null; 33673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 33773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 33873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 33973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * The Revocation Status of a certificate. 34073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 34173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root public static interface RevocationStatus { 34273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root public enum CertStatus { GOOD, REVOKED, UNKNOWN }; 34373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 34473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 34573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Returns the revocation status. 34673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 34773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root CertStatus getCertStatus(); 34873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 34973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Returns the time when the certificate was revoked, or null 35073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * if it has not been revoked. 35173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 35273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root Date getRevocationTime(); 35373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 35473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Returns the reason the certificate was revoked, or null if it 35573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * has not been revoked. 35673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 35773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root CRLReason getRevocationReason(); 35873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root 35973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root /** 36073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Returns a Map of additional extensions. 36173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */ 36273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root Map<String, Extension> getSingleExtensions(); 36373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root } 36473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root} 365