PR_ASSERT(env!=NULL && (type == rsaKey || type == dsaKey));
PR_ASSERT(env!=NULL && (type == CKK_RSA || type == CKK_DSA));
pubkFromRaw(JNIEnv *env, KeyType type, jbyteArray rawBA){    jobject pubkObj=NULL;    SECKEYPublicKey *pubk=NULL;    SECStatus rv;    SECItem *pubkDER=NULL;    /* validate args */    PR_ASSERT(env!=NULL && (type == rsaKey || type == dsaKey));    if( rawBA == NULL ) {        JSS_throw(env, NULL_POINTER_EXCEPTION);        goto finish;    }    pubkDER = JSS_ByteArrayToSECItem(env, rawBA);    if( pubkDER == NULL ) {        /* exception was thrown */        goto finish;    }    pubk = PR_NEW(SECKEYPublicKey);    if(pubk == NULL) {        JSS_throw(env, OUT_OF_MEMORY_ERROR);        goto finish;    }    pubk->arena = NULL;    pubk->pkcs11Slot = NULL;    pubk->pkcs11ID = CK_INVALID_HANDLE;    pubk->keyType = type;    if( type == rsaKey ) {        rv = SEC_ASN1DecodeItem(NULL, pubk, SECKEY_RSAPublicKeyTemplate,                                pubkDER);    } else {        rv = SEC_ASN1DecodeItem(NULL, pubk, SECKEY_DSAPublicKeyTemplate,                                pubkDER);    }    if( rv != SECSuccess ) {        JSS_throw(env, INVALID_KEY_FORMAT_EXCEPTION);        goto finish;    }    /* this clears pubk */    pubkObj = JSS_PK11_wrapPubKey(env, &pubk);    if( pubkObj == NULL ) {        /* exception was thrown */        goto finish;    }finish:    if(pubk!=NULL) {        /* this will only happen if we failed the ASN1 decoding, meaning         * there's no data stored in the internal SECItems */        PR_Free(pubk);    }    if(pubkDER!=NULL) {        SECITEM_FreeItem(pubkDER, PR_TRUE /*freeit*/);    }    return pubkObj;}