if (NSS_GetError() == NSS_ERROR_INVALID_CERTIFICATE) { PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL); SECITEM_FreeItem(keyID,PR_TRUE); return SECFailure; }
PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, 		CK_OBJECT_HANDLE key, char *nickname, PRBool includeTrust) {#ifdef NSS_CLASSIC    int len = 0;    SECItem *keyID = pk11_mkcertKeyID(cert);    CK_ATTRIBUTE keyAttrs[] = {	{ CKA_LABEL, NULL, 0},	{ CKA_SUBJECT, NULL, 0},    };    CK_OBJECT_CLASS certc = CKO_CERTIFICATE;    CK_CERTIFICATE_TYPE certType = CKC_X_509;    CK_OBJECT_HANDLE certID;    CK_SESSION_HANDLE rwsession;    CK_BBOOL cktrue = CK_TRUE;    SECStatus rv = SECFailure;    CK_ATTRIBUTE certAttrs[] = {	{ CKA_ID, NULL, 0 },	{ CKA_LABEL, NULL, 0},	{ CKA_CLASS,  NULL, 0},	{ CKA_TOKEN,  NULL, 0},	{ CKA_CERTIFICATE_TYPE, NULL, 0},	{ CKA_SUBJECT, NULL, 0},	{ CKA_ISSUER, NULL, 0},	{ CKA_SERIAL_NUMBER,  NULL, 0},	{ CKA_VALUE,  NULL, 0},	{ CKA_NETSCAPE_TRUST,  NULL, 0},	{ CKA_NETSCAPE_EMAIL,  NULL, 0},    };    int certCount = sizeof(certAttrs)/sizeof(certAttrs[0]), keyCount = 2;    int realCount = 0;    CK_ATTRIBUTE *attrs;    CK_RV crv;    SECCertUsage *certUsage = NULL;    SECItem derSerial = { 0 };    NSSToken *token;    if (keyID == NULL) {	PORT_SetError(SEC_ERROR_ADDING_CERT);	return rv;    }    len = ((nickname) ? PORT_Strlen(nickname) : 0);        attrs = certAttrs;    PK11_SETATTRS(attrs,CKA_ID, keyID->data, keyID->len); attrs++;    if (nickname) {	PK11_SETATTRS(attrs,CKA_LABEL, nickname, len ); attrs++;    }    PK11_SETATTRS(attrs,CKA_CLASS, &certc, sizeof(certc) ); attrs++;    PK11_SETATTRS(attrs,CKA_TOKEN, &cktrue, sizeof(cktrue) ); attrs++;    PK11_SETATTRS(attrs,CKA_CERTIFICATE_TYPE, &certType,						sizeof(certType)); attrs++;    PK11_SETATTRS(attrs,CKA_SUBJECT, cert->derSubject.data,					 cert->derSubject.len ); attrs++;    PK11_SETATTRS(attrs,CKA_ISSUER, cert->derIssuer.data,					 cert->derIssuer.len ); attrs++;    if (PR_TRUE) {	/* CERTCertificate stores serial numbers decoded.  I need the DER	* here.  sigh.	*/	CERT_SerialNumberFromDERCert(&cert->derCert, &derSerial);	PK11_SETATTRS(attrs,CKA_SERIAL_NUMBER, derSerial.data, derSerial.len); 	attrs++;    }    PK11_SETATTRS(attrs,CKA_VALUE, cert->derCert.data, 						cert->derCert.len); attrs++;    if (includeTrust && PK11_IsInternal(slot)) {	certUsage = (SECCertUsage*)PORT_Alloc(sizeof(SECCertUsage));	if(!certUsage) {	    SECITEM_FreeItem(keyID,PR_TRUE);	    PORT_SetError(SEC_ERROR_NO_MEMORY);	    return rv;	}	*certUsage = certUsageUserCertImport;	PK11_SETATTRS(attrs,CKA_NETSCAPE_TRUST, certUsage,							 sizeof(SECCertUsage));	attrs++;	if (cert->emailAddr) {	    PK11_SETATTRS(attrs,CKA_NETSCAPE_EMAIL, cert->emailAddr,						PORT_Strlen(cert->emailAddr);	    attrs++;	}    }    realCount = attrs - certAttrs;    PORT_Assert(realCount <= certCount);    attrs = keyAttrs;    if(nickname) {	PK11_SETATTRS(attrs,CKA_LABEL, nickname, len ); attrs++;    }    PK11_SETATTRS(attrs,CKA_SUBJECT, cert->derSubject.data,					 cert->derSubject.len );    if(!nickname) {	certCount--;	keyCount--;    }    rwsession = PK11_GetRWSession(slot);    if (key != CK_INVALID_HANDLE) {	crv = PK11_GETTAB(slot)->C_SetAttributeValue(rwsession,key,keyAttrs,								keyCount);	if (crv != CKR_OK) {	    PORT_SetError( PK11_MapError(crv) );	    goto done;	}    }    crv = PK11_GETTAB(slot)->			C_CreateObject(rwsession,certAttrs,realCount,&certID);    if (crv == CKR_OK) {	rv = SECSuccess;    } else {	PORT_SetError( PK11_MapError(crv) );    }    if (!cert->nickname && nickname) {	cert->nickname = PORT_ArenaStrdup(cert->arena, nickname);    }    cert->pkcs11ID = certID;    cert->dbhandle = STAN_GetDefaultTrustDomain();    if (cert->slot == NULL) {	cert->slot = PK11_ReferenceSlot(slot);	cert->series = slot->series;	cert->ownSlot = PR_TRUE;	if (cert->nssCertificate) {	    nssCryptokiInstance *instance;	    NSSCertificate *c = cert->nssCertificate;	    instance = nss_ZNEW(c->object.arena, nssCryptokiInstance);	    instance->token = slot->nssToken;	    instance->handle = cert->pkcs11ID;	    instance->isTokenObject = PR_TRUE;	    nssPKIObject_AddInstance(&c->object, instance);	} else {	    cert->nssCertificate = STAN_GetNSSCertificate(cert);	}    }    cert->trust = nssTrust_GetCERTCertTrustForCert(cert->nssCertificate, cert);    token = PK11Slot_GetNSSToken(slot);done:    if (derSerial.data) PORT_Free(derSerial.data);    SECITEM_FreeItem(keyID,PR_TRUE);    PK11_RestoreROSession(slot,rwsession);    if(certUsage) {	PORT_Free(certUsage);    }    return rv;#else    PRStatus status;    NSSCertificate *c;    nssCryptokiObject *keyobj, *certobj;    NSSToken *token = PK11Slot_GetNSSToken(slot);    SECItem *keyID = pk11_mkcertKeyID(cert);    char *emailAddr = NULL;    if (keyID == NULL) {	goto loser;    }    if (PK11_IsInternal(slot) && cert->emailAddr) {	emailAddr = cert->emailAddr;    }    /* need to get the cert as a stan cert */    if (cert->nssCertificate) {	c = cert->nssCertificate;    } else {	c = STAN_GetNSSCertificate(cert);    }    if (c->object.cryptoContext) {	/* Delete the temp instance */	NSSCryptoContext *cc = c->object.cryptoContext;	nssCertificateStore_Lock(cc->certStore);	nssCertificateStore_RemoveCertLOCKED(cc->certStore, c);	nssCertificateStore_Unlock(cc->certStore);	c->object.cryptoContext = NULL;	cert->istemp = PR_FALSE;	cert->isperm = PR_TRUE;    }    /* set the id for the cert */    nssItem_Create(c->object.arena, &c->id, keyID->len, keyID->data);    if (!c->id.data) {	goto loser;    }    if (key != CK_INVALID_HANDLE) {	/* create an object for the key, ... */	keyobj = nss_ZNEW(NULL, nssCryptokiObject);	if (!keyobj) {	    goto loser;	}	keyobj->token = nssToken_AddRef(token);	keyobj->handle = key;	keyobj->isTokenObject = PR_TRUE;	/* ... in order to set matching attributes for the key */	status = nssCryptokiPrivateKey_SetCertificate(keyobj, NULL, nickname, 	                                              &c->id, &c->subject);	nssCryptokiObject_Destroy(keyobj);	if (status != PR_SUCCESS) {	    goto loser;	}    }    /* do the token import */    certobj = nssToken_ImportCertificate(token, NULL,                                         NSSCertificateType_PKIX,                                         &c->id,                                         nickname,                                         &c->encoding,                                         &c->issuer,                                         &c->subject,                                         &c->serial,					 emailAddr,                                         PR_TRUE);    if (!certobj) {	goto loser;    }    /* add the new instance to the cert, force an update of the     * CERTCertificate, and finish     */    nssPKIObject_AddInstance(&c->object, certobj);    nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);    (void)STAN_ForceCERTCertificateUpdate(c);    SECITEM_FreeItem(keyID,PR_TRUE);    return SECSuccess;loser:    SECITEM_FreeItem(keyID,PR_TRUE);    PORT_SetError(SEC_ERROR_ADDING_CERT);    return SECFailure;#endif}