rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_KEAParamsTemplate,
rv = SEC_QuickDERDecodeItem(arena, pubk, SECKEY_KEAParamsTemplate,
seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki){    SECKEYPublicKey *pubk;    SECItem os;    SECStatus rv;    PRArenaPool *arena;    SECOidTag tag;    arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);    if (arena == NULL)	return NULL;    pubk = (SECKEYPublicKey *) PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));    if (pubk == NULL) {	PORT_FreeArena (arena, PR_FALSE);	return NULL;    }    pubk->arena = arena;    pubk->pkcs11Slot = 0;    pubk->pkcs11ID = CK_INVALID_HANDLE;    /* Convert bit string length from bits to bytes */    os = spki->subjectPublicKey;    DER_ConvertBitString (&os);    tag = SECOID_GetAlgorithmTag(&spki->algorithm);    switch ( tag ) {      case SEC_OID_X500_RSA_ENCRYPTION:      case SEC_OID_PKCS1_RSA_ENCRYPTION:	pubk->keyType = rsaKey;	prepare_rsa_pub_key_for_asn1(pubk);	rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_RSAPublicKeyTemplate, &os);	if (rv == SECSuccess)	    return pubk;	break;      case SEC_OID_ANSIX9_DSA_SIGNATURE:      case SEC_OID_SDN702_DSA_SIGNATURE:	pubk->keyType = dsaKey;	prepare_dsa_pub_key_for_asn1(pubk);	rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_DSAPublicKeyTemplate, &os);	if (rv != SECSuccess) break;        rv = SECKEY_DSADecodePQG(arena, pubk,                                 &spki->algorithm.parameters); 	if (rv == SECSuccess) return pubk;	break;      case SEC_OID_X942_DIFFIE_HELMAN_KEY:	pubk->keyType = dhKey;	prepare_dh_pub_key_for_asn1(pubk);	rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_DHPublicKeyTemplate, &os);	if (rv != SECSuccess) break;        rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_DHParamKeyTemplate,                                 &spki->algorithm.parameters); 	if (rv == SECSuccess) return pubk;	break;      case SEC_OID_MISSI_KEA_DSS_OLD:      case SEC_OID_MISSI_KEA_DSS:      case SEC_OID_MISSI_DSS_OLD:      case SEC_OID_MISSI_DSS:	pubk->keyType = fortezzaKey;	rv = SECKEY_FortezzaDecodeCertKey(arena, pubk, &os,				          &spki->algorithm.parameters);	if (rv == SECSuccess)	    return pubk;	break;      case SEC_OID_MISSI_KEA:	pubk->keyType = keaKey;	prepare_kea_pub_key_for_asn1(pubk);        rv = SEC_ASN1DecodeItem(arena, pubk,                                SECKEY_KEAPublicKeyTemplate, &os);        if (rv != SECSuccess) break;        rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_KEAParamsTemplate,                        &spki->algorithm.parameters);	if (rv == SECSuccess)	    return pubk;        break;      case SEC_OID_MISSI_ALT_KEA:	pubk->keyType = keaKey;        rv = SECITEM_CopyItem(arena,&pubk->u.kea.publicValue,&os);        if (rv != SECSuccess) break;         rv = SEC_ASN1DecodeItem(arena, pubk, SECKEY_KEAParamsTemplate,                        &spki->algorithm.parameters);	if (rv == SECSuccess)	    return pubk;        break;      default:	rv = SECFailure;	break;    }    SECKEY_DestroyPublicKey (pubk);    return NULL;}