Beispiel #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;
}
Beispiel #2
0
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;
}
Beispiel #3
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
        }
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}