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