ocsp.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 2,187 行 · 第 1/5 页
C
2,187 行
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape security libraries. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. *//* * Implementation of OCSP services, for both client and server. * (XXX, really, mostly just for client right now, but intended to do both.) * * $Id: ocsp.c,v 1.1 2000/03/31 19:43:00 relyea%netscape.com Exp $ */#include "prerror.h"#include "prprf.h"#include "plarena.h"#include "prnetdb.h"#include "seccomon.h"#include "secitem.h"#include "secoidt.h"#include "secasn1.h"#include "secder.h"#include "cert.h"#include "xconst.h"#include "secerr.h"#include "secoid.h"#include "hasht.h"#include "sechash.h"#include "secasn1.h"#include "keyhi.h"#include "cryptohi.h"#include "ocsp.h"#include "ocspti.h"#include "genname.h"#include "certxutl.h"#include "pk11func.h" /* for PK11_HashBuf */#include <stdarg.h>/* * The following structure is only used internally. It is allocated when * someone turns on OCSP checking, and hangs off of the status-configuration * structure in the certdb structure. We use it to keep configuration * information specific to OCSP checking. */typedef struct ocspCheckingContextStr { PRBool useDefaultResponder; char *defaultResponderURI; char *defaultResponderNickname; CERTCertificate *defaultResponderCert;} ocspCheckingContext;/* * Forward declarations of sub-types, so I can lay out the types in the * same order as the ASN.1 is laid out in the OCSP spec itself. * * These are in alphabetical order (case-insensitive); please keep it that way! */extern const SEC_ASN1Template ocsp_CertIDTemplate[];extern const SEC_ASN1Template ocsp_PointerToSignatureTemplate[];extern const SEC_ASN1Template ocsp_PointerToResponseBytesTemplate[];extern const SEC_ASN1Template ocsp_ResponseDataTemplate[];extern const SEC_ASN1Template ocsp_RevokedInfoTemplate[];extern const SEC_ASN1Template ocsp_SingleRequestTemplate[];extern const SEC_ASN1Template ocsp_SingleResponseTemplate[];extern const SEC_ASN1Template ocsp_TBSRequestTemplate[];/* * Request-related templates... *//* * OCSPRequest ::= SEQUENCE { * tbsRequest TBSRequest, * optionalSignature [0] EXPLICIT Signature OPTIONAL } */static const SEC_ASN1Template ocsp_OCSPRequestTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTOCSPRequest) }, { SEC_ASN1_POINTER, offsetof(CERTOCSPRequest, tbsRequest), ocsp_TBSRequestTemplate }, { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(CERTOCSPRequest, optionalSignature), ocsp_PointerToSignatureTemplate }, { 0 }};/* * TBSRequest ::= SEQUENCE { * version [0] EXPLICIT Version DEFAULT v1, * requestorName [1] EXPLICIT GeneralName OPTIONAL, * requestList SEQUENCE OF Request, * requestExtensions [2] EXPLICIT Extensions OPTIONAL } * * Version ::= INTEGER { v1(0) } * * Note: this should be static but the AIX compiler doesn't like it (because it * was forward-declared above); it is not meant to be exported, but this * is the only way it will compile. */const SEC_ASN1Template ocsp_TBSRequestTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(ocspTBSRequest) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(ocspTBSRequest, version), SEC_IntegerTemplate }, { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, offsetof(ocspTBSRequest, derRequestorName), SEC_PointerToAnyTemplate }, { SEC_ASN1_SEQUENCE_OF, offsetof(ocspTBSRequest, requestList), ocsp_SingleRequestTemplate }, { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2, offsetof(ocspTBSRequest, requestExtensions), CERT_SequenceOfCertExtensionTemplate }, { 0 }};/* * Signature ::= SEQUENCE { * signatureAlgorithm AlgorithmIdentifier, * signature BIT STRING, * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } */static const SEC_ASN1Template ocsp_SignatureTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(ocspSignature) }, { SEC_ASN1_INLINE, offsetof(ocspSignature, signatureAlgorithm), SECOID_AlgorithmIDTemplate }, { SEC_ASN1_BIT_STRING, offsetof(ocspSignature, signature) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(ocspSignature, derCerts), SEC_SequenceOfAnyTemplate }, { 0 }};/* * This template is just an extra level to use in an explicitly-tagged * reference to a Signature. * * Note: this should be static but the AIX compiler doesn't like it (because it * was forward-declared above); it is not meant to be exported, but this * is the only way it will compile. */const SEC_ASN1Template ocsp_PointerToSignatureTemplate[] = { { SEC_ASN1_POINTER, 0, ocsp_SignatureTemplate }};/* * Request ::= SEQUENCE { * reqCert CertID, * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } * * Note: this should be static but the AIX compiler doesn't like it (because it * was forward-declared above); it is not meant to be exported, but this * is the only way it will compile. */const SEC_ASN1Template ocsp_SingleRequestTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(ocspSingleRequest) }, { SEC_ASN1_POINTER, offsetof(ocspSingleRequest, reqCert), ocsp_CertIDTemplate }, { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(ocspSingleRequest, singleRequestExtensions), CERT_SequenceOfCertExtensionTemplate }, { 0 }};/* * This data structure and template (CertID) is used by both OCSP * requests and responses. It is the only one that is shared. * * CertID ::= SEQUENCE { * hashAlgorithm AlgorithmIdentifier, * issuerNameHash OCTET STRING, -- Hash of Issuer DN * issuerKeyHash OCTET STRING, -- Hash of Issuer public key * serialNumber CertificateSerialNumber } * * CertificateSerialNumber ::= INTEGER * * Note: this should be static but the AIX compiler doesn't like it (because it * was forward-declared above); it is not meant to be exported, but this * is the only way it will compile. */const SEC_ASN1Template ocsp_CertIDTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTOCSPCertID) }, { SEC_ASN1_INLINE, offsetof(CERTOCSPCertID, hashAlgorithm), SECOID_AlgorithmIDTemplate }, { SEC_ASN1_OCTET_STRING, offsetof(CERTOCSPCertID, issuerNameHash) }, { SEC_ASN1_OCTET_STRING, offsetof(CERTOCSPCertID, issuerKeyHash) }, { SEC_ASN1_INTEGER, offsetof(CERTOCSPCertID, serialNumber) }, { 0 }};/* * Response-related templates... *//* * OCSPResponse ::= SEQUENCE { * responseStatus OCSPResponseStatus, * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } */static const SEC_ASN1Template ocsp_OCSPResponseTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTOCSPResponse) }, { SEC_ASN1_ENUMERATED, offsetof(CERTOCSPResponse, responseStatus) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(CERTOCSPResponse, responseBytes), ocsp_PointerToResponseBytesTemplate }, { 0 }};/* * ResponseBytes ::= SEQUENCE { * responseType OBJECT IDENTIFIER, * response OCTET STRING } */static const SEC_ASN1Template ocsp_ResponseBytesTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(ocspResponseBytes) }, { SEC_ASN1_OBJECT_ID, offsetof(ocspResponseBytes, responseType) }, { SEC_ASN1_OCTET_STRING, offsetof(ocspResponseBytes, response) }, { 0 }};/* * This template is just an extra level to use in an explicitly-tagged * reference to a ResponseBytes. * * Note: this should be static but the AIX compiler doesn't like it (because it * was forward-declared above); it is not meant to be exported, but this * is the only way it will compile. */const SEC_ASN1Template ocsp_PointerToResponseBytesTemplate[] = { { SEC_ASN1_POINTER, 0, ocsp_ResponseBytesTemplate }};/* * BasicOCSPResponse ::= SEQUENCE { * tbsResponseData ResponseData, * signatureAlgorithm AlgorithmIdentifier, * signature BIT STRING, * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } */static const SEC_ASN1Template ocsp_BasicOCSPResponseTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(ocspBasicOCSPResponse) }, { SEC_ASN1_POINTER, offsetof(ocspBasicOCSPResponse, tbsResponseData), ocsp_ResponseDataTemplate }, { SEC_ASN1_INLINE, offsetof(ocspBasicOCSPResponse, responseSignature.signatureAlgorithm), SECOID_AlgorithmIDTemplate }, { SEC_ASN1_BIT_STRING, offsetof(ocspBasicOCSPResponse, responseSignature.signature) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(ocspBasicOCSPResponse, responseSignature.derCerts), SEC_SequenceOfAnyTemplate }, { 0 }};/* * ResponseData ::= SEQUENCE { * version [0] EXPLICIT Version DEFAULT v1, * responderID ResponderID, * producedAt GeneralizedTime, * responses SEQUENCE OF SingleResponse, * responseExtensions [1] EXPLICIT Extensions OPTIONAL } * * Note: this should be static but the AIX compiler doesn't like it (because it * was forward-declared above); it is not meant to be exported, but this * is the only way it will compile. */const SEC_ASN1Template ocsp_ResponseDataTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(ocspResponseData) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | /* XXX DER_DEFAULT */ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(ocspResponseData, version), SEC_IntegerTemplate }, { SEC_ASN1_ANY, offsetof(ocspResponseData, derResponderID) }, { SEC_ASN1_GENERALIZED_TIME, offsetof(ocspResponseData, producedAt) }, { SEC_ASN1_SEQUENCE_OF, offsetof(ocspResponseData, responses), ocsp_SingleResponseTemplate }, { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, offsetof(ocspResponseData, responseExtensions), CERT_SequenceOfCertExtensionTemplate }, { 0 }};/* * ResponderID ::= CHOICE { * byName [1] EXPLICIT Name, * byKey [2] EXPLICIT KeyHash } * * KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key * (excluding the tag and length fields) * * XXX Because the ASN.1 encoder and decoder currently do not provide * a way to automatically handle a CHOICE, we need to do it in two * steps, looking at the type tag and feeding the exact choice back * to the ASN.1 code. Hopefully that will change someday and this * can all be simplified down into a single template. Anyway, for * now we list each choice as its own template: */static const SEC_ASN1Template ocsp_ResponderIDByNameTemplate[] = { { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, offsetof(ocspResponderID, responderIDValue.name), CERT_NameTemplate }};static const SEC_ASN1Template ocsp_ResponderIDByKeyTemplate[] = { { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2, offsetof(ocspResponderID, responderIDValue.keyHash), SEC_OctetStringTemplate }};static const SEC_ASN1Template ocsp_ResponderIDOtherTemplate[] = { { SEC_ASN1_ANY, offsetof(ocspResponderID, responderIDValue.other) }};/* * SingleResponse ::= SEQUENCE { * certID CertID, * certStatus CertStatus, * thisUpdate GeneralizedTime, * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, * singleExtensions [1] EXPLICIT Extensions OPTIONAL } * * Note: this should be static but the AIX compiler doesn't like it (because it * was forward-declared above); it is not meant to be exported, but this * is the only way it will compile. */const SEC_ASN1Template ocsp_SingleResponseTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTOCSPSingleResponse) }, { SEC_ASN1_POINTER, offsetof(CERTOCSPSingleResponse, certID), ocsp_CertIDTemplate }, { SEC_ASN1_ANY, offsetof(CERTOCSPSingleResponse, derCertStatus) }, { SEC_ASN1_GENERALIZED_TIME, offsetof(CERTOCSPSingleResponse, thisUpdate) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(CERTOCSPSingleResponse, nextUpdate), SEC_PointerToGeneralizedTimeTemplate }, { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, offsetof(CERTOCSPSingleResponse, singleExtensions), CERT_SequenceOfCertExtensionTemplate }, { 0 }};/* * CertStatus ::= CHOICE { * good [0] IMPLICIT NULL, * revoked [1] IMPLICIT RevokedInfo, * unknown [2] IMPLICIT UnknownInfo } * * Because the ASN.1 encoder and decoder currently do not provide * a way to automatically handle a CHOICE, we need to do it in two * steps, looking at the type tag and feeding the exact choice back * to the ASN.1 code. Hopefully that will change someday and this * can all be simplified down into a single template. Anyway, for * now we list each choice as its own template: */static const SEC_ASN1Template ocsp_CertStatusGoodTemplate[] = { { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(ocspCertStatus, certStatusInfo.goodInfo), SEC_NullTemplate }};static const SEC_ASN1Template ocsp_CertStatusRevokedTemplate[] = { { SEC_ASN1_POINTER | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1, offsetof(ocspCertStatus, certStatusInfo.revokedInfo), ocsp_RevokedInfoTemplate }};static const SEC_ASN1Template ocsp_CertStatusUnknownTemplate[] = { { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 2, offsetof(ocspCertStatus, certStatusInfo.unknownInfo), SEC_NullTemplate }};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?