rv = SEC_ASN1DecodeItem(arena, &sd, CERT_SignedDataTemplate, &signedItem );
rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, &signedItem );
SECKEY_ConvertAndDecodePublicKeyAndChallenge(char *pkacstr, char *challenge,								void *wincx){    CERTSubjectPublicKeyInfo *spki = NULL;    CERTPublicKeyAndChallenge pkac;    SECStatus rv;    SECItem signedItem;    PRArenaPool *arena = NULL;    CERTSignedData sd;    SECItem sig;    SECKEYPublicKey *pubKey = NULL;    unsigned int len;        signedItem.data = NULL;        /* convert the base64 encoded data to binary */    rv = ATOB_ConvertAsciiToItem(&signedItem, pkacstr);    if (rv != SECSuccess) {	goto loser;    }    /* create an arena */    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if (arena == NULL) {	goto loser;    }    /* decode the outer wrapping of signed data */    PORT_Memset(&sd, 0, sizeof(CERTSignedData));    rv = SEC_ASN1DecodeItem(arena, &sd, CERT_SignedDataTemplate, &signedItem );    if ( rv ) {	goto loser;    }    /* decode the public key and challenge wrapper */    PORT_Memset(&pkac, 0, sizeof(CERTPublicKeyAndChallenge));    rv = SEC_ASN1DecodeItem(arena, &pkac, CERT_PublicKeyAndChallengeTemplate, 			    &sd.data);    if ( rv ) {	goto loser;    }    /* decode the subject public key info */    spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&pkac.spki);    if ( spki == NULL ) {	goto loser;    }        /* get the public key */    pubKey = seckey_ExtractPublicKey(spki);    if ( pubKey == NULL ) {	goto loser;    }    /* check the signature */    sig = sd.signature;    DER_ConvertBitString(&sig);    rv = VFY_VerifyData(sd.data.data, sd.data.len, pubKey, &sig,			SECOID_GetAlgorithmTag(&(sd.signatureAlgorithm)), wincx);    if ( rv != SECSuccess ) {	goto loser;    }        /* check the challenge */    if ( challenge ) {	len = PORT_Strlen(challenge);	/* length is right */	if ( len != pkac.challenge.len ) {	    goto loser;	}	/* actual data is right */	if ( PORT_Memcmp(challenge, pkac.challenge.data, len) != 0 ) {	    goto loser;	}    }    goto done;loser:    /* make sure that we return null if we got an error */    if ( spki ) {	SECKEY_DestroySubjectPublicKeyInfo(spki);    }    spki = NULL;    done:    if ( signedItem.data ) {	PORT_Free(signedItem.data);    }    if ( arena ) {	PORT_FreeArena(arena, PR_FALSE);    }    if ( pubKey ) {	SECKEY_DestroyPublicKey(pubKey);    }        return spki;}