static void testNameConstraints(char *dataDir) { char *goodPname = "nameConstraintsDN5CACert.crt"; PKIX_PL_Cert *goodCert = NULL; PKIX_PL_CertNameConstraints *goodNC = NULL; char *expectedAscii = "[\n" "\t\tPermitted Name: (OU=permittedSubtree1," "O=Test Certificates,C=US)\n" "\t\tExcluded Name: (OU=excludedSubtree1," "OU=permittedSubtree1,O=Test Certificates,C=US)\n" "\t]\n"; PKIX_TEST_STD_VARS(); subTest("PKIX_PL_CertNameConstraints"); goodCert = createCert(dataDir, goodPname, plContext); subTest("PKIX_PL_Cert_GetNameConstraints"); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetNameConstraints (goodCert, &goodNC, plContext)); testToStringHelper ((PKIX_PL_Object *)goodNC, expectedAscii, plContext); cleanup: PKIX_TEST_DECREF_AC(goodNC); PKIX_TEST_DECREF_AC(goodCert); PKIX_TEST_RETURN(); }
static void test_NameConstraints(char *dirName) { PKIX_PL_Cert *goodCert = NULL; PKIX_PL_CertNameConstraints *getNameConstraints = NULL; PKIX_PL_CertNameConstraints *setNameConstraints = NULL; PKIX_ComCertSelParams *goodParams = NULL; char *expectedAscii = "[\n" "\t\tPermitted Name: (OU=permittedSubtree1," "O=Test Certificates,C=US, OU=permittedSubtree2," "O=Test Certificates,C=US)\n" "\t\tExcluded Name: (EMPTY)\n" "\t]\n"; PKIX_TEST_STD_VARS(); subTest("Create Cert for NameConstraints test"); goodCert = createCert (dirName, "nameConstraintsDN2CACert.crt", plContext); subTest("PKIX_PL_Cert_GetNameConstraints"); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetNameConstraints (goodCert, &setNameConstraints, plContext)); subTest("PKIX_ComCertSelParams_Create"); PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create (&goodParams, plContext)); subTest("PKIX_ComCertSelParams_SetNameConstraints"); PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetNameConstraints (goodParams, setNameConstraints, plContext)); subTest("PKIX_ComCertSelParams_GetNameConstraints"); PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetNameConstraints (goodParams, &getNameConstraints, plContext)); subTest("Compare NameConstraints"); testEqualsHelper((PKIX_PL_Object *)setNameConstraints, (PKIX_PL_Object *)getNameConstraints, PKIX_TRUE, plContext); subTest("Compare NameConstraints with canned string"); testToStringHelper ((PKIX_PL_Object *)getNameConstraints, expectedAscii, plContext); cleanup: PKIX_TEST_DECREF_AC(goodCert); PKIX_TEST_DECREF_AC(getNameConstraints); PKIX_TEST_DECREF_AC(setNameConstraints); PKIX_TEST_DECREF_AC(goodParams); PKIX_TEST_RETURN(); }
PKIX_TrustAnchor * createTrustAnchor( char *dirName, char *certFileName, PKIX_Boolean useCert, void *plContext) { PKIX_TrustAnchor *anchor = NULL; PKIX_PL_Cert *cert = NULL; PKIX_PL_X500Name *name = NULL; PKIX_PL_PublicKey *pubKey = NULL; PKIX_PL_CertNameConstraints *nameConstraints = NULL; PKIX_TEST_STD_VARS(); cert = createCert(dirName, certFileName, plContext); if (useCert){ PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert (cert, &anchor, plContext)); } else { PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubject (cert, &name, plContext)); if (name == NULL){ goto cleanup; } PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubjectPublicKey (cert, &pubKey, plContext)); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetNameConstraints (cert, &nameConstraints, NULL)); PKIX_TEST_EXPECT_NO_ERROR (PKIX_TrustAnchor_CreateWithNameKeyPair (name, pubKey, nameConstraints, &anchor, plContext)); } cleanup: if (PKIX_TEST_ERROR_RECEIVED){ PKIX_TEST_DECREF_AC(anchor); } PKIX_TEST_DECREF_AC(cert); PKIX_TEST_DECREF_AC(name); PKIX_TEST_DECREF_AC(pubKey); PKIX_TEST_DECREF_AC(nameConstraints); PKIX_TEST_RETURN(); return (anchor); }
/* * FUNCTION: PKIX_TrustAnchor_CreateWithCert (see comments in pkix_params.h) */ PKIX_Error * PKIX_TrustAnchor_CreateWithCert( PKIX_PL_Cert *cert, PKIX_TrustAnchor **pAnchor, void *plContext) { PKIX_TrustAnchor *anchor = NULL; PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_CreateWithCert"); PKIX_NULLCHECK_TWO(cert, pAnchor); PKIX_CHECK(PKIX_PL_Object_Alloc (PKIX_TRUSTANCHOR_TYPE, sizeof (PKIX_TrustAnchor), (PKIX_PL_Object **)&anchor, plContext), PKIX_COULDNOTCREATETRUSTANCHOROBJECT); /* initialize fields */ PKIX_CHECK( PKIX_PL_Cert_SetAsTrustAnchor(cert, plContext), PKIX_CERTSETASTRUSTANCHORFAILED); PKIX_INCREF(cert); anchor->trustedCert = cert; anchor->caName = NULL; anchor->caPubKey = NULL; PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints (anchor->trustedCert, &anchor->nameConstraints, plContext), PKIX_CERTGETNAMECONSTRAINTSFAILED); *pAnchor = anchor; anchor = NULL; cleanup: PKIX_DECREF(anchor); PKIX_RETURN(TRUSTANCHOR); }
static void testGetNameConstraints(char *dirName) { PKIX_TrustAnchor *goodObject = NULL; PKIX_TrustAnchor *equalObject = NULL; PKIX_TrustAnchor *diffObject = NULL; PKIX_PL_Cert *diffCert; PKIX_PL_CertNameConstraints *diffNC = NULL; PKIX_PL_CertNameConstraints *equalNC = NULL; char *goodInput = "nameConstraintsDN5CACert.crt"; char *expectedAscii = "[\n" "\tTrusted CA Name: CN=nameConstraints DN5 CA," "O=Test Certificates,C=US\n" "\tTrusted CA PublicKey: PKCS #1 RSA Encryption\n" "\tInitial Name Constraints:[\n" "\t\tPermitted Name: (OU=permittedSubtree1," "O=Test Certificates,C=US)\n" "\t\tExcluded Name: (OU=excludedSubtree1," "OU=permittedSubtree1,O=Test Certificates,C=US)\n" "\t]\n" "\n" "]\n"; PKIX_TEST_STD_VARS(); subTest("Create TrustAnchors and compare"); createTrustAnchors(dirName, goodInput, &goodObject, &equalObject, &diffObject); PKIX_TEST_EQ_HASH_TOSTR_DUP(goodObject, equalObject, diffObject, expectedAscii, TrustAnchor, PKIX_TRUE); subTest("PKIX_TrustAnchor_GetTrustedCert"); PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_GetTrustedCert(diffObject, &diffCert, plContext)); subTest("PKIX_PL_Cert_GetNameConstraints"); PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetNameConstraints(diffCert, &diffNC, plContext)); subTest("PKIX_TrustAnchor_GetNameConstraints"); PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_GetNameConstraints(equalObject, &equalNC, plContext)); testEqualsHelper((PKIX_PL_Object *)diffNC, (PKIX_PL_Object *)equalNC, PKIX_TRUE, plContext); cleanup: PKIX_TEST_DECREF_AC(diffNC); PKIX_TEST_DECREF_AC(equalNC); PKIX_TEST_DECREF_BC(diffCert); PKIX_TEST_DECREF_BC(goodObject); PKIX_TEST_DECREF_BC(equalObject); PKIX_TEST_DECREF_BC(diffObject); PKIX_TEST_RETURN(); }
/* * FUNCTION: pkix_NameConstraintsChecker_Check * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h) */ static PKIX_Error * pkix_NameConstraintsChecker_Check( PKIX_CertChainChecker *checker, PKIX_PL_Cert *cert, PKIX_List *unresolvedCriticalExtensions, void **pNBIOContext, void *plContext) { pkix_NameConstraintsCheckerState *state = NULL; PKIX_PL_CertNameConstraints *nameConstraints = NULL; PKIX_PL_CertNameConstraints *mergedNameConstraints = NULL; PKIX_Boolean selfIssued = PKIX_FALSE; PKIX_Boolean lastCert = PKIX_FALSE; PKIX_ENTER(CERTCHAINCHECKER, "pkix_NameConstraintsChecker_Check"); PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext); *pNBIOContext = NULL; /* we never block on pending I/O */ PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState (checker, (PKIX_PL_Object **)&state, plContext), PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED); state->certsRemaining--; lastCert = state->certsRemaining == 0; /* Get status of self issued */ PKIX_CHECK(pkix_IsCertSelfIssued(cert, &selfIssued, plContext), PKIX_ISCERTSELFISSUEDFAILED); /* Check on non self-issued and if so only for last cert */ if (selfIssued == PKIX_FALSE || (selfIssued == PKIX_TRUE && lastCert)) { PKIX_CHECK(PKIX_PL_Cert_CheckNameConstraints (cert, state->nameConstraints, lastCert, plContext), PKIX_CERTCHECKNAMECONSTRAINTSFAILED); } if (!lastCert) { PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints (cert, &nameConstraints, plContext), PKIX_CERTGETNAMECONSTRAINTSFAILED); /* Merge with previous name constraints kept in state */ if (nameConstraints != NULL) { if (state->nameConstraints == NULL) { state->nameConstraints = nameConstraints; } else { PKIX_CHECK(PKIX_PL_Cert_MergeNameConstraints (nameConstraints, state->nameConstraints, &mergedNameConstraints, plContext), PKIX_CERTMERGENAMECONSTRAINTSFAILED); PKIX_DECREF(nameConstraints); PKIX_DECREF(state->nameConstraints); state->nameConstraints = mergedNameConstraints; } /* Remove Name Constraints Extension OID from list */ if (unresolvedCriticalExtensions != NULL) { PKIX_CHECK(pkix_List_Remove (unresolvedCriticalExtensions, (PKIX_PL_Object *)state->nameConstraintsOID, plContext), PKIX_LISTREMOVEFAILED); } } } PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState (checker, (PKIX_PL_Object *)state, plContext), PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED); cleanup: PKIX_DECREF(state); PKIX_RETURN(CERTCHAINCHECKER); }
/* * FUNCTION: pkix_TargetCertChecker_Check * (see comments for PKIX_CertChainChecker_CheckCallback in pkix_checker.h) */ PKIX_Error * pkix_TargetCertChecker_Check( PKIX_CertChainChecker *checker, PKIX_PL_Cert *cert, PKIX_List *unresolvedCriticalExtensions, void **pNBIOContext, void *plContext) { pkix_TargetCertCheckerState *state = NULL; PKIX_CertSelector_MatchCallback certSelectorMatch = NULL; PKIX_PL_CertNameConstraints *nameConstraints = NULL; PKIX_List *certSubjAltNames = NULL; PKIX_List *certExtKeyUsageList = NULL; PKIX_PL_GeneralName *name = NULL; PKIX_PL_X500Name *certSubjectName = NULL; PKIX_Boolean checkPassed = PKIX_FALSE; PKIX_UInt32 numItems, i; PKIX_UInt32 matchCount = 0; PKIX_ENTER(CERTCHAINCHECKER, "pkix_TargetCertChecker_Check"); PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext); *pNBIOContext = NULL; /* we never block on pending I/O */ PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState (checker, (PKIX_PL_Object **)&state, plContext), PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED); (state->certsRemaining)--; if (state->pathToNameList != NULL) { PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints (cert, &nameConstraints, plContext), PKIX_CERTGETNAMECONSTRAINTSFAILED); /* * XXX We should either make the following call a public one * so it is legal to call from the portability layer or we * should try to create pathToNameList as CertNameConstraints * then call the existing check function. */ PKIX_CHECK(PKIX_PL_CertNameConstraints_CheckNamesInNameSpace (state->pathToNameList, nameConstraints, &checkPassed, plContext), PKIX_CERTNAMECONSTRAINTSCHECKNAMEINNAMESPACEFAILED); if (checkPassed != PKIX_TRUE) { PKIX_ERROR(PKIX_VALIDATIONFAILEDPATHTONAMECHECKFAILED); } } PKIX_CHECK(PKIX_PL_Cert_GetSubjectAltNames (cert, &certSubjAltNames, plContext), PKIX_CERTGETSUBJALTNAMESFAILED); if (state->subjAltNameList != NULL && certSubjAltNames != NULL) { PKIX_CHECK(PKIX_List_GetLength (state->subjAltNameList, &numItems, plContext), PKIX_LISTGETLENGTHFAILED); for (i = 0; i < numItems; i++) { PKIX_CHECK(PKIX_List_GetItem (state->subjAltNameList, i, (PKIX_PL_Object **) &name, plContext), PKIX_LISTGETITEMFAILED); PKIX_CHECK(pkix_List_Contains (certSubjAltNames, (PKIX_PL_Object *) name, &checkPassed, plContext), PKIX_LISTCONTAINSFAILED); PKIX_DECREF(name); if (checkPassed == PKIX_TRUE) { if (state->subjAltNameMatchAll == PKIX_FALSE) { matchCount = numItems; break; } else { /* else continue checking next */ matchCount++; } } } if (matchCount != numItems) { PKIX_ERROR(PKIX_SUBJALTNAMECHECKFAILED); } } if (state->certsRemaining == 0) { if (state->certSelector != NULL) { PKIX_CHECK(PKIX_CertSelector_GetMatchCallback (state->certSelector, &certSelectorMatch, plContext), PKIX_CERTSELECTORGETMATCHCALLBACKFAILED); PKIX_CHECK(certSelectorMatch (state->certSelector, cert, plContext), PKIX_CERTSELECTORMATCHFAILED); } else { /* Check at least cert/key usages if target cert selector * is not set. */ PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert, PKIX_FALSE /* is chain cert*/, plContext), PKIX_CERTVERIFYCERTTYPEFAILED); } /* * There are two Extended Key Usage Checkings * available : * 1) here at the targetcertchecker where we * verify the Extended Key Usage OIDs application * specifies via ComCertSelParams are included * in Cert's Extended Key Usage OID's. Note, * this is an OID to OID comparison and only last * Cert is checked. * 2) at user defined ekuchecker where checking * is applied to all Certs on the chain and * the NSS Extended Key Usage algorithm is * used. In order to invoke this checking, not * only does the ComCertSelparams needs to be * set, the EKU initialize call is required to * activate the checking. * * XXX We use the same ComCertSelParams Set/Get * functions to set the parameters for both cases. * We may want to separate them in the future. */ PKIX_CHECK(PKIX_PL_Cert_GetExtendedKeyUsage (cert, &certExtKeyUsageList, plContext), PKIX_CERTGETEXTENDEDKEYUSAGEFAILED); if (state->extKeyUsageList != NULL && certExtKeyUsageList != NULL) { PKIX_CHECK(PKIX_List_GetLength (state->extKeyUsageList, &numItems, plContext), PKIX_LISTGETLENGTHFAILED); for (i = 0; i < numItems; i++) { PKIX_CHECK(PKIX_List_GetItem (state->extKeyUsageList, i, (PKIX_PL_Object **) &name, plContext), PKIX_LISTGETITEMFAILED); PKIX_CHECK(pkix_List_Contains (certExtKeyUsageList, (PKIX_PL_Object *) name, &checkPassed, plContext), PKIX_LISTCONTAINSFAILED); PKIX_DECREF(name); if (checkPassed != PKIX_TRUE) { PKIX_ERROR (PKIX_EXTENDEDKEYUSAGECHECKINGFAILED); } } } } else { /* Check key usage and cert type based on certificate usage. */ PKIX_CHECK(PKIX_PL_Cert_VerifyCertAndKeyType(cert, PKIX_TRUE, plContext), PKIX_CERTVERIFYCERTTYPEFAILED); } /* Remove Critical Extension OID from list */ if (unresolvedCriticalExtensions != NULL) { PKIX_CHECK(pkix_List_Remove (unresolvedCriticalExtensions, (PKIX_PL_Object *) state->extKeyUsageOID, plContext), PKIX_LISTREMOVEFAILED); PKIX_CHECK(PKIX_PL_Cert_GetSubject (cert, &certSubjectName, plContext), PKIX_CERTGETSUBJECTFAILED); if (certSubjAltNames != NULL) { PKIX_CHECK(pkix_List_Remove (unresolvedCriticalExtensions, (PKIX_PL_Object *) state->subjAltNameOID, plContext), PKIX_LISTREMOVEFAILED); } } cleanup: PKIX_DECREF(name); PKIX_DECREF(nameConstraints); PKIX_DECREF(certSubjAltNames); PKIX_DECREF(certExtKeyUsageList); PKIX_DECREF(certSubjectName); PKIX_DECREF(state); PKIX_RETURN(CERTCHAINCHECKER); }