2 * Copyright (c) 2008-2009,2012,2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * SecOCSPRequest.c - Trust policies dealing with certificate revocation.
28 #include <securityd/SecOCSPRequest.h>
29 #include <Security/SecCertificateInternal.h>
30 #include <AssertMacros.h>
31 #include <utilities/debugging.h>
32 #include <security_asn1/SecAsn1Coder.h>
33 #include <security_asn1/ocspTemplates.h>
34 #include <security_asn1/oidsalg.h>
35 #include <security_asn1/oidsocsp.h>
36 #include <CommonCrypto/CommonDigest.h>
38 #include "SecInternal.h"
41 OCSPRequest ::= SEQUENCE {
42 tbsRequest TBSRequest,
43 optionalSignature [0] EXPLICIT Signature OPTIONAL }
45 TBSRequest ::= SEQUENCE {
46 version [0] EXPLICIT Version DEFAULT v1,
47 requestorName [1] EXPLICIT GeneralName OPTIONAL,
48 requestList SEQUENCE OF Request,
49 requestExtensions [2] EXPLICIT Extensions OPTIONAL }
51 Signature ::= SEQUENCE {
52 signatureAlgorithm AlgorithmIdentifier,
54 certs [0] EXPLICIT SEQUENCE OF Certificate
57 Version ::= INTEGER { v1(0) }
59 Request ::= SEQUENCE {
61 singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL }
64 hashAlgorithm AlgorithmIdentifier,
65 issuerNameHash OCTET STRING, -- Hash of Issuer's DN
66 issuerKeyHash OCTET STRING, -- Hash of Issuers public key
67 serialNumber CertificateSerialNumber }
69 static CFDataRef
_SecOCSPRequestCopyDEREncoding(SecOCSPRequestRef
this) {
70 /* fields obtained from issuer */
71 SecAsn1OCSPSignedRequest signedReq
= {};
72 SecAsn1OCSPTbsRequest
*tbs
= &signedReq
.tbsRequest
;
73 SecAsn1OCSPRequest singleReq
= {};
74 SecAsn1OCSPCertID
*certId
= &singleReq
.reqCert
;
75 SecAsn1OCSPRequest
*reqArray
[2] = { &singleReq
, NULL
};
77 SecAsn1Item vers
= {1, &version
};
79 SecAsn1CoderRef coder
= NULL
;
80 CFDataRef issuerNameDigest
;
82 CFDataRef issuerPubKeyDigest
;
85 /* algId refers to the hash we'll perform in issuer name and key */
86 certId
->algId
.algorithm
= CSSMOID_SHA1
;
87 /* preencoded DER NULL */
88 static uint8_t nullParam
[2] = {5, 0};
89 certId
->algId
.parameters
.Data
= nullParam
;
90 certId
->algId
.parameters
.Length
= sizeof(nullParam
);
92 /* @@@ Change this from using SecCertificateCopyIssuerSHA1Digest() /
93 SecCertificateCopyPublicKeySHA1Digest() to
94 SecCertificateCopyIssuerSequence() / SecCertificateGetPublicKeyData()
95 and call SecDigestCreate here instead. */
96 issuerNameDigest
= SecCertificateCopyIssuerSHA1Digest(this->certificate
);
97 serial
= SecCertificateCopySerialNumber(this->certificate
);
98 issuerPubKeyDigest
= SecCertificateCopyPublicKeySHA1Digest(this->issuer
);
100 /* build the CertID from those components */
101 certId
->issuerNameHash
.Length
= CC_SHA1_DIGEST_LENGTH
;
102 certId
->issuerNameHash
.Data
= (uint8_t *)CFDataGetBytePtr(issuerNameDigest
);
103 certId
->issuerPubKeyHash
.Length
= CC_SHA1_DIGEST_LENGTH
;
104 certId
->issuerPubKeyHash
.Data
= (uint8_t *)CFDataGetBytePtr(issuerPubKeyDigest
);
105 certId
->serialNumber
.Length
= CFDataGetLength(serial
);
106 certId
->serialNumber
.Data
= (uint8_t *)CFDataGetBytePtr(serial
);
108 /* Build top level request with one entry in requestList, no signature,
109 and no optional extensions. */
110 tbs
->version
= &vers
;
111 tbs
->requestList
= reqArray
;
113 /* Encode the request. */
114 require_noerr(SecAsn1CoderCreate(&coder
), errOut
);
116 require_noerr(SecAsn1EncodeItem(coder
, &signedReq
,
117 kSecAsn1OCSPSignedRequestTemplate
, &encoded
), errOut
);
118 der
= CFDataCreate(kCFAllocatorDefault
, encoded
.Data
,
123 SecAsn1CoderRelease(coder
);
124 CFReleaseSafe(issuerNameDigest
);
125 CFReleaseSafe(serial
);
126 CFReleaseSafe(issuerPubKeyDigest
);
131 SecOCSPRequestRef
SecOCSPRequestCreate(SecCertificateRef certificate
,
132 SecCertificateRef issuer
) {
133 SecOCSPRequestRef
this;
134 require(this = (SecOCSPRequestRef
)calloc(1, sizeof(struct __SecOCSPRequest
)),
136 this->certificate
= certificate
;
137 this->issuer
= issuer
;
142 SecOCSPRequestFinalize(this);
147 CFDataRef
SecOCSPRequestGetDER(SecOCSPRequestRef
this) {
148 CFDataRef der
= this->der
;
150 this->der
= der
= _SecOCSPRequestCopyDEREncoding(this);
155 void SecOCSPRequestFinalize(SecOCSPRequestRef
this) {
156 CFReleaseSafe(this->der
);