case certUsageVerifyCA:
CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert,		PRBool checkSig, SECCertificateUsage requiredUsages, int64 t,		void *wincx, CERTVerifyLog *log, SECCertificateUsage* returnedUsages){    SECStatus rv;    SECStatus valid;    unsigned int requiredKeyUsage;    unsigned int requiredCertType;    unsigned int flags;    unsigned int certType;    PRBool       allowOverride;    SECCertTimeValidity validity;    CERTStatusConfig *statusConfig;    PRBool checkedChain = PR_FALSE;    PRInt32 i;    SECCertUsage certUsage = 0;    PRBool doOCSP = PR_FALSE;    PRBool checkedCRL = PR_FALSE;    PRBool checkedOCSP = PR_FALSE;    PRBool checkAllUsages = PR_FALSE;    PRBool revoked = PR_FALSE;    if (!requiredUsages) {        /* there are no required usages, so the user probably wants to           get status for all usages */        checkAllUsages = PR_TRUE;    }    if (returnedUsages) {        *returnedUsages = 0;    } else {        /* we don't have a place to return status for all usages,           so we can skip checks for usages that aren't required */        checkAllUsages = PR_FALSE;    }    valid = SECSuccess ; /* start off assuming cert is valid */   #ifdef notdef     /* check if this cert is in the Evil list */    rv = CERT_CheckForEvilCert(cert);    if ( rv != SECSuccess ) {	PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);	LOG_ERROR(log,cert,0,0);	return SECFailure;    }#endif        /* make sure that the cert is valid at time t */    allowOverride = (PRBool)((requiredUsages & certUsageSSLServer) ||                             (requiredUsages & certificateUsageSSLServerWithStepUp));    validity = CERT_CheckCertValidTimes(cert, t, allowOverride);    if ( validity != secCertTimeValid ) {        LOG_ERROR(log,cert,0,validity);	return SECFailure;    }    /* check key usage and netscape cert type */    CERT_GetCertType(cert);    certType = cert->nsCertType;    for (i=1;i<=highestUsage && !(SECFailure == valid && !returnedUsages) ;) {        PRBool requiredUsage = (i & requiredUsages) ? PR_TRUE : PR_FALSE;        if (PR_FALSE == requiredUsage && PR_FALSE == checkAllUsages) {            NEXT_ITERATION();        }        if (returnedUsages) {            *returnedUsages |= i; /* start off assuming this usage is valid */        }        switch ( certUsage ) {          case certUsageSSLClient:          case certUsageSSLServer:          case certUsageSSLServerWithStepUp:          case certUsageSSLCA:          case certUsageEmailSigner:          case certUsageEmailRecipient:          case certUsageObjectSigner:          case certUsageStatusResponder:            rv = CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_FALSE,                                                  &requiredKeyUsage,                                                  &requiredCertType);            if ( rv != SECSuccess ) {                PORT_Assert(0);                /* EXIT_IF_NOT_LOGGING(log); XXX ??? */                requiredKeyUsage = 0;                requiredCertType = 0;                INVALID_USAGE();            }            break;          case certUsageVerifyCA:            requiredKeyUsage = KU_KEY_CERT_SIGN;            requiredCertType = NS_CERT_TYPE_CA;            if ( ! ( certType & NS_CERT_TYPE_CA ) ) {                certType |= NS_CERT_TYPE_CA;            }            break;          case certUsageAnyCA:          case certUsageProtectedObjectSigner:          case certUsageUserCertImport:              /* these usages cannot be verified */              NEXT_ITERATION();          default:            PORT_Assert(0);            requiredKeyUsage = 0;            requiredCertType = 0;            INVALID_USAGE();        }        if ( CERT_CheckKeyUsage(cert, requiredKeyUsage) != SECSuccess ) {            if (PR_TRUE == requiredUsage) {                PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);            }            LOG_ERROR(log,cert,0,requiredKeyUsage);            INVALID_USAGE();        }        if ( !( certType & requiredCertType ) ) {            if (PR_TRUE == requiredUsage) {                PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE);            }            LOG_ERROR(log,cert,0,requiredCertType);            INVALID_USAGE();        }        /* check trust flags to see if this cert is directly trusted */        if ( cert->trust ) { /* the cert is in the DB */            switch ( certUsage ) {              case certUsageSSLClient:              case certUsageSSLServer:                flags = cert->trust->sslFlags;                /* is the cert directly trusted or not trusted ? */                if ( flags & CERTDB_VALID_PEER ) {/*the trust record is valid*/                    if ( flags & CERTDB_TRUSTED ) {	/* trust this cert */                        VALID_USAGE();                    } else { /* don't trust this cert */                        if (PR_TRUE == requiredUsage) {                            PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);                        }                        LOG_ERROR(log,cert,0,flags);                        INVALID_USAGE();                    }                }                break;              case certUsageSSLServerWithStepUp:                /* XXX - step up certs can't be directly trusted */                break;              case certUsageSSLCA:                break;              case certUsageEmailSigner:              case certUsageEmailRecipient:                flags = cert->trust->emailFlags;                /* is the cert directly trusted or not trusted ? */                if ( ( flags & ( CERTDB_VALID_PEER | CERTDB_TRUSTED ) ) ==                    ( CERTDB_VALID_PEER | CERTDB_TRUSTED ) ) {                    VALID_USAGE();                }                break;              case certUsageObjectSigner:                flags = cert->trust->objectSigningFlags;                /* is the cert directly trusted or not trusted ? */                if ( flags & CERTDB_VALID_PEER ) {/*the trust record is valid*/                    if ( flags & CERTDB_TRUSTED ) {	/* trust this cert */                        VALID_USAGE();                    } else { /* don't trust this cert */                        if (PR_TRUE == requiredUsage) {                            PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);                        }                        LOG_ERROR(log,cert,0,flags);                        INVALID_USAGE();                    }                }                break;              case certUsageVerifyCA:              case certUsageStatusResponder:                flags = cert->trust->sslFlags;                /* is the cert directly trusted or not trusted ? */                if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) ==                    ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) {                    VALID_USAGE();                }                flags = cert->trust->emailFlags;                /* is the cert directly trusted or not trusted ? */                if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) ==                    ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) {                    VALID_USAGE();                }                flags = cert->trust->objectSigningFlags;                /* is the cert directly trusted or not trusted ? */                if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) ==                    ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) {                    VALID_USAGE();                }                break;              case certUsageAnyCA:              case certUsageProtectedObjectSigner:              case certUsageUserCertImport:                /* XXX to make the compiler happy.  Should these be                 * explicitly handled?                 */                break;            }        }        if (PR_TRUE == revoked) {            INVALID_USAGE();        }        /* only optionally check signature the first time */        /* don't check CRL as part of cert chain, we are doing that separately */        /* rv = __CERT_VerifyCertChain(handle, cert, (PR_TRUE == checkedChain) ? PR_FALSE : checkSig,            certUsage, t, wincx, log, issuerCert, PR_TRUE); */        rv = __CERT_VerifyCertChain(handle, cert, (PR_TRUE == checkedChain) ? PR_FALSE : checkSig,            certUsage, t, wincx, log, checkedChain?PR_FALSE:PR_TRUE, &revoked);        checkedChain = PR_TRUE;        if (rv != SECSuccess) {            /* EXIT_IF_NOT_LOGGING(log); XXX ???? */            INVALID_USAGE();        }        /*         * Check OCSP revocation status, but only if the cert we are checking         * is not a status reponder itself.  We only do this in the case         * where we checked the cert chain (above); explicit trust "wins"         * (avoids status checking, just as it avoids CRL checking) by         * bypassing this code.         */        if (PR_FALSE == checkedOCSP) {            checkedOCSP = PR_TRUE; /* only check OCSP once */            statusConfig = CERT_GetStatusConfig(handle);            if ( (! (requiredUsages & certificateUsageStatusResponder)) &&                statusConfig != NULL) {                if (statusConfig->statusChecker != NULL) {                    rv = (* statusConfig->statusChecker)(handle, cert,                                                                 t, wincx);                    if (rv != SECSuccess) {                        LOG_ERROR(log,cert,0,0);                        revoked = PR_TRUE;                        INVALID_USAGE();                    }                }            }        }        NEXT_ITERATION();    }        return(valid);}