/* ** 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; }
static CERTCertificate * stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate) { nssDecodedCert *dc = NULL; CERTCertificate *cc = NULL; CERTCertTrust certTrust; 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); return cc; }
/* ** 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; }
NSS_IMPLEMENT nssDecodedCert * nssCertificate_GetDecoding ( NSSCertificate *c ) { nssDecodedCert* deco = NULL; if (c->type == NSSCertificateType_PKIX) { (void)STAN_GetCERTCertificate(c); } nssPKIObject_Lock(&c->object); if (!c->decoding) { deco = nssDecodedCert_Create(NULL, &c->encoding, c->type); PORT_Assert(!c->decoding); c->decoding = deco; } else { deco = c->decoding; } nssPKIObject_Unlock(&c->object); return deco; }
static void remove_token_certs(NSSCertificate *c, struct token_cert_dtor *dtor) { nssPKIObject *object = &c->object; PRUint32 i; nssPKIObject_AddRef(object); nssPKIObject_Lock(object); for (i = 0; i < object->numInstances; i++) { if (object->instances[i]->token == dtor->token) { nssCryptokiObject_Destroy(object->instances[i]); object->instances[i] = object->instances[object->numInstances - 1]; object->instances[object->numInstances - 1] = NULL; object->numInstances--; dtor->certs[dtor->numCerts++] = c; if (dtor->numCerts == dtor->arrSize) { dtor->arrSize *= 2; dtor->certs = nss_ZREALLOCARRAY(dtor->certs, NSSCertificate *, dtor->arrSize); } break; }
NSS_IMPLEMENT NSSTrust * nssTrust_Create ( nssPKIObject *object, NSSItem *certData ) { PRStatus status; PRUint32 i; PRUint32 lastTrustOrder, myTrustOrder; unsigned char sha1_hashcmp[SHA1_LENGTH]; unsigned char sha1_hashin[SHA1_LENGTH]; NSSItem sha1_hash; NSSTrust *rvt; nssCryptokiObject *instance; nssTrustLevel serverAuth, clientAuth, codeSigning, emailProtection; SECStatus rv; /* Should be stan flavor */ PRBool stepUp; lastTrustOrder = 1<<16; /* just make it big */ PR_ASSERT(object->instances != NULL && object->numInstances > 0); rvt = nss_ZNEW(object->arena, NSSTrust); if (!rvt) { return (NSSTrust *)NULL; } rvt->object = *object; /* should be stan flavor of Hashbuf */ rv = PK11_HashBuf(SEC_OID_SHA1,sha1_hashcmp,certData->data,certData->size); if (rv != SECSuccess) { return (NSSTrust *)NULL; } sha1_hash.data = sha1_hashin; sha1_hash.size = sizeof (sha1_hashin); /* trust has to peek into the base object members */ nssPKIObject_Lock(object); for (i=0; i<object->numInstances; i++) { instance = object->instances[i]; myTrustOrder = nssToken_GetTrustOrder(instance->token); status = nssCryptokiTrust_GetAttributes(instance, NULL, &sha1_hash, &serverAuth, &clientAuth, &codeSigning, &emailProtection, &stepUp); if (status != PR_SUCCESS) { nssPKIObject_Unlock(object); return (NSSTrust *)NULL; } if (PORT_Memcmp(sha1_hashin,sha1_hashcmp,SHA1_LENGTH) != 0) { nssPKIObject_Unlock(object); return (NSSTrust *)NULL; } if (rvt->serverAuth == nssTrustLevel_Unknown || myTrustOrder < lastTrustOrder) { rvt->serverAuth = serverAuth; } if (rvt->clientAuth == nssTrustLevel_Unknown || myTrustOrder < lastTrustOrder) { rvt->clientAuth = clientAuth; } if (rvt->emailProtection == nssTrustLevel_Unknown || myTrustOrder < lastTrustOrder) { rvt->emailProtection = emailProtection; } if (rvt->codeSigning == nssTrustLevel_Unknown || myTrustOrder < lastTrustOrder) { rvt->codeSigning = codeSigning; } rvt->stepUpApproved = stepUp; lastTrustOrder = myTrustOrder; } nssPKIObject_Unlock(object); return rvt; }
NSS_IMPLEMENT NSSTrust * nssTrust_Create ( nssPKIObject *object, NSSItem *certData ) { PRStatus status; PRUint32 i; PRUint32 lastTrustOrder, myTrustOrder; unsigned char sha1_hashcmp[SHA1_LENGTH]; unsigned char sha1_hashin[SHA1_LENGTH]; NSSItem sha1_hash; NSSTrust *rvt; nssCryptokiObject *instance; nssTrustLevel serverAuth, clientAuth, codeSigning, emailProtection; SECStatus rv; /* Should be stan flavor */ PRBool stepUp; lastTrustOrder = 1<<16; /* just make it big */ PR_ASSERT(object->instances != NULL && object->numInstances > 0); rvt = nss_ZNEW(object->arena, NSSTrust); if (!rvt) { return (NSSTrust *)NULL; } rvt->object = *object; /* should be stan flavor of Hashbuf */ rv = PK11_HashBuf(SEC_OID_SHA1,sha1_hashcmp,certData->data,certData->size); if (rv != SECSuccess) { return (NSSTrust *)NULL; } sha1_hash.data = sha1_hashin; sha1_hash.size = sizeof (sha1_hashin); /* trust has to peek into the base object members */ nssPKIObject_Lock(object); for (i=0; i<object->numInstances; i++) { instance = object->instances[i]; myTrustOrder = nssToken_GetTrustOrder(instance->token); status = nssCryptokiTrust_GetAttributes(instance, NULL, &sha1_hash, &serverAuth, &clientAuth, &codeSigning, &emailProtection, &stepUp); if (status != PR_SUCCESS) { nssPKIObject_Unlock(object); return (NSSTrust *)NULL; } /* if no hash is specified, then trust applies to all certs with * this issuer/SN. NOTE: This is only true for entries that * have distrust and unknown record */ if (!( /* we continue if there is no hash, and the trust type is * safe to accept without a hash ... or ... */ ((sha1_hash.size == 0) && nssTrust_IsSafeToIgnoreCertHash(serverAuth,clientAuth, codeSigning, emailProtection,stepUp)) || /* we have a hash of the correct size, and it matches */ ((sha1_hash.size == SHA1_LENGTH) && (PORT_Memcmp(sha1_hashin, sha1_hashcmp,SHA1_LENGTH) == 0)) )) { nssPKIObject_Unlock(object); return (NSSTrust *)NULL; } if (rvt->serverAuth == nssTrustLevel_Unknown || myTrustOrder < lastTrustOrder) { rvt->serverAuth = serverAuth; } if (rvt->clientAuth == nssTrustLevel_Unknown || myTrustOrder < lastTrustOrder) { rvt->clientAuth = clientAuth; } if (rvt->emailProtection == nssTrustLevel_Unknown || myTrustOrder < lastTrustOrder) { rvt->emailProtection = emailProtection; } if (rvt->codeSigning == nssTrustLevel_Unknown || myTrustOrder < lastTrustOrder) { rvt->codeSigning = codeSigning; } rvt->stepUpApproved = stepUp; lastTrustOrder = myTrustOrder; } nssPKIObject_Unlock(object); return rvt; }