// RFC 6960 section 4.2.2.2: The OCSP responder must either be the issuer of // the cert or it must be a delegated OCSP response signing cert directly // issued by the issuer. If the OCSP responder is a delegated OCSP response // signer, then its certificate is (probably) embedded within the OCSP // response and we'll need to verify that it is a valid certificate that chains // *directly* to issuerCert. static Result VerifySignature(Context& context, ResponderIDType responderIDType, Input responderID, const DERArray& certs, const SignedDataWithSignature& signedResponseData) { bool match; Result rv = MatchResponderID(context.trustDomain, responderIDType, responderID, context.certID.issuer, context.certID.issuerSubjectPublicKeyInfo, match); if (rv != Success) { return rv; } if (match) { return VerifyOCSPSignedData(context.trustDomain, signedResponseData, context.certID.issuerSubjectPublicKeyInfo); } size_t numCerts = certs.GetLength(); for (size_t i = 0; i < numCerts; ++i) { BackCert cert(*certs.GetDER(i), EndEntityOrCA::MustBeEndEntity, nullptr); rv = cert.Init(); if (rv != Success) { return rv; } rv = MatchResponderID(context.trustDomain, responderIDType, responderID, cert.GetSubject(), cert.GetSubjectPublicKeyInfo(), match); if (rv != Success) { if (IsFatalError(rv)) { return rv; } continue; } if (match) { rv = CheckOCSPResponseSignerCert(context.trustDomain, cert, context.certID.issuer, context.certID.issuerSubjectPublicKeyInfo, context.time); if (rv != Success) { if (IsFatalError(rv)) { return rv; } continue; } return VerifyOCSPSignedData(context.trustDomain, signedResponseData, cert.GetSubjectPublicKeyInfo()); } } return Result::ERROR_OCSP_INVALID_SIGNING_CERT; }
// RFC 6960 section 4.2.2.2: The OCSP responder must either be the issuer of // the cert or it must be a delegated OCSP response signing cert directly // issued by the issuer. If the OCSP responder is a delegated OCSP response // signer, then its certificate is (probably) embedded within the OCSP // response and we'll need to verify that it is a valid certificate that chains // *directly* to issuerCert. static Result VerifySignature(Context& context, ResponderIDType responderIDType, const SECItem& responderID, const SECItem* certs, size_t numCerts, const SignedDataWithSignature& signedResponseData) { bool match; Result rv = MatchResponderID(context.trustDomain, responderIDType, responderID, context.certID.issuer, context.certID.issuerSubjectPublicKeyInfo, match); if (rv != Success) { return rv; } if (match) { return VerifyOCSPSignedData(context.trustDomain, signedResponseData, context.certID.issuerSubjectPublicKeyInfo); } for (size_t i = 0; i < numCerts; ++i) { BackCert cert(certs[i], EndEntityOrCA::MustBeEndEntity, nullptr); rv = cert.Init(); if (rv != Success) { return rv; } rv = MatchResponderID(context.trustDomain, responderIDType, responderID, cert.GetSubject(), cert.GetSubjectPublicKeyInfo(), match); if (rv == FatalError) { return rv; } if (rv == RecoverableError) { continue; } if (match) { rv = CheckOCSPResponseSignerCert(context.trustDomain, cert, context.certID.issuer, context.certID.issuerSubjectPublicKeyInfo, context.time); if (rv == FatalError) { return rv; } if (rv == RecoverableError) { continue; } return VerifyOCSPSignedData(context.trustDomain, signedResponseData, cert.GetSubjectPublicKeyInfo()); } } return Fail(RecoverableError, SEC_ERROR_OCSP_INVALID_SIGNING_CERT); }