summaryrefslogtreecommitdiff
path: root/security/nss/lib/pki/pki3hack.c
diff options
context:
space:
mode:
authoremaldona%redhat.com <devnull@localhost>2011-03-26 17:34:22 +0000
committeremaldona%redhat.com <devnull@localhost>2011-03-26 17:34:22 +0000
commit246607987b88c8de376dd1fa6a71659d9bace747 (patch)
treeb012cb8b8af37ee8b0b28f3c5e89fa8056d16782 /security/nss/lib/pki/pki3hack.c
parent2100d6cea7b550950f4cb57a70abf97cc147adae (diff)
downloadnss-hg-246607987b88c8de376dd1fa6a71659d9bace747.tar.gz
Bug 625675 - trust flags are not being deleted when we delete the associated certificate, r=rrelyea
Diffstat (limited to 'security/nss/lib/pki/pki3hack.c')
-rw-r--r--security/nss/lib/pki/pki3hack.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c
index 8ccc15d58..9891367a2 100644
--- a/security/nss/lib/pki/pki3hack.c
+++ b/security/nss/lib/pki/pki3hack.c
@@ -1215,6 +1215,98 @@ done:
return nssrv;
}
+/*
+** 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 */
+ int index;
+
+ 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);
+
+ 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;
+
+ 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;
+}
+
/* CERT_TraversePermCertsForSubject */
NSS_IMPLEMENT PRStatus
nssTrustDomain_TraverseCertificatesBySubject (