/* * must be called holding the ModuleListLock (either read or write). */ NSS_IMPLEMENT SECStatus STAN_RemoveModuleFromDefaultTrustDomain( SECMODModule *module) { NSSToken *token; NSSTrustDomain *td; int i; td = STAN_GetDefaultTrustDomain(); for (i = 0; i < module->slotCount; i++) { token = PK11Slot_GetNSSToken(module->slots[i]); if (token) { nssToken_NotifyCertsNotVisible(token); NSSRWLock_LockWrite(td->tokensLock); nssList_Remove(td->tokenList, token); NSSRWLock_UnlockWrite(td->tokensLock); PK11Slot_SetNSSToken(module->slots[i], NULL); nssToken_Destroy(token); } } NSSRWLock_LockWrite(td->tokensLock); nssListIterator_Destroy(td->tokens); td->tokens = nssList_CreateIterator(td->tokenList); NSSRWLock_UnlockWrite(td->tokensLock); return SECSuccess; }
CERTCertTrust * nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc) { CERTCertTrust *rvTrust = NULL; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); NSSTrust *t; t = nssTrustDomain_FindTrustForCertificate(td, c); if (t) { rvTrust = cert_trust_from_stan_trust(t, cc->arena); if (!rvTrust) { nssTrust_Destroy(t); return NULL; } nssTrust_Destroy(t); } else { rvTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust)); if (!rvTrust) { return NULL; } memset(rvTrust, 0, sizeof(*rvTrust)); } if (NSSCertificate_IsPrivateKeyAvailable(c, NULL, NULL)) { rvTrust->sslFlags |= CERTDB_USER; rvTrust->emailFlags |= CERTDB_USER; rvTrust->objectSigningFlags |= CERTDB_USER; } return rvTrust; }
/* ** Delete trust objects matching the slot of the given certificate. ** Returns an error if any device fails to delete. */ NSS_EXTERN PRStatus STAN_DeleteCertTrustMatchingSlot(NSSCertificate *c) { PRStatus nssrv = PR_SUCCESS; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); NSSTrust *nssTrust = nssTrustDomain_FindTrustForCertificate(td, c); /* caller made sure nssTrust isn't NULL */ nssPKIObject *tobject = &nssTrust->object; nssPKIObject *cobject = &c->object; int i; /* Iterate through the cert and trust object instances looking for * those with matching pk11 slots to delete. Even if some device * can't delete we keep going. Keeping a status variable for the * loop so that once it's failed the other gets set. */ NSSRWLock_LockRead(td->tokensLock); nssPKIObject_Lock(cobject); for (i = 0; i < cobject->numInstances; i++) { nssCryptokiObject *cInstance = cobject->instances[i]; if (cInstance && !PK11_IsReadOnly(cInstance->token->pk11slot)) { PRStatus status; if (!tobject->numInstances || !tobject->instances) continue; status = DeleteCertTrustMatchingSlot(cInstance->token->pk11slot, tobject); if (status == PR_FAILURE) { /* set the outer one but keep going */ nssrv = PR_FAILURE; } } } nssPKIObject_Unlock(cobject); NSSRWLock_UnlockRead(td->tokensLock); return nssrv; }
NSS_IMPLEMENT PRStatus nssCertificate_Destroy ( NSSCertificate *c ) { nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE}; if (c) { PRUint32 i; nssDecodedCert *dc = c->decoding; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); NSSCryptoContext *cc = c->object.cryptoContext; PR_ASSERT(c->object.refCount > 0); /* --- LOCK storage --- */ if (cc) { nssCertificateStore_Lock(cc->certStore, &lockTrace); } else { nssTrustDomain_LockCertCache(td); } if (PR_ATOMIC_DECREMENT(&c->object.refCount) == 0) { /* --- remove cert and UNLOCK storage --- */ if (cc) { nssCertificateStore_RemoveCertLOCKED(cc->certStore, c); nssCertificateStore_Unlock(cc->certStore, &lockTrace, &unlockTrace); } else { nssTrustDomain_RemoveCertFromCacheLOCKED(td, c); nssTrustDomain_UnlockCertCache(td); } /* free cert data */ for (i=0; i<c->object.numInstances; i++) { nssCryptokiObject_Destroy(c->object.instances[i]); } nssPKIObject_DestroyLock(&c->object); nssArena_Destroy(c->object.arena); nssDecodedCert_Destroy(dc); } else { /* --- UNLOCK storage --- */ if (cc) { nssCertificateStore_Unlock(cc->certStore, &lockTrace, &unlockTrace); } else { nssTrustDomain_UnlockCertCache(td); } } } return PR_SUCCESS; }
/* * must be called holding the ModuleListLock (either read or write). */ NSS_IMPLEMENT SECStatus STAN_AddModuleToDefaultTrustDomain( SECMODModule *module) { NSSTrustDomain *td; int i; td = STAN_GetDefaultTrustDomain(); for (i = 0; i < module->slotCount; i++) { STAN_InitTokenForSlotInfo(td, module->slots[i]); } STAN_ResetTokenInterator(td); return SECSuccess; }
void nss_DumpCertificateCacheInfo() { NSSTrustDomain *td; NSSCryptoContext *cc; td = STAN_GetDefaultTrustDomain(); cc = STAN_GetDefaultCryptoContext(); printf("\n\nCertificates in the cache:\n"); nssTrustDomain_DumpCacheInfo(td, cert_dump_iter, NULL); printf("\n\nCertificates in the temporary store:\n"); if (cc->certStore) { nssCertificateStore_DumpStoreInfo(cc->certStore, cert_dump_iter, NULL); } }
SECStatus SEC_DeletePermCertificate(CERTCertificate *cert) { PRStatus nssrv; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); NSSCertificate *c = STAN_GetNSSCertificate(cert); if (c == NULL) { /* error code is set */ return SECFailure; } /* get rid of the token instances */ nssrv = NSSCertificate_DeleteStoredObject(c, NULL); /* get rid of the cache entry */ nssTrustDomain_LockCertCache(td); nssTrustDomain_RemoveCertFromCacheLOCKED(td, c); nssTrustDomain_UnlockCertCache(td); return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; }
SECStatus SEC_DeletePermCertificate(CERTCertificate *cert) { PRStatus nssrv; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); NSSCertificate *c = STAN_GetNSSCertificate(cert); CERTCertTrust *certTrust; if (c == NULL) { /* error code is set */ return SECFailure; } certTrust = nssTrust_GetCERTCertTrustForCert(c, cert); if (certTrust) { NSSTrust *nssTrust = nssTrustDomain_FindTrustForCertificate(td, c); if (nssTrust) { nssrv = STAN_DeleteCertTrustMatchingSlot(c); if (nssrv != PR_SUCCESS) { CERT_MapStanError(); } /* This call always returns PR_SUCCESS! */ (void)nssTrust_Destroy(nssTrust); } } /* get rid of the token instances */ nssrv = NSSCertificate_DeleteStoredObject(c, NULL); /* get rid of the cache entry */ nssTrustDomain_LockCertCache(td); nssTrustDomain_RemoveCertFromCacheLOCKED(td, c); nssTrustDomain_UnlockCertCache(td); return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; }
CERTCertificateList * CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage, PRBool includeRoot) { CERTCertificateList *chain = NULL; NSSCertificate **stanChain; NSSCertificate *stanCert; PRArenaPool *arena; NSSUsage nssUsage; int i, len; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); NSSCryptoContext *cc = STAN_GetDefaultCryptoContext(); stanCert = STAN_GetNSSCertificate(cert); if (!stanCert) { /* error code is set */ return NULL; } nssUsage.anyUsage = PR_FALSE; nssUsage.nss3usage = usage; nssUsage.nss3lookingForCA = PR_FALSE; stanChain = NSSCertificate_BuildChain(stanCert, NULL, &nssUsage, NULL, NULL, CERT_MAX_CERT_CHAIN, NULL, NULL, td, cc); if (!stanChain) { PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); return NULL; } len = 0; stanCert = stanChain[0]; while (stanCert) { stanCert = stanChain[++len]; } arena = PORT_NewArena(4096); if (arena == NULL) { goto loser; } chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, sizeof(CERTCertificateList)); if (!chain) goto loser; chain->certs = (SECItem*)PORT_ArenaAlloc(arena, len * sizeof(SECItem)); if (!chain->certs) goto loser; i = 0; stanCert = stanChain[i]; while (stanCert) { SECItem derCert; CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert); if (!cCert) { goto loser; } derCert.len = (unsigned int)stanCert->encoding.size; derCert.data = (unsigned char *)stanCert->encoding.data; derCert.type = siBuffer; SECITEM_CopyItem(arena, &chain->certs[i], &derCert); stanCert = stanChain[++i]; if (!stanCert && !cCert->isRoot) { /* reached the end of the chain, but the final cert is * not a root. Don't discard it. */ includeRoot = PR_TRUE; } CERT_DestroyCertificate(cCert); } if ( !includeRoot && len > 1) { chain->len = len - 1; } else { chain->len = len; } chain->arena = arena; nss_ZFreeIf(stanChain); return chain; loser: i = 0; stanCert = stanChain[i]; while (stanCert) { CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert); if (cCert) { CERT_DestroyCertificate(cCert); } stanCert = stanChain[++i]; } nss_ZFreeIf(stanChain); if (arena) { PORT_FreeArena(arena, PR_FALSE); } return NULL; }
NSS_EXTERN PRStatus STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust) { PRStatus nssrv; NSSCertificate *c = STAN_GetNSSCertificate(cc); NSSToken *tok; NSSTrustDomain *td; NSSTrust *nssTrust; NSSArena *arena; CERTCertTrust *oldTrust; CERTCertTrust *newTrust; nssListIterator *tokens; PRBool moving_object; nssCryptokiObject *newInstance; nssPKIObject *pkiob; if (c == NULL) { return PR_FAILURE; } oldTrust = nssTrust_GetCERTCertTrustForCert(c, cc); if (oldTrust) { if (memcmp(oldTrust, trust, sizeof (CERTCertTrust)) == 0) { /* ... and the new trust is no different, done) */ return PR_SUCCESS; } else { /* take over memory already allocated in cc's arena */ newTrust = oldTrust; } } else { newTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust)); } memcpy(newTrust, trust, sizeof(CERTCertTrust)); CERT_LockCertTrust(cc); cc->trust = newTrust; CERT_UnlockCertTrust(cc); /* Set the NSSCerticate's trust */ arena = nssArena_Create(); if (!arena) return PR_FAILURE; nssTrust = nss_ZNEW(arena, NSSTrust); if (!nssTrust) { nssArena_Destroy(arena); return PR_FAILURE; } pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL, nssPKILock); if (!pkiob) { nssArena_Destroy(arena); return PR_FAILURE; } nssTrust->object = *pkiob; nssTrust->certificate = c; nssTrust->serverAuth = get_stan_trust(trust->sslFlags, PR_FALSE); nssTrust->clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE); nssTrust->emailProtection = get_stan_trust(trust->emailFlags, PR_FALSE); nssTrust->codeSigning = get_stan_trust(trust->objectSigningFlags, PR_FALSE); nssTrust->stepUpApproved = (PRBool)(trust->sslFlags & CERTDB_GOVT_APPROVED_CA); if (c->object.cryptoContext != NULL) { /* The cert is in a context, set the trust there */ NSSCryptoContext *cc = c->object.cryptoContext; nssrv = nssCryptoContext_ImportTrust(cc, nssTrust); if (nssrv != PR_SUCCESS) { goto done; } if (c->object.numInstances == 0) { /* The context is the only instance, finished */ goto done; } } td = STAN_GetDefaultTrustDomain(); tok = stan_GetTrustToken(c); moving_object = PR_FALSE; if (tok && PK11_IsReadOnly(tok->pk11slot)) { NSSRWLock_LockRead(td->tokensLock); tokens = nssList_CreateIterator(td->tokenList); if (!tokens) { nssrv = PR_FAILURE; NSSRWLock_UnlockRead(td->tokensLock); goto done; } for (tok = (NSSToken *)nssListIterator_Start(tokens); tok != (NSSToken *)NULL; tok = (NSSToken *)nssListIterator_Next(tokens)) { if (!PK11_IsReadOnly(tok->pk11slot)) break; } nssListIterator_Finish(tokens); nssListIterator_Destroy(tokens); NSSRWLock_UnlockRead(td->tokensLock); moving_object = PR_TRUE; } if (tok) { if (moving_object) { /* this is kind of hacky. the softoken needs the cert * object in order to store trust. forcing it to be perm */ NSSUTF8 *nickname = nssCertificate_GetNickname(c, NULL); NSSASCII7 *email = NULL; if (PK11_IsInternal(tok->pk11slot)) { email = c->email; } newInstance = nssToken_ImportCertificate(tok, NULL, NSSCertificateType_PKIX, &c->id, nickname, &c->encoding, &c->issuer, &c->subject, &c->serial, email, PR_TRUE); nss_ZFreeIf(nickname); nickname = NULL; if (!newInstance) { nssrv = PR_FAILURE; goto done; } nssPKIObject_AddInstance(&c->object, newInstance); } newInstance = nssToken_ImportTrust(tok, NULL, &c->encoding, &c->issuer, &c->serial, nssTrust->serverAuth, nssTrust->clientAuth, nssTrust->codeSigning, nssTrust->emailProtection, nssTrust->stepUpApproved, PR_TRUE); /* If the selected token can't handle trust, dump the trust on * the internal token */ if (!newInstance && !PK11_IsInternalKeySlot(tok->pk11slot)) { PK11SlotInfo *slot = PK11_GetInternalKeySlot(); NSSUTF8 *nickname = nssCertificate_GetNickname(c, NULL); NSSASCII7 *email = c->email; tok = PK11Slot_GetNSSToken(slot); PK11_FreeSlot(slot); newInstance = nssToken_ImportCertificate(tok, NULL, NSSCertificateType_PKIX, &c->id, nickname, &c->encoding, &c->issuer, &c->subject, &c->serial, email, PR_TRUE); nss_ZFreeIf(nickname); nickname = NULL; if (!newInstance) { nssrv = PR_FAILURE; goto done; } nssPKIObject_AddInstance(&c->object, newInstance); newInstance = nssToken_ImportTrust(tok, NULL, &c->encoding, &c->issuer, &c->serial, nssTrust->serverAuth, nssTrust->clientAuth, nssTrust->codeSigning, nssTrust->emailProtection, nssTrust->stepUpApproved, PR_TRUE); } if (newInstance) { nssCryptokiObject_Destroy(newInstance); nssrv = PR_SUCCESS; } else { nssrv = PR_FAILURE; } } else { nssrv = PR_FAILURE; } done: (void)nssTrust_Destroy(nssTrust); return nssrv; }
/* * return the crl associated with a derSubjectName */ SECItem * PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle, SECItem *name, int type, char **pUrl) { NSSCRL **crls, **crlp, *crl = NULL; NSSDER subject; SECItem *rvItem; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); char * url = NULL; PORT_SetError(0); NSSITEM_FROM_SECITEM(&subject, name); if (*slot) { nssCryptokiObject **instances; nssPKIObjectCollection *collection; nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; NSSToken *token = PK11Slot_GetNSSToken(*slot); collection = nssCRLCollection_Create(td, NULL); if (!collection) { goto loser; } instances = nssToken_FindCRLsBySubject(token, NULL, &subject, tokenOnly, 0, NULL); nssPKIObjectCollection_AddInstances(collection, instances, 0); nss_ZFreeIf(instances); crls = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL); nssPKIObjectCollection_Destroy(collection); } else { crls = nssTrustDomain_FindCRLsBySubject(td, &subject); } if ((!crls) || (*crls == NULL)) { if (crls) { nssCRLArray_Destroy(crls); } if (NSS_GetError() == NSS_ERROR_NOT_FOUND) { PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); } goto loser; } for (crlp = crls; *crlp; crlp++) { if ((!(*crlp)->isKRL && type == SEC_CRL_TYPE) || ((*crlp)->isKRL && type != SEC_CRL_TYPE)) { crl = nssCRL_AddRef(*crlp); break; } } nssCRLArray_Destroy(crls); if (!crl) { /* CRL collection was found, but no interesting CRL's were on it. * Not an error */ PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); goto loser; } if (crl->url) { url = PORT_Strdup(crl->url); if (!url) { goto loser; } } rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size); if (!rvItem) { goto loser; } memcpy(rvItem->data, crl->encoding.data, crl->encoding.size); *slot = PK11_ReferenceSlot(crl->object.instances[0]->token->pk11slot); *crlHandle = crl->object.instances[0]->handle; *pUrl = url; nssCRL_Destroy(crl); return rvItem; loser: if (url) PORT_Free(url); if (crl) nssCRL_Destroy(crl); if (PORT_GetError() == 0) { PORT_SetError(SEC_ERROR_CRL_NOT_FOUND); } return NULL; }
CERTCertificate * CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, char *nickname, PRBool isperm, PRBool copyDER) { NSSCertificate *c; CERTCertificate *cc; NSSCertificate *tempCert = NULL; nssPKIObject *pkio; NSSCryptoContext *gCC = STAN_GetDefaultCryptoContext(); NSSTrustDomain *gTD = STAN_GetDefaultTrustDomain(); if (!isperm) { NSSDER encoding; NSSITEM_FROM_SECITEM(&encoding, derCert); /* First, see if it is already a temp cert */ c = NSSCryptoContext_FindCertificateByEncodedCertificate(gCC, &encoding); if (!c) { /* Then, see if it is already a perm cert */ c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle, &encoding); } if (c) { /* actually, that search ends up going by issuer/serial, * so it is still possible to return a cert with the same * issuer/serial but a different encoding, and we're * going to reject that */ if (!nssItem_Equal(&c->encoding, &encoding, NULL)) { nssCertificate_Destroy(c); PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL); cc = NULL; } else { cc = STAN_GetCERTCertificateOrRelease(c); if (cc == NULL) { CERT_MapStanError(); } } return cc; } } pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC, nssPKIMonitor); if (!pkio) { CERT_MapStanError(); return NULL; } c = nss_ZNEW(pkio->arena, NSSCertificate); if (!c) { CERT_MapStanError(); nssPKIObject_Destroy(pkio); return NULL; } c->object = *pkio; if (copyDER) { nssItem_Create(c->object.arena, &c->encoding, derCert->len, derCert->data); } else { NSSITEM_FROM_SECITEM(&c->encoding, derCert); } /* Forces a decoding of the cert in order to obtain the parts used * below */ /* 'c' is not adopted here, if we fail loser frees what has been * allocated so far for 'c' */ cc = STAN_GetCERTCertificate(c); if (!cc) { CERT_MapStanError(); goto loser; } nssItem_Create(c->object.arena, &c->issuer, cc->derIssuer.len, cc->derIssuer.data); nssItem_Create(c->object.arena, &c->subject, cc->derSubject.len, cc->derSubject.data); if (PR_TRUE) { /* CERTCertificate stores serial numbers decoded. I need the DER * here. sigh. */ SECItem derSerial = { 0 }; CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial); if (!derSerial.data) goto loser; nssItem_Create(c->object.arena, &c->serial, derSerial.len, derSerial.data); PORT_Free(derSerial.data); } if (nickname) { c->object.tempName = nssUTF8_Create(c->object.arena, nssStringType_UTF8String, (NSSUTF8 *)nickname, PORT_Strlen(nickname)); } if (cc->emailAddr && cc->emailAddr[0]) { c->email = nssUTF8_Create( c->object.arena, nssStringType_PrintableString, (NSSUTF8 *)cc->emailAddr, PORT_Strlen(cc->emailAddr)); } tempCert = NSSCryptoContext_FindOrImportCertificate(gCC, c); if (!tempCert) { CERT_MapStanError(); goto loser; } /* destroy our copy */ NSSCertificate_Destroy(c); /* and use the stored entry */ c = tempCert; cc = STAN_GetCERTCertificateOrRelease(c); if (!cc) { /* STAN_GetCERTCertificateOrRelease destroys c on failure. */ CERT_MapStanError(); return NULL; } cc->istemp = PR_TRUE; cc->isperm = PR_FALSE; return cc; loser: /* Perhaps this should be nssCertificate_Destroy(c) */ nssPKIObject_Destroy(&c->object); return NULL; }
SECStatus __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, CERTCertTrust *trust) { NSSUTF8 *stanNick; PK11SlotInfo *slot; NSSToken *internal; NSSCryptoContext *context; nssCryptokiObject *permInstance; NSSCertificate *c = STAN_GetNSSCertificate(cert); nssCertificateStoreTrace lockTrace = { NULL, NULL, PR_FALSE, PR_FALSE }; nssCertificateStoreTrace unlockTrace = { NULL, NULL, PR_FALSE, PR_FALSE }; SECStatus rv; PRStatus ret; if (c == NULL) { CERT_MapStanError(); return SECFailure; } context = c->object.cryptoContext; if (!context) { PORT_SetError(SEC_ERROR_ADDING_CERT); return SECFailure; /* wasn't a temp cert */ } stanNick = nssCertificate_GetNickname(c, NULL); if (stanNick && nickname && strcmp(nickname, stanNick) != 0) { /* different: take the new nickname */ cert->nickname = NULL; nss_ZFreeIf(stanNick); stanNick = NULL; } if (!stanNick && nickname) { /* Either there was no nickname yet, or we have a new nickname */ stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, NULL); } /* else: old stanNick is identical to new nickname */ /* Delete the temp instance */ nssCertificateStore_Lock(context->certStore, &lockTrace); nssCertificateStore_RemoveCertLOCKED(context->certStore, c); nssCertificateStore_Unlock(context->certStore, &lockTrace, &unlockTrace); c->object.cryptoContext = NULL; /* Import the perm instance onto the internal token */ slot = PK11_GetInternalKeySlot(); internal = PK11Slot_GetNSSToken(slot); permInstance = nssToken_ImportCertificate( internal, NULL, NSSCertificateType_PKIX, &c->id, stanNick, &c->encoding, &c->issuer, &c->subject, &c->serial, cert->emailAddr, PR_TRUE); nss_ZFreeIf(stanNick); stanNick = NULL; PK11_FreeSlot(slot); if (!permInstance) { if (NSS_GetError() == NSS_ERROR_INVALID_CERTIFICATE) { PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL); } return SECFailure; } nssPKIObject_AddInstance(&c->object, permInstance); nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1); /* reset the CERTCertificate fields */ cert->nssCertificate = NULL; cert = STAN_GetCERTCertificateOrRelease(c); /* should return same pointer */ if (!cert) { CERT_MapStanError(); return SECFailure; } cert->istemp = PR_FALSE; cert->isperm = PR_TRUE; if (!trust) { return SECSuccess; } ret = STAN_ChangeCertTrust(cert, trust); rv = SECSuccess; if (ret != PR_SUCCESS) { rv = SECFailure; CERT_MapStanError(); } return rv; }