]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/certTime/extenCooker.cpp
c294fa7853e6e11b90ae024481bb054393169fff
[apple/security.git] / SecurityTests / clxutils / certTime / extenCooker.cpp
1 /*
2 * extenCooker.cpp - module to cook up random (but reasonable)
3 * versions of cert extensions
4 */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include "extenCooker.h"
10 #include <utilLib/common.h>
11 #include <utilLib/cspwrap.h>
12 #include <Security/oidsattr.h>
13 #include <Security/oidscert.h>
14
15 CSSM_BOOL randBool()
16 {
17 unsigned r = genRand(1, 0x10000000);
18 return (r & 0x1) ? CSSM_TRUE : CSSM_FALSE;
19 }
20
21 /* Fill a CSSM_DATA with random data. Its referent is allocd with malloc. */
22 void randData(
23 CSSM_DATA_PTR data,
24 uint8 maxLen)
25 {
26 data->Data = (uint8 *)malloc(maxLen);
27 simpleGenData(data, 1, maxLen);
28 }
29
30 /*
31 * Various compare tests
32 */
33 int compBool(
34 CSSM_BOOL pre,
35 CSSM_BOOL post,
36 const char *desc)
37 {
38 if(pre == post) {
39 return 0;
40 }
41 printf("***Boolean miscompare on %s\n", desc);
42 /* in case a CSSM_TRUE isn't exactly right... */
43 switch(post) {
44 case CSSM_FALSE:
45 case CSSM_TRUE:
46 break;
47 default:
48 printf("*** post value is %d expected %d\n",
49 (int)post, (int)pre);
50 break;
51 }
52 return 1;
53 }
54
55 int compCssmData(
56 CSSM_DATA &d1,
57 CSSM_DATA &d2,
58 const char *desc)
59 {
60 if(appCompareCssmData(&d1, &d2)) {
61 return 0;
62 }
63 printf("CSSM_DATA miscompare on %s\n", desc);
64 return 1;
65 }
66
67 #pragma mark ----- individual extension tests -----
68
69 #pragma mark --- CE_KeyUsage ---
70 void kuCreate(void *arg)
71 {
72 CE_KeyUsage *ku = (CE_KeyUsage *)arg;
73
74 /* set two random valid bits */
75 *ku = 0;
76 *ku |= 1 << genRand(7, 15);
77 *ku |= 1 << genRand(7, 15);
78 }
79
80 unsigned kuCompare(const void *pre, const void *post)
81 {
82 const CE_KeyUsage *kuPre = (CE_KeyUsage *)pre;
83 const CE_KeyUsage *kuPost = (CE_KeyUsage *)post;
84 if(*kuPre != *kuPost) {
85 printf("***Miscompare in CE_KeyUsage\n");
86 return 1;
87 }
88 return 0;
89 }
90
91 #pragma mark --- CE_BasicConstraints ---
92 void bcCreate(void *arg)
93 {
94 CE_BasicConstraints *bc = (CE_BasicConstraints *)arg;
95 bc->cA = randBool();
96 bc->pathLenConstraintPresent = randBool();
97 if(bc->pathLenConstraintPresent) {
98 bc->pathLenConstraint = genRand(1,10);
99 }
100 }
101
102 unsigned bcCompare(const void *pre, const void *post)
103 {
104 const CE_BasicConstraints *bcpre = (CE_BasicConstraints *)pre;
105 const CE_BasicConstraints *bcpost = (CE_BasicConstraints *)post;
106 unsigned rtn = 0;
107
108 rtn += compBool(bcpre->cA, bcpost->cA, "BasicConstraints.cA");
109 rtn += compBool(bcpre->pathLenConstraintPresent,
110 bcpost->pathLenConstraintPresent,
111 "BasicConstraints.pathLenConstraintPresent");
112 if(bcpre->pathLenConstraint != bcpost->pathLenConstraint) {
113 printf("BasicConstraints.pathLenConstraint mismatch\n");
114 rtn++;
115 }
116 return rtn;
117 }
118
119 #pragma mark --- CE_SubjectKeyID ---
120 void skidCreate(void *arg)
121 {
122 CSSM_DATA_PTR skid = (CSSM_DATA_PTR)arg;
123 randData(skid, 16);
124 }
125
126 unsigned skidCompare(const void *pre, const void *post)
127 {
128 CSSM_DATA_PTR spre = (CSSM_DATA_PTR)pre;
129 CSSM_DATA_PTR spost = (CSSM_DATA_PTR)post;
130 return compCssmData(*spre, *spost, "SubjectKeyID");
131 }
132
133 void skidFree(void *arg)
134 {
135 CSSM_DATA_PTR skid = (CSSM_DATA_PTR)arg;
136 free(skid->Data);
137 }
138
139 #pragma mark --- CE_NetscapeCertType ---
140 void nctCreate(void *arg)
141 {
142 CE_NetscapeCertType *nct = (CE_NetscapeCertType *)arg;
143
144 /* set two random valid bits */
145 *nct = 0;
146 *nct |= 1 << genRand(8, 15);
147 *nct |= 1 << genRand(8, 15);
148 }
149
150 unsigned nctCompare(const void *pre, const void *post)
151 {
152 const CE_NetscapeCertType *nPre = (CE_NetscapeCertType *)pre;
153 const CE_NetscapeCertType *nPost = (CE_NetscapeCertType *)post;
154 if(*nPre != *nPost) {
155 printf("***Miscompare in CE_NetscapeCertType\n");
156 return 1;
157 }
158 return 0;
159 }
160
161 #pragma mark --- CE_ExtendedKeyUsage ---
162
163 /* a static array of meaningless OIDs, use 1.. NUM_SKU_OIDS */
164 CSSM_OID ekuOids[] = {
165 CSSMOID_CrlNumber,
166 CSSMOID_CrlReason,
167 CSSMOID_HoldInstructionCode,
168 CSSMOID_InvalidityDate
169 };
170 #define NUM_SKU_OIDS 4
171
172 void ekuCreate(void *arg)
173 {
174 CE_ExtendedKeyUsage *eku = (CE_ExtendedKeyUsage *)arg;
175 eku->numPurposes = genRand(1, NUM_SKU_OIDS);
176 eku->purposes = ekuOids;
177 }
178
179 unsigned ekuCompare(const void *pre, const void *post)
180 {
181 CE_ExtendedKeyUsage *ekupre = (CE_ExtendedKeyUsage *)pre;
182 CE_ExtendedKeyUsage *ekupost = (CE_ExtendedKeyUsage *)post;
183
184 if(ekupre->numPurposes != ekupost->numPurposes) {
185 printf("CE_ExtendedKeyUsage.numPurposes miscompare\n");
186 return 1;
187 }
188 unsigned rtn = 0;
189 for(unsigned dex=0; dex<ekupre->numPurposes; dex++) {
190 rtn += compCssmData(ekupre->purposes[dex],
191 ekupost->purposes[dex], "CE_ExtendedKeyUsage.purposes");
192 }
193 return rtn;
194 }
195
196
197 #pragma mark --- general purpose X509 name generator ---
198
199 /* Attr/Value pairs, pick one of NUM_ATTR_STRINGS */
200 static char *attrStrings[] = {
201 (char *)"thisName",
202 (char *)"anotherName",
203 (char *)"someOtherName"
204 };
205 #define NUM_ATTR_STRINGS 3
206
207 /* A/V type, pick one of NUM_ATTR_TYPES */
208 static CSSM_OID attrTypes[] = {
209 CSSMOID_Surname,
210 CSSMOID_CountryName,
211 CSSMOID_OrganizationName,
212 CSSMOID_Description
213 };
214 #define NUM_ATTR_TYPES 4
215
216 /* A/V tag, pick one of NUM_ATTR_TAGS */
217 static char attrTags[] = {
218 BER_TAG_PRINTABLE_STRING,
219 BER_TAG_IA5_STRING,
220 BER_TAG_T61_STRING
221 };
222 #define NUM_ATTR_TAGS 3
223
224 void rdnCreate(
225 CSSM_X509_RDN_PTR rdn)
226 {
227 unsigned numPairs = genRand(1,4);
228 rdn->numberOfPairs = numPairs;
229 unsigned len = numPairs * sizeof(CSSM_X509_TYPE_VALUE_PAIR);
230 rdn->AttributeTypeAndValue =
231 (CSSM_X509_TYPE_VALUE_PAIR_PTR)malloc(len);
232 memset(rdn->AttributeTypeAndValue, 0, len);
233
234 for(unsigned atvDex=0; atvDex<numPairs; atvDex++) {
235 CSSM_X509_TYPE_VALUE_PAIR &pair =
236 rdn->AttributeTypeAndValue[atvDex];
237 unsigned die = genRand(1, NUM_ATTR_TYPES);
238 pair.type = attrTypes[die - 1];
239 die = genRand(1, NUM_ATTR_STRINGS);
240 char *str = attrStrings[die - 1];
241 pair.value.Data = (uint8 *)str;
242 pair.value.Length = strlen(str);
243 die = genRand(1, NUM_ATTR_TAGS);
244 pair.valueType = attrTags[die - 1];
245 }
246 }
247
248 unsigned rdnCompare(
249 CSSM_X509_RDN_PTR rdn1,
250 CSSM_X509_RDN_PTR rdn2)
251 {
252 if(rdn1->numberOfPairs != rdn2->numberOfPairs) {
253 printf("***Mismatch in numberOfPairs\n");
254 return 1;
255 }
256 unsigned rtn = 0;
257 for(unsigned atvDex=0; atvDex<rdn1->numberOfPairs; atvDex++) {
258 CSSM_X509_TYPE_VALUE_PAIR &p1 =
259 rdn1->AttributeTypeAndValue[atvDex];
260 CSSM_X509_TYPE_VALUE_PAIR &p2 =
261 rdn2->AttributeTypeAndValue[atvDex];
262 if(p1.valueType != p2.valueType) {
263 printf("***valueType miscompare\n");
264 rtn++;
265 }
266 if(compCssmData(p1.type, p2.type, "ATV.type")) {
267 rtn++;
268 }
269 if(compCssmData(p1.value, p2.value, "ATV.value")) {
270 rtn++;
271 }
272 }
273 return rtn;
274 }
275
276 void rdnFree(
277 CSSM_X509_RDN_PTR rdn)
278 {
279 free(rdn->AttributeTypeAndValue);
280 }
281
282 void x509NameCreate(
283 CSSM_X509_NAME_PTR x509Name)
284 {
285 memset(x509Name, 0, sizeof(*x509Name));
286 unsigned numRdns = genRand(1,4);
287 x509Name->numberOfRDNs = numRdns;
288 unsigned len = numRdns * sizeof(CSSM_X509_RDN);
289 x509Name->RelativeDistinguishedName = (CSSM_X509_RDN_PTR)malloc(len);
290 memset(x509Name->RelativeDistinguishedName, 0, len);
291
292 for(unsigned rdnDex=0; rdnDex<numRdns; rdnDex++) {
293 CSSM_X509_RDN &rdn = x509Name->RelativeDistinguishedName[rdnDex];
294 rdnCreate(&rdn);
295 }
296 }
297
298 unsigned x509NameCompare(
299 const CSSM_X509_NAME_PTR n1,
300 const CSSM_X509_NAME_PTR n2)
301 {
302 if(n1->numberOfRDNs != n2->numberOfRDNs) {
303 printf("***Mismatch in numberOfRDNs\n");
304 return 1;
305 }
306 unsigned rtn = 0;
307 for(unsigned rdnDex=0; rdnDex<n1->numberOfRDNs; rdnDex++) {
308 CSSM_X509_RDN &rdn1 = n1->RelativeDistinguishedName[rdnDex];
309 CSSM_X509_RDN &rdn2 = n2->RelativeDistinguishedName[rdnDex];
310 rtn += rdnCompare(&rdn1, &rdn2);
311 }
312 return rtn;
313 }
314
315 void x509NameFree(
316 CSSM_X509_NAME_PTR n)
317 {
318 for(unsigned rdnDex=0; rdnDex<n->numberOfRDNs; rdnDex++) {
319 CSSM_X509_RDN &rdn = n->RelativeDistinguishedName[rdnDex];
320 rdnFree(&rdn);
321 }
322 free(n->RelativeDistinguishedName);
323 }
324
325 #pragma mark --- general purpose GeneralNames generator ---
326
327 #define SOME_URL_1 "http://foo.bar.com"
328 #define SOME_URL_2 "http://bar.foo.com"
329 #define SOME_DNS_1 "Some DNS"
330 #define SOME_DNS_2 "Another DNS"
331 unsigned char someIpAdr_1[] = {208, 161, 124, 209 };
332 unsigned char someIpAdr_2[] = {10, 0, 61, 5};
333
334 void genNamesCreate(void *arg)
335 {
336 CE_GeneralNames *names = (CE_GeneralNames *)arg;
337 names->numNames = genRand(1, 3);
338 // one at a time
339 //names->numNames = 1;
340 names->generalName = (CE_GeneralName *)malloc(names->numNames *
341 sizeof(CE_GeneralName));
342 memset(names->generalName, 0, names->numNames * sizeof(CE_GeneralName));
343 const char *src;
344 unsigned char *usrc;
345
346 for(unsigned i=0; i<names->numNames; i++) {
347 CE_GeneralName *name = &names->generalName[i];
348 unsigned type = genRand(1, 5);
349 // unsigned type = 5;
350 switch(type) {
351 case 1:
352 name->nameType = GNT_URI;
353 name->berEncoded = CSSM_FALSE;
354 src = randBool() ? SOME_URL_1 : SOME_URL_2;
355 appCopyData(src, strlen(src), &name->name);
356 break;
357
358 case 2:
359 name->nameType = GNT_RegisteredID;
360 name->berEncoded = CSSM_FALSE;
361 appCopyData(CSSMOID_SubjectDirectoryAttributes.Data,
362 CSSMOID_SubjectDirectoryAttributes.Length,
363 &name->name);
364 break;
365
366 case 3:
367 name->nameType = GNT_DNSName;
368 name->berEncoded = CSSM_FALSE;
369 src = randBool() ? SOME_DNS_1 : SOME_DNS_2;
370 appCopyData(src, strlen(src), &name->name);
371 break;
372
373 case 4:
374 name->nameType = GNT_IPAddress;
375 name->berEncoded = CSSM_FALSE;
376 usrc = randBool() ? someIpAdr_1 : someIpAdr_2;
377 appCopyData(usrc, 4, &name->name);
378 break;
379
380 case 5:
381 {
382 /* X509_NAME, the hard one */
383 name->nameType = GNT_DirectoryName;
384 name->berEncoded = CSSM_FALSE;
385 appSetupCssmData(&name->name, sizeof(CSSM_X509_NAME));
386 x509NameCreate((CSSM_X509_NAME_PTR)name->name.Data);
387 }
388 }
389 }
390 }
391
392 unsigned genNamesCompare(const void *pre, const void *post)
393 {
394 const CE_GeneralNames *gnPre = (CE_GeneralNames *)pre;
395 const CE_GeneralNames *gnPost = (CE_GeneralNames *)post;
396 unsigned rtn = 0;
397
398 if((gnPre == NULL) || (gnPost == NULL)) {
399 printf("***Bad GenNames pointer\n");
400 return 1;
401 }
402 if(gnPre->numNames != gnPost->numNames) {
403 printf("***CE_GeneralNames.numNames miscompare\n");
404 return 1;
405 }
406 for(unsigned dex=0; dex<gnPre->numNames; dex++) {
407 CE_GeneralName *npre = &gnPre->generalName[dex];
408 CE_GeneralName *npost = &gnPost->generalName[dex];
409 if(npre->nameType != npost->nameType) {
410 printf("***CE_GeneralName.nameType miscompare\n");
411 rtn++;
412 }
413 if(compBool(npre->berEncoded, npost->berEncoded,
414 "CE_GeneralName.berEncoded")) {
415 rtn++;
416 }
417
418 /* nameType-specific compare */
419 switch(npre->nameType) {
420 case GNT_RFC822Name:
421 rtn += compCssmData(npre->name, npost->name,
422 "CE_GeneralName.RFC822Name");
423 break;
424 case GNT_DNSName:
425 rtn += compCssmData(npre->name, npost->name,
426 "CE_GeneralName.DNSName");
427 break;
428 case GNT_URI:
429 rtn += compCssmData(npre->name, npost->name,
430 "CE_GeneralName.URI");
431 break;
432 case GNT_IPAddress:
433 rtn += compCssmData(npre->name, npost->name,
434 "CE_GeneralName.RFIPAddressC822Name");
435 break;
436 case GNT_RegisteredID:
437 rtn += compCssmData(npre->name, npost->name,
438 "CE_GeneralName.RegisteredID");
439 break;
440 case GNT_DirectoryName:
441 rtn += x509NameCompare((CSSM_X509_NAME_PTR)npre->name.Data,
442 (CSSM_X509_NAME_PTR)npost->name.Data);
443 break;
444 default:
445 printf("****BRRZAP! genNamesCompare needs work\n");
446 rtn++;
447 }
448 }
449 return rtn;
450 }
451
452 void genNamesFree(void *arg)
453 {
454 const CE_GeneralNames *gn = (CE_GeneralNames *)arg;
455 for(unsigned dex=0; dex<gn->numNames; dex++) {
456 CE_GeneralName *n = (CE_GeneralName *)&gn->generalName[dex];
457 switch(n->nameType) {
458 case GNT_DirectoryName:
459 x509NameFree((CSSM_X509_NAME_PTR)n->name.Data);
460 CSSM_FREE(n->name.Data);
461 break;
462 default:
463 CSSM_FREE(n->name.Data);
464 break;
465 }
466 }
467 free(gn->generalName);
468 }
469
470 #pragma mark --- CE_CRLDistPointsSyntax ---
471 void cdpCreate(void *arg)
472 {
473 CE_CRLDistPointsSyntax *cdp = (CE_CRLDistPointsSyntax *)arg;
474 //cdp->numDistPoints = genRand(1,3);
475 // one at a time
476 cdp->numDistPoints = 1;
477 unsigned len = sizeof(CE_CRLDistributionPoint) * cdp->numDistPoints;
478 cdp->distPoints = (CE_CRLDistributionPoint *)malloc(len);
479 memset(cdp->distPoints, 0, len);
480
481 for(unsigned dex=0; dex<cdp->numDistPoints; dex++) {
482 CE_CRLDistributionPoint *pt = &cdp->distPoints[dex];
483
484 /* all fields optional */
485 if(randBool()) {
486 CE_DistributionPointName *dpn = pt->distPointName =
487 (CE_DistributionPointName *)malloc(
488 sizeof(CE_DistributionPointName));
489 memset(dpn, 0, sizeof(CE_DistributionPointName));
490
491 /* CE_DistributionPointName has two flavors */
492 if(randBool()) {
493 dpn->nameType = CE_CDNT_FullName;
494 dpn->dpn.fullName = (CE_GeneralNames *)malloc(
495 sizeof(CE_GeneralNames));
496 memset(dpn->dpn.fullName, 0, sizeof(CE_GeneralNames));
497 genNamesCreate(dpn->dpn.fullName);
498 }
499 else {
500 dpn->nameType = CE_CDNT_NameRelativeToCrlIssuer;
501 dpn->dpn.rdn = (CSSM_X509_RDN_PTR)malloc(
502 sizeof(CSSM_X509_RDN));
503 memset(dpn->dpn.rdn, 0, sizeof(CSSM_X509_RDN));
504 rdnCreate(dpn->dpn.rdn);
505 }
506 } /* creating CE_DistributionPointName */
507
508 pt->reasonsPresent = randBool();
509 if(pt->reasonsPresent) {
510 CE_CrlDistReasonFlags *cdr = &pt->reasons;
511 /* set two random valid bits */
512 *cdr = 0;
513 *cdr |= 1 << genRand(0,7);
514 *cdr |= 1 << genRand(0,7);
515 }
516
517 /* make sure at least one present */
518 if((!pt->distPointName && !pt->reasonsPresent) || randBool()) {
519 pt->crlIssuer = (CE_GeneralNames *)malloc(sizeof(CE_GeneralNames));
520 memset(pt->crlIssuer, 0, sizeof(CE_GeneralNames));
521 genNamesCreate(pt->crlIssuer);
522 }
523 }
524 }
525
526 unsigned cdpCompare(const void *pre, const void *post)
527 {
528 CE_CRLDistPointsSyntax *cpre = (CE_CRLDistPointsSyntax *)pre;
529 CE_CRLDistPointsSyntax *cpost = (CE_CRLDistPointsSyntax *)post;
530
531 if(cpre->numDistPoints != cpost->numDistPoints) {
532 printf("***CE_CRLDistPointsSyntax.numDistPoints miscompare\n");
533 return 1;
534 }
535 unsigned rtn = 0;
536 for(unsigned dex=0; dex<cpre->numDistPoints; dex++) {
537 CE_CRLDistributionPoint *ptpre = &cpre->distPoints[dex];
538 CE_CRLDistributionPoint *ptpost = &cpost->distPoints[dex];
539
540 if(ptpre->distPointName) {
541 if(ptpost->distPointName == NULL) {
542 printf("***NULL distPointName post decode\n");
543 rtn++;
544 goto checkReason;
545 }
546 CE_DistributionPointName *dpnpre = ptpre->distPointName;
547 CE_DistributionPointName *dpnpost = ptpost->distPointName;
548 if(dpnpre->nameType != dpnpost->nameType) {
549 printf("***CE_DistributionPointName.nameType miscompare\n");
550 rtn++;
551 goto checkReason;
552 }
553 if(dpnpre->nameType == CE_CDNT_FullName) {
554 rtn += genNamesCompare(dpnpre->dpn.fullName, dpnpost->dpn.fullName);
555 }
556 else {
557 rtn += rdnCompare(dpnpre->dpn.rdn, dpnpost->dpn.rdn);
558 }
559
560 }
561 else if(ptpost->distPointName != NULL) {
562 printf("***NON NULL distPointName post decode\n");
563 rtn++;
564 }
565
566 checkReason:
567 if(ptpre->reasons != ptpost->reasons) {
568 printf("***CE_CRLDistributionPoint.reasons miscompare\n");
569 rtn++;
570 }
571
572 if(ptpre->crlIssuer) {
573 if(ptpost->crlIssuer == NULL) {
574 printf("***NULL crlIssuer post decode\n");
575 rtn++;
576 continue;
577 }
578 CE_GeneralNames *gnpre = ptpre->crlIssuer;
579 CE_GeneralNames *gnpost = ptpost->crlIssuer;
580 rtn += genNamesCompare(gnpre, gnpost);
581 }
582 else if(ptpost->crlIssuer != NULL) {
583 printf("***NON NULL crlIssuer post decode\n");
584 rtn++;
585 }
586 }
587 return rtn;
588 }
589
590 void cdpFree(void *arg)
591 {
592 CE_CRLDistPointsSyntax *cdp = (CE_CRLDistPointsSyntax *)arg;
593 for(unsigned dex=0; dex<cdp->numDistPoints; dex++) {
594 CE_CRLDistributionPoint *pt = &cdp->distPoints[dex];
595 if(pt->distPointName) {
596 CE_DistributionPointName *dpn = pt->distPointName;
597 if(dpn->nameType == CE_CDNT_FullName) {
598 genNamesFree(dpn->dpn.fullName);
599 free(dpn->dpn.fullName);
600 }
601 else {
602 rdnFree(dpn->dpn.rdn);
603 free(dpn->dpn.rdn);
604 }
605 free(dpn);
606 }
607
608 if(pt->crlIssuer) {
609 genNamesFree(pt->crlIssuer);
610 free(pt->crlIssuer);
611 }
612 }
613 free(cdp->distPoints);
614 }
615
616 #pragma mark --- CE_AuthorityKeyID ---
617 void authKeyIdCreate(void *arg)
618 {
619 CE_AuthorityKeyID *akid = (CE_AuthorityKeyID *)arg;
620
621 /* all three fields optional */
622
623 akid->keyIdentifierPresent = randBool();
624 if(akid->keyIdentifierPresent) {
625 randData(&akid->keyIdentifier, 16);
626 }
627
628 akid->generalNamesPresent = randBool();
629 if(akid->generalNamesPresent) {
630 akid->generalNames =
631 (CE_GeneralNames *)malloc(sizeof(CE_GeneralNames));
632 memset(akid->generalNames, 0, sizeof(CE_GeneralNames));
633 genNamesCreate(akid->generalNames);
634 }
635
636 if(!akid->keyIdentifierPresent & !akid->generalNamesPresent) {
637 /* force at least one to be present */
638 akid->serialNumberPresent = CSSM_TRUE;
639 }
640 else {
641 akid->serialNumberPresent = randBool();
642 }
643 if(akid->serialNumberPresent) {
644 randData(&akid->serialNumber, 16);
645 }
646
647 }
648
649 unsigned authKeyIdCompare(const void *pre, const void *post)
650 {
651 CE_AuthorityKeyID *akpre = (CE_AuthorityKeyID *)pre;
652 CE_AuthorityKeyID *akpost = (CE_AuthorityKeyID *)post;
653 unsigned rtn = 0;
654
655 if(compBool(akpre->keyIdentifierPresent, akpost->keyIdentifierPresent,
656 "CE_AuthorityKeyID.keyIdentifierPresent")) {
657 rtn++;
658 }
659 else if(akpre->keyIdentifierPresent) {
660 rtn += compCssmData(akpre->keyIdentifier,
661 akpost->keyIdentifier, "CE_AuthorityKeyID.keyIdentifier");
662 }
663
664 if(compBool(akpre->generalNamesPresent, akpost->generalNamesPresent,
665 "CE_AuthorityKeyID.generalNamesPresent")) {
666 rtn++;
667 }
668 else if(akpre->generalNamesPresent) {
669 rtn += genNamesCompare(akpre->generalNames,
670 akpost->generalNames);
671 }
672
673 if(compBool(akpre->serialNumberPresent, akpost->serialNumberPresent,
674 "CE_AuthorityKeyID.serialNumberPresent")) {
675 rtn++;
676 }
677 else if(akpre->serialNumberPresent) {
678 rtn += compCssmData(akpre->serialNumber,
679 akpost->serialNumber, "CE_AuthorityKeyID.serialNumber");
680 }
681 return rtn;
682 }
683
684 void authKeyIdFree(void *arg)
685 {
686 CE_AuthorityKeyID *akid = (CE_AuthorityKeyID *)arg;
687
688 if(akid->keyIdentifier.Data) {
689 free(akid->keyIdentifier.Data);
690 }
691 if(akid->generalNames) {
692 genNamesFree(akid->generalNames); // genNamesCreate mallocd
693 free(akid->generalNames); // we mallocd
694 }
695 if(akid->serialNumber.Data) {
696 free(akid->serialNumber.Data);
697 }
698 }
699
700 #pragma mark --- CE_CertPolicies ---
701
702 /* random OIDs, pick 1..NUM_CP_OIDS */
703 static CSSM_OID cpOids[] =
704 {
705 CSSMOID_EmailAddress,
706 CSSMOID_UnstructuredName,
707 CSSMOID_ContentType,
708 CSSMOID_MessageDigest
709 };
710 #define NUM_CP_OIDS 4
711
712 /* CPS strings, pick one of NUM_CPS_STR */
713 static char *someCPSs[] =
714 {
715 (char *)"http://www.apple.com",
716 (char *)"https://cdnow.com",
717 (char *)"ftp:backwards.com"
718 };
719 #define NUM_CPS_STR 3
720
721 /* make these looks like real sequences */
722 static uint8 someUnotice[] = {0x30, 0x03, BER_TAG_BOOLEAN, 1, 0xff};
723 static uint8 someOtherData[] = {0x30, 0x02, BER_TAG_NULL, 0};
724
725 void cpCreate(void *arg)
726 {
727 CE_CertPolicies *cp = (CE_CertPolicies *)arg;
728 cp->numPolicies = genRand(1,3);
729 //cp->numPolicies = 1;
730 unsigned len = sizeof(CE_PolicyInformation) * cp->numPolicies;
731 cp->policies = (CE_PolicyInformation *)malloc(len);
732 memset(cp->policies, 0, len);
733
734 for(unsigned polDex=0; polDex<cp->numPolicies; polDex++) {
735 CE_PolicyInformation *pi = &cp->policies[polDex];
736 unsigned die = genRand(1, NUM_CP_OIDS);
737 pi->certPolicyId = cpOids[die - 1];
738 unsigned numQual = genRand(1,3);
739 pi->numPolicyQualifiers = numQual;
740 len = sizeof(CE_PolicyQualifierInfo) * numQual;
741 pi->policyQualifiers = (CE_PolicyQualifierInfo *)
742 malloc(len);
743 memset(pi->policyQualifiers, 0, len);
744 for(unsigned cpiDex=0; cpiDex<numQual; cpiDex++) {
745 CE_PolicyQualifierInfo *qi =
746 &pi->policyQualifiers[cpiDex];
747 if(randBool()) {
748 qi->policyQualifierId = CSSMOID_QT_CPS;
749 die = genRand(1, NUM_CPS_STR);
750 qi->qualifier.Data = (uint8 *)someCPSs[die - 1];
751 qi->qualifier.Length = strlen((char *)qi->qualifier.Data);
752 }
753 else {
754 qi->policyQualifierId = CSSMOID_QT_UNOTICE;
755 if(randBool()) {
756 qi->qualifier.Data = someUnotice;
757 qi->qualifier.Length = 5;
758 }
759 else {
760 qi->qualifier.Data = someOtherData;
761 qi->qualifier.Length = 4;
762 }
763 }
764 }
765 }
766 }
767
768 unsigned cpCompare(const void *pre, const void *post)
769 {
770 CE_CertPolicies *cppre = (CE_CertPolicies *)pre;
771 CE_CertPolicies *cppost = (CE_CertPolicies *)post;
772
773 if(cppre->numPolicies != cppost->numPolicies) {
774 printf("CE_CertPolicies.numPolicies mismatch\n");
775 return 1;
776 }
777 unsigned rtn = 0;
778 for(unsigned polDex=0; polDex<cppre->numPolicies; polDex++) {
779 CE_PolicyInformation *pipre = &cppre->policies[polDex];
780 CE_PolicyInformation *pipost = &cppost->policies[polDex];
781 rtn += compCssmData(pipre->certPolicyId, pipost->certPolicyId,
782 "CE_PolicyInformation.certPolicyId");
783 if(pipre->numPolicyQualifiers != pipost->numPolicyQualifiers) {
784 printf("CE_PolicyInformation.CE_PolicyInformation mismatch\n");
785 rtn++;
786 continue;
787 }
788
789 for(unsigned qiDex=0; qiDex<pipre->numPolicyQualifiers; qiDex++) {
790 CE_PolicyQualifierInfo *qipre = &pipre->policyQualifiers[qiDex];
791 CE_PolicyQualifierInfo *qipost = &pipost->policyQualifiers[qiDex];
792 rtn += compCssmData(qipre->policyQualifierId,
793 qipost->policyQualifierId,
794 "CE_PolicyQualifierInfo.policyQualifierId");
795 rtn += compCssmData(qipre->qualifier,
796 qipost->qualifier,
797 "CE_PolicyQualifierInfo.qualifier");
798 }
799 }
800 return rtn;
801 }
802
803 void cpFree(void *arg)
804 {
805 CE_CertPolicies *cp = (CE_CertPolicies *)arg;
806 for(unsigned polDex=0; polDex<cp->numPolicies; polDex++) {
807 CE_PolicyInformation *pi = &cp->policies[polDex];
808 free(pi->policyQualifiers);
809 }
810 free(cp->policies);
811 }