]> git.saurik.com Git - apple/security.git/blob - CdsaUtils/cuCdsaUtils.cpp
Security-163.tar.gz
[apple/security.git] / CdsaUtils / cuCdsaUtils.cpp
1 /*
2 * Copyright (c) 2001-2003 Apple Computer, 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
7 * obtain a copy of the License at http://www.apple.com/publicsource and
8 * read it before 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
12 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
13 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
15 * Please see the License for the specific language governing rights and
16 * limitations under the License.
17 */
18
19 /*
20 File: cuCdsaUtils.cpp
21
22 Description: common CDSA access utilities
23
24 Author: dmitch
25 */
26
27 #include "cuCdsaUtils.h"
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <Security/SecCertificate.h>
31 #include <Security/cssmapple.h> /* for cssmPerror() */
32 #include <Security/oidsalg.h> /* for cssmPerror() */
33 #include <strings.h>
34
35 static CSSM_VERSION vers = {2, 0};
36 static const CSSM_GUID testGuid = { 0xFADE, 0, 0, { 1,2,3,4,5,6,7,0 }};
37
38 /*
39 * Standard app-level memory functions required by CDSA.
40 */
41 void * cuAppMalloc (uint32 size, void *allocRef) {
42 return( malloc(size) );
43 }
44
45 void cuAppFree (void *mem_ptr, void *allocRef) {
46 free(mem_ptr);
47 return;
48 }
49
50 void * cuAppRealloc (void *ptr, uint32 size, void *allocRef) {
51 return( realloc( ptr, size ) );
52 }
53
54 void * cuAppCalloc (uint32 num, uint32 size, void *allocRef) {
55 return( calloc( num, size ) );
56 }
57
58 static CSSM_API_MEMORY_FUNCS memFuncs = {
59 cuAppMalloc,
60 cuAppFree,
61 cuAppRealloc,
62 cuAppCalloc,
63 NULL
64 };
65
66 CSSM_BOOL cuCompareCssmData(const CSSM_DATA *d1,
67 const CSSM_DATA *d2)
68 {
69 if(d1->Length != d2->Length) {
70 return CSSM_FALSE;
71 }
72 if(memcmp(d1->Data, d2->Data, d1->Length)) {
73 return CSSM_FALSE;
74 }
75 return CSSM_TRUE;
76 }
77
78 /*
79 * Init CSSM; returns CSSM_FALSE on error. Reusable.
80 */
81 static CSSM_BOOL cssmInitd = CSSM_FALSE;
82
83 CSSM_BOOL cuCssmStartup()
84 {
85 CSSM_RETURN crtn;
86 CSSM_PVC_MODE pvcPolicy = CSSM_PVC_NONE;
87
88 if(cssmInitd) {
89 return CSSM_TRUE;
90 }
91 crtn = CSSM_Init (&vers,
92 CSSM_PRIVILEGE_SCOPE_NONE,
93 &testGuid,
94 CSSM_KEY_HIERARCHY_NONE,
95 &pvcPolicy,
96 NULL /* reserved */);
97 if(crtn != CSSM_OK)
98 {
99 cuPrintError("CSSM_Init", crtn);
100 return CSSM_FALSE;
101 }
102 else {
103 cssmInitd = CSSM_TRUE;
104 return CSSM_TRUE;
105 }
106 }
107
108 /*
109 * Attach to CSP. Returns zero on error.
110 */
111 CSSM_CSP_HANDLE cuCspStartup(
112 CSSM_BOOL bareCsp) // true ==> CSP, false ==> CSP/DL
113 {
114 CSSM_CSP_HANDLE cspHand;
115 CSSM_RETURN crtn;
116 const CSSM_GUID *guid;
117
118 /* common CSSM init */
119 if(cuCssmStartup() == CSSM_FALSE) {
120 return 0;
121 }
122 if(bareCsp) {
123 guid = &gGuidAppleCSP;
124 }
125 else {
126 guid = &gGuidAppleCSPDL;
127 }
128 crtn = CSSM_ModuleLoad(guid,
129 CSSM_KEY_HIERARCHY_NONE,
130 NULL, // eventHandler
131 NULL); // AppNotifyCallbackCtx
132 if(crtn) {
133 cuPrintError("CSSM_ModuleLoad()", crtn);
134 return 0;
135 }
136 crtn = CSSM_ModuleAttach (guid,
137 &vers,
138 &memFuncs, // memFuncs
139 0, // SubserviceID
140 CSSM_SERVICE_CSP,
141 0, // AttachFlags
142 CSSM_KEY_HIERARCHY_NONE,
143 NULL, // FunctionTable
144 0, // NumFuncTable
145 NULL, // reserved
146 &cspHand);
147 if(crtn) {
148 cuPrintError("CSSM_ModuleAttach()", crtn);
149 return 0;
150 }
151 return cspHand;
152 }
153
154 /* Attach to DL side of CSPDL */
155 CSSM_DL_HANDLE cuDlStartup()
156 {
157 CSSM_DL_HANDLE dlHand = 0;
158 CSSM_RETURN crtn;
159
160 if(cuCssmStartup() == CSSM_FALSE) {
161 return 0;
162 }
163 crtn = CSSM_ModuleLoad(&gGuidAppleCSPDL,
164 CSSM_KEY_HIERARCHY_NONE,
165 NULL, // eventHandler
166 NULL); // AppNotifyCallbackCtx
167 if(crtn) {
168 cuPrintError("CSSM_ModuleLoad(Apple CSPDL)", crtn);
169 return 0;
170 }
171 crtn = CSSM_ModuleAttach (&gGuidAppleCSPDL,
172 &vers,
173 &memFuncs, // memFuncs
174 0, // SubserviceID
175 CSSM_SERVICE_DL,
176 0, // AttachFlags
177 CSSM_KEY_HIERARCHY_NONE,
178 NULL, // FunctionTable
179 0, // NumFuncTable
180 NULL, // reserved
181 &dlHand);
182 if(crtn) {
183 cuPrintError("CSSM_ModuleAttach(Apple CSPDL)", crtn);
184 return 0;
185 }
186 return dlHand;
187 }
188
189 CSSM_CL_HANDLE cuClStartup()
190 {
191 CSSM_CL_HANDLE clHand;
192 CSSM_RETURN crtn;
193
194 if(cuCssmStartup() == CSSM_FALSE) {
195 return 0;
196 }
197 crtn = CSSM_ModuleLoad(&gGuidAppleX509CL,
198 CSSM_KEY_HIERARCHY_NONE,
199 NULL, // eventHandler
200 NULL); // AppNotifyCallbackCtx
201 if(crtn) {
202 cuPrintError("CSSM_ModuleLoad(AppleCL)", crtn);
203 return 0;
204 }
205 crtn = CSSM_ModuleAttach (&gGuidAppleX509CL,
206 &vers,
207 &memFuncs, // memFuncs
208 0, // SubserviceID
209 CSSM_SERVICE_CL, // SubserviceFlags - Where is this used?
210 0, // AttachFlags
211 CSSM_KEY_HIERARCHY_NONE,
212 NULL, // FunctionTable
213 0, // NumFuncTable
214 NULL, // reserved
215 &clHand);
216 if(crtn) {
217 cuPrintError("CSSM_ModuleAttach(AppleCL)", crtn);
218 return 0;
219 }
220 else {
221 return clHand;
222 }
223 }
224
225 CSSM_TP_HANDLE cuTpStartup()
226 {
227 CSSM_TP_HANDLE tpHand;
228 CSSM_RETURN crtn;
229
230 if(cuCssmStartup() == CSSM_FALSE) {
231 return 0;
232 }
233 crtn = CSSM_ModuleLoad(&gGuidAppleX509TP,
234 CSSM_KEY_HIERARCHY_NONE,
235 NULL, // eventHandler
236 NULL); // AppNotifyCallbackCtx
237 if(crtn) {
238 cuPrintError("CSSM_ModuleLoad(AppleTP)", crtn);
239 return 0;
240 }
241 crtn = CSSM_ModuleAttach (&gGuidAppleX509TP,
242 &vers,
243 &memFuncs, // memFuncs
244 0, // SubserviceID
245 CSSM_SERVICE_TP, // SubserviceFlags
246 0, // AttachFlags
247 CSSM_KEY_HIERARCHY_NONE,
248 NULL, // FunctionTable
249 0, // NumFuncTable
250 NULL, // reserved
251 &tpHand);
252 if(crtn) {
253 cuPrintError("CSSM_ModuleAttach(AppleTP)", crtn);
254 return 0;
255 }
256 else {
257 return tpHand;
258 }
259 }
260
261 /*
262 * open a DB, ensure it's empty.
263 */
264 CSSM_DB_HANDLE cuDbStartup(
265 CSSM_DL_HANDLE dlHand, // from dlStartup()
266 const char *dbName)
267 {
268 CSSM_DB_HANDLE dbHand = 0;
269 CSSM_RETURN crtn;
270 CSSM_DBINFO dbInfo;
271
272 /* first delete possible existing DB, ignore error */
273 crtn = CSSM_DL_DbDelete(dlHand, dbName, NULL, NULL);
274 switch(crtn) {
275 /* only allowed error is "no such file" */
276 case CSSM_OK:
277 case CSSMERR_DL_DATASTORE_DOESNOT_EXIST:
278 break;
279 default:
280 cuPrintError("CSSM_DL_DbDelete", crtn);
281 return 0;
282 }
283
284 memset(&dbInfo, 0, sizeof(CSSM_DBINFO));
285
286 /* now create it */
287 crtn = CSSM_DL_DbCreate(dlHand,
288 dbName,
289 NULL, // DbLocation
290 &dbInfo,
291 // &Security::KeychainCore::Schema::DBInfo,
292 CSSM_DB_ACCESS_PRIVILEGED,
293 NULL, // CredAndAclEntry
294 NULL, // OpenParameters
295 &dbHand);
296 if(crtn) {
297 cuPrintError("CSSM_DL_DbCreate", crtn);
298 }
299 return dbHand;
300 }
301
302 /*
303 * Attach to existing DB or create an empty new one.
304 */
305 CSSM_DB_HANDLE cuDbStartupByName(CSSM_DL_HANDLE dlHand,
306 char *dbName,
307 CSSM_BOOL doCreate,
308 CSSM_BOOL quiet)
309 {
310 CSSM_RETURN crtn;
311 CSSM_DB_HANDLE dbHand;
312
313 /* try open existing DB in either case */
314
315 crtn = CSSM_DL_DbOpen(dlHand,
316 dbName,
317 NULL, // DbLocation
318 CSSM_DB_ACCESS_READ | CSSM_DB_ACCESS_WRITE,
319 NULL, // CSSM_ACCESS_CREDENTIALS *AccessCred
320 NULL, // void *OpenParameters
321 &dbHand);
322 if(crtn == CSSM_OK) {
323 return dbHand;
324 }
325 if(!doCreate) {
326 if(!quiet) {
327 printf("***no such data base (%s)\n", dbName);
328 cuPrintError("CSSM_DL_DbOpen", crtn);
329 }
330 return 0;
331 }
332 /* have to create one */
333 return cuDbStartup(dlHand, dbName);
334 }
335
336 /*
337 * Given a context specified via a CSSM_CC_HANDLE, add a new
338 * CSSM_CONTEXT_ATTRIBUTE to the context as specified by AttributeType,
339 * AttributeLength, and an untyped pointer.
340 */
341 CSSM_RETURN cuAddContextAttribute(CSSM_CC_HANDLE CCHandle,
342 uint32 AttributeType,
343 uint32 AttributeLength,
344 const void *AttributePtr)
345 {
346 CSSM_CONTEXT_ATTRIBUTE newAttr;
347 CSSM_RETURN crtn;
348
349 newAttr.AttributeType = AttributeType;
350 newAttr.AttributeLength = AttributeLength;
351 newAttr.Attribute.Data = (CSSM_DATA_PTR)AttributePtr;
352 crtn = CSSM_UpdateContextAttributes(CCHandle, 1, &newAttr);
353 if(crtn) {
354 cuPrintError("CSSM_UpdateContextAttributes", crtn);
355 }
356 return crtn;
357 }
358
359
360 /*
361 * Derive symmetric key.
362 * Note in the X CSP, we never return an IV.
363 */
364 CSSM_RETURN cuCspDeriveKey(CSSM_CSP_HANDLE cspHand,
365 uint32 keyAlg, // CSSM_ALGID_RC5, etc.
366 const char *keyLabel,
367 unsigned keyLabelLen,
368 uint32 keyUsage, // CSSM_KEYUSE_ENCRYPT, etc.
369 uint32 keySizeInBits,
370 CSSM_DATA_PTR password, // in PKCS-5 lingo
371 CSSM_DATA_PTR salt, // ditto
372 uint32 iterationCnt, // ditto
373 CSSM_KEY_PTR key)
374 {
375 CSSM_RETURN crtn;
376 CSSM_CC_HANDLE ccHand;
377 uint32 keyAttr;
378 CSSM_DATA dummyLabel;
379 CSSM_PKCS5_PBKDF2_PARAMS pbeParams;
380 CSSM_DATA pbeData;
381 CSSM_ACCESS_CREDENTIALS creds;
382
383 memset(key, 0, sizeof(CSSM_KEY));
384 memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS));
385 crtn = CSSM_CSP_CreateDeriveKeyContext(cspHand,
386 CSSM_ALGID_PKCS5_PBKDF2,
387 keyAlg,
388 keySizeInBits,
389 &creds,
390 NULL, // BaseKey
391 iterationCnt,
392 salt,
393 NULL, // seed
394 &ccHand);
395 if(crtn) {
396 cuPrintError("CSSM_CSP_CreateDeriveKeyContext", crtn);
397 return crtn;
398 }
399 keyAttr = CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_REF |
400 CSSM_KEYATTR_SENSITIVE;
401 dummyLabel.Length = keyLabelLen;
402 dummyLabel.Data = (uint8 *)keyLabel;
403
404 /* passing in password is pretty strange....*/
405 pbeParams.Passphrase = *password;
406 pbeParams.PseudoRandomFunction = CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1;
407 pbeData.Data = (uint8 *)&pbeParams;
408 pbeData.Length = sizeof(pbeParams);
409 crtn = CSSM_DeriveKey(ccHand,
410 &pbeData,
411 keyUsage,
412 keyAttr,
413 &dummyLabel,
414 NULL, // cred and acl
415 key);
416 if(crtn) {
417 cuPrintError("CSSM_DeriveKey", crtn);
418 return crtn;
419 }
420 crtn = CSSM_DeleteContext(ccHand);
421 if(crtn) {
422 cuPrintError("CSSM_DeleteContext", crtn);
423 }
424 return crtn;
425 }
426
427 /*
428 * Generate key pair of arbitrary algorithm.
429 */
430
431 /* CSP DL currently does not perform DSA generate params; let CSP do it implicitly */
432 #define DO_DSA_GEN_PARAMS 0
433
434 CSSM_RETURN cuCspGenKeyPair(CSSM_CSP_HANDLE cspHand,
435 CSSM_DL_DB_HANDLE *dlDbHand, // optional
436 uint32 algorithm,
437 const char *keyLabel,
438 unsigned keyLabelLen,
439 uint32 keySize, // in bits
440 CSSM_KEY_PTR pubKey, // mallocd by caller
441 CSSM_KEYUSE pubKeyUsage, // CSSM_KEYUSE_ENCRYPT, etc.
442 CSSM_KEYATTR_FLAGS pubAttrs, // CSSM_KEYATTR_EXTRACTABLE, etc.
443 CSSM_KEY_PTR privKey, // mallocd by caller
444 CSSM_KEYUSE privKeyUsage, // CSSM_KEYUSE_DECRYPT, etc.
445 CSSM_KEYATTR_FLAGS privAttrs) // CSSM_KEYATTR_EXTRACTABLE, etc.
446 {
447 CSSM_RETURN crtn;
448 CSSM_RETURN ocrtn;
449 CSSM_CC_HANDLE ccHand;
450 CSSM_DATA keyLabelData;
451
452 keyLabelData.Data = (uint8 *)keyLabel,
453 keyLabelData.Length = keyLabelLen;
454 memset(pubKey, 0, sizeof(CSSM_KEY));
455 memset(privKey, 0, sizeof(CSSM_KEY));
456
457 crtn = CSSM_CSP_CreateKeyGenContext(cspHand,
458 algorithm,
459 keySize,
460 NULL, // Seed
461 NULL, // Salt
462 NULL, // StartDate
463 NULL, // EndDate
464 NULL, // Params
465 &ccHand);
466 if(crtn) {
467 cuPrintError("CSSM_CSP_CreateKeyGenContext", crtn);
468 return crtn;
469 }
470
471 /* post-context-create algorithm-specific stuff */
472 switch(algorithm) {
473 #if DO_DSA_GEN_PARAMS
474 case CSSM_ALGID_DSA:
475 /*
476 * extra step - generate params - this just adds some
477 * info to the context
478 */
479 {
480 CSSM_DATA dummy = {0, NULL};
481 crtn = CSSM_GenerateAlgorithmParams(ccHand,
482 keySize, &dummy);
483 if(crtn) {
484 cuPrintError("CSSM_GenerateAlgorithmParams", crtn);
485 CSSM_DeleteContext(ccHand);
486 return crtn;
487 }
488 cuAppFree(dummy.Data, NULL);
489 }
490 break;
491 #endif /* DO_DSA_GEN_PARAMS */
492 default:
493 break;
494 }
495
496 /* optionally specify DL/DB storage location */
497 if(dlDbHand) {
498 crtn = cuAddContextAttribute(ccHand,
499 CSSM_ATTRIBUTE_DL_DB_HANDLE,
500 sizeof(CSSM_ATTRIBUTE_DL_DB_HANDLE),
501 dlDbHand);
502 if(crtn) {
503 CSSM_DeleteContext(ccHand);
504 return crtn;
505 }
506 }
507 ocrtn = CSSM_GenerateKeyPair(ccHand,
508 pubKeyUsage,
509 pubAttrs,
510 &keyLabelData,
511 pubKey,
512 privKeyUsage,
513 privAttrs,
514 &keyLabelData, // same labels
515 NULL, // CredAndAclEntry
516 privKey);
517 if(ocrtn) {
518 cuPrintError("CSSM_GenerateKeyPair", ocrtn);
519 }
520 crtn = CSSM_DeleteContext(ccHand);
521 if(crtn) {
522 cuPrintError("CSSM_DeleteContext", crtn);
523 if(ocrtn == CSSM_OK) {
524 /* error on CSSM_GenerateKeyPair takes precedence */
525 ocrtn = crtn;
526 }
527 }
528 return ocrtn;
529 }
530
531
532 /*
533 * Add a certificate to an open Keychain.
534 */
535 CSSM_RETURN cuAddCertToKC(
536 SecKeychainRef keychain,
537 const CSSM_DATA *cert,
538 CSSM_CERT_TYPE certType,
539 CSSM_CERT_ENCODING certEncoding,
540 const char *printName, // C string
541 const CSSM_DATA *keyLabel) // ??
542 {
543 SecCertificateRef certificate;
544
545 OSStatus rslt = SecCertificateCreateFromData(cert, certType, certEncoding, &certificate);
546 if (!rslt)
547 {
548 rslt = SecCertificateAddToKeychain(certificate, keychain);
549 CFRelease(certificate);
550 }
551
552 return rslt;
553 }
554
555 /*
556 * Convert a CSSM_DATA_PTR, referring to a DER-encoded int, to an
557 * unsigned.
558 */
559 unsigned cuDER_ToInt(const CSSM_DATA *DER_Data)
560 {
561 uint32 rtn = 0;
562 unsigned i = 0;
563
564 while(i < DER_Data->Length) {
565 rtn |= DER_Data->Data[i];
566 if(++i == DER_Data->Length) {
567 break;
568 }
569 rtn <<= 8;
570 }
571 return rtn;
572 }
573
574 /*
575 * Log CSSM error.
576 */
577 void cuPrintError(const char *op, CSSM_RETURN err)
578 {
579 cssmPerror(op, err);
580 }
581
582 /*
583 * Verify a CRL against system anchors and intermediate certs.
584 */
585 CSSM_RETURN cuCrlVerify(
586 CSSM_TP_HANDLE tpHand,
587 CSSM_CL_HANDLE clHand,
588 CSSM_CSP_HANDLE cspHand,
589 const CSSM_DATA *crlData,
590 CSSM_DL_DB_HANDLE_PTR certKeychain, // intermediate certs
591 const CSSM_DATA *anchors,
592 uint32 anchorCount)
593 {
594 /* main job is building a CSSM_TP_VERIFY_CONTEXT and its components */
595 CSSM_TP_VERIFY_CONTEXT vfyCtx;
596 CSSM_TP_CALLERAUTH_CONTEXT authCtx;
597
598 memset(&vfyCtx, 0, sizeof(CSSM_TP_VERIFY_CONTEXT));
599 memset(&authCtx, 0, sizeof(CSSM_TP_CALLERAUTH_CONTEXT));
600
601 /* CSSM_TP_CALLERAUTH_CONTEXT components */
602 /*
603 typedef struct cssm_tp_callerauth_context {
604 CSSM_TP_POLICYINFO Policy;
605 CSSM_TIMESTRING VerifyTime;
606 CSSM_TP_STOP_ON VerificationAbortOn;
607 CSSM_TP_VERIFICATION_RESULTS_CALLBACK CallbackWithVerifiedCert;
608 uint32 NumberOfAnchorCerts;
609 CSSM_DATA_PTR AnchorCerts;
610 CSSM_DL_DB_LIST_PTR DBList;
611 CSSM_ACCESS_CREDENTIALS_PTR CallerCredentials;
612 } CSSM_TP_CALLERAUTH_CONTEXT, *CSSM_TP_CALLERAUTH_CONTEXT_PTR;
613 */
614 CSSM_FIELD policyId;
615 CSSM_APPLE_TP_CRL_OPTIONS crlOpts;
616 policyId.FieldOid = CSSMOID_APPLE_TP_REVOCATION_CRL;
617 policyId.FieldValue.Data = (uint8 *)&crlOpts;
618 policyId.FieldValue.Length = sizeof(crlOpts);
619 crlOpts.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION;
620 /* perhaps this should be user-specifiable */
621 crlOpts.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET;
622 crlOpts.crlStore = NULL;
623
624 authCtx.Policy.NumberOfPolicyIds = 1;
625 authCtx.Policy.PolicyIds = &policyId;
626 authCtx.Policy.PolicyControl = NULL;
627
628 authCtx.VerifyTime = NULL;
629 authCtx.VerificationAbortOn = CSSM_TP_STOP_ON_POLICY;
630 authCtx.CallbackWithVerifiedCert = NULL;
631
632 /* anchors */
633 authCtx.NumberOfAnchorCerts = anchorCount;
634 authCtx.AnchorCerts = const_cast<CSSM_DATA_PTR>(anchors);
635
636 /* DBList of intermediate certs */
637 CSSM_DL_DB_HANDLE handles[1];
638 unsigned numDbs = 0;
639 if(certKeychain != NULL) {
640 handles[0] = *certKeychain;
641 numDbs++;
642 }
643 CSSM_DL_DB_LIST dlDbList;
644 dlDbList.DLDBHandle = certKeychain;
645 dlDbList.NumHandles = (certKeychain ? 1 : 0);
646
647 authCtx.DBList = &dlDbList;
648 authCtx.CallerCredentials = NULL;
649
650 /* CSSM_TP_VERIFY_CONTEXT */
651 vfyCtx.ActionData.Data = NULL;
652 vfyCtx.ActionData.Length = 0;
653 vfyCtx.Action = CSSM_TP_ACTION_DEFAULT;
654 vfyCtx.Cred = &authCtx;
655
656 /* cook up CSSM_ENCODED_CRL */
657 CSSM_ENCODED_CRL encCrl;
658 encCrl.CrlType = CSSM_CRL_TYPE_X_509v2;
659 encCrl.CrlEncoding = CSSM_CRL_ENCODING_DER;
660 encCrl.CrlBlob = *crlData;
661
662 /* CDSA API requires a SignerCertGroup; for us, all the certs are in
663 * certKeyChain... */
664 CSSM_CERTGROUP certGroup;
665 certGroup.CertType = CSSM_CERT_X_509v1;
666 certGroup.CertEncoding = CSSM_CERT_ENCODING_DER;
667 certGroup.NumCerts = 0;
668 certGroup.GroupList.CertList = NULL;
669 certGroup.CertGroupType = CSSM_CERTGROUP_DATA;
670
671 CSSM_RETURN crtn = CSSM_TP_CrlVerify(tpHand,
672 clHand,
673 cspHand,
674 &encCrl,
675 &certGroup,
676 &vfyCtx,
677 NULL); // RevokerVerifyResult
678 if(crtn) {
679 cuPrintError("CSSM_TP_CrlVerify", crtn);
680 }
681 return crtn;
682 }
683