| /* ocsp.c */ |
| /* |
| * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project |
| * 2000. |
| */ |
| /* ==================================================================== |
| * Copyright (c) 2000 The OpenSSL Project. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * 3. All advertising materials mentioning features or use of this |
| * software must display the following acknowledgment: |
| * "This product includes software developed by the OpenSSL Project |
| * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" |
| * |
| * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to |
| * endorse or promote products derived from this software without |
| * prior written permission. For written permission, please contact |
| * licensing@OpenSSL.org. |
| * |
| * 5. Products derived from this software may not be called "OpenSSL" |
| * nor may "OpenSSL" appear in their names without prior written |
| * permission of the OpenSSL Project. |
| * |
| * 6. Redistributions of any form whatsoever must retain the following |
| * acknowledgment: |
| * "This product includes software developed by the OpenSSL Project |
| * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY |
| * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR |
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
| * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
| * OF THE POSSIBILITY OF SUCH DAMAGE. |
| * ==================================================================== |
| * |
| * This product includes cryptographic software written by Eric Young |
| * (eay@cryptsoft.com). This product includes software written by Tim |
| * Hudson (tjh@cryptsoft.com). |
| * |
| */ |
| #include <openssl/asn1.h> |
| #include <openssl/asn1t.h> |
| #include <openssl/x509v3.h> |
| |
| /*- |
| Example of new ASN1 code, OCSP request |
| |
| OCSPRequest ::= SEQUENCE { |
| tbsRequest TBSRequest, |
| optionalSignature [0] EXPLICIT Signature OPTIONAL } |
| |
| TBSRequest ::= SEQUENCE { |
| version [0] EXPLICIT Version DEFAULT v1, |
| requestorName [1] EXPLICIT GeneralName OPTIONAL, |
| requestList SEQUENCE OF Request, |
| requestExtensions [2] EXPLICIT Extensions OPTIONAL } |
| |
| Signature ::= SEQUENCE { |
| signatureAlgorithm AlgorithmIdentifier, |
| signature BIT STRING, |
| certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } |
| |
| Version ::= INTEGER { v1(0) } |
| |
| Request ::= SEQUENCE { |
| reqCert CertID, |
| singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } |
| |
| CertID ::= SEQUENCE { |
| hashAlgorithm AlgorithmIdentifier, |
| issuerNameHash OCTET STRING, -- Hash of Issuer's DN |
| issuerKeyHash OCTET STRING, -- Hash of Issuers public key |
| serialNumber CertificateSerialNumber } |
| |
| 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 } |
| |
| 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, --EXPLICIT |
| 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 |
| |
| ArchiveCutoff ::= GeneralizedTime |
| |
| AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER |
| |
| ServiceLocator ::= SEQUENCE { |
| issuer Name, |
| locator AuthorityInfoAccessSyntax } |
| |
| -- Object Identifiers |
| |
| id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } |
| id-pkix-ocsp OBJECT IDENTIFIER ::= { id-ad-ocsp } |
| id-pkix-ocsp-basic OBJECT IDENTIFIER ::= { id-pkix-ocsp 1 } |
| id-pkix-ocsp-nonce OBJECT IDENTIFIER ::= { id-pkix-ocsp 2 } |
| id-pkix-ocsp-crl OBJECT IDENTIFIER ::= { id-pkix-ocsp 3 } |
| id-pkix-ocsp-response OBJECT IDENTIFIER ::= { id-pkix-ocsp 4 } |
| id-pkix-ocsp-nocheck OBJECT IDENTIFIER ::= { id-pkix-ocsp 5 } |
| id-pkix-ocsp-archive-cutoff OBJECT IDENTIFIER ::= { id-pkix-ocsp 6 } |
| id-pkix-ocsp-service-locator OBJECT IDENTIFIER ::= { id-pkix-ocsp 7 } |
| |
| */ |
| |
| /* Request Structures */ |
| |
| DECLARE_STACK_OF(Request) |
| |
| typedef struct { |
| ASN1_INTEGER *version; |
| GENERAL_NAME *requestorName; |
| STACK_OF(Request) *requestList; |
| STACK_OF(X509_EXTENSION) *requestExtensions; |
| } TBSRequest; |
| |
| typedef struct { |
| X509_ALGOR *signatureAlgorithm; |
| ASN1_BIT_STRING *signature; |
| STACK_OF(X509) *certs; |
| } Signature; |
| |
| typedef struct { |
| TBSRequest *tbsRequest; |
| Signature *optionalSignature; |
| } OCSPRequest; |
| |
| typedef struct { |
| X509_ALGOR *hashAlgorithm; |
| ASN1_OCTET_STRING *issuerNameHash; |
| ASN1_OCTET_STRING *issuerKeyHash; |
| ASN1_INTEGER *certificateSerialNumber; |
| } CertID; |
| |
| typedef struct { |
| CertID *reqCert; |
| STACK_OF(X509_EXTENSION) *singleRequestExtensions; |
| } Request; |
| |
| /* Response structures */ |
| |
| typedef struct { |
| ASN1_OBJECT *responseType; |
| ASN1_OCTET_STRING *response; |
| } ResponseBytes; |
| |
| typedef struct { |
| ASN1_ENUMERATED *responseStatus; |
| ResponseBytes *responseBytes; |
| } OCSPResponse; |
| |
| typedef struct { |
| int type; |
| union { |
| X509_NAME *byName; |
| ASN1_OCTET_STRING *byKey; |
| } d; |
| } ResponderID; |
| |
| typedef struct { |
| ASN1_INTEGER *version; |
| ResponderID *responderID; |
| ASN1_GENERALIZEDTIME *producedAt; |
| STACK_OF(SingleResponse) *responses; |
| STACK_OF(X509_EXTENSION) *responseExtensions; |
| } ResponseData; |
| |
| typedef struct { |
| ResponseData *tbsResponseData; |
| X509_ALGOR *signatureAlgorithm; |
| ASN1_BIT_STRING *signature; |
| STACK_OF(X509) *certs; |
| } BasicOCSPResponse; |
| |
| typedef struct { |
| ASN1_GENERALIZEDTIME *revocationTime; |
| ASN1_ENUMERATED *revocationReason; |
| } RevokedInfo; |
| |
| typedef struct { |
| int type; |
| union { |
| ASN1_NULL *good; |
| RevokedInfo *revoked; |
| ASN1_NULL *unknown; |
| } d; |
| } CertStatus; |
| |
| typedef struct { |
| CertID *certID; |
| CertStatus *certStatus; |
| ASN1_GENERALIZEDTIME *thisUpdate; |
| ASN1_GENERALIZEDTIME *nextUpdate; |
| STACK_OF(X509_EXTENSION) *singleExtensions; |
| } SingleResponse; |
| |
| typedef struct { |
| X509_NAME *issuer; |
| STACK_OF(ACCESS_DESCRIPTION) *locator; |
| } ServiceLocator; |
| |
| /* Now the ASN1 templates */ |
| |
| IMPLEMENT_COMPAT_ASN1(X509); |
| IMPLEMENT_COMPAT_ASN1(X509_ALGOR); |
| // IMPLEMENT_COMPAT_ASN1(X509_EXTENSION); |
| IMPLEMENT_COMPAT_ASN1(GENERAL_NAME); |
| IMPLEMENT_COMPAT_ASN1(X509_NAME); |
| |
| ASN1_SEQUENCE(X509_EXTENSION) = { |
| ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT), |
| ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN), |
| ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING) |
| } ASN1_SEQUENCE_END(X509_EXTENSION); |
| |
| |
| ASN1_SEQUENCE(Signature) = { |
| ASN1_SIMPLE(Signature, signatureAlgorithm, X509_ALGOR), |
| ASN1_SIMPLE(Signature, signature, ASN1_BIT_STRING), |
| ASN1_SEQUENCE_OF(Signature, certs, X509) |
| } ASN1_SEQUENCE_END(Signature); |
| |
| ASN1_SEQUENCE(CertID) = { |
| ASN1_SIMPLE(CertID, hashAlgorithm, X509_ALGOR), |
| ASN1_SIMPLE(CertID, issuerNameHash, ASN1_OCTET_STRING), |
| ASN1_SIMPLE(CertID, issuerKeyHash, ASN1_OCTET_STRING), |
| ASN1_SIMPLE(CertID, certificateSerialNumber, ASN1_INTEGER) |
| } ASN1_SEQUENCE_END(CertID); |
| |
| ASN1_SEQUENCE(Request) = { |
| ASN1_SIMPLE(Request, reqCert, CertID), |
| ASN1_EXP_SEQUENCE_OF_OPT(Request, singleRequestExtensions, X509_EXTENSION, 0) |
| } ASN1_SEQUENCE_END(Request); |
| |
| ASN1_SEQUENCE(TBSRequest) = { |
| ASN1_EXP_OPT(TBSRequest, version, ASN1_INTEGER, 0), |
| ASN1_EXP_OPT(TBSRequest, requestorName, GENERAL_NAME, 1), |
| ASN1_SEQUENCE_OF(TBSRequest, requestList, Request), |
| ASN1_EXP_SEQUENCE_OF_OPT(TBSRequest, requestExtensions, X509_EXTENSION, 2) |
| } ASN1_SEQUENCE_END(TBSRequest); |
| |
| ASN1_SEQUENCE(OCSPRequest) = { |
| ASN1_SIMPLE(OCSPRequest, tbsRequest, TBSRequest), |
| ASN1_EXP_OPT(OCSPRequest, optionalSignature, Signature, 0) |
| } ASN1_SEQUENCE_END(OCSPRequest); |
| |
| /* Response templates */ |
| |
| ASN1_SEQUENCE(ResponseBytes) = { |
| ASN1_SIMPLE(ResponseBytes, responseType, ASN1_OBJECT), |
| ASN1_SIMPLE(ResponseBytes, response, ASN1_OCTET_STRING) |
| } ASN1_SEQUENCE_END(ResponseBytes); |
| |
| ASN1_SEQUENCE(OCSPResponse) = { |
| ASN1_SIMPLE(OCSPResponse, responseStatus, ASN1_ENUMERATED), |
| ASN1_EXP_OPT(OCSPResponse, responseBytes, ResponseBytes, 0) |
| } ASN1_SEQUENCE_END(OCSPResponse); |
| |
| ASN1_CHOICE(ResponderID) = { |
| ASN1_EXP(ResponderID, d.byName, X509_NAME, 1), |
| ASN1_IMP(ResponderID, d.byKey, ASN1_OCTET_STRING, 2) |
| } ASN1_CHOICE_END(ResponderID); |
| |
| ASN1_SEQUENCE(RevokedInfo) = { |
| ASN1_SIMPLE(RevokedInfo, revocationTime, ASN1_GENERALIZEDTIME), |
| ASN1_EXP_OPT(RevokedInfo, revocationReason, ASN1_ENUMERATED, 0) |
| } ASN1_SEQUENCE_END(RevokedInfo); |
| |
| ASN1_CHOICE(CertStatus) = { |
| ASN1_IMP(CertStatus, d.good, ASN1_NULL, 0), |
| ASN1_IMP(CertStatus, d.revoked, RevokedInfo, 1), |
| ASN1_IMP(CertStatus, d.unknown, ASN1_NULL, 2) |
| } ASN1_CHOICE_END(CertStatus); |
| |
| ASN1_SEQUENCE(SingleResponse) = { |
| ASN1_SIMPLE(SingleResponse, certID, CertID), |
| ASN1_SIMPLE(SingleResponse, certStatus, CertStatus), |
| ASN1_SIMPLE(SingleResponse, thisUpdate, ASN1_GENERALIZEDTIME), |
| ASN1_EXP_OPT(SingleResponse, nextUpdate, ASN1_GENERALIZEDTIME, 0), |
| ASN1_EXP_SEQUENCE_OF_OPT(SingleResponse, singleExtensions, X509_EXTENSION, 1) |
| } ASN1_SEQUENCE_END(SingleResponse); |
| |
| ASN1_SEQUENCE(ResponseData) = { |
| ASN1_EXP_OPT(ResponseData, version, ASN1_INTEGER, 0), |
| ASN1_SIMPLE(ResponseData, responderID, ResponderID), |
| ASN1_SIMPLE(ResponseData, producedAt, ASN1_GENERALIZEDTIME), |
| ASN1_SEQUENCE_OF(ResponseData, responses, SingleResponse), |
| ASN1_EXP_SEQUENCE_OF_OPT(ResponseData, responseExtensions, X509_EXTENSION, 1) |
| } ASN1_SEQUENCE_END(ResponseData); |
| |
| ASN1_SEQUENCE(BasicOCSPResponse) = { |
| ASN1_SIMPLE(BasicOCSPResponse, tbsResponseData, ResponseData), |
| ASN1_SIMPLE(BasicOCSPResponse, signatureAlgorithm, X509_ALGOR), |
| ASN1_SIMPLE(BasicOCSPResponse, signature, ASN1_BIT_STRING), |
| ASN1_EXP_SEQUENCE_OF_OPT(BasicOCSPResponse, certs, X509, 0) |
| } ASN1_SEQUENCE_END(BasicOCSPResponse); |