]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_apple_x509_tp/lib/tpOcspCertVfy.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / Security / libsecurity_apple_x509_tp / lib / tpOcspCertVfy.cpp
diff --git a/Security/libsecurity_apple_x509_tp/lib/tpOcspCertVfy.cpp b/Security/libsecurity_apple_x509_tp/lib/tpOcspCertVfy.cpp
deleted file mode 100644 (file)
index 5356ca7..0000000
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- * Copyright (c) 2004,2011-2012,2014 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * tpOcspCertVfy.cpp - OCSP cert verification routines
- */
-
-#include "tpOcspCertVfy.h"
-#include "tpdebugging.h"
-#include "certGroupUtils.h"
-#include <Security/oidscert.h>
-#include <CommonCrypto/CommonDigest.h>
-#include <security_ocspd/ocspdUtils.h>
-
-#ifndef        NDEBUG
-#include <Security/SecCertificate.h>
-#endif
-
-/*
- * Is signerCert authorized to sign OCSP responses by issuerCert? IssuerCert is
- * assumed to be (i.e., must, but we don't check that here) the signer of the
- * cert being verified, which is not in the loop for this op. Just a bool returned;
- * it's authorized or it's not.
- */
-static bool tpIsAuthorizedOcspSigner(
-       TPCertInfo &issuerCert,         // issuer of cert being verified
-       TPCertInfo &signerCert)         // potential signer of OCSP response
-{
-       CSSM_DATA_PTR           fieldValue = NULL;                      // mallocd by CL
-       CSSM_RETURN                     crtn;
-       bool                            ourRtn = false;
-       CE_ExtendedKeyUsage *eku = NULL;
-       bool                            foundEku = false;
-
-       /*
-        * First see if issuerCert issued signerCert (No signature vfy yet, just
-        * subject/issuer check).
-        */
-       if(!issuerCert.isIssuerOf(signerCert)) {
-#ifndef        NDEBUG
-               SecCertificateRef issuerRef = NULL;
-               SecCertificateRef signerRef = NULL;
-               const CSSM_DATA *issuerData = issuerCert.itemData();
-               const CSSM_DATA *signerData = signerCert.itemData();
-               crtn = SecCertificateCreateFromData(issuerData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_BER, &issuerRef);
-               crtn = SecCertificateCreateFromData(signerData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_BER, &signerRef);
-               CFStringRef issuerName = SecCertificateCopySubjectSummary(issuerRef);
-               CFStringRef signerName = SecCertificateCopySubjectSummary(signerRef);
-               if(issuerName) {
-                       CFIndex maxLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(issuerName), kCFStringEncodingUTF8) + 1;
-                       char* buf = (char*) malloc(maxLength);
-                       if (buf) {
-                               if (CFStringGetCString(issuerName, buf, (CFIndex)maxLength, kCFStringEncodingUTF8)) {
-                                       tpOcspDebug("tpIsAuthorizedOcspSigner: issuerCert \"%s\"", buf);
-                               }
-                               free(buf);
-                       }
-                       CFRelease(issuerName);
-               }
-               if(signerName) {
-                       CFIndex maxLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(signerName), kCFStringEncodingUTF8) + 1;
-                       char* buf = (char*) malloc(maxLength);
-                       if (buf) {
-                               if (CFStringGetCString(signerName, buf, (CFIndex)maxLength, kCFStringEncodingUTF8)) {
-                                       tpOcspDebug("tpIsAuthorizedOcspSigner: signerCert \"%s\"", buf);
-                               }
-                               free(buf);
-                       }
-                       CFRelease(signerName);
-               }
-               if(issuerRef) {
-                       CFRelease(issuerRef);
-               }
-               if(signerRef) {
-                       CFRelease(signerRef);
-               }
-#endif
-               tpOcspDebug("tpIsAuthorizedOcspSigner: signer is not issued by issuerCert");
-               return false;
-       }
-
-       /* Fetch ExtendedKeyUse field from signerCert */
-       crtn = signerCert.fetchField(&CSSMOID_ExtendedKeyUsage, &fieldValue);
-       if(crtn) {
-               tpOcspDebug("tpIsAuthorizedOcspSigner: signer is issued by issuer, no EKU");
-               return false;
-       }
-       CSSM_X509_EXTENSION *cssmExt = (CSSM_X509_EXTENSION *)fieldValue->Data;
-       if(cssmExt->format != CSSM_X509_DATAFORMAT_PARSED) {
-               tpOcspDebug("tpIsAuthorizedOcspSigner: bad extension format");
-               goto errOut;
-       }
-       eku = (CE_ExtendedKeyUsage *)cssmExt->value.parsedValue;
-
-       /* Look for OID_KP_OCSPSigning */
-       for(unsigned dex=0; dex<eku->numPurposes; dex++) {
-               if(tpCompareCssmData(&eku->purposes[dex], &CSSMOID_OCSPSigning)) {
-                       foundEku = true;
-                       break;
-               }
-       }
-       if(!foundEku) {
-               tpOcspDebug("tpIsAuthorizedOcspSigner: signer is issued by issuer, no OCSP "
-                       "signing EKU");
-               goto errOut;
-       }
-
-       /*
-        * OK, signerCert is authorized by *someone* to sign OCSP requests, and
-        * it claims to be issued by issuer. Sig verify to be sure.
-        * FIXME this is not handling partial public keys, which would be a colossal
-        * mess to handle in this module...so we don't.
-        */
-       crtn = signerCert.verifyWithIssuer(&issuerCert, NULL);
-       if(crtn == CSSM_OK) {
-               tpOcspDebug("tpIsAuthorizedOcspSigner: FOUND authorized signer");
-               ourRtn = true;
-       }
-       else {
-               /* This is a highly irregular situation... */
-               tpOcspDebug("tpIsAuthorizedOcspSigner: signer sig verify FAIL");
-       }
-errOut:
-       if(fieldValue != NULL) {
-               signerCert.freeField(&CSSMOID_ExtendedKeyUsage, fieldValue);
-       }
-       return ourRtn;
-}
-
-/*
- * Check ResponderID linkage between an OCSPResponse and a cert we believe to
- * be the issuer of both that response and the cert being verified. Returns
- * true if OK.
- */
-static
-bool tpOcspResponderIDCheck(
-       OCSPResponse    &ocspResp,
-       TPCertInfo              &signer)
-{
-       bool shouldBeSigner = false;
-       if(ocspResp.responderIDTag() == RIT_Name) {
-               /*
-                * Name inside response must == signer's SubjectName.
-                * Note we can't use signer.subjectName(); that's normalized.
-                */
-
-               const CSSM_DATA *respIdName = ocspResp.encResponderName();
-               CSSM_DATA *subjectName = NULL;
-               CSSM_RETURN crtn = signer.fetchField(&CSSMOID_X509V1SubjectNameStd,
-                       &subjectName);
-               if(crtn) {
-                       /* bad cert */
-                       tpOcspDebug("tpOcspResponderIDCheck: error on fetchField(subjectName");
-                       return false;
-               }
-               if(tpCompareCssmData(respIdName, subjectName)) {
-                       tpOcspDebug("tpOcspResponderIDCheck: good ResponderID.byName");
-                       shouldBeSigner = true;
-               }
-               else {
-                       tpOcspDebug("tpOcspResponderIDCheck: BAD ResponderID.byName");
-               }
-               signer.freeField(&CSSMOID_X509V1SubjectNameStd, subjectName);
-       }
-       else {
-               /* ResponderID.byKey must == SHA1(signer's public key) */
-               const CSSM_KEY_PTR pubKey = signer.pubKey();
-               assert(pubKey != NULL);
-               uint8 digest[CC_SHA1_DIGEST_LENGTH];
-               CSSM_DATA keyHash = {CC_SHA1_DIGEST_LENGTH, digest};
-               CSSM_DATA pubKeyBytes = {0, NULL};
-               ocspdGetPublicKeyBytes(NULL, pubKey, pubKeyBytes);
-               ocspdSha1(pubKeyBytes.Data, (CC_LONG)pubKeyBytes.Length, digest);
-               const CSSM_DATA *respKeyHash = &ocspResp.responderID().byKey;
-               if(tpCompareCssmData(&keyHash, respKeyHash)) {
-                       tpOcspDebug("tpOcspResponderIDCheck: good ResponderID.byKey");
-                       shouldBeSigner = true;
-               }
-               else {
-                       tpOcspDebug("tpOcspResponderIDCheck: BAD ResponderID.byKey");
-               }
-       }
-       return shouldBeSigner;
-}
-
-/*
- * Verify the signature of an OCSP response. Caller is responsible for all other
- * verification of the response, this is just the crypto.
- * Returns true on success.
- */
-static bool tpOcspResponseSigVerify(
-       TPVerifyContext         &vfyCtx,
-       OCSPResponse            &ocspResp,              // parsed response
-       TPCertInfo                      &signer)
-{
-       /* get signature algorithm in CSSM form from the response */
-       const SecAsn1OCSPBasicResponse &basicResp = ocspResp.basicResponse();
-       const CSSM_OID *algOid = &basicResp.algId.algorithm;
-       CSSM_ALGORITHMS sigAlg;
-
-       if(!cssmOidToAlg(algOid, &sigAlg)) {
-               tpOcspDebug("tpOcspResponseSigVerify: unknown signature algorithm");
-       }
-
-       /* signer's public key from the cert */
-       const CSSM_KEY *pubKey = signer.pubKey();
-
-       /* signature: on decode, length is in BITS */
-       CSSM_DATA sig = basicResp.sig;
-       sig.Length /= 8;
-
-       CSSM_RETURN crtn;
-       CSSM_CC_HANDLE sigHand;
-       bool ourRtn = false;
-       crtn = CSSM_CSP_CreateSignatureContext(vfyCtx.cspHand, sigAlg, NULL,
-               pubKey, &sigHand);
-       if(crtn) {
-               #ifndef NDEBUG
-               cssmPerror("tpOcspResponseSigVerify, CSSM_CSP_CreateSignatureContext", crtn);
-               #endif
-               return false;
-       }
-       crtn = CSSM_VerifyData(sigHand, &basicResp.tbsResponseData, 1,
-               CSSM_ALGID_NONE, &sig);
-       if(crtn) {
-               #ifndef NDEBUG
-               cssmPerror("tpOcspResponseSigVerify, CSSM_VerifyData", crtn);
-               #endif
-       }
-       else {
-               ourRtn = true;
-       }
-       CSSM_DeleteContext(sigHand);
-       return ourRtn;
-}
-
-/* possible return from tpIsOcspIssuer() */
-typedef enum {
-       OIS_No,                 // not the issuer
-       OIS_Good,               // is the issuer and signature matches
-       OIS_BadSig,             // appears to be issuer, but signature doesn't match
-} OcspIssuerStatus;
-
-/* type of rawCert passed to tpIsOcspIssuer */
-typedef enum {
-       OCT_Local,              // LocalResponder - no checking other than signature
-       OCT_Issuer,             // it's the issuer of the cert being verified
-       OCT_Provided,   // came with response, provenance unknown
-} OcspCertType;
-
-/*
- * Did specified cert issue the OCSP response?
- *
- * This implements the algorithm described in RFC2560, section 4.2.2.2,
- * "Authorized Responders". It sees if the cert could be the issuer of the
- * OCSP response per that algorithm; then if it could, it performs signature
- * verification.
- */
-static OcspIssuerStatus tpIsOcspIssuer(
-       TPVerifyContext         &vfyCtx,
-       OCSPResponse            &ocspResp,              // parsed response
-       /* on input specify at least one of the following two */
-       const CSSM_DATA         *signerData,
-       TPCertInfo                      *signer,
-       OcspCertType            certType,               // where rawCert came from
-       TPCertInfo                      *issuer,                // OPTIONAL, if known
-       TPCertInfo                      **signerRtn)    // optionally RETURNED if at all possible
-{
-       assert((signerData != NULL) || (signer != NULL));
-
-       /* get signer as TPCertInfo if caller hasn't provided */
-       TPCertInfo *tmpSigner = NULL;
-       if(signer == NULL) {
-               try {
-                       tmpSigner = new TPCertInfo(vfyCtx.clHand, vfyCtx.cspHand, signerData,
-                               TIC_CopyData, vfyCtx.verifyTime);
-               }
-               catch(...) {
-                       tpOcspDebug("tpIsOcspIssuer: bad cert");
-                       return OIS_No;
-               }
-               signer = tmpSigner;
-       }
-       if(signer == NULL) {
-               return OIS_No;
-       }
-       if(signerRtn != NULL) {
-               *signerRtn = signer;
-       }
-
-       /*
-        * Qualification of "this can be the signer" depends on where the
-        * signer came from.
-        */
-       bool shouldBeSigner = false;
-       OcspIssuerStatus ourRtn = OIS_No;
-
-       switch(certType) {
-               case OCT_Local:                 // caller trusts this and thinks it's the signer
-                       shouldBeSigner = true;
-                       break;
-               case OCT_Issuer:                // last resort, the actual issuer
-                       /* check ResponderID linkage */
-                       shouldBeSigner = tpOcspResponderIDCheck(ocspResp, *signer);
-                       break;
-               case OCT_Provided:
-               {
-                       /*
-                        * This cert came with the response.
-                        */
-                       if(issuer == NULL) {
-                               /*
-                                * careful, might not know the issuer...how would this path ever
-                                * work then? I don't think it needs to because you can NOT
-                                * do OCSP on a cert without its issuer in hand.
-                                */
-                               break;
-                       }
-
-                       /* check EKU linkage */
-                       shouldBeSigner = tpIsAuthorizedOcspSigner(*issuer, *signer);
-                       break;
-               }
-       }
-       if(!shouldBeSigner) {
-               goto errOut;
-       }
-
-       /* verify the signature */
-       if(tpOcspResponseSigVerify(vfyCtx, ocspResp, *signer)) {
-               ourRtn = OIS_Good;
-       }
-
-errOut:
-       if((signerRtn == NULL) && (tmpSigner != NULL)) {
-               delete tmpSigner;
-       }
-       return ourRtn;
-
-}
-
-OcspRespStatus tpVerifyOcspResp(
-       TPVerifyContext         &vfyCtx,
-       SecNssCoder                     &coder,
-       TPCertInfo                      *issuer,                // issuer of the related cert, may be issuer of
-                                                                               //   reply, may not be known
-       OCSPResponse            &ocspResp,
-       CSSM_RETURN                     &cssmErr)               // possible per-cert error
-{
-       OcspRespStatus  ourRtn = ORS_Unknown;
-       CSSM_RETURN             crtn;
-
-       tpOcspDebug("tpVerifyOcspResp top");
-
-       switch(ocspResp.responseStatus()) {
-               case RS_Success:
-                       crtn = CSSM_OK;
-                       break;
-               case RS_MalformedRequest:
-                       crtn = CSSMERR_APPLETP_OCSP_RESP_MALFORMED_REQ;
-                       break;
-               case RS_InternalError:
-                       crtn = CSSMERR_APPLETP_OCSP_RESP_INTERNAL_ERR;
-                       break;
-               case RS_TryLater:
-                       crtn = CSSMERR_APPLETP_OCSP_RESP_TRY_LATER;
-                       break;
-               case RS_SigRequired:
-                       crtn = CSSMERR_APPLETP_OCSP_RESP_SIG_REQUIRED;
-                       break;
-               case RS_Unauthorized:
-                       crtn = CSSMERR_APPLETP_OCSP_RESP_UNAUTHORIZED;
-                       break;
-               default:
-                       crtn = CSSMERR_APPLETP_OCSP_BAD_RESPONSE;
-                       break;
-       }
-       if(crtn) {
-               tpOcspDebug("tpVerifyOcspResp aborting due to response status %d",
-                       (int)(ocspResp.responseStatus()));
-               cssmErr = crtn;
-               return ORS_Unknown;
-       }
-       cssmErr = CSSM_OK;
-
-       /* one of our main jobs is to locate the signer of the response, here */
-       TPCertInfo *signerInfo = NULL;
-       TPCertInfo *signerInfoTBD = NULL;               // if non NULL at end, we delete
-       /* we'll be verifying into this cert group */
-       TPCertGroup     ocspCerts(vfyCtx.alloc, TGO_Caller);
-       CSSM_BOOL verifiedToRoot;
-       CSSM_BOOL verifiedToAnchor;
-       CSSM_BOOL verifiedViaTrustSetting;
-
-       const CSSM_APPLE_TP_OCSP_OPTIONS *ocspOpts = vfyCtx.ocspOpts;
-       OcspIssuerStatus issuerStat;
-
-       /*
-        * Set true if we ever find an apparent issuer which does not correctly
-        * pass signature verify. If true and we never success, that's a XXX error.
-        */
-       bool foundBadIssuer = false;
-       bool foundLocalResponder = false;
-       uint32 numSignerCerts = ocspResp.numSignerCerts();
-
-       /*
-        * This cert group, allocated by AppleTPSession::CertGroupVerify(),
-        * serves two functions here:
-        *
-        * -- it accumulates certs we get from the net (as parts of OCSP responses)
-        *    for user in verifying OCSPResponse-related certs.
-        *    TPCertGroup::buildCertGroup() uses this group as one of the many
-        *    sources of certs when building a cert chain.
-        *
-        * -- it provides a container into which to stash TPCertInfos which
-        *    persist at least as long as the TPVerifyContext; it's of type TGO_Group,
-        *    so all of the certs added to it get freed when the group does.
-        */
-       assert(vfyCtx.signerCerts != NULL);
-
-       TPCertGroup &gatheredCerts = vfyCtx.gatheredCerts;
-
-       /* set up for disposal of TPCertInfos created by TPCertGroup::buildCertGroup() */
-       TPCertGroup     certsToBeFreed(vfyCtx.alloc, TGO_Group);
-
-       /*
-        * First job is to find the cert which signed this response.
-        * Give priority to caller's LocalResponderCert.
-        */
-       if((ocspOpts != NULL) && (ocspOpts->LocalResponderCert != NULL)) {
-               TPCertInfo *responderInfo = NULL;
-               issuerStat = tpIsOcspIssuer(vfyCtx, ocspResp,
-                       ocspOpts->LocalResponderCert, NULL,
-                       OCT_Local, issuer, &responderInfo);
-               switch(issuerStat) {
-                       case OIS_BadSig:
-                               foundBadIssuer = true;
-                               /* drop thru */
-                       case OIS_No:
-                               if(responderInfo != NULL) {
-                                       /* can't use it - should this be an immediate error? */
-                                       delete responderInfo;
-                               }
-                               break;
-                       case OIS_Good:
-                               assert(responderInfo != NULL);
-                               signerInfo = signerInfoTBD = responderInfo;
-                               foundLocalResponder = true;
-                               tpOcspDebug("tpVerifyOcspResp: signer := LocalResponderCert");
-                               break;
-               }
-       }
-
-       if((signerInfo == NULL) && (numSignerCerts != 0)) {
-               /*
-                * App did not specify a local responder (or provided a bad one)
-                * and the response came with some certs. Try those.
-                */
-               TPCertInfo *respCert = NULL;
-               for(unsigned dex=0; dex<numSignerCerts; dex++) {
-                       const CSSM_DATA *certData = ocspResp.signerCert(dex);
-                       if(signerInfo == NULL) {
-                               /* stop trying this after we succeed... */
-                               issuerStat = tpIsOcspIssuer(vfyCtx, ocspResp,
-                                       certData, NULL,
-                                       OCT_Provided, issuer, &respCert);
-                               switch(issuerStat) {
-                                       case OIS_No:
-                                               break;
-                                       case OIS_Good:
-                                               assert(respCert != NULL);
-                                               signerInfo = signerInfoTBD = respCert;
-                                               tpOcspDebug("tpVerifyOcspResp: signer := signerCert[%u]", dex);
-                                               break;
-                                       case OIS_BadSig:
-                                               foundBadIssuer = true;
-                                               break;
-                               }
-                       }
-                       else {
-                               /*
-                                * At least add this cert to certGroup for verification.
-                                * OcspCert will own the TPCertInfo.
-                                */
-                               try {
-                                       respCert = new TPCertInfo(vfyCtx.clHand, vfyCtx.cspHand, certData,
-                                               TIC_CopyData, vfyCtx.verifyTime);
-                               }
-                               catch(...) {
-                                       tpOcspDebug("tpVerifyOcspResp: BAD signerCert[%u]", dex);
-                               }
-                       }
-                       /* if we got a TPCertInfo, and it's not the signer, add it to certGroup */
-                       if((respCert != NULL) && (respCert != signerInfo)) {
-                               gatheredCerts.appendCert(respCert);
-                       }
-               }
-       }
-
-       if((signerInfo == NULL) && (issuer != NULL)) {
-               /*
-                * Haven't found it yet, try the actual issuer
-                */
-               issuerStat = tpIsOcspIssuer(vfyCtx, ocspResp,
-                       NULL, issuer,
-                       OCT_Issuer, issuer, NULL);
-               switch(issuerStat) {
-                       case OIS_BadSig:
-                               ourRtn = ORS_Unknown;
-                               cssmErr = CSSMERR_APPLETP_OCSP_SIG_ERROR;
-                               goto errOut;
-                       case OIS_No:
-                               break;
-                       case OIS_Good:
-                               signerInfo = issuer;
-                               tpOcspDebug("tpVerifyOcspResp: signer := issuer");
-                               break;
-               }
-       }
-
-       if(signerInfo == NULL) {
-               if((issuer != NULL) && !issuer->isStatusFatal(CSSMERR_APPLETP_OCSP_NO_SIGNER)) {
-                       /* user wants to proceed without verifying! */
-                       tpOcspDebug("tpVerifyOcspResp: no signer found, user allows!");
-                       ourRtn = ORS_Good;
-               }
-               else {
-                       tpOcspDebug("tpVerifyOcspResp: no signer found");
-                       ourRtn = ORS_Unknown;
-                       /* caller adds to per-cert status */
-                       cssmErr = CSSMERR_APPLETP_OCSP_NO_SIGNER;
-               }
-               goto errOut;
-       }
-
-       if(signerInfo != NULL && !foundLocalResponder) {
-               /*
-                * tpIsOcspIssuer has verified that signerInfo is the signer of the
-                * OCSP response, and that it is either the issuer of the cert being
-                * checked or is a valid authorized responder for that issuer based on
-                * key id linkage and EKU. There is no stipulation in RFC2560 to also
-                * build the chain back to a trusted anchor; however, we'll continue to
-                * enforce this for the local responder case. (10742723)
-                */
-               tpOcspDebug("tpVerifyOcspResp SUCCESS");
-               ourRtn = ORS_Good;
-               goto errOut;
-       }
-
-       /*
-        * Last remaining task is to verify the signer, and all the certs back to
-        * an anchor
-        */
-
-       /* start from scratch with both of these groups */
-       gatheredCerts.setAllUnused();
-       vfyCtx.signerCerts->setAllUnused();
-       crtn = ocspCerts.buildCertGroup(
-                       *signerInfo,                    // subject item
-                       vfyCtx.signerCerts,             // inCertGroup the original group-to-be-verified
-                       vfyCtx.dbList,                  // optional
-                       vfyCtx.clHand,
-                       vfyCtx.cspHand,
-                       vfyCtx.verifyTime,
-                       vfyCtx.numAnchorCerts,
-                       vfyCtx.anchorCerts,
-                       certsToBeFreed,                 // local to-be-freed right now
-                       &gatheredCerts,                 // accumulate gathered certs here
-                       CSSM_FALSE,                             // subjectIsInGroup
-                       vfyCtx.actionFlags,
-                       vfyCtx.policyOid,
-                       vfyCtx.policyStr,
-                       vfyCtx.policyStrLen,
-                       kSecTrustSettingsKeyUseSignRevocation,
-                       verifiedToRoot,
-                       verifiedToAnchor,
-                       verifiedViaTrustSetting);
-       if(crtn) {
-               tpOcspDebug("tpVerifyOcspResp buildCertGroup failure");
-               cssmErr = crtn;
-               ourRtn = ORS_Unknown;
-               goto errOut;
-       }
-
-       if(!verifiedToAnchor && !verifiedViaTrustSetting) {
-               /* required */
-               ourRtn = ORS_Unknown;
-               if(verifiedToRoot) {
-                       /* verified to root which is not an anchor */
-                       tpOcspDebug("tpVerifyOcspResp root, no anchor");
-                       cssmErr = CSSMERR_APPLETP_OCSP_INVALID_ANCHOR_CERT;
-               }
-               else {
-                       /* partial chain, no root, not verifiable by anchor */
-                       tpOcspDebug("tpVerifyOcspResp no root, no anchor");
-                       cssmErr = CSSMERR_APPLETP_OCSP_NOT_TRUSTED;
-               }
-               if((issuer != NULL) && !issuer->isStatusFatal(cssmErr)) {
-                       tpOcspDebug("...ignoring last error per trust setting");
-                       ourRtn = ORS_Good;
-               }
-               else {
-                       ourRtn = ORS_Unknown;
-               }
-       }
-       else {
-               tpOcspDebug("tpVerifyOcspResp SUCCESS; chain verified");
-               ourRtn = ORS_Good;
-       }
-
-       /* FIXME policy verify? */
-
-errOut:
-       delete signerInfoTBD;
-       /* any other cleanup? */
-       return ourRtn;
-}