PORT_Free(encodedExtKeyUsage.data);
cert_GetCertType(CERTCertificate *cert){    SECStatus rv;    SECItem tmpitem;    SECItem encodedExtKeyUsage;    CERTOidSequence *extKeyUsage = NULL;    PRBool basicConstraintPresent = PR_FALSE;    CERTBasicConstraints basicConstraint;    unsigned int nsCertType = 0;    if (cert->nsCertType) {        /* once set, no need to recalculate */        return SECSuccess;    }    tmpitem.data = NULL;    CERT_FindNSCertTypeExtension(cert, &tmpitem);    rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, 				&encodedExtKeyUsage);    if (rv == SECSuccess) {	extKeyUsage = CERT_DecodeOidSequence(&encodedExtKeyUsage);    }    rv = CERT_FindBasicConstraintExten(cert, &basicConstraint);    if (rv == SECSuccess) {	basicConstraintPresent = PR_TRUE;    }    if (tmpitem.data != NULL || extKeyUsage != NULL) {	if (tmpitem.data == NULL) {	    nsCertType = 0;	} else {	    nsCertType = tmpitem.data[0];	}	/* free tmpitem data pointer to avoid memory leak */	PORT_Free(tmpitem.data);	tmpitem.data = NULL;		/*	 * for this release, we will allow SSL certs with an email address	 * to be used for email	 */	if ( ( nsCertType & NS_CERT_TYPE_SSL_CLIENT ) &&	    cert->emailAddr && cert->emailAddr[0]) {	    nsCertType |= NS_CERT_TYPE_EMAIL;	}	/*	 * for this release, we will allow SSL intermediate CAs to be	 * email intermediate CAs too.	 */	if ( nsCertType & NS_CERT_TYPE_SSL_CA ) {	    nsCertType |= NS_CERT_TYPE_EMAIL_CA;	}	/*	 * allow a cert with the extended key usage of EMail Protect	 * to be used for email or as an email CA, if basic constraints	 * indicates that it is a CA.	 */	if (findOIDinOIDSeqByTagNum(extKeyUsage, 				    SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT) ==	    SECSuccess) {	    if (basicConstraintPresent == PR_TRUE &&		(basicConstraint.isCA)) {		nsCertType |= NS_CERT_TYPE_EMAIL_CA;	    } else {		nsCertType |= NS_CERT_TYPE_EMAIL;	    }	}	if (findOIDinOIDSeqByTagNum(extKeyUsage, 				    SEC_OID_EXT_KEY_USAGE_SERVER_AUTH) ==	    SECSuccess){	    if (basicConstraintPresent == PR_TRUE &&		(basicConstraint.isCA)) {		nsCertType |= NS_CERT_TYPE_SSL_CA;	    } else {		nsCertType |= NS_CERT_TYPE_SSL_SERVER;	    }	}	/* Treat certs with step-up OID as also having SSL server type. */	if (findOIDinOIDSeqByTagNum(extKeyUsage, 				    SEC_OID_NS_KEY_USAGE_GOVT_APPROVED) ==	    SECSuccess){	    if (basicConstraintPresent == PR_TRUE &&		(basicConstraint.isCA)) {		nsCertType |= NS_CERT_TYPE_SSL_CA;	    } else {		nsCertType |= NS_CERT_TYPE_SSL_SERVER;	    }	}	if (findOIDinOIDSeqByTagNum(extKeyUsage,				    SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) ==	    SECSuccess){	    if (basicConstraintPresent == PR_TRUE &&		(basicConstraint.isCA)) {		nsCertType |= NS_CERT_TYPE_SSL_CA;	    } else {		nsCertType |= NS_CERT_TYPE_SSL_CLIENT;	    }	}	if (findOIDinOIDSeqByTagNum(extKeyUsage,				    SEC_OID_EXT_KEY_USAGE_CODE_SIGN) ==	    SECSuccess) {	    if (basicConstraintPresent == PR_TRUE &&		(basicConstraint.isCA)) {		nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING_CA;	    } else {		nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING;	    }	}	if (findOIDinOIDSeqByTagNum(extKeyUsage,				    SEC_OID_EXT_KEY_USAGE_TIME_STAMP) ==	    SECSuccess) {	    nsCertType |= EXT_KEY_USAGE_TIME_STAMP;	}	if (findOIDinOIDSeqByTagNum(extKeyUsage,				    SEC_OID_OCSP_RESPONDER) == 	    SECSuccess) {	    nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;	}    } else {	/* if no extension, then allow any ssl or email (no ca or object	 * signing)	 */	nsCertType = NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER |	    NS_CERT_TYPE_EMAIL;	/* if the basic constraint extension says the cert is a CA, then	   allow SSL CA and EMAIL CA and Status Responder */	if ((basicConstraintPresent == PR_TRUE)	    && (basicConstraint.isCA)) {		nsCertType |= NS_CERT_TYPE_SSL_CA;		nsCertType |= NS_CERT_TYPE_EMAIL_CA;		nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;	} else if (CERT_IsCACert(cert, NULL) == PR_TRUE) {		nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;	}	/* if the cert is a fortezza CA cert, then allow SSL CA and EMAIL CA */	if (fortezzaIsCA(cert)) {		nsCertType |= NS_CERT_TYPE_SSL_CA;		nsCertType |= NS_CERT_TYPE_EMAIL_CA;	}    }    if (extKeyUsage != NULL) {	PORT_Free(encodedExtKeyUsage.data);	CERT_DestroyOidSequence(extKeyUsage);    }    /* Assert that it is safe to cast &cert->nsCertType to "PRInt32 *" */    PORT_Assert(sizeof(cert->nsCertType) == sizeof(PRInt32));    PR_AtomicSet((PRInt32 *)&cert->nsCertType, nsCertType);    return(SECSuccess);}