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 + -
显示快捷键?