Esempio n. 1
0
/*
** 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;
}
Esempio n. 2
0
/*
** 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;
}
Esempio n. 3
0
static NSSToken*
stan_GetTrustToken (
  NSSCertificate *c
)
{
    NSSToken *ttok = NULL;
    NSSToken *rtok = NULL;
    NSSToken *tok = NULL;
    nssCryptokiObject **ip;
    nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
    if (!instances) {
	return PR_FALSE;
    }
    for (ip = instances; *ip; ip++) {
	nssCryptokiObject *instance = *ip;
        nssCryptokiObject *to = 
		nssToken_FindTrustForCertificate(instance->token, NULL,
		&c->encoding, &c->issuer, &c->serial, 
		nssTokenSearchType_TokenOnly);
	NSSToken *ctok = instance->token;
	PRBool ro = PK11_IsReadOnly(ctok->pk11slot);

	if (to) {
	    nssCryptokiObject_Destroy(to);
	    ttok = ctok;
 	    if (!ro) {
		break;
	    }
	} else {
	    if (!rtok && ro) {
		rtok = ctok;
	    } 
	    if (!tok && !ro) {
		tok = ctok;
	    }
	}
    }
    nssCryptokiObjectArray_Destroy(instances);
    return ttok ? ttok : (tok ? tok : rtok);
}
Esempio n. 4
0
void nsNSSCertificate::destructorSafeDestroyNSSReference()
{
  if (isAlreadyShutDown())
    return;

  if (mPermDelete) {
    if (mCertType == nsNSSCertificate::USER_CERT) {
      nsCOMPtr<nsIInterfaceRequestor> cxt = new PipUIContext();
      PK11_DeleteTokenCertAndKey(mCert, cxt);
    } else if (!PK11_IsReadOnly(mCert->slot)) {
      // If the list of built-ins does contain a non-removable
      // copy of this certificate, our call will not remove
      // the certificate permanently, but rather remove all trust.
      SEC_DeletePermCertificate(mCert);
    }
  }

  if (mCert) {
    CERT_DestroyCertificate(mCert);
    mCert = nullptr;
  }
}
Esempio n. 5
0
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;
}