nssSlot_Destroy(slot); return (nssCryptokiObject *)NULL; }  NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize); NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE); NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize); status = nssCKObject_GetAttributes(rvObject->handle, cert_tmpl, ctsize, NULL, session, slot); NSS_CK_ATTRIBUTE_TO_ITEM(cert_tmpl, &existingDER); if (status == PR_SUCCESS) { if (!nssItem_Equal(encoding, &existingDER, NULL)) { nss_SetError(NSS_ERROR_INVALID_CERTIFICATE); status = PR_FAILURE; } nss_ZFreeIf(existingDER.data); } if (status == PR_FAILURE) { nssCryptokiObject_Destroy(rvObject); nssSession_Destroy(session); nssSlot_Destroy(slot);
nssToken_ImportCertificate(  NSSToken *tok,  nssSession *sessionOpt,  NSSCertificateType certType,  NSSItem *id,  NSSUTF8 *nickname,  NSSDER *encoding,  NSSDER *issuer,  NSSDER *subject,  NSSDER *serial,  NSSASCII7 *email,  PRBool asTokenObject){    CK_CERTIFICATE_TYPE cert_type;    CK_ATTRIBUTE_PTR attr;    CK_ATTRIBUTE cert_tmpl[10];    CK_ULONG ctsize;    nssTokenSearchType searchType;    nssCryptokiObject *rvObject = NULL;    if (certType == NSSCertificateType_PKIX) {	cert_type = CKC_X_509;    } else {	return (nssCryptokiObject *)NULL;    }    NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize);    if (asTokenObject) {	NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);	searchType = nssTokenSearchType_TokenOnly;    } else {	NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);	searchType = nssTokenSearchType_SessionOnly;    }    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS,            &g_ck_class_cert);    NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CERTIFICATE_TYPE,  cert_type);    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID,                id);    NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL,             nickname);    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE,             encoding);    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER,            issuer);    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT,           subject);    NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER,     serial);    if (email) {	NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_NETSCAPE_EMAIL,    email);    }    NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);    /* see if the cert is already there */    rvObject = nssToken_FindCertificateByIssuerAndSerialNumber(tok,                                                               sessionOpt,                                                               issuer,                                                               serial,                                                               searchType,                                                               NULL);    if (rvObject) {	NSSSlot *slot = nssToken_GetSlot(tok);	nssSession *session = nssSlot_CreateSession(slot, NULL, PR_TRUE);	if (!session) {	    nssCryptokiObject_Destroy(rvObject);	    return (nssCryptokiObject *)NULL;	}	/* according to PKCS#11, label, ID, issuer, and serial number 	 * may change after the object has been created.  For PKIX, the	 * last two attributes can't change, so for now we'll only worry	 * about the first two.	 */	NSS_CK_TEMPLATE_START(cert_tmpl, attr, ctsize);	NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID,    id);	NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);	NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);	/* reset the mutable attributes on the token */	nssCKObject_SetAttributes(rvObject->handle, 	                          cert_tmpl, ctsize,	                          session, slot);	if (!rvObject->label && nickname) {	    rvObject->label = nssUTF8_Duplicate(nickname, NULL);	}	nssSession_Destroy(session);	nssSlot_Destroy(slot);    } else {	/* Import the certificate onto the token */	rvObject = import_object(tok, sessionOpt, cert_tmpl, ctsize);    }    if (rvObject && tok->cache) {	/* The cache will overwrite the attributes if the object already	 * exists.	 */	nssTokenObjectCache_ImportObject(tok->cache, rvObject,	                                 CKO_CERTIFICATE,	                                 cert_tmpl, ctsize);    }    return rvObject;}