]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_apple_x509_cl/lib/Session_CRL.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / libsecurity_apple_x509_cl / lib / Session_CRL.cpp
1 /*
2 * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 //
20 // Apple X.509 CRL-related session functions.
21 //
22
23 #include "AppleX509CLSession.h"
24 #include "clNssUtils.h"
25 #include "clNameUtils.h"
26
27 void
28 AppleX509CLSession::CrlDescribeFormat(
29 uint32 &NumberOfFields,
30 CSSM_OID_PTR &OidList)
31 {
32 DecodedCrl::describeFormat(*this, NumberOfFields, OidList);
33 }
34
35
36 void
37 AppleX509CLSession::CrlGetAllFields(
38 const CssmData &Crl,
39 uint32 &NumberOfCrlFields,
40 CSSM_FIELD_PTR &CrlFields)
41 {
42 class DecodedCrl decodedCrl(*this, Crl);
43 decodedCrl.getAllParsedCrlFields(NumberOfCrlFields, CrlFields);
44 }
45
46
47 CSSM_HANDLE
48 AppleX509CLSession::CrlGetFirstFieldValue(
49 const CssmData &Crl,
50 const CssmData &CrlField,
51 uint32 &NumberOfMatchedFields,
52 CSSM_DATA_PTR &Value)
53 {
54 NumberOfMatchedFields = 0;
55 Value = NULL;
56 CssmAutoData aData(*this);
57
58 DecodedCrl *decodedCrl = new DecodedCrl(*this, Crl);
59 uint32 numMatches;
60
61 /* this returns false if field not there, throws on bad OID */
62 bool brtn;
63 try {
64 brtn = decodedCrl->getCrlFieldData(CrlField,
65 0, // index
66 numMatches,
67 aData);
68 }
69 catch (...) {
70 delete decodedCrl;
71 throw;
72 }
73 if(!brtn) {
74 delete decodedCrl;
75 return CSSM_INVALID_HANDLE;
76 }
77
78 /* cook up a CLCachedCRL, stash it in cache */
79 CLCachedCRL *cachedCrl = new CLCachedCRL(*decodedCrl);
80 cacheMap.addEntry(*cachedCrl, cachedCrl->handle());
81
82 /* cook up a CLQuery, stash it */
83 CLQuery *query = new CLQuery(
84 CLQ_CRL,
85 CrlField,
86 numMatches,
87 false, // isFromCache
88 cachedCrl->handle());
89 queryMap.addEntry(*query, query->handle());
90
91 /* success - copy field data to outgoing Value */
92 Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
93 *Value = aData.release();
94 NumberOfMatchedFields = numMatches;
95 return query->handle();
96 }
97
98
99 bool
100 AppleX509CLSession::CrlGetNextFieldValue(
101 CSSM_HANDLE ResultsHandle,
102 CSSM_DATA_PTR &Value)
103 {
104 /* fetch & validate the query */
105 CLQuery *query = queryMap.lookupEntry(ResultsHandle);
106 if(query == NULL) {
107 CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
108 }
109 if(query->queryType() != CLQ_CRL) {
110 clErrorLog("CrlGetNextFieldValue: bad queryType (%d)",
111 (int)query->queryType());
112 CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
113 }
114 if(query->nextIndex() >= query->numFields()) {
115 return false;
116 }
117
118 /* fetch the associated cached CRL */
119 CLCachedCRL *cachedCrl = lookupCachedCRL(query->cachedObject());
120 uint32 dummy;
121 CssmAutoData aData(*this);
122 if(!cachedCrl->crl().getCrlFieldData(query->fieldId(),
123 query->nextIndex(),
124 dummy,
125 aData)) {
126 return false;
127 }
128
129 /* success - copy field data to outgoing Value */
130 Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
131 *Value = aData.release();
132 query->incrementIndex();
133 return true;
134 }
135
136
137 void
138 AppleX509CLSession::IsCertInCrl(
139 const CssmData &Cert,
140 const CssmData &Crl,
141 CSSM_BOOL &CertFound)
142 {
143 /*
144 * Decode the two entities. Note that doing it this way incurs
145 * the unnecessary (for our purposes) overhead of decoding
146 * extensions, but doing it this way is so spiffy that I can't
147 * resist.
148 */
149 DecodedCert decodedCert(*this, Cert);
150 DecodedCrl decodedCrl(*this, Crl);
151
152 NSS_TBSCertificate &tbsCert = decodedCert.mCert.tbs;
153 NSS_TBSCrl &tbsCrl = decodedCrl.mCrl.tbs;
154
155 /* trivial case - empty CRL */
156 unsigned numCrlEntries =
157 clNssArraySize((const void **)tbsCrl.revokedCerts);
158 if(numCrlEntries == 0) {
159 clFieldLog("IsCertInCrl: empty CRL");
160 CertFound = CSSM_FALSE;
161 return;
162 }
163
164 /*
165 * Get normalized and encoded versions of issuer names.
166 * Since the decoded entities are local, we can normalize in place.
167 */
168 CssmAutoData encCertIssuer(*this);
169 CssmAutoData encCrlIssuer(*this);
170 try {
171 /* snag a handy temp allocator */
172 SecNssCoder &coder = decodedCert.coder();
173 CL_normalizeX509NameNSS(tbsCert.issuer, coder);
174 PRErrorCode prtn = SecNssEncodeItemOdata(&tbsCert.issuer,
175 kSecAsn1NameTemplate, encCertIssuer);
176 if(prtn) {
177 CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR);
178 }
179
180 CL_normalizeX509NameNSS(tbsCrl.issuer, coder);
181 prtn = SecNssEncodeItemOdata(&tbsCrl.issuer,
182 kSecAsn1NameTemplate, encCrlIssuer);
183 if(prtn) {
184 CssmError::throwMe(CSSMERR_CL_MEMORY_ERROR);
185 }
186 }
187 catch(...) {
188 clFieldLog("IsCertInCrl: normalize failure");
189 throw;
190 }
191
192 /* issuer names match? */
193 CertFound = CSSM_FALSE;
194 if(encCertIssuer.get() != encCrlIssuer.get()) {
195 clFieldLog("IsCertInCrl: issuer name mismatch");
196 return;
197 }
198
199 /* is this cert's serial number in the CRL? */
200 CSSM_DATA &certSerial = tbsCert.serialNumber;
201 for(unsigned dex=0; dex<numCrlEntries; dex++) {
202 NSS_RevokedCert *revokedCert = tbsCrl.revokedCerts[dex];
203 assert(revokedCert != NULL);
204 CSSM_DATA &revokedSerial = revokedCert->userCertificate;
205 if(clCompareCssmData(&certSerial, &revokedSerial)) {
206 /* success */
207 CertFound = CSSM_TRUE;
208 break;
209 }
210 }
211 }
212
213 #pragma mark --- Cached ---
214
215 void
216 AppleX509CLSession::CrlCache(
217 const CssmData &Crl,
218 CSSM_HANDLE &CrlHandle)
219 {
220 DecodedCrl *decodedCrl = new DecodedCrl(*this, Crl);
221
222 /* cook up a CLCachedCRL, stash it in cache */
223 CLCachedCRL *cachedCrl = new CLCachedCRL(*decodedCrl);
224 cacheMap.addEntry(*cachedCrl, cachedCrl->handle());
225 CrlHandle = cachedCrl->handle();
226 }
227
228 /*
229 * FIXME - CrlRecordIndex not supported, it'll require mods to
230 * the DecodedCrl::getCrlFieldData mechanism
231 */
232 CSSM_HANDLE
233 AppleX509CLSession::CrlGetFirstCachedFieldValue(
234 CSSM_HANDLE CrlHandle,
235 const CssmData *CrlRecordIndex,
236 const CssmData &CrlField,
237 uint32 &NumberOfMatchedFields,
238 CSSM_DATA_PTR &Value)
239 {
240 if(CrlRecordIndex != NULL) {
241 /* not yet */
242 CssmError::throwMe(CSSMERR_CL_INVALID_CRL_INDEX);
243 }
244
245 /* fetch the associated cached CRL */
246 CLCachedCRL *cachedCrl = lookupCachedCRL(CrlHandle);
247 if(cachedCrl == NULL) {
248 CssmError::throwMe(CSSMERR_CL_INVALID_CACHE_HANDLE);
249 }
250
251 CssmAutoData aData(*this);
252 uint32 numMatches;
253
254 /* this returns false if field not there, throws on bad OID */
255 if(!cachedCrl->crl().getCrlFieldData(CrlField,
256 0, // index
257 numMatches,
258 aData)) {
259 return CSSM_INVALID_HANDLE;
260 }
261
262 /* cook up a CLQuery, stash it */
263 CLQuery *query = new CLQuery(
264 CLQ_CRL,
265 CrlField,
266 numMatches,
267 true, // isFromCache
268 cachedCrl->handle());
269 queryMap.addEntry(*query, query->handle());
270
271 /* success - copy field data to outgoing Value */
272 Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
273 *Value = aData.release();
274 NumberOfMatchedFields = numMatches;
275 return query->handle();
276 }
277
278
279 bool
280 AppleX509CLSession::CrlGetNextCachedFieldValue(
281 CSSM_HANDLE ResultsHandle,
282 CSSM_DATA_PTR &Value)
283 {
284 /* Identical to, so just call... */
285 return CrlGetNextFieldValue(ResultsHandle, Value);
286 }
287
288
289 void
290 AppleX509CLSession::IsCertInCachedCrl(
291 const CssmData &Cert,
292 CSSM_HANDLE CrlHandle,
293 CSSM_BOOL &CertFound,
294 CssmData &CrlRecordIndex)
295 {
296 unimplemented();
297 }
298
299
300 void
301 AppleX509CLSession::CrlAbortCache(
302 CSSM_HANDLE CrlHandle)
303 {
304 /* fetch the associated cached CRL, remove from map, delete it */
305 CLCachedCRL *cachedCrl = lookupCachedCRL(CrlHandle);
306 if(cachedCrl == NULL) {
307 CssmError::throwMe(CSSMERR_CL_INVALID_CACHE_HANDLE);
308 }
309 cacheMap.removeEntry(cachedCrl->handle());
310 delete cachedCrl;
311 }
312
313
314 void
315 AppleX509CLSession::CrlAbortQuery(
316 CSSM_HANDLE ResultsHandle)
317 {
318 /* fetch & validate the query */
319 CLQuery *query = queryMap.lookupEntry(ResultsHandle);
320 if(query == NULL) {
321 CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
322 }
323 if(query->queryType() != CLQ_CRL) {
324 clErrorLog("CrlAbortQuery: bad queryType (%d)", (int)query->queryType());
325 CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
326 }
327
328 if(!query->fromCache()) {
329 /* the associated cached CRL was created just for this query; dispose */
330 CLCachedCRL *cachedCrl = lookupCachedCRL(query->cachedObject());
331 if(cachedCrl == NULL) {
332 /* should never happen */
333 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
334 }
335 cacheMap.removeEntry(cachedCrl->handle());
336 delete cachedCrl;
337 }
338 queryMap.removeEntry(query->handle());
339 delete query;
340 }
341
342 #pragma mark --- Template ---
343
344 void
345 AppleX509CLSession::CrlCreateTemplate(
346 uint32 NumberOfFields,
347 const CSSM_FIELD *CrlTemplate,
348 CssmData &NewCrl)
349 {
350 unimplemented();
351 }
352
353
354 void
355 AppleX509CLSession::CrlSetFields(
356 uint32 NumberOfFields,
357 const CSSM_FIELD *CrlTemplate,
358 const CssmData &OldCrl,
359 CssmData &ModifiedCrl)
360 {
361 unimplemented();
362 }
363
364
365 void
366 AppleX509CLSession::CrlAddCert(
367 CSSM_CC_HANDLE CCHandle,
368 const CssmData &Cert,
369 uint32 NumberOfFields,
370 const CSSM_FIELD CrlEntryFields[],
371 const CssmData &OldCrl,
372 CssmData &NewCrl)
373 {
374 unimplemented();
375 }
376
377
378 void
379 AppleX509CLSession::CrlRemoveCert(
380 const CssmData &Cert,
381 const CssmData &OldCrl,
382 CssmData &NewCrl)
383 {
384 unimplemented();
385 }
386
387
388 void
389 AppleX509CLSession::CrlGetAllCachedRecordFields(
390 CSSM_HANDLE CrlHandle,
391 const CssmData &CrlRecordIndex,
392 uint32 &NumberOfFields,
393 CSSM_FIELD_PTR &CrlFields)
394 {
395 unimplemented();
396 }
397
398 /*
399 * These are functionally identical to the corresponding
400 * Cert functions.
401 */
402 void
403 AppleX509CLSession::CrlVerifyWithKey(
404 CSSM_CC_HANDLE CCHandle,
405 const CssmData &CrlToBeVerified)
406 {
407 CertVerifyWithKey(CCHandle, CrlToBeVerified);
408 }
409
410
411 void
412 AppleX509CLSession::CrlVerify(
413 CSSM_CC_HANDLE CCHandle,
414 const CssmData &CrlToBeVerified,
415 const CssmData *SignerCert,
416 const CSSM_FIELD *VerifyScope,
417 uint32 ScopeSize)
418 {
419 CertVerify(CCHandle, CrlToBeVerified, SignerCert, VerifyScope,
420 ScopeSize);
421 }
422
423 void
424 AppleX509CLSession::CrlSign(
425 CSSM_CC_HANDLE CCHandle,
426 const CssmData &UnsignedCrl,
427 const CSSM_FIELD *SignScope,
428 uint32 ScopeSize,
429 CssmData &SignedCrl)
430 {
431 unimplemented();
432 }
433
434
435
436