]> git.saurik.com Git - apple/security.git/blob - OSX/include/security_ocspd/ocspExtensions.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / include / security_ocspd / ocspExtensions.cpp
1 /*
2 * Copyright (c) 2004,2011,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 * ocspExtensions.cpp - OCSP Extension support.
26 */
27
28 #include "ocspExtensions.h"
29 #include "ocspdDebug.h"
30 #include "ocspdUtils.h"
31 #include <Security/oidscrl.h>
32 #include <Security/cssmapple.h>
33 #include <strings.h>
34 #include "ocspdDebug.h"
35 #include <security_cdsa_utilities/cssmerrors.h>
36
37 #pragma mark ----- base class : OCSCExtension -----
38
39 /*
40 * Public means to vend a subclass of this object while decoding.
41 */
42 OCSPExtension *OCSPExtension::createFromNSS(
43 SecAsn1CoderRef coder,
44 const NSS_CertExtension &nssExt)
45 {
46 const CSSM_OID *extnId = &nssExt.extnId;
47 if(ocspdCompareCssmData(extnId, &CSSMOID_PKIX_OCSP_NONCE)) {
48 return new OCSPNonce(coder, nssExt);
49 }
50 /* more here */
51 else {
52 return new OCSPExtension(coder, nssExt, OET_Unknown);
53 }
54 }
55
56 /*
57 * Called in two circumstances:
58 *
59 * -- from subclass-specific constructor during decode
60 * -- from createFromNSS (during decode) when we don't recognize the extension ID
61 */
62 OCSPExtension::OCSPExtension(
63 SecAsn1CoderRef coder,
64 const NSS_CertExtension &nssExt,
65 OCSPExtensionTag tag)
66 : mNssExt(const_cast<NSS_CertExtension *>(&nssExt)),
67 mCoder(coder),
68 mTag(tag),
69 mUnrecognizedCritical(false)
70 {
71 if((nssExt.critical.Data != NULL) && (*nssExt.critical.Data != 0)) {
72 mCritical = true;
73 }
74 else {
75 mCritical = false;
76 }
77 if(mCritical && (tag == OET_Unknown)) {
78 mUnrecognizedCritical = true;
79 }
80 }
81
82 /*
83 * Constructor during encode, called from subclass-specific constructorÊ(which
84 * always has all of the subclass-specific arguments).
85 */
86 OCSPExtension::OCSPExtension(
87 SecAsn1CoderRef coder, // passed to subclass constructor
88 const CSSM_OID &extnId, // subclass knows this
89 OCSPExtensionTag tag, // subclass knows this
90 bool critical) // passed to subclass constructor
91 : mNssExt(NULL), // we'll cook this up
92 mCoder(coder),
93 mCritical(critical),
94 mTag(tag),
95 mUnrecognizedCritical(false) // this is a tautology
96 {
97 mNssExt = (NSS_CertExtension *)SecAsn1Malloc(coder, sizeof(NSS_CertExtension));
98 memset(mNssExt, 0, sizeof(NSS_CertExtension));
99 SecAsn1AllocCopyItem(coder, &extnId, &mNssExt->extnId);
100 /* alloc one byte for critical flag */
101 SecAsn1AllocItem(coder, &mNssExt->critical, 1);
102 mNssExt->critical.Data[0] = critical ? 0xff : 0;
103 }
104
105 OCSPExtension::~OCSPExtension()
106 {
107 /* nothing for now, need a virtual function for dynamic casts */
108 }
109
110 #pragma mark ---- Nonce -----
111
112 /*
113 * Public constructor on encode
114 */
115 OCSPNonce::OCSPNonce(
116 SecAsn1CoderRef coder,
117 bool critical,
118 const CSSM_DATA &nonce)
119 : OCSPExtension(coder, CSSMOID_PKIX_OCSP_NONCE, OET_Nonce, critical)
120 {
121 /*
122 * They don't get much simpler than this: the nonce is the literal value
123 * of NSS_CertExtension.value.
124 */
125 SecAsn1AllocCopyItem(coder, &nonce, &mNonce);
126 setDerValue(mNonce);
127 }
128
129 /* construct during decode, called only by OCSPExtension::createFromNSS() */
130 OCSPNonce::OCSPNonce(
131 SecAsn1CoderRef coder,
132 const NSS_CertExtension &nssExt)
133 : OCSPExtension(coder, nssExt, OET_Nonce)
134 {
135 /* only subclass-specific stuff is the nonce, no further processing needed */
136 SecAsn1AllocCopyItem(coder, &nssExt.value, &mNonce);
137 }
138
139 OCSPNonce::~OCSPNonce()
140 {
141 /* nothing for now, need a virtual function for dynamic casts */
142 }
143
144 #pragma mark ----- Extensions array -----
145
146 OCSPExtensions::OCSPExtensions(
147 NSS_CertExtension **nssExts)
148 : mCoder(NULL), mNumExtensions(0), mExtensions(NULL)
149 {
150 SecAsn1CoderCreate(&mCoder);
151 mNumExtensions = ocspdArraySize((const void **)nssExts);
152 if(mNumExtensions == 0) {
153 return;
154 }
155
156 mExtensions = (OCSPExtension **)SecAsn1Malloc(mCoder,
157 (mNumExtensions * sizeof(OCSPExtension *)));
158 for(unsigned dex=0; dex<mNumExtensions; dex++) {
159 try {
160 mExtensions[dex] =
161 OCSPExtension::createFromNSS(mCoder, *nssExts[dex]);
162 if(mExtensions[dex] == NULL) {
163 ocspdErrorLog("OCSPExtensions: extension failure (NULL) dex %u\n", dex);
164 CssmError::throwMe(CSSMERR_APPLETP_OCSP_BAD_RESPONSE);
165 }
166 if(mExtensions[dex]->unrecognizedCritical()) {
167 ocspdErrorLog("OCSPExtensions: unrecognized critical extension\n");
168 CssmError::throwMe(CSSMERR_APPLETP_OCSP_BAD_RESPONSE);
169 }
170 }
171 catch (...) {
172 ocspdErrorLog("OCSPExtensions: extension failure dex %u\n", dex);
173 CssmError::throwMe(CSSMERR_APPLETP_OCSP_BAD_RESPONSE);
174 }
175 }
176 }
177
178 OCSPExtensions::~OCSPExtensions()
179 {
180 for(unsigned dex=0; dex<mNumExtensions; dex++) {
181 delete mExtensions[dex];
182 }
183 if(mCoder) {
184 SecAsn1CoderRelease(mCoder);
185 }
186 }
187
188 /* find parsed extension in mExtensions with specified OID */
189 OCSPExtension *OCSPExtensions::findExtension(
190 const CSSM_OID &oid)
191 {
192 for(unsigned dex=0; dex<mNumExtensions; dex++) {
193 const CSSM_OID &extnId = mExtensions[dex]->extnId();
194 if(ocspdCompareCssmData(&oid, &extnId)) {
195 return mExtensions[dex];
196 }
197 }
198 return NULL;
199 }
200