ocspresponse.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 731 行 · 第 1/2 页

JAVA
731
字号
/* * * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program 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 program 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 at /legal/license.txt). * * 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 or visit www.sun.com if you need additional * information or have any questions. */                                                             package com.sun.midp.pki.ocsp;import java.util.Date;import java.util.Vector;import java.io.IOException;import javax.microedition.pki.CertificateException;import com.sun.midp.pki.AlgorithmId;import com.sun.midp.pki.DerInputStream;import com.sun.midp.pki.ObjectIdentifier;import com.sun.midp.pki.X509Certificate;import com.sun.midp.pki.DerValue;import com.sun.midp.pki.Extension;import com.sun.midp.pki.Utils;import com.sun.midp.pki.CertStore;import com.sun.midp.crypto.Signature;import com.sun.midp.crypto.SignatureException;import com.sun.midp.crypto.InvalidKeyException;import com.sun.midp.crypto.NoSuchAlgorithmException;import com.sun.midp.crypto.PublicKey;import com.sun.midp.log.Logging;import com.sun.midp.log.LogChannels;/** * This class is used to process an OCSP response. * The OCSP Response is defined * in RFC 2560 and the ASN.1 encoding is as follows: * <pre> * *  OCSPResponse ::= SEQUENCE { *      responseStatus         OCSPResponseStatus, *      responseBytes          [0] EXPLICIT ResponseBytes OPTIONAL } * *   OCSPResponseStatus ::= ENUMERATED { *       successful            (0),  --Response has valid confirmations *       malformedRequest      (1),  --Illegal confirmation request *       internalError         (2),  --Internal error in issuer *       tryLater              (3),  --Try again later *                                   --(4) is not used *       sigRequired           (5),  --Must sign the request *       unauthorized          (6)   --Request unauthorized *   } * *   ResponseBytes ::=       SEQUENCE { *       responseType   OBJECT IDENTIFIER, *       response       OCTET STRING } * *   BasicOCSPResponse       ::= SEQUENCE { *      tbsResponseData      ResponseData, *      signatureAlgorithm   AlgorithmIdentifier, *      signature            BIT STRING, *      certs                [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } * *   The value for signature SHALL be computed on the hash of the DER *   encoding ResponseData. * *   ResponseData ::= SEQUENCE { *      version              [0] EXPLICIT Version DEFAULT v1, *      responderID              ResponderID, *      producedAt               GeneralizedTime, *      responses                SEQUENCE OF SingleResponse, *      responseExtensions   [1] EXPLICIT Extensions OPTIONAL } * *   ResponderID ::= CHOICE { *      byName               [1] Name, *      byKey                [2] KeyHash } * *   KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key *   (excluding the tag and length fields) * *   SingleResponse ::= SEQUENCE { *      certID                       CertID, *      certStatus                   CertStatus, *      thisUpdate                   GeneralizedTime, *      nextUpdate         [0]       EXPLICIT GeneralizedTime OPTIONAL, *      singleExtensions   [1]       EXPLICIT Extensions OPTIONAL } * *   CertStatus ::= CHOICE { *       good        [0]     IMPLICIT NULL, *       revoked     [1]     IMPLICIT RevokedInfo, *       unknown     [2]     IMPLICIT UnknownInfo } * *   RevokedInfo ::= SEQUENCE { *       revocationTime              GeneralizedTime, *       revocationReason    [0]     EXPLICIT CRLReason OPTIONAL } * *   UnknownInfo ::= NULL -- this can be replaced with an enumeration * * </pre> */class OCSPResponse {    private static final ObjectIdentifier OCSP_BASIC_RESPONSE_OID;    private static final ObjectIdentifier OCSP_NONCE_EXTENSION_OID;    static {        ObjectIdentifier tmp1 = null;        ObjectIdentifier tmp2 = null;        try {            tmp1 = new ObjectIdentifier("1.3.6.1.5.5.7.48.1.1");            tmp2 = new ObjectIdentifier("1.3.6.1.5.5.7.48.1.2");        } catch (Exception e) {            // should not happen; log and exit        }        OCSP_BASIC_RESPONSE_OID = tmp1;        OCSP_NONCE_EXTENSION_OID = tmp2;    }    // OCSP response status code    private static final int OCSP_RESPONSE_OK = 0;    // ResponderID CHOICE tags    private static final int NAME_TAG = 1;    private static final int KEY_TAG = 2;    // Object identifier for the OCSPSigning key purpose    private static final String KP_OCSP_SIGNING_OID = "1.3.6.1.5.5.7.3.9";    private SingleResponse singleResponse;    /*     * Create an OCSP response from its ASN.1 DER encoding.     */    // used by OCSPValidatorImpl    OCSPResponse(byte[] bytes, Vector certs, CertId reqCertId,                 X509Certificate issuerCert, CertStore keyStore,                 byte[] reqNonce)            throws IOException, OCSPException {        try {            int responseStatus;            ObjectIdentifier  responseType;            int version;            Date producedAtDate;            AlgorithmId sigAlgId;            byte[] respNonce = null;            // OCSPResponse            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {                Logging.report(Logging.INFORMATION, LogChannels.LC_SECURITY,                    "OCSPResponse first bytes are... " +                        Utils.hexEncode(bytes, 0,                                (bytes.length > 256) ? 256 : bytes.length));            }            DerValue der = new DerValue(bytes);            if (der.tag != DerValue.tag_Sequence) {                throw new IOException("Bad encoding in OCSP response: " +                    "expected ASN.1 SEQUENCE tag.");            }            DerInputStream derIn = der.getData();            // responseStatus            responseStatus = derIn.getEnumerated();            if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {                Logging.report(Logging.INFORMATION, LogChannels.LC_SECURITY,                           "OCSP response: " + responseStatus);            }                        if (responseStatus != OCSP_RESPONSE_OK) {                throw new OCSPException((byte)responseStatus,                    "OCSP Response Failure: " + responseStatus);            }            // responseBytes            der = derIn.getDerValue();            if (! der.isContextSpecific((byte)0)) {                throw new IOException("Bad encoding in responseBytes element " +                    "of OCSP response: expected ASN.1 context specific tag 0.");            }            DerValue tmp = der.data.getDerValue();            if (tmp.tag != DerValue.tag_Sequence) {                throw new IOException("Bad encoding in responseBytes element " +                    "of OCSP response: expected ASN.1 SEQUENCE tag.");            }            // responseType            derIn = tmp.data;            responseType = derIn.getOID();            if (responseType.equals(OCSP_BASIC_RESPONSE_OID)) {                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {                    Logging.report(Logging.INFORMATION, LogChannels.LC_SECURITY,                               "OCSP response type: basic");                }            } else {                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {                    Logging.report(Logging.INFORMATION, LogChannels.LC_SECURITY,                               "OCSP response type: " + responseType);                }                throw new IOException("Unsupported OCSP response type: " +                    responseType);            }            // BasicOCSPResponse            DerInputStream basicOCSPResponse =                new DerInputStream(derIn.getOctetString());            DerValue[]  seqTmp = basicOCSPResponse.getSequence(2);            DerValue responseData = seqTmp[0];            // Need the DER encoded ResponseData to verify the signature later            byte[] responseDataDer = seqTmp[0].toByteArray();            // tbsResponseData            if (responseData.tag != DerValue.tag_Sequence) {                throw new IOException("Bad encoding in tbsResponseData " +                    " element of OCSP response: expected ASN.1 SEQUENCE tag.");            }                        DerInputStream seqDerIn = responseData.data;            DerValue seq = seqDerIn.getDerValue();            // version            if (seq.isContextSpecific((byte)0)) {                // seq[0] is version                if (seq.isConstructed() && seq.isContextSpecific()) {                    seq = seq.data.getDerValue();                    version = seq.getInteger();                    if (seq.data.available() != 0) {                        throw new IOException("Bad encoding in version " +                            " element of OCSP response: bad format");                    }                    seq = seqDerIn.getDerValue();                }            }            // responderID            short tag = (byte)(seq.tag & 0x1f);            if (tag == NAME_TAG) {                String responderName = parsex500Name(seq.getData());                if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {                    Logging.report(Logging.INFORMATION, LogChannels.LC_SECURITY,                               "OCSP Responder name: " + responderName);                }            } else if (tag == KEY_TAG) {                // Ignore, for now            } else {                throw new IOException("Bad encoding in responderID element " +                    "of OCSP response: expected ASN.1 context specific tag 0 " +                    "or 1");            }            // producedAt            seq = seqDerIn.getDerValue();            producedAtDate = seq.getGeneralizedTime();            // responses            DerValue[] singleResponseDer = seqDerIn.getSequence(1);            // Search the response with the same CertId as given in the request            int n;            for (n = 0; n < singleResponseDer.length; n++) {                singleResponse = new SingleResponse(singleResponseDer[n]);                if (singleResponse.getCertId().equals(reqCertId)) {                    break;                }            }            if (n == singleResponseDer.length) {                throw new IOException("Response doesn't contain information" +                                      "about the requested certificate");            }            // responseExtensions            if (seqDerIn.available() > 0) {                seq = seqDerIn.getDerValue();                if (seq.isContextSpecific((byte)1)) {                    DerValue[]  responseExtDer = seq.data.getSequence(3);                    Extension[] responseExtension =                        new Extension[responseExtDer.length];                    for (int i = 0; i < responseExtDer.length; i++) {                        responseExtension[i] = new Extension(responseExtDer[i]);                        if (Logging.REPORT_LEVEL <= Logging.INFORMATION) {                            Logging.report(Logging.INFORMATION,                                LogChannels.LC_SECURITY,                                    "OCSP extension: " + responseExtension[i]);                        }                        if ((responseExtension[i].getExtensionId()).equals(                            OCSP_NONCE_EXTENSION_OID)) {                            respNonce =                                responseExtension[i].getExtensionValue();                        } else if (responseExtension[i].isCritical())  {                            throw new IOException(                                "Unsupported OCSP critical extension: " +                                responseExtension[i].getExtensionId());                        }                    }                }            }            // Check that the nonce value is the same as given in the request.            if (reqNonce != null) {                if (respNonce == null)  {                    throw new IOException(                            "nonce extension is missing in the response.");                }                                // get response nonce bytes                if ((reqNonce.length != respNonce.length) ||                           !Utils.byteMatch(reqNonce, 0, respNonce, 0,                                            reqNonce.length)) {                    throw new IOException(                            "Invalid nonce value in the response.");                }            }            // signatureAlgorithmId            sigAlgId = AlgorithmId.parse(seqTmp[1]);            // signature            byte[] signature = seqTmp[2].getBitString();            X509Certificate[] x509Certs = null;            // if seq[3] is available, then it is a sequence of certificates            if (seqTmp.length > 3) {                // certs are available                DerValue seqCert = seqTmp[3];                                if (! seqCert.isContextSpecific((byte)0)) {                    throw new IOException("Bad encoding in certs element " +                    "of OCSP response: expected ASN.1 context specific tag 0.");                }                DerValue[] certsDer = (seqCert.getData()).getSequence(3);                x509Certs = new X509Certificate[certsDer.length];                for (int i = 0; i < certsDer.length; i++) {                    byte[] data = certsDer[i].toByteArray();                    x509Certs[i] = X509Certificate.generateCertificate(                            data, 0 , data.length);                }            }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?