}
ocsp_CheckSignature(ocspSignature *signature, void *tbs,		    const SEC_ASN1Template *encodeTemplate,		    CERTCertDBHandle *handle, SECCertUsage certUsage,		    int64 checkTime, PRBool lookupByName, void *certIndex,		    void *pwArg, CERTCertificate **pSignerCert,		    CERTCertificate *issuer){    SECItem rawSignature;    SECItem *encodedTBS = NULL;    CERTCertificate *responder = NULL;    CERTCertificate *signerCert = NULL;    SECKEYPublicKey *signerKey = NULL;    CERTCertificate **certs = NULL;    SECStatus rv = SECFailure;    int certCount;    int i;    /*     * If this signature has already gone through verification, just     * return the cached result.     */    if (signature->wasChecked) {	if (signature->status == SECSuccess) {	    if (pSignerCert != NULL)		*pSignerCert = CERT_DupCertificate(signature->cert);	} else {	    PORT_SetError(signature->failureReason);	}	return signature->status;    }    /*     * If the signature contains some certificates as well, temporarily     * import them in case they are needed for verification.     *     * Note that the result of this is that each cert in "certs" needs     * to be destroyed.     */    certCount = 0;    if (signature->derCerts != NULL) {	for (; signature->derCerts[certCount] != NULL; certCount++) {	    /* just counting */	    /*IMPORT CERT TO SPKI TABLE */	}    }    rv = CERT_ImportCerts(handle, certUsage, certCount,			  signature->derCerts, &certs,			  PR_FALSE, PR_FALSE, NULL);    if (rv != SECSuccess)	goto finish;    /*     * Now look up the certificate that did the signing.     * The signer can be specified either by name or by key hash.     */    if (lookupByName) {	SECItem *encodedName;	encodedName = SEC_ASN1EncodeItem(NULL, NULL, certIndex,					 CERT_NameTemplate);	if (encodedName == NULL)	    goto finish;	signerCert = CERT_FindCertByName(handle, encodedName);	SECITEM_FreeItem(encodedName, PR_TRUE);    } else {	/*	 * The signer is either 1) a known issuer CA we passed in,	 * 2) the default OCSP responder, or 3) an intermediate CA	 * passed in the cert list to use. Figure out which it is.	 */	responder = ocsp_CertGetDefaultResponder(handle,NULL);	if (responder && ocsp_matchcert(certIndex,responder)) {	    signerCert = CERT_DupCertificate(responder);	} else if (issuer && ocsp_matchcert(certIndex,issuer)) {	    signerCert = CERT_DupCertificate(issuer);	} 	for (i=0; (signerCert == NULL) && (i < certCount); i++) {	    if (ocsp_matchcert(certIndex,certs[i])) {		signerCert = CERT_DupCertificate(certs[i]);	    }	}    }    if (signerCert == NULL) {	rv = SECFailure;	if (PORT_GetError() == SEC_ERROR_UNKNOWN_CERT) {	    /* Make the error a little more specific. */	    PORT_SetError(SEC_ERROR_UNKNOWN_SIGNER);	}	goto finish;    }    /*     * We could mark this true at the top of this function, or always     * below at "finish", but if the problem was just that we could not     * find the signer's cert, leave that as if the signature hasn't     * been checked in case a subsequent call might have better luck.     */    signature->wasChecked = PR_TRUE;    /*     * Just because we have a cert does not mean it is any good; check     * it for validity, trust and usage.     */    rv = CERT_VerifyCert(handle, signerCert, PR_TRUE, certUsage, checkTime,			 pwArg, NULL);    if (rv != SECSuccess)	goto finish;    /*     * Now get the public key from the signer's certificate; we need     * it to perform the verification.     */    signerKey = CERT_ExtractPublicKey(signerCert);    if (signerKey == NULL)	goto finish;    /*     * Prepare the data to be verified; it needs to be DER encoded first.     */    encodedTBS = SEC_ASN1EncodeItem(NULL, NULL, tbs, encodeTemplate);    if (encodedTBS == NULL)	goto finish;    /*     * We copy the signature data *pointer* and length, so that we can     * modify the length without damaging the original copy.  This is a     * simple copy, not a dup, so no destroy/free is necessary.     */    rawSignature = signature->signature;    /*     * The raw signature is a bit string, but we need to represent its     * length in bytes, because that is what the verify function expects.     */    DER_ConvertBitString(&rawSignature);    rv = VFY_VerifyData(encodedTBS->data, encodedTBS->len, signerKey,			&rawSignature,			SECOID_GetAlgorithmTag(&signature->signatureAlgorithm),			pwArg);finish:    if (signature->wasChecked)	signature->status = rv;    if (rv != SECSuccess) {	signature->failureReason = PORT_GetError();	if (signerCert != NULL)	    CERT_DestroyCertificate(signerCert);    } else {	/*	 * Save signer's certificate in signature.	 */	signature->cert = signerCert;	if (pSignerCert != NULL) {	    /*	     * Pass pointer to signer's certificate back to our caller,	     * who is also now responsible for destroying it.	     */	    *pSignerCert = CERT_DupCertificate(signerCert);	}    }    if (encodedTBS != NULL)	SECITEM_FreeItem(encodedTBS, PR_TRUE);    if (signerKey != NULL)	SECKEY_DestroyPublicKey(signerKey);    if (certs != NULL)	CERT_DestroyCertArray(certs, certCount);	/* Free CERTS from SPKDigest Table */    return rv;}