if ( cert->nsCertType & NS_CERT_TYPE_CA ) { if ( cert->nsCertType & caCertType ) { isca = PR_TRUE; } else { isca = PR_FALSE; }
if (!isca || (cert->nsCertType & NS_CERT_TYPE_CA)) { isca = (cert->nsCertType & caCertType) ? PR_TRUE : PR_FALSE;
CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,		PRBool checkSig, SECCertUsage certUsage, int64 t,		void *wincx, CERTVerifyLog *log){    SECTrustType trustType;    CERTBasicConstraints basicConstraint;    PRBool isca;    SECStatus rv;    SECComparison rvCompare;    SECStatus rvFinal = SECSuccess;    int flags;    unsigned int caCertType;    unsigned int requiredCAKeyUsage;    unsigned int requiredFlags;    CERTCertificate *issuerCert;    if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE,					 &requiredCAKeyUsage,					 &caCertType) != SECSuccess ) {	PORT_Assert(0);	EXIT_IF_NOT_LOGGING(log);	requiredCAKeyUsage = 0;	caCertType = 0;    }    switch ( certUsage ) {      case certUsageSSLClient:      case certUsageSSLServer:      case certUsageSSLCA:      case certUsageSSLServerWithStepUp:      case certUsageEmailSigner:      case certUsageEmailRecipient:      case certUsageObjectSigner:      case certUsageVerifyCA:      case certUsageStatusResponder:	if ( CERT_TrustFlagsForCACertUsage(certUsage, &requiredFlags,					   &trustType) != SECSuccess ) {	    PORT_Assert(0);	    EXIT_IF_NOT_LOGGING(log);	    requiredFlags = 0;	    trustType = trustSSL;	}	break;      default:	PORT_Assert(0);	EXIT_IF_NOT_LOGGING(log);	requiredFlags = 0;	trustType = trustSSL;/* This used to be 0, but we need something			      * that matches the enumeration type.			      */	caCertType = 0;    }        /* If the basicConstraint extension is included in an immediate CA     * certificate, make sure that the isCA flag is on.  If the     * pathLenConstraint component exists, it must be greater than the     * number of CA certificates we have seen so far.  If the extension     * is omitted, we will assume that this is a CA certificate with     * an unlimited pathLenConstraint (since it already passes the     * netscape-cert-type extension checking).     *     * In the fortezza (V1) case, we've already checked the CA bits     * in the key, so we're presumed to be a CA; however we really don't     * want to bypass Basic constraint or netscape extension parsing.     *      * In Fortezza V2, basicConstraint will be set for every CA,PCA,PAA     */    rv = CERT_FindBasicConstraintExten(cert, &basicConstraint);    if ( rv != SECSuccess ) {	if (PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND) {	    LOG_ERROR_OR_EXIT(log,cert,0,0);	} 	/* no basic constraints found, if we're fortezza, CA bit is already	 * verified (isca = PR_TRUE). otherwise, we aren't (yet) a ca	 * isca = PR_FALSE */	isca = PR_FALSE;    } else  {	if ( basicConstraint.isCA == PR_FALSE ) {	    PORT_SetError (SEC_ERROR_CA_CERT_INVALID);	    LOG_ERROR_OR_EXIT(log,cert,0,0);	}	/* can't check path length if we don't know the previous path */	isca = PR_TRUE;    }	    if ( cert->trust ) {	/*	 * check the trust parms of the issuer	 */	flags = SEC_GET_TRUST_FLAGS(cert->trust, trustType);	    	if ( (flags & CERTDB_VALID_CA) ||		 (certUsage == certUsageStatusResponder)) {	    if ( ( flags & requiredFlags ) == requiredFlags ||		     certUsage == certUsageStatusResponder ) {		    /* we found a trusted one, so return */        /* Check  the special case of certUsageStatusResponder */        if(certUsage == certUsageStatusResponder) {           issuerCert = CERT_FindCertIssuer(cert, t, certUsage);	         if (issuerCert) {              if(SEC_CheckCRL(handle, cert, issuerCert, t, wincx) != SECSuccess) {                 PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);                 CERT_DestroyCertificate(issuerCert);                 goto loser;              }              CERT_DestroyCertificate(issuerCert);           }        }		    rv = rvFinal; 		    goto done;	    }	}    }    /*     * Make sure that if this is an intermediate CA in the chain that     * it was given permission by its signer to be a CA.     */    if ( isca ) {	/*	 * if basicConstraints says it is a ca, then we check the	 * nsCertType.  If the nsCertType has any CA bits set, then	 * it must have the right one.	 */	if ( cert->nsCertType & NS_CERT_TYPE_CA ) {	    if ( cert->nsCertType & caCertType ) {		isca = PR_TRUE;	    } else {		isca = PR_FALSE;	    }	}    } else {	if ( cert->nsCertType & caCertType ) {	    isca = PR_TRUE;	} else {	    isca = PR_FALSE;	}    }	    if (  !isca  ) {	PORT_SetError(SEC_ERROR_CA_CERT_INVALID);	LOG_ERROR_OR_EXIT(log,cert,0,0);    }	        /* make sure key usage allows cert signing */    if (CERT_CheckKeyUsage(cert, requiredCAKeyUsage) != SECSuccess) {	    PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);	    LOG_ERROR_OR_EXIT(log,cert,0,requiredCAKeyUsage);    }    /* make sure that the issuer is not self signed.  If it is, then     * stop here to prevent looping.     */    rvCompare = SECITEM_CompareItem(&cert->derSubject,				 &cert->derIssuer);    if (rvCompare == SECEqual) {	    PORT_SetError(SEC_ERROR_UNTRUSTED_ISSUER);	    LOG_ERROR(log, cert, 0, 0);	    goto loser;    }    return CERT_VerifyCertChain(handle, cert, checkSig, certUsage, t, 		     					wincx, log);loser:    rv = SECFailure;done:    return rv;}