]> git.saurik.com Git - apple/security.git/blob - Security/sec/securityd/SecOCSPRequest.c
Security-57031.30.12.tar.gz
[apple/security.git] / Security / sec / securityd / SecOCSPRequest.c
1 /*
2 * Copyright (c) 2008-2009,2012,2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * SecOCSPRequest.c - Trust policies dealing with certificate revocation.
26 */
27
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>
37 #include <stdlib.h>
38 #include "SecInternal.h"
39
40 /*
41 OCSPRequest ::= SEQUENCE {
42 tbsRequest TBSRequest,
43 optionalSignature [0] EXPLICIT Signature OPTIONAL }
44
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 }
50
51 Signature ::= SEQUENCE {
52 signatureAlgorithm AlgorithmIdentifier,
53 signature BIT STRING,
54 certs [0] EXPLICIT SEQUENCE OF Certificate
55 OPTIONAL}
56
57 Version ::= INTEGER { v1(0) }
58
59 Request ::= SEQUENCE {
60 reqCert CertID,
61 singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL }
62
63 CertID ::= SEQUENCE {
64 hashAlgorithm AlgorithmIdentifier,
65 issuerNameHash OCTET STRING, -- Hash of Issuer's DN
66 issuerKeyHash OCTET STRING, -- Hash of Issuers public key
67 serialNumber CertificateSerialNumber }
68 */
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 };
76 uint8_t version = 0;
77 SecAsn1Item vers = {1, &version};
78 CFDataRef der = NULL;
79 SecAsn1CoderRef coder = NULL;
80 CFDataRef issuerNameDigest;
81 CFDataRef serial;
82 CFDataRef issuerPubKeyDigest;
83
84
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);
91
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);
99
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);
107
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;
112
113 /* Encode the request. */
114 require_noerr(SecAsn1CoderCreate(&coder), errOut);
115 SecAsn1Item encoded;
116 require_noerr(SecAsn1EncodeItem(coder, &signedReq,
117 kSecAsn1OCSPSignedRequestTemplate, &encoded), errOut);
118 der = CFDataCreate(kCFAllocatorDefault, encoded.Data,
119 encoded.Length);
120
121 errOut:
122 if (coder)
123 SecAsn1CoderRelease(coder);
124 CFReleaseSafe(issuerNameDigest);
125 CFReleaseSafe(serial);
126 CFReleaseSafe(issuerPubKeyDigest);
127
128 return der;
129 }
130
131 SecOCSPRequestRef SecOCSPRequestCreate(SecCertificateRef certificate,
132 SecCertificateRef issuer) {
133 SecOCSPRequestRef this;
134 require(this = (SecOCSPRequestRef)calloc(1, sizeof(struct __SecOCSPRequest)),
135 errOut);
136 this->certificate = certificate;
137 this->issuer = issuer;
138
139 return this;
140 errOut:
141 if (this) {
142 SecOCSPRequestFinalize(this);
143 }
144 return NULL;
145 }
146
147 CFDataRef SecOCSPRequestGetDER(SecOCSPRequestRef this) {
148 CFDataRef der = this->der;
149 if (!der) {
150 this->der = der = _SecOCSPRequestCopyDEREncoding(this);
151 }
152 return der;
153 }
154
155 void SecOCSPRequestFinalize(SecOCSPRequestRef this) {
156 CFReleaseSafe(this->der);
157 free(this);
158 }
159