/* * 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_DefaultCRLChecker_Check * * DESCRIPTION: * Check if the Cert has been revoked based the CRLs data. This function * maintains the checker state to be current. * * PARAMETERS * "checker" * Address of CertChainChecker which has the state data. * Must be non-NULL. * "cert" * Address of Certificate that is to be validated. Must be non-NULL. * "unresolvedCriticalExtensions" * A List OIDs. Not **yet** used in this checker function. * "plContext" * Platform-specific context pointer. * * THREAD SAFETY: * Not Thread Safe * (see Thread Safety Definitions in Programmer's Guide) * * RETURNS: * Returns NULL if the function succeeds. * Returns a CertChainChecker Error if the function fails in a non-fatal way. * Returns a Fatal Error */ static PKIX_Error * pkix_DefaultCRLChecker_Check( PKIX_CertChainChecker *checker, PKIX_PL_Cert *cert, PKIX_List *unresolvedCriticalExtensions, void **pNBIOContext, void *plContext) { pkix_DefaultCRLCheckerState *state = NULL; PKIX_PL_PublicKey *publicKey = NULL; PKIX_PL_PublicKey *newPublicKey = NULL; PKIX_Error *checkKeyUsageFail = NULL; PKIX_Boolean selfIssued = PKIX_FALSE; void *nbioContext = NULL; PKIX_ENTER(CERTCHAINCHECKER, "pkix_DefaultCRLChecker_Check"); PKIX_NULLCHECK_THREE(checker, cert, pNBIOContext); nbioContext = *pNBIOContext; *pNBIOContext = NULL; /* prepare for Error exit */ PKIX_CHECK(PKIX_CertChainChecker_GetCertChainCheckerState (checker, (PKIX_PL_Object **)&state, plContext), PKIX_CERTCHAINCHECKERGETCERTCHAINCHECKERSTATEFAILED); PKIX_CHECK(PKIX_PL_Cert_GetSubjectPublicKey (cert, &publicKey, plContext), PKIX_CERTGETSUBJECTPUBLICKEYFAILED); /* * If we already have a selector, we were in the middle of checking * when a certStore returned with non-blocking I/O pendning. */ if ((state->crlSelector) == NULL) { state->certsRemaining--; PKIX_NULLCHECK_ONE(state->prevPublicKey); if (state->prevCertCrlSign == PKIX_FALSE) { PKIX_ERROR (PKIX_KEYUSAGEKEYCRLSIGNBITNOTON); } /* Set up CRLSelector */ PKIX_CHECK(pkix_DefaultCRLChecker_Check_SetSelector (cert, state, plContext), PKIX_DEFAULTCRLCHECKERCHECKSETSELECTORFAILED); } PKIX_CHECK(pkix_DefaultCRLChecker_Check_Helper (checker, cert, state->prevPublicKey, state, unresolvedCriticalExtensions, PKIX_FALSE, &nbioContext, plContext), PKIX_DEFAULTCRLCHECKERCHECKHELPERFAILED); if (nbioContext != NULL) { *pNBIOContext = nbioContext; goto cleanup; } PKIX_DECREF(state->crlSelector); /* * Some NIST test case in 4.5.* use different publicKeys for * Cert and its CRL on the chain. Self-issued Certs are used * to speciy multiple keys for those cases. That is why we apply * the following algorithm: * * Check if Cert is self-issued. If so, the public key of the Cert * that issues this Cert (old key) can be used together with this * current key (new key) for key verification. If there are multiple * self-issued certs, keys of those Certs (old keys) can also be used * for key verification. Old key(s) is saved in a list (PrevPublickKey- * List) and cleared when a Cert is no longer self-issued. * PrevPublicKey keep key of the previous Cert. * PrevPublicKeyList keep key(s) of Cert before the previous one. */ PKIX_CHECK(pkix_IsCertSelfIssued(cert, &selfIssued, plContext), PKIX_ISCERTSELFISSUEFAILED); if (selfIssued == PKIX_TRUE) { if (state->prevPublicKeyList == NULL) { PKIX_CHECK(PKIX_List_Create (&state->prevPublicKeyList, plContext), PKIX_LISTCREATEFAILED); } PKIX_CHECK(PKIX_List_AppendItem (state->prevPublicKeyList, (PKIX_PL_Object *) state->prevPublicKey, plContext), PKIX_LISTAPPENDITEMFAILED); } else { /* Not self-issued Cert any more, clear old key(s) saved */ PKIX_DECREF(state->prevPublicKeyList); } /* Make inheritance and save current Public Key */ PKIX_CHECK(PKIX_PL_PublicKey_MakeInheritedDSAPublicKey (publicKey, state->prevPublicKey, &newPublicKey, plContext), PKIX_PUBLICKEYMAKEINHERITEDDSAPUBLICKEYFAILED); if (newPublicKey == NULL){ PKIX_INCREF(publicKey); newPublicKey = publicKey; } PKIX_DECREF(state->prevPublicKey); PKIX_INCREF(newPublicKey); state->prevPublicKey = newPublicKey; /* Save current Cert's crlSign bit for CRL checking later */ if (state->certsRemaining != 0) { checkKeyUsageFail = PKIX_PL_Cert_VerifyKeyUsage (cert, PKIX_CRL_SIGN, plContext); state->prevCertCrlSign = (checkKeyUsageFail == NULL)? PKIX_TRUE : PKIX_FALSE; PKIX_DECREF(checkKeyUsageFail); } /* PKIX_CHECK(PKIX_CertChainChecker_SetCertChainCheckerState (checker, (PKIX_PL_Object *)state, plContext), PKIX_CERTCHAINCHECKERSETCERTCHAINCHECKERSTATEFAILED); */ cleanup: PKIX_DECREF(state); PKIX_DECREF(publicKey); PKIX_DECREF(newPublicKey); PKIX_DECREF(checkKeyUsageFail); PKIX_RETURN(CERTCHAINCHECKER); }