NSS_IMPLEMENT PRStatus nssSMIMEProfile_Destroy ( nssSMIMEProfile *profile ) { if (profile) { (void)nssPKIObject_Destroy(&profile->object); } return PR_SUCCESS; }
NSS_IMPLEMENT PRStatus nssCRL_Destroy ( NSSCRL *crl ) { if (crl) { (void)nssPKIObject_Destroy(&crl->object); } return PR_SUCCESS; }
NSS_IMPLEMENT PRStatus nssTrust_Destroy ( NSSTrust *trust ) { if (trust) { (void)nssPKIObject_Destroy(&trust->object); } return PR_SUCCESS; }
/* ** Delete trust objects matching the given slot. ** Returns error if a device fails to delete. ** ** This function has the side effect of moving the ** surviving entries to the front of the object list ** and nullifying the rest. */ static PRStatus DeleteCertTrustMatchingSlot(PK11SlotInfo *pk11slot, nssPKIObject *tObject) { int numNotDestroyed = 0; /* the ones skipped plus the failures */ int failureCount = 0; /* actual deletion failures by devices */ unsigned int index; nssPKIObject_AddRef(tObject); nssPKIObject_Lock(tObject); /* Keep going even if a module fails to delete. */ for (index = 0; index < tObject->numInstances; index++) { nssCryptokiObject *instance = tObject->instances[index]; if (!instance) { continue; } /* ReadOnly and not matched treated the same */ if (PK11_IsReadOnly(instance->token->pk11slot) || pk11slot != instance->token->pk11slot) { tObject->instances[numNotDestroyed++] = instance; continue; } /* Here we have found a matching one */ tObject->instances[index] = NULL; if (nssToken_DeleteStoredObject(instance) == PR_SUCCESS) { nssCryptokiObject_Destroy(instance); } else { tObject->instances[numNotDestroyed++] = instance; failureCount++; } } if (numNotDestroyed == 0) { nss_ZFreeIf(tObject->instances); tObject->numInstances = 0; } else { tObject->numInstances = numNotDestroyed; } nssPKIObject_Unlock(tObject); nssPKIObject_Destroy(tObject); return failureCount == 0 ? PR_SUCCESS : PR_FAILURE; }
/* ** 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; unsigned int i; nssPKIObject *tobject = NULL; nssPKIObject *cobject = &c->object; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); NSSTrust *nssTrust = nssTrustDomain_FindTrustForCertificate(td, c); if (!nssTrust) { return PR_FAILURE; } tobject = &nssTrust->object; /* 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_AddRef(cobject); 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; } } } nssTrust_Destroy(nssTrust); nssPKIObject_Unlock(cobject); nssPKIObject_Destroy(cobject); NSSRWLock_UnlockRead(td->tokensLock); return nssrv; }
NSS_IMPLEMENT nssSMIMEProfile * nssSMIMEProfile_Create ( NSSCertificate *cert, NSSItem *profileTime, NSSItem *profileData ) { NSSArena *arena; nssSMIMEProfile *rvProfile; nssPKIObject *object; NSSTrustDomain *td = nssCertificate_GetTrustDomain(cert); NSSCryptoContext *cc = nssCertificate_GetCryptoContext(cert); arena = nssArena_Create(); if (!arena) { return NULL; } object = nssPKIObject_Create(arena, NULL, td, cc, nssPKILock); if (!object) { goto loser; } rvProfile = nss_ZNEW(arena, nssSMIMEProfile); if (!rvProfile) { goto loser; } rvProfile->object = *object; rvProfile->certificate = cert; rvProfile->email = nssUTF8_Duplicate(cert->email, arena); rvProfile->subject = nssItem_Duplicate(&cert->subject, arena, NULL); if (profileTime) { rvProfile->profileTime = nssItem_Duplicate(profileTime, arena, NULL); } if (profileData) { rvProfile->profileData = nssItem_Duplicate(profileData, arena, NULL); } return rvProfile; loser: if (object) nssPKIObject_Destroy(object); else if (arena) nssArena_Destroy(arena); return (nssSMIMEProfile *)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; }
static CERTCertificate * stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate) { nssDecodedCert *dc = NULL; CERTCertificate *cc = NULL; CERTCertTrust certTrust; /* make sure object does not go away until we finish */ nssPKIObject_AddRef(&c->object); nssPKIObject_Lock(&c->object); dc = c->decoding; if (!dc) { dc = nssDecodedPKIXCertificate_Create(NULL, &c->encoding); if (!dc) { goto loser; } cc = (CERTCertificate *)dc->data; PORT_Assert(cc); /* software error */ if (!cc) { nssDecodedPKIXCertificate_Destroy(dc); nss_SetError(NSS_ERROR_INTERNAL_ERROR); goto loser; } PORT_Assert(!c->decoding); if (!c->decoding) { c->decoding = dc; } else { /* this should never happen. Fail. */ nssDecodedPKIXCertificate_Destroy(dc); nss_SetError(NSS_ERROR_INTERNAL_ERROR); goto loser; } } cc = (CERTCertificate *)dc->data; PORT_Assert(cc); if (!cc) { nss_SetError(NSS_ERROR_INTERNAL_ERROR); goto loser; } if (!cc->nssCertificate || forceUpdate) { fill_CERTCertificateFields(c, cc, forceUpdate); } else if (CERT_GetCertTrust(cc, &certTrust) != SECSuccess && !c->object.cryptoContext) { /* if it's a perm cert, it might have been stored before the * trust, so look for the trust again. But a temp cert can be * ignored. */ CERTCertTrust* trust = NULL; trust = nssTrust_GetCERTCertTrustForCert(c, cc); CERT_LockCertTrust(cc); cc->trust = trust; CERT_UnlockCertTrust(cc); } loser: nssPKIObject_Unlock(&c->object); nssPKIObject_Destroy(&c->object); return cc; }