SECStatus CertVerifier::VerifySSLServerCert(const UniqueCERTCertificate& peerCert, /*optional*/ const SECItem* stapledOCSPResponse, Time time, /*optional*/ void* pinarg, const char* hostname, /*out*/ ScopedCERTCertList& builtChain, /*optional*/ bool saveIntermediatesInPermanentDatabase, /*optional*/ Flags flags, /*optional out*/ SECOidTag* evOidPolicy, /*optional out*/ OCSPStaplingStatus* ocspStaplingStatus, /*optional out*/ KeySizeStatus* keySizeStatus, /*optional out*/ SHA1ModeResult* sha1ModeResult, /*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo) { PR_ASSERT(peerCert); // XXX: PR_ASSERT(pinarg) PR_ASSERT(hostname); PR_ASSERT(hostname[0]); if (evOidPolicy) { *evOidPolicy = SEC_OID_UNKNOWN; } if (!hostname || !hostname[0]) { PR_SetError(SSL_ERROR_BAD_CERT_DOMAIN, 0); return SECFailure; } // CreateCertErrorRunnable assumes that CheckCertHostname is only called // if VerifyCert succeeded. SECStatus rv = VerifyCert(peerCert.get(), certificateUsageSSLServer, time, pinarg, hostname, builtChain, flags, stapledOCSPResponse, evOidPolicy, ocspStaplingStatus, keySizeStatus, sha1ModeResult, pinningTelemetryInfo); if (rv != SECSuccess) { return rv; } Input peerCertInput; Result result = peerCertInput.Init(peerCert->derCert.data, peerCert->derCert.len); if (result != Success) { PR_SetError(MapResultToPRErrorCode(result), 0); return SECFailure; } Input stapledOCSPResponseInput; Input* responseInputPtr = nullptr; if (stapledOCSPResponse) { result = stapledOCSPResponseInput.Init(stapledOCSPResponse->data, stapledOCSPResponse->len); if (result != Success) { // The stapled OCSP response was too big. PR_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE, 0); return SECFailure; } responseInputPtr = &stapledOCSPResponseInput; } if (!(flags & FLAG_TLS_IGNORE_STATUS_REQUEST)) { result = CheckTLSFeaturesAreSatisfied(peerCertInput, responseInputPtr); if (result != Success) { PR_SetError(MapResultToPRErrorCode(result), 0); return SECFailure; } } Input hostnameInput; result = hostnameInput.Init(uint8_t_ptr_cast(hostname), strlen(hostname)); if (result != Success) { PR_SetError(SEC_ERROR_INVALID_ARGS, 0); return SECFailure; } bool isBuiltInRoot; result = IsCertChainRootBuiltInRoot(builtChain, isBuiltInRoot); if (result != Success) { PR_SetError(MapResultToPRErrorCode(result), 0); return SECFailure; } BRNameMatchingPolicy nameMatchingPolicy( isBuiltInRoot ? mNameMatchingMode : BRNameMatchingPolicy::Mode::DoNotEnforce); result = CheckCertHostname(peerCertInput, hostnameInput, nameMatchingPolicy); if (result != Success) { // Treat malformed name information as a domain mismatch. if (result == Result::ERROR_BAD_DER) { PR_SetError(SSL_ERROR_BAD_CERT_DOMAIN, 0); } else { PR_SetError(MapResultToPRErrorCode(result), 0); } return SECFailure; } if (saveIntermediatesInPermanentDatabase) { SaveIntermediateCerts(builtChain); } return SECSuccess; }
SECStatus CertVerifier::VerifySSLServerCert(CERTCertificate* peerCert, /*optional*/ const SECItem* stapledOCSPResponse, Time time, /*optional*/ void* pinarg, const char* hostname, bool saveIntermediatesInPermanentDatabase, Flags flags, /*optional out*/ ScopedCERTCertList* builtChain, /*optional out*/ SECOidTag* evOidPolicy, /*optional out*/ OCSPStaplingStatus* ocspStaplingStatus, /*optional out*/ KeySizeStatus* keySizeStatus) { PR_ASSERT(peerCert); // XXX: PR_ASSERT(pinarg) PR_ASSERT(hostname); PR_ASSERT(hostname[0]); if (builtChain) { *builtChain = nullptr; } if (evOidPolicy) { *evOidPolicy = SEC_OID_UNKNOWN; } if (!hostname || !hostname[0]) { PR_SetError(SSL_ERROR_BAD_CERT_DOMAIN, 0); return SECFailure; } ScopedCERTCertList builtChainTemp; // CreateCertErrorRunnable assumes that CheckCertHostname is only called // if VerifyCert succeeded. SECStatus rv = VerifyCert(peerCert, certificateUsageSSLServer, time, pinarg, hostname, flags, stapledOCSPResponse, &builtChainTemp, evOidPolicy, ocspStaplingStatus, keySizeStatus); if (rv != SECSuccess) { return rv; } Input peerCertInput; Result result = peerCertInput.Init(peerCert->derCert.data, peerCert->derCert.len); if (result != Success) { PR_SetError(MapResultToPRErrorCode(result), 0); return SECFailure; } Input hostnameInput; result = hostnameInput.Init(uint8_t_ptr_cast(hostname), strlen(hostname)); if (result != Success) { PR_SetError(SEC_ERROR_INVALID_ARGS, 0); return SECFailure; } result = CheckCertHostname(peerCertInput, hostnameInput); if (result != Success) { PR_SetError(MapResultToPRErrorCode(result), 0); return SECFailure; } if (saveIntermediatesInPermanentDatabase) { SaveIntermediateCerts(builtChainTemp); } if (builtChain) { *builtChain = builtChainTemp.forget(); } return SECSuccess; }