X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/b04fe171f0375ecd5d8a24747ca1dff85720a0ca..6b200bc335dc93c5516ccb52f14bd896d8c7fad7:/SecurityTests/clxutils/extenTestTp/extenTestTp.cpp diff --git a/SecurityTests/clxutils/extenTestTp/extenTestTp.cpp b/SecurityTests/clxutils/extenTestTp/extenTestTp.cpp deleted file mode 100644 index 73908b32..00000000 --- a/SecurityTests/clxutils/extenTestTp/extenTestTp.cpp +++ /dev/null @@ -1,1430 +0,0 @@ -/* - * extenTestTp - verify encoding and decoding of extensions using - * CSSM_TP_SubmitCredRequest() to create the certs. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define KEY_ALG CSSM_ALGID_RSA -#define SIG_ALG CSSM_ALGID_SHA1WithRSA -#define SIG_OID CSSMOID_SHA1WithRSA -#define KEY_SIZE_BITS CSP_RSA_KEY_SIZE_DEFAULT -#define SUBJ_KEY_LABEL "subjectKey" - -#define LOOPS_DEF 10 - -static void usage(char **argv) -{ - printf("Usage: %s [options]\n", argv[0]); - printf("Options:\n"); - printf(" e=extenSpec (default = all)\n"); - printf(" k keyUsage\n"); - printf(" b basicConstraints\n"); - printf(" x extendedKeyUsage\n"); - printf(" s subjectKeyId\n"); - printf(" a authorityKeyId\n"); - printf(" t SubjectAltName\n"); - printf(" i IssuerAltName\n"); - printf(" c certPolicies\n"); - printf(" n netscapeCertType\n"); - printf(" p CRLDistributionPoints\n"); - printf(" A AuthorityInfoAccess\n"); - printf(" S SubjectInfoAccess\n"); - printf(" w(rite blobs)\n"); - printf(" f=fileName (default is extension-specific file name)\n"); - printf(" d(isplay certs)\n"); - printf(" l=loops (default = %d)\n", LOOPS_DEF); - printf(" p(ause on each loop)\n"); - printf(" P(ause on each cert)\n"); - exit(1); -} - -/* subject and issuer - we aren't testing this */ -CSSM_APPLE_TP_NAME_OID dummyRdn[] = -{ - { "Apple Computer", &CSSMOID_OrganizationName }, - { "Doug Mitchell", &CSSMOID_CommonName } -}; -#define NUM_DUMMY_NAMES (sizeof(dummyRdn) / sizeof(CB_NameOid)) - -/* - * Static components we reuse for each encode/decode. - */ -static CSSM_KEY subjPrivKey; -static CSSM_KEY subjPubKey; - -static CSSM_BOOL randBool() -{ - unsigned r = genRand(1, 0x10000000); - return (r & 0x1) ? CSSM_TRUE : CSSM_FALSE; -} - -/* Fill a CSSM_DATA with random data. Its referent is allocd with malloc. */ -static void randData( - CSSM_DATA_PTR data, - uint8 maxLen) -{ - data->Data = (uint8 *)malloc(maxLen); - simpleGenData(data, 1, maxLen); -} - -/* - * Various compare tests - */ -int compBool( - CSSM_BOOL pre, - CSSM_BOOL post, - const char *desc) -{ - if(pre == post) { - return 0; - } - printf("***Boolean miscompare on %s\n", desc); - /* in case a CSSM_TRUE isn't exactly right... */ - switch(post) { - case CSSM_FALSE: - case CSSM_TRUE: - break; - default: - printf("*** post value is %d expected %d\n", - (int)post, (int)pre); - break; - } - return 1; -} - -static int compCssmData( - CSSM_DATA &d1, - CSSM_DATA &d2, - const char *desc) -{ - if(appCompareCssmData(&d1, &d2)) { - return 0; - } - printf("CSSM_DATA miscompare on %s\n", desc); - return 1; -} - -#pragma mark ----- individual extension tests ----- - -#pragma mark --- CE_KeyUsage --- -static void kuCreate(void *arg) -{ - CE_KeyUsage *ku = (CE_KeyUsage *)arg; - - /* set two random valid bits */ - *ku = 0; - *ku |= 1 << genRand(7, 15); - *ku |= 1 << genRand(7, 15); -} - -static unsigned kuCompare(const void *pre, const void *post) -{ - const CE_KeyUsage *kuPre = (CE_KeyUsage *)pre; - const CE_KeyUsage *kuPost = (CE_KeyUsage *)post; - if(*kuPre != *kuPost) { - printf("***Miscompare in CE_KeyUsage\n"); - return 1; - } - return 0; -} - -#pragma mark --- CE_BasicConstraints --- -static void bcCreate(void *arg) -{ - CE_BasicConstraints *bc = (CE_BasicConstraints *)arg; - bc->cA = randBool(); - bc->pathLenConstraintPresent = randBool(); - if(bc->pathLenConstraintPresent) { - bc->pathLenConstraint = genRand(1,10); - } -} - -static unsigned bcCompare(const void *pre, const void *post) -{ - const CE_BasicConstraints *bcpre = (CE_BasicConstraints *)pre; - const CE_BasicConstraints *bcpost = (CE_BasicConstraints *)post; - unsigned rtn = 0; - - rtn += compBool(bcpre->cA, bcpost->cA, "BasicConstraints.cA"); - rtn += compBool(bcpre->pathLenConstraintPresent, - bcpost->pathLenConstraintPresent, - "BasicConstraints.pathLenConstraintPresent"); - if(bcpre->pathLenConstraint != bcpost->pathLenConstraint) { - printf("BasicConstraints.pathLenConstraint mismatch\n"); - rtn++; - } - return rtn; -} - -#pragma mark --- CE_SubjectKeyID --- -static void skidCreate(void *arg) -{ - CSSM_DATA_PTR skid = (CSSM_DATA_PTR)arg; - randData(skid, 16); -} - -static unsigned skidCompare(const void *pre, const void *post) -{ - CSSM_DATA_PTR spre = (CSSM_DATA_PTR)pre; - CSSM_DATA_PTR spost = (CSSM_DATA_PTR)post; - return compCssmData(*spre, *spost, "SubjectKeyID"); -} - -static void skidFree(void *arg) -{ - CSSM_DATA_PTR skid = (CSSM_DATA_PTR)arg; - free(skid->Data); -} - -#pragma mark --- CE_NetscapeCertType --- -static void nctCreate(void *arg) -{ - CE_NetscapeCertType *nct = (CE_NetscapeCertType *)arg; - - /* set two random valid bits */ - *nct = 0; - *nct |= 1 << genRand(8, 15); - *nct |= 1 << genRand(8, 15); -} - -static unsigned nctCompare(const void *pre, const void *post) -{ - const CE_NetscapeCertType *nPre = (CE_NetscapeCertType *)pre; - const CE_NetscapeCertType *nPost = (CE_NetscapeCertType *)post; - if(*nPre != *nPost) { - printf("***Miscompare in CE_NetscapeCertType\n"); - return 1; - } - return 0; -} - -#pragma mark --- CE_ExtendedKeyUsage --- - -/* a static array of meaningless OIDs, use 1.. NUM_SKU_OIDS */ -CSSM_OID ekuOids[] = { - CSSMOID_CrlNumber, - CSSMOID_CrlReason, - CSSMOID_HoldInstructionCode, - CSSMOID_InvalidityDate -}; -#define NUM_SKU_OIDS 4 - -static void ekuCreate(void *arg) -{ - CE_ExtendedKeyUsage *eku = (CE_ExtendedKeyUsage *)arg; - eku->numPurposes = genRand(1, NUM_SKU_OIDS); - eku->purposes = ekuOids; -} - -static unsigned ekuCompare(const void *pre, const void *post) -{ - CE_ExtendedKeyUsage *ekupre = (CE_ExtendedKeyUsage *)pre; - CE_ExtendedKeyUsage *ekupost = (CE_ExtendedKeyUsage *)post; - - if(ekupre->numPurposes != ekupost->numPurposes) { - printf("CE_ExtendedKeyUsage.numPurposes miscompare\n"); - return 1; - } - unsigned rtn = 0; - for(unsigned dex=0; dexnumPurposes; dex++) { - rtn += compCssmData(ekupre->purposes[dex], - ekupost->purposes[dex], "CE_ExtendedKeyUsage.purposes"); - } - return rtn; -} - - -#pragma mark --- general purpose X509 name generator --- - -/* Attr/Value pairs, pick one of NUM_ATTR_STRINGS */ -static char *attrStrings[] = { - (char *)"thisName", - (char *)"anotherName", - (char *)"someOtherName" -}; -#define NUM_ATTR_STRINGS 3 - -/* A/V type, pick one of NUM_ATTR_TYPES */ -static CSSM_OID attrTypes[] = { - CSSMOID_Surname, - CSSMOID_CountryName, - CSSMOID_OrganizationName, - CSSMOID_Description -}; -#define NUM_ATTR_TYPES 4 - -/* A/V tag, pick one of NUM_ATTR_TAGS */ -static char attrTags[] = { - BER_TAG_PRINTABLE_STRING, - BER_TAG_IA5_STRING, - BER_TAG_T61_STRING -}; -#define NUM_ATTR_TAGS 3 - -static void rdnCreate( - CSSM_X509_RDN_PTR rdn) -{ - unsigned numPairs = genRand(1,4); - rdn->numberOfPairs = numPairs; - unsigned len = numPairs * sizeof(CSSM_X509_TYPE_VALUE_PAIR); - rdn->AttributeTypeAndValue = - (CSSM_X509_TYPE_VALUE_PAIR_PTR)malloc(len); - memset(rdn->AttributeTypeAndValue, 0, len); - - for(unsigned atvDex=0; atvDexAttributeTypeAndValue[atvDex]; - unsigned die = genRand(1, NUM_ATTR_TYPES); - pair.type = attrTypes[die - 1]; - die = genRand(1, NUM_ATTR_STRINGS); - char *str = attrStrings[die - 1]; - pair.value.Data = (uint8 *)str; - pair.value.Length = strlen(str); - die = genRand(1, NUM_ATTR_TAGS); - pair.valueType = attrTags[die - 1]; - } -} - -static unsigned rdnCompare( - CSSM_X509_RDN_PTR rdn1, - CSSM_X509_RDN_PTR rdn2) -{ - if(rdn1->numberOfPairs != rdn2->numberOfPairs) { - printf("***Mismatch in numberOfPairs\n"); - return 1; - } - unsigned rtn = 0; - for(unsigned atvDex=0; atvDexnumberOfPairs; atvDex++) { - CSSM_X509_TYPE_VALUE_PAIR &p1 = - rdn1->AttributeTypeAndValue[atvDex]; - CSSM_X509_TYPE_VALUE_PAIR &p2 = - rdn2->AttributeTypeAndValue[atvDex]; - if(p1.valueType != p2.valueType) { - printf("***valueType miscompare\n"); - rtn++; - } - if(compCssmData(p1.type, p2.type, "ATV.type")) { - rtn++; - } - if(compCssmData(p1.value, p2.value, "ATV.value")) { - rtn++; - } - } - return rtn; -} - -static void rdnFree( - CSSM_X509_RDN_PTR rdn) -{ - free(rdn->AttributeTypeAndValue); -} - -static void x509NameCreate( - CSSM_X509_NAME_PTR x509Name) -{ - memset(x509Name, 0, sizeof(*x509Name)); - unsigned numRdns = genRand(1,4); - x509Name->numberOfRDNs = numRdns; - unsigned len = numRdns * sizeof(CSSM_X509_RDN); - x509Name->RelativeDistinguishedName = (CSSM_X509_RDN_PTR)malloc(len); - memset(x509Name->RelativeDistinguishedName, 0, len); - - for(unsigned rdnDex=0; rdnDexRelativeDistinguishedName[rdnDex]; - rdnCreate(&rdn); - } -} - -static unsigned x509NameCompare( - const CSSM_X509_NAME_PTR n1, - const CSSM_X509_NAME_PTR n2) -{ - if(n1->numberOfRDNs != n2->numberOfRDNs) { - printf("***Mismatch in numberOfRDNs\n"); - return 1; - } - unsigned rtn = 0; - for(unsigned rdnDex=0; rdnDexnumberOfRDNs; rdnDex++) { - CSSM_X509_RDN &rdn1 = n1->RelativeDistinguishedName[rdnDex]; - CSSM_X509_RDN &rdn2 = n2->RelativeDistinguishedName[rdnDex]; - rtn += rdnCompare(&rdn1, &rdn2); - } - return rtn; -} - -static void x509NameFree( - CSSM_X509_NAME_PTR n) -{ - for(unsigned rdnDex=0; rdnDexnumberOfRDNs; rdnDex++) { - CSSM_X509_RDN &rdn = n->RelativeDistinguishedName[rdnDex]; - rdnFree(&rdn); - } - free(n->RelativeDistinguishedName); -} - -#pragma mark --- general purpose GeneralNames generator --- - -#define SOME_URL_1 (char *)"http://foo.bar.com" -#define SOME_URL_2 (char *)"http://bar.foo.com" -#define SOME_DNS_1 (char *)"Some DNS" -#define SOME_DNS_2 (char *)"Another DNS" -unsigned char someIpAdr_1[] = {208, 161, 124, 209 }; -unsigned char someIpAdr_2[] = {10, 0, 61, 5}; - -static void genNameCreate(CE_GeneralName *name) -{ - unsigned type = genRand(1, 5); - const char *src; - unsigned char *usrc; - switch(type) { - case 1: - name->nameType = GNT_URI; - name->berEncoded = CSSM_FALSE; - src = randBool() ? SOME_URL_1 : SOME_URL_2; - appCopyData(src, strlen(src), &name->name); - break; - - case 2: - name->nameType = GNT_RegisteredID; - name->berEncoded = CSSM_FALSE; - appCopyData(CSSMOID_SubjectDirectoryAttributes.Data, - CSSMOID_SubjectDirectoryAttributes.Length, - &name->name); - break; - - case 3: - name->nameType = GNT_DNSName; - name->berEncoded = CSSM_FALSE; - src = randBool() ? SOME_DNS_1 : SOME_DNS_2; - appCopyData(src, strlen(src), &name->name); - break; - - case 4: - name->nameType = GNT_IPAddress; - name->berEncoded = CSSM_FALSE; - usrc = randBool() ? someIpAdr_1 : someIpAdr_2; - appCopyData(usrc, 4, &name->name); - break; - - case 5: - { - /* X509_NAME, the hard one */ - name->nameType = GNT_DirectoryName; - name->berEncoded = CSSM_FALSE; - appSetupCssmData(&name->name, sizeof(CSSM_X509_NAME)); - x509NameCreate((CSSM_X509_NAME_PTR)name->name.Data); - } - } -} - -static void genNamesCreate(void *arg) -{ - CE_GeneralNames *names = (CE_GeneralNames *)arg; - names->numNames = genRand(1, 3); - // one at a time - //names->numNames = 1; - names->generalName = (CE_GeneralName *)malloc(names->numNames * - sizeof(CE_GeneralName)); - memset(names->generalName, 0, names->numNames * sizeof(CE_GeneralName)); - - for(unsigned i=0; inumNames; i++) { - CE_GeneralName *name = &names->generalName[i]; - genNameCreate(name); - } -} - -static unsigned genNameCompare( - CE_GeneralName *npre, - CE_GeneralName *npost) -{ - unsigned rtn = 0; - if(npre->nameType != npost->nameType) { - printf("***CE_GeneralName.nameType miscompare\n"); - rtn++; - } - if(compBool(npre->berEncoded, npost->berEncoded, - "CE_GeneralName.berEncoded")) { - rtn++; - } - - /* nameType-specific compare */ - switch(npre->nameType) { - case GNT_RFC822Name: - rtn += compCssmData(npre->name, npost->name, - "CE_GeneralName.RFC822Name"); - break; - case GNT_DNSName: - rtn += compCssmData(npre->name, npost->name, - "CE_GeneralName.DNSName"); - break; - case GNT_URI: - rtn += compCssmData(npre->name, npost->name, - "CE_GeneralName.URI"); - break; - case GNT_IPAddress: - rtn += compCssmData(npre->name, npost->name, - "CE_GeneralName.RFIPAddressC822Name"); - break; - case GNT_RegisteredID: - rtn += compCssmData(npre->name, npost->name, - "CE_GeneralName.RegisteredID"); - break; - case GNT_DirectoryName: - rtn += x509NameCompare((CSSM_X509_NAME_PTR)npre->name.Data, - (CSSM_X509_NAME_PTR)npost->name.Data); - break; - default: - printf("****BRRZAP! genNamesCompare needs work\n"); - rtn++; - } - return rtn; -} - -static unsigned genNamesCompare(const void *pre, const void *post) -{ - const CE_GeneralNames *gnPre = (CE_GeneralNames *)pre; - const CE_GeneralNames *gnPost = (CE_GeneralNames *)post; - unsigned rtn = 0; - - if((gnPre == NULL) || (gnPost == NULL)) { - printf("***Bad GenNames pointer\n"); - return 1; - } - if(gnPre->numNames != gnPost->numNames) { - printf("***CE_GeneralNames.numNames miscompare\n"); - return 1; - } - for(unsigned dex=0; dexnumNames; dex++) { - CE_GeneralName *npre = &gnPre->generalName[dex]; - CE_GeneralName *npost = &gnPost->generalName[dex]; - rtn += genNameCompare(npre, npost); - } - return rtn; -} - - -static void genNameFree(CE_GeneralName *n) -{ - switch(n->nameType) { - case GNT_DirectoryName: - x509NameFree((CSSM_X509_NAME_PTR)n->name.Data); - CSSM_FREE(n->name.Data); - break; - default: - CSSM_FREE(n->name.Data); - break; - } -} - - -static void genNamesFree(void *arg) -{ - const CE_GeneralNames *gn = (CE_GeneralNames *)arg; - for(unsigned dex=0; dexnumNames; dex++) { - CE_GeneralName *n = (CE_GeneralName *)&gn->generalName[dex]; - genNameFree(n); - } - free(gn->generalName); -} - -#pragma mark --- CE_CRLDistPointsSyntax --- -static void cdpCreate(void *arg) -{ - CE_CRLDistPointsSyntax *cdp = (CE_CRLDistPointsSyntax *)arg; - //cdp->numDistPoints = genRand(1,3); - // one at a time - cdp->numDistPoints = 1; - unsigned len = sizeof(CE_CRLDistributionPoint) * cdp->numDistPoints; - cdp->distPoints = (CE_CRLDistributionPoint *)malloc(len); - memset(cdp->distPoints, 0, len); - - for(unsigned dex=0; dexnumDistPoints; dex++) { - CE_CRLDistributionPoint *pt = &cdp->distPoints[dex]; - - /* all fields optional */ - if(randBool()) { - CE_DistributionPointName *dpn = pt->distPointName = - (CE_DistributionPointName *)malloc( - sizeof(CE_DistributionPointName)); - memset(dpn, 0, sizeof(CE_DistributionPointName)); - - /* CE_DistributionPointName has two flavors */ - if(randBool()) { - dpn->nameType = CE_CDNT_FullName; - dpn->dpn.fullName = (CE_GeneralNames *)malloc( - sizeof(CE_GeneralNames)); - memset(dpn->dpn.fullName, 0, sizeof(CE_GeneralNames)); - genNamesCreate(dpn->dpn.fullName); - } - else { - dpn->nameType = CE_CDNT_NameRelativeToCrlIssuer; - dpn->dpn.rdn = (CSSM_X509_RDN_PTR)malloc( - sizeof(CSSM_X509_RDN)); - memset(dpn->dpn.rdn, 0, sizeof(CSSM_X509_RDN)); - rdnCreate(dpn->dpn.rdn); - } - } /* creating CE_DistributionPointName */ - - pt->reasonsPresent = randBool(); - if(pt->reasonsPresent) { - CE_CrlDistReasonFlags *cdr = &pt->reasons; - /* set two random valid bits */ - *cdr = 0; - *cdr |= 1 << genRand(0,7); - *cdr |= 1 << genRand(0,7); - } - - /* make sure at least one present */ - if((!pt->distPointName && !pt->reasonsPresent) || randBool()) { - pt->crlIssuer = (CE_GeneralNames *)malloc(sizeof(CE_GeneralNames)); - memset(pt->crlIssuer, 0, sizeof(CE_GeneralNames)); - genNamesCreate(pt->crlIssuer); - } - } -} - -static unsigned cdpCompare(const void *pre, const void *post) -{ - CE_CRLDistPointsSyntax *cpre = (CE_CRLDistPointsSyntax *)pre; - CE_CRLDistPointsSyntax *cpost = (CE_CRLDistPointsSyntax *)post; - - if(cpre->numDistPoints != cpost->numDistPoints) { - printf("***CE_CRLDistPointsSyntax.numDistPoints miscompare\n"); - return 1; - } - unsigned rtn = 0; - for(unsigned dex=0; dexnumDistPoints; dex++) { - CE_CRLDistributionPoint *ptpre = &cpre->distPoints[dex]; - CE_CRLDistributionPoint *ptpost = &cpost->distPoints[dex]; - - if(ptpre->distPointName) { - if(ptpost->distPointName == NULL) { - printf("***NULL distPointName post decode\n"); - rtn++; - goto checkReason; - } - CE_DistributionPointName *dpnpre = ptpre->distPointName; - CE_DistributionPointName *dpnpost = ptpost->distPointName; - if(dpnpre->nameType != dpnpost->nameType) { - printf("***CE_DistributionPointName.nameType miscompare\n"); - rtn++; - goto checkReason; - } - if(dpnpre->nameType == CE_CDNT_FullName) { - rtn += genNamesCompare(dpnpre->dpn.fullName, dpnpost->dpn.fullName); - } - else { - rtn += rdnCompare(dpnpre->dpn.rdn, dpnpost->dpn.rdn); - } - - } - else if(ptpost->distPointName != NULL) { - printf("***NON NULL distPointName post decode\n"); - rtn++; - } - - checkReason: - if(ptpre->reasons != ptpost->reasons) { - printf("***CE_CRLDistributionPoint.reasons miscompare\n"); - rtn++; - } - - if(ptpre->crlIssuer) { - if(ptpost->crlIssuer == NULL) { - printf("***NULL crlIssuer post decode\n"); - rtn++; - continue; - } - CE_GeneralNames *gnpre = ptpre->crlIssuer; - CE_GeneralNames *gnpost = ptpost->crlIssuer; - rtn += genNamesCompare(gnpre, gnpost); - } - else if(ptpost->crlIssuer != NULL) { - printf("***NON NULL crlIssuer post decode\n"); - rtn++; - } - } - return rtn; -} - -static void cdpFree(void *arg) -{ - CE_CRLDistPointsSyntax *cdp = (CE_CRLDistPointsSyntax *)arg; - for(unsigned dex=0; dexnumDistPoints; dex++) { - CE_CRLDistributionPoint *pt = &cdp->distPoints[dex]; - if(pt->distPointName) { - CE_DistributionPointName *dpn = pt->distPointName; - if(dpn->nameType == CE_CDNT_FullName) { - genNamesFree(dpn->dpn.fullName); - free(dpn->dpn.fullName); - } - else { - rdnFree(dpn->dpn.rdn); - free(dpn->dpn.rdn); - } - free(dpn); - } - - if(pt->crlIssuer) { - genNamesFree(pt->crlIssuer); - free(pt->crlIssuer); - } - } - free(cdp->distPoints); -} - -#pragma mark --- CE_AuthorityKeyID --- -static void authKeyIdCreate(void *arg) -{ - CE_AuthorityKeyID *akid = (CE_AuthorityKeyID *)arg; - - /* all three fields optional */ - - akid->keyIdentifierPresent = randBool(); - if(akid->keyIdentifierPresent) { - randData(&akid->keyIdentifier, 16); - } - - akid->generalNamesPresent = randBool(); - if(akid->generalNamesPresent) { - akid->generalNames = - (CE_GeneralNames *)malloc(sizeof(CE_GeneralNames)); - memset(akid->generalNames, 0, sizeof(CE_GeneralNames)); - genNamesCreate(akid->generalNames); - } - - if(!akid->keyIdentifierPresent & !akid->generalNamesPresent) { - /* force at least one to be present */ - akid->serialNumberPresent = CSSM_TRUE; - } - else { - akid->serialNumberPresent = randBool(); - } - if(akid->serialNumberPresent) { - randData(&akid->serialNumber, 16); - } - -} - -static unsigned authKeyIdCompare(const void *pre, const void *post) -{ - CE_AuthorityKeyID *akpre = (CE_AuthorityKeyID *)pre; - CE_AuthorityKeyID *akpost = (CE_AuthorityKeyID *)post; - unsigned rtn = 0; - - if(compBool(akpre->keyIdentifierPresent, akpost->keyIdentifierPresent, - "CE_AuthorityKeyID.keyIdentifierPresent")) { - rtn++; - } - else if(akpre->keyIdentifierPresent) { - rtn += compCssmData(akpre->keyIdentifier, - akpost->keyIdentifier, "CE_AuthorityKeyID.keyIdentifier"); - } - - if(compBool(akpre->generalNamesPresent, akpost->generalNamesPresent, - "CE_AuthorityKeyID.generalNamesPresent")) { - rtn++; - } - else if(akpre->generalNamesPresent) { - rtn += genNamesCompare(akpre->generalNames, - akpost->generalNames); - } - - if(compBool(akpre->serialNumberPresent, akpost->serialNumberPresent, - "CE_AuthorityKeyID.serialNumberPresent")) { - rtn++; - } - else if(akpre->serialNumberPresent) { - rtn += compCssmData(akpre->serialNumber, - akpost->serialNumber, "CE_AuthorityKeyID.serialNumber"); - } - return rtn; -} - -static void authKeyIdFree(void *arg) -{ - CE_AuthorityKeyID *akid = (CE_AuthorityKeyID *)arg; - - if(akid->keyIdentifier.Data) { - free(akid->keyIdentifier.Data); - } - if(akid->generalNames) { - genNamesFree(akid->generalNames); // genNamesCreate mallocd - free(akid->generalNames); // we mallocd - } - if(akid->serialNumber.Data) { - free(akid->serialNumber.Data); - } -} - -#pragma mark --- CE_CertPolicies --- - -/* random OIDs, pick 1..NUM_CP_OIDS */ -static CSSM_OID cpOids[] = -{ - CSSMOID_EmailAddress, - CSSMOID_UnstructuredName, - CSSMOID_ContentType, - CSSMOID_MessageDigest -}; -#define NUM_CP_OIDS 4 - -/* CPS strings, pick one of NUM_CPS_STR */ -static char *someCPSs[] = -{ - (char *)"http://www.apple.com", - (char *)"https://cdnow.com", - (char *)"ftp:backwards.com" -}; -#define NUM_CPS_STR 3 - -/* make these looks like real sequences */ -static uint8 someUnotice[] = {0x30, 0x03, BER_TAG_BOOLEAN, 1, 0xff}; -static uint8 someOtherData[] = {0x30, 0x02, BER_TAG_NULL, 0}; - -static void cpCreate(void *arg) -{ - CE_CertPolicies *cp = (CE_CertPolicies *)arg; - cp->numPolicies = genRand(1,3); - //cp->numPolicies = 1; - unsigned len = sizeof(CE_PolicyInformation) * cp->numPolicies; - cp->policies = (CE_PolicyInformation *)malloc(len); - memset(cp->policies, 0, len); - - for(unsigned polDex=0; polDexnumPolicies; polDex++) { - CE_PolicyInformation *pi = &cp->policies[polDex]; - unsigned die = genRand(1, NUM_CP_OIDS); - pi->certPolicyId = cpOids[die - 1]; - unsigned numQual = genRand(1,3); - pi->numPolicyQualifiers = numQual; - len = sizeof(CE_PolicyQualifierInfo) * numQual; - pi->policyQualifiers = (CE_PolicyQualifierInfo *) - malloc(len); - memset(pi->policyQualifiers, 0, len); - for(unsigned cpiDex=0; cpiDexpolicyQualifiers[cpiDex]; - if(randBool()) { - qi->policyQualifierId = CSSMOID_QT_CPS; - die = genRand(1, NUM_CPS_STR); - qi->qualifier.Data = (uint8 *)someCPSs[die - 1]; - qi->qualifier.Length = strlen((char *)qi->qualifier.Data); - } - else { - qi->policyQualifierId = CSSMOID_QT_UNOTICE; - if(randBool()) { - qi->qualifier.Data = someUnotice; - qi->qualifier.Length = 5; - } - else { - qi->qualifier.Data = someOtherData; - qi->qualifier.Length = 4; - } - } - } - } -} - -static unsigned cpCompare(const void *pre, const void *post) -{ - CE_CertPolicies *cppre = (CE_CertPolicies *)pre; - CE_CertPolicies *cppost = (CE_CertPolicies *)post; - - if(cppre->numPolicies != cppost->numPolicies) { - printf("CE_CertPolicies.numPolicies mismatch\n"); - return 1; - } - unsigned rtn = 0; - for(unsigned polDex=0; polDexnumPolicies; polDex++) { - CE_PolicyInformation *pipre = &cppre->policies[polDex]; - CE_PolicyInformation *pipost = &cppost->policies[polDex]; - rtn += compCssmData(pipre->certPolicyId, pipost->certPolicyId, - "CE_PolicyInformation.certPolicyId"); - if(pipre->numPolicyQualifiers != pipost->numPolicyQualifiers) { - printf("CE_PolicyInformation.CE_PolicyInformation mismatch\n"); - rtn++; - continue; - } - - for(unsigned qiDex=0; qiDexnumPolicyQualifiers; qiDex++) { - CE_PolicyQualifierInfo *qipre = &pipre->policyQualifiers[qiDex]; - CE_PolicyQualifierInfo *qipost = &pipost->policyQualifiers[qiDex]; - rtn += compCssmData(qipre->policyQualifierId, - qipost->policyQualifierId, - "CE_PolicyQualifierInfo.policyQualifierId"); - rtn += compCssmData(qipre->qualifier, - qipost->qualifier, - "CE_PolicyQualifierInfo.qualifier"); - } - } - return rtn; -} - -static void cpFree(void *arg) -{ - CE_CertPolicies *cp = (CE_CertPolicies *)arg; - for(unsigned polDex=0; polDexnumPolicies; polDex++) { - CE_PolicyInformation *pi = &cp->policies[polDex]; - free(pi->policyQualifiers); - } - free(cp->policies); -} - -#pragma mark --- CE_AuthorityInfoAccess --- - -/* random OIDs, pick 1..NUM_AI_OIDS */ -static CSSM_OID aiOids[] = -{ - CSSMOID_AD_OCSP, - CSSMOID_AD_CA_ISSUERS, - CSSMOID_AD_TIME_STAMPING, - CSSMOID_AD_CA_REPOSITORY -}; -#define NUM_AI_OIDS 4 - -static void aiaCreate(void *arg) -{ - CE_AuthorityInfoAccess *aia = (CE_AuthorityInfoAccess *)arg; - aia->numAccessDescriptions = genRand(1,3); - unsigned len = aia->numAccessDescriptions * sizeof(CE_AccessDescription); - aia->accessDescriptions = (CE_AccessDescription *)malloc(len); - memset(aia->accessDescriptions, 0, len); - - for(unsigned dex=0; dexnumAccessDescriptions; dex++) { - CE_AccessDescription *ad = &aia->accessDescriptions[dex]; - int die = genRand(1, NUM_AI_OIDS); - ad->accessMethod = aiOids[die - 1]; - genNameCreate(&ad->accessLocation); - } -} - -static unsigned aiaCompare(const void *pre, const void *post) -{ - CE_AuthorityInfoAccess *apre = (CE_AuthorityInfoAccess *)pre; - CE_AuthorityInfoAccess *apost = (CE_AuthorityInfoAccess *)post; - unsigned rtn = 0; - - if(apre->numAccessDescriptions != apost->numAccessDescriptions) { - printf("***CE_AuthorityInfoAccess.numAccessDescriptions miscompare\n"); - return 1; - } - for(unsigned dex=0; dexnumAccessDescriptions; dex++) { - CE_AccessDescription *adPre = &apre->accessDescriptions[dex]; - CE_AccessDescription *adPost = &apost->accessDescriptions[dex]; - if(compCssmData(adPre->accessMethod, adPost->accessMethod, - "CE_AccessDescription.accessMethod")) { - rtn++; - } - rtn += genNameCompare(&adPre->accessLocation, &adPost->accessLocation); - } - return rtn; -} - -static void aiaFree(void *arg) -{ - CE_AuthorityInfoAccess *aia = (CE_AuthorityInfoAccess *)arg; - for(unsigned dex=0; dexnumAccessDescriptions; dex++) { - CE_AccessDescription *ad = &aia->accessDescriptions[dex]; - genNameFree(&ad->accessLocation); - } - free(aia->accessDescriptions); -} - -#pragma mark --- test definitions --- - -/* - * Define one extension test. - */ - -/* - * Cook up this extension with random, reasonable values. - * Incoming pointer refers to extension-specific C struct, mallocd - * and zeroed by main test routine. - */ -typedef void (*extenCreateFcn)(void *arg); - -/* - * Compare two instances of this extension. Return number of - * compare errors. - */ -typedef unsigned (*extenCompareFcn)( - const void *preEncode, - const void *postEncode); - -/* - * Free struct components mallocd in extenCreateFcn. Do not free - * the outer struct. - */ -typedef void (*extenFreeFcn)(void *arg); - -typedef struct { - /* three extension-specific functions */ - extenCreateFcn createFcn; - extenCompareFcn compareFcn; - extenFreeFcn freeFcn; - - /* size of C struct passed to all three functions */ - unsigned extenSize; - - /* the CE_DataType for this extension, used on encode */ - CE_DataType extenType; - - /* the OID for this extension, tested on decode */ - CSSM_OID extenOid; - - /* description for error logging and blob writing */ - const char *extenDescr; - - /* command-line letter for this one */ - char extenLetter; - -} ExtenTest; - -/* empty freeFcn means no extension-specific resources to free */ -#define NO_FREE NULL - -static ExtenTest extenTests[] = { - { kuCreate, kuCompare, NO_FREE, - sizeof(CE_KeyUsage), - DT_KeyUsage, CSSMOID_KeyUsage, - "KeyUsage", 'k' }, - { bcCreate, bcCompare, NO_FREE, - sizeof(CE_BasicConstraints), - DT_BasicConstraints, CSSMOID_BasicConstraints, - "BasicConstraints", 'b' }, - { ekuCreate, ekuCompare, NO_FREE, - sizeof(CE_ExtendedKeyUsage), - DT_ExtendedKeyUsage, CSSMOID_ExtendedKeyUsage, - "ExtendedKeyUsage", 'x' }, - { skidCreate, skidCompare, skidFree, - sizeof(CSSM_DATA), - DT_SubjectKeyID, CSSMOID_SubjectKeyIdentifier, - "SubjectKeyID", 's' }, - { authKeyIdCreate, authKeyIdCompare, authKeyIdFree, - sizeof(CE_AuthorityKeyID), - DT_AuthorityKeyID, CSSMOID_AuthorityKeyIdentifier, - "AuthorityKeyID", 'a' }, - { genNamesCreate, genNamesCompare, genNamesFree, - sizeof(CE_GeneralNames), - DT_SubjectAltName, CSSMOID_SubjectAltName, - "SubjectAltName", 't' }, - { genNamesCreate, genNamesCompare, genNamesFree, - sizeof(CE_GeneralNames), - DT_IssuerAltName, CSSMOID_IssuerAltName, - "IssuerAltName", 'i' }, - { nctCreate, nctCompare, NO_FREE, - sizeof(CE_NetscapeCertType), - DT_NetscapeCertType, CSSMOID_NetscapeCertType, - "NetscapeCertType", 'n' }, - { cdpCreate, cdpCompare, cdpFree, - sizeof(CE_CRLDistPointsSyntax), - DT_CrlDistributionPoints, CSSMOID_CrlDistributionPoints, - "CRLDistPoints", 'p' }, - { cpCreate, cpCompare, cpFree, - sizeof(CE_CertPolicies), - DT_CertPolicies, CSSMOID_CertificatePolicies, - "CertPolicies", 'c' }, - { aiaCreate, aiaCompare, aiaFree, - sizeof(CE_AuthorityInfoAccess), - DT_AuthorityInfoAccess, CSSMOID_AuthorityInfoAccess, - "AuthorityInfoAccess", 'A' }, - #if 0 - /* TP doesn't have this, neither does certextensions.h! */ - { aiaCreate, aiaCompare, aiaFree, - sizeof(CE_AuthorityInfoAccess), CSSMOID_SubjectInfoAccess, - "SubjectInfoAccess", 'S' }, - #endif -}; - -#define NUM_EXTEN_TESTS (sizeof(extenTests) / sizeof(ExtenTest)) - -static void printExtenPre( - CE_DataAndType *extenData, - CSSM_OID *extenOid, - OidParser &parser) -{ - CSSM_FIELD field; - CSSM_X509_EXTENSION extn; - - /* - * Convert pre-digested into CSSM_X509_EXTENSION that - * printCertField() can understand - */ - extn.extnId = *extenOid; - extn.critical = extenData->critical; - extn.format = CSSM_X509_DATAFORMAT_PARSED; - extn.value.parsedValue = &extenData->extension; - field.FieldOid = *extenOid; - field.FieldValue.Data = (uint8 *)&extn; - field.FieldValue.Length = sizeof(CSSM_X509_EXTENSION); - printf("=== PRE-ENCODE:\n"); - printCertField(field, parser, CSSM_TRUE); -} - - -static void printExten( - CSSM_X509_EXTENSION &extn, - OidParser &parser) -{ - CSSM_FIELD field; - field.FieldOid = extn.extnId; - field.FieldValue.Data = (uint8 *)&extn; - field.FieldValue.Length = sizeof(CSSM_X509_EXTENSION); - printf("=== POST-DECODE:\n"); - printCertField(field, parser, CSSM_TRUE); -} - -static int doTest( - CSSM_CL_HANDLE clHand, - CSSM_TP_HANDLE tpHand, - CSSM_CSP_HANDLE cspHand, - ExtenTest &extenTest, - bool writeBlobs, - const char *constFileName, // all blobs to this file if non-NULL - bool displayExtens, - OidParser &parser) -{ - CSSM_APPLE_TP_CERT_REQUEST certReq; - CSSM_TP_REQUEST_SET reqSet; - sint32 estTime; - CSSM_BOOL confirmRequired; - CSSM_TP_RESULT_SET_PTR resultSet; - CSSM_ENCODED_CERT *encCert; - CSSM_TP_CALLERAUTH_CONTEXT CallerAuthContext; - CSSM_FIELD policyId; - CE_DataAndType extPre; - CSSM_RETURN crtn; - CSSM_DATA refId; // mallocd by CSSM_TP_SubmitCredRequest - CSSM_DATA signedCert = {0, NULL}; - - memset(&certReq, 0, sizeof(certReq)); - memset(&extPre, 0, sizeof(extPre)); - - /* - * Cook up a random and reasonable instance of the C struct - * associated with this extension. - */ - extenTest.createFcn(&extPre.extension); - - /* - * Cook up the associated CSSM_X509_EXTENSION. - */ - extPre.type = extenTest.extenType; - extPre.critical = randBool(); - - /* - * Now the cert request proper. - */ - certReq.cspHand = cspHand; - certReq.clHand = clHand; - certReq.serialNumber = 0x8765; - certReq.numSubjectNames = NUM_DUMMY_NAMES; - certReq.subjectNames = dummyRdn; - certReq.numIssuerNames = NUM_DUMMY_NAMES; - certReq.issuerNames = dummyRdn; - certReq.certPublicKey = &subjPubKey; - certReq.issuerPrivateKey = &subjPrivKey; - certReq.signatureAlg = CSSM_ALGID_SHA1WithRSA; - certReq.signatureOid = SIG_OID; - certReq.notBefore = 0; // now - certReq.notAfter = 10000; // seconds from now - certReq.numExtensions = 1; - certReq.extensions = &extPre; - - reqSet.NumberOfRequests = 1; - reqSet.Requests = &certReq; - - /* a big CSSM_TP_CALLERAUTH_CONTEXT just to specify an OID */ - memset(&CallerAuthContext, 0, sizeof(CSSM_TP_CALLERAUTH_CONTEXT)); - memset(&policyId, 0, sizeof(CSSM_FIELD)); - policyId.FieldOid = CSSMOID_APPLE_TP_LOCAL_CERT_GEN; - CallerAuthContext.Policy.NumberOfPolicyIds = 1; - CallerAuthContext.Policy.PolicyIds = &policyId; - - /* GO */ - crtn = CSSM_TP_SubmitCredRequest(tpHand, - NULL, // PreferredAuthority - CSSM_TP_AUTHORITY_REQUEST_CERTISSUE, - &reqSet, - &CallerAuthContext, - &estTime, - &refId); - if(crtn) { - printError("CSSM_TP_SubmitCredRequest", crtn); - /* show what we tried to encode and decode */ - printExtenPre(&extPre, &extenTest.extenOid, parser); - return 1; - } - crtn = CSSM_TP_RetrieveCredResult(tpHand, - &refId, - NULL, // CallerAuthCredentials - &estTime, - &confirmRequired, - &resultSet); // leaks..... - if(crtn) { - printError("CSSM_TP_RetrieveCredResult", crtn); - /* show what we tried to encode and decode */ - printExtenPre(&extPre, &extenTest.extenOid, parser); - return 1; - } - if(resultSet == NULL) { - printf("***CSSM_TP_RetrieveCredResult returned NULL result set.\n"); - /* show what we tried to encode and decode */ - printExtenPre(&extPre, &extenTest.extenOid, parser); - return 1; - } - encCert = (CSSM_ENCODED_CERT *)resultSet->Results; - signedCert = encCert->CertBlob; - - if(writeBlobs) { - char fileName[200]; - if(constFileName) { - strcpy(fileName, constFileName); - } - else { - sprintf(fileName, "%scert.der", extenTest.extenDescr); - } - writeFile(fileName, signedCert.Data, signedCert.Length); - printf("...wrote %lu bytes to %s\n", signedCert.Length, fileName); - } - - /* snag the same extension from the encoded cert */ - CSSM_DATA_PTR postField; - CSSM_HANDLE resultHand; - uint32 numFields; - - crtn = CSSM_CL_CertGetFirstFieldValue(clHand, - &signedCert, - &extenTest.extenOid, - &resultHand, - &numFields, - &postField); - if(crtn) { - printf("****Extension field not found on decode for %s\n", - extenTest.extenDescr); - printError("CSSM_CL_CertGetFirstFieldValue", crtn); - - /* show what we tried to encode and decode */ - printExtenPre(&extPre, &extenTest.extenOid, parser); - return 1; - } - - if(numFields != 1) { - printf("****GetFirstFieldValue: expect 1 value, got %u\n", - (unsigned)numFields); - return 1; - } - CSSM_CL_CertAbortQuery(clHand, resultHand); - - /* verify the fields we generated */ - CSSM_X509_EXTENSION *extnPost = (CSSM_X509_EXTENSION *)postField->Data; - if((extnPost == NULL) || - (postField->Length != sizeof(CSSM_X509_EXTENSION))) { - printf("***Malformed CSSM_X509_EXTENSION (1) after decode\n"); - return 1; - } - int rtn = 0; - rtn += compBool(extPre.critical, extnPost->critical, - "CSSM_X509_EXTENSION.critical"); - rtn += compCssmData(extenTest.extenOid, extnPost->extnId, - "CSSM_X509_EXTENSION.extnId"); - - if(extnPost->format != CSSM_X509_DATAFORMAT_PARSED) { - printf("***Expected CSSM_X509_DATAFORMAT_PARSED (%x(x), got %x(x)\n", - CSSM_X509_DATAFORMAT_PARSED, extnPost->format); - } - if(extnPost->value.parsedValue == NULL) { - printf("***no parsedValue pointer!\n"); - return 1; - } - - /* down to extension-specific compare */ - rtn += extenTest.compareFcn(&extPre.extension, extnPost->value.parsedValue); - - if(rtn) { - /* print preencode only on error */ - printExtenPre(&extPre, &extenTest.extenOid, parser); - } - if(displayExtens || rtn) { - printExten(*extnPost, parser); - } - - /* free the allocated data */ - if(extenTest.freeFcn) { - extenTest.freeFcn(&extPre.extension); - } - CSSM_CL_FreeFieldValue(clHand, &extenTest.extenOid, postField); - CSSM_FREE(signedCert.Data); - CSSM_FREE(encCert); - CSSM_FREE(resultSet); - return rtn; -} - -static void doPause(bool pause) -{ - if(!pause) { - return; - } - fpurge(stdin); - printf("CR to continue "); - getchar(); -} - -int main(int argc, char **argv) -{ - CSSM_CL_HANDLE clHand; - CSSM_TP_HANDLE tpHand; - CSSM_CSP_HANDLE cspHand; - CSSM_RETURN crtn; - int arg; - int rtn; - OidParser parser; - char *argp; - unsigned i; - - /* user-specificied params */ - unsigned minExtenNum = 0; - unsigned maxExtenNum = NUM_EXTEN_TESTS-1; - bool writeBlobs = false; - bool displayExtens = false; - bool quiet = false; - unsigned loops = LOOPS_DEF; - bool pauseLoop = false; - bool pauseCert = false; - const char *constFileName = NULL; - - for(arg=1; arg