Result IsCertChainRootBuiltInRoot(CERTCertList* chain, bool& result) { if (!chain || CERT_LIST_EMPTY(chain)) { return Result::FATAL_ERROR_LIBRARY_FAILURE; } CERTCertListNode* rootNode = CERT_LIST_TAIL(chain); if (!rootNode) { return Result::FATAL_ERROR_LIBRARY_FAILURE; } CERTCertificate* root = rootNode->cert; if (!root) { return Result::FATAL_ERROR_LIBRARY_FAILURE; } return IsCertBuiltInRoot(root, result); }
Result CertListContainsExpectedKeys(const CERTCertList* certList, const char* hostname, Time time, CertVerifier::PinningMode pinningMode) { if (pinningMode == CertVerifier::pinningDisabled) { PR_LOG(gCertVerifierLog, PR_LOG_DEBUG, ("Pinning is disabled; not checking keys.")); return Success; } if (!certList) { return Result::FATAL_ERROR_INVALID_ARGS; } CERTCertListNode* rootNode = CERT_LIST_TAIL(certList); if (CERT_LIST_END(rootNode, certList)) { return Result::FATAL_ERROR_INVALID_ARGS; } bool isBuiltInRoot = false; SECStatus srv = IsCertBuiltInRoot(rootNode->cert, isBuiltInRoot); if (srv != SECSuccess) { return MapPRErrorCodeToResult(PR_GetError()); } // If desired, the user can enable "allow user CA MITM mode", in which // case key pinning is not enforced for certificates that chain to trust // anchors that are not in Mozilla's root program if (!isBuiltInRoot && pinningMode == CertVerifier::pinningAllowUserCAMITM) { return Success; } bool enforceTestMode = (pinningMode == CertVerifier::pinningEnforceTestMode); if (PublicKeyPinningService::ChainHasValidPins(certList, hostname, time, enforceTestMode)) { return Success; } return Result::ERROR_KEY_PINNING_FAILURE; }