Exemplo 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;
}
Exemplo n.º 2
0
CERTCertTrust * 
nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc)
{
    CERTCertTrust *rvTrust = NULL;
    NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
    NSSTrust *t;
    t = nssTrustDomain_FindTrustForCertificate(td, c);
    if (t) {
	rvTrust = cert_trust_from_stan_trust(t, cc->arena);
	if (!rvTrust) {
	    nssTrust_Destroy(t);
	    return NULL;
	}
	nssTrust_Destroy(t);
    } else {
	rvTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
	if (!rvTrust) {
	    return NULL;
	}
	memset(rvTrust, 0, sizeof(*rvTrust));
    }
    if (NSSCertificate_IsPrivateKeyAvailable(c, NULL, NULL)) {
	rvTrust->sslFlags |= CERTDB_USER;
	rvTrust->emailFlags |= CERTDB_USER;
	rvTrust->objectSigningFlags |= CERTDB_USER;
    }
    return rvTrust;
}
Exemplo n.º 3
0
SECStatus
SEC_DeletePermCertificate(CERTCertificate *cert)
{
    PRStatus nssrv;
    NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
    NSSCertificate *c = STAN_GetNSSCertificate(cert);
    CERTCertTrust *certTrust;

    if (c == NULL) {
        /* error code is set */
        return SECFailure;
    }

    certTrust = nssTrust_GetCERTCertTrustForCert(c, cert);
    if (certTrust) {
        NSSTrust *nssTrust = nssTrustDomain_FindTrustForCertificate(td, c);
        if (nssTrust) {
            nssrv = STAN_DeleteCertTrustMatchingSlot(c);
            if (nssrv != PR_SUCCESS) {
                CERT_MapStanError();
            }
            /* This call always returns PR_SUCCESS! */
            (void)nssTrust_Destroy(nssTrust);
        }
    }

    /* get rid of the token instances */
    nssrv = NSSCertificate_DeleteStoredObject(c, NULL);

    /* get rid of the cache entry */
    nssTrustDomain_LockCertCache(td);
    nssTrustDomain_RemoveCertFromCacheLOCKED(td, c);
    nssTrustDomain_UnlockCertCache(td);

    return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
}
static PRStatus
CollectNicknames( NSSCertificate *c, void *data)
{
    CERTCertNicknames *names;
    PRBool saveit = PR_FALSE;
    stringNode *node;
    int len;
#ifdef notdef
    NSSTrustDomain *td;
    NSSTrust *trust;
#endif
    char *stanNickname;
    char *nickname = NULL;
    
    names = (CERTCertNicknames *)data;

    stanNickname = nssCertificate_GetNickname(c,NULL);
    
    if ( stanNickname ) {
        nss_ZFreeIf(stanNickname);
        stanNickname = NULL;
	if (names->what == SEC_CERT_NICKNAMES_USER) {
	    saveit = NSSCertificate_IsPrivateKeyAvailable(c, NULL, NULL);
	}
#ifdef notdef
	  else {
	    td = NSSCertificate_GetTrustDomain(c);
	    if (!td) {
		return PR_SUCCESS;
	    }
	    trust = nssTrustDomain_FindTrustForCertificate(td,c);
	
	    switch(names->what) {
	     case SEC_CERT_NICKNAMES_ALL:
		if ((trust->sslFlags & (CERTDB_VALID_CA|CERTDB_VALID_PEER) ) ||
		 (trust->emailFlags & (CERTDB_VALID_CA|CERTDB_VALID_PEER) ) ||
		 (trust->objectSigningFlags & 
					(CERTDB_VALID_CA|CERTDB_VALID_PEER))) {
		    saveit = PR_TRUE;
		}
	    
		break;
	     case SEC_CERT_NICKNAMES_SERVER:
		if ( trust->sslFlags & CERTDB_VALID_PEER ) {
		    saveit = PR_TRUE;
		}
	    
		break;
	     case SEC_CERT_NICKNAMES_CA:
		if (((trust->sslFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA)||
		 ((trust->emailFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA) ||
		 ((trust->objectSigningFlags & CERTDB_VALID_CA ) 
							== CERTDB_VALID_CA)) {
		    saveit = PR_TRUE;
		}
		break;
	    }
	}
#endif
    }

    /* traverse the list of collected nicknames and make sure we don't make
     * a duplicate
     */
    if ( saveit ) {
	nickname = STAN_GetCERTCertificateName(NULL, c);
	/* nickname can only be NULL here if we are having memory 
	 * alloc problems */
	if (nickname == NULL) {
	    return PR_FAILURE;
	}
	node = (stringNode *)names->head;
	while ( node != NULL ) {
	    if ( PORT_Strcmp(nickname, node->string) == 0 ) { 
		/* if the string matches, then don't save this one */
		saveit = PR_FALSE;
		break;
	    }
	    node = node->next;
	}
    }

    if ( saveit ) {
	
	/* allocate the node */
	node = (stringNode*)PORT_ArenaAlloc(names->arena, sizeof(stringNode));
	if ( node == NULL ) {
	    PORT_Free(nickname);
	    return PR_FAILURE;
	}

	/* copy the string */
	len = PORT_Strlen(nickname) + 1;
	node->string = (char*)PORT_ArenaAlloc(names->arena, len);
	if ( node->string == NULL ) {
	    PORT_Free(nickname);
	    return PR_FAILURE;
	}
	PORT_Memcpy(node->string, nickname, len);

	/* link it into the list */
	node->next = (stringNode *)names->head;
	names->head = (void *)node;

	/* bump the count */
	names->numnicknames++;
    }
    
    if (nickname) PORT_Free(nickname);
    return(PR_SUCCESS);
}
Exemplo n.º 5
0
static void
fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced)
{
    CERTCertTrust* trust = NULL;
    NSSTrust *nssTrust;
    NSSCryptoContext *context = c->object.cryptoContext;
    nssCryptokiInstance *instance;
    NSSUTF8 *stanNick = NULL;

    /* We are holding the base class object's lock on entry of this function
     * This lock protects writes to fields of the CERTCertificate .
     * It is also needed by some functions to compute values such as trust.
     */
    instance = get_cert_instance(c);

    if (instance) {
	stanNick = instance->label;
    } else if (context) {
	stanNick = c->object.tempName;
    }
    /* fill other fields needed by NSS3 functions using CERTCertificate */
    if ((!cc->nickname && stanNick) || forced) {
	PRStatus nssrv;
	int nicklen, tokenlen, len;
	NSSUTF8 *tokenName = NULL;
	char *nick;
	if (instance && 
	     (!PK11_IsInternalKeySlot(instance->token->pk11slot) || 
	      (stanNick && PORT_Strchr(stanNick, ':') != NULL))) {
	    tokenName = nssToken_GetName(instance->token);
	    tokenlen = nssUTF8_Size(tokenName, &nssrv);
	} else {
	    /* don't use token name for internal slot; 3.3 didn't */
	    tokenlen = 0;
	}
	if (stanNick) {
	    nicklen = nssUTF8_Size(stanNick, &nssrv);
	    len = tokenlen + nicklen;
	    nick = PORT_ArenaAlloc(cc->arena, len);
	    if (tokenName) {
		memcpy(nick, tokenName, tokenlen-1);
		nick[tokenlen-1] = ':';
		memcpy(nick+tokenlen, stanNick, nicklen-1);
	    } else {
		memcpy(nick, stanNick, nicklen-1);
	    }
	    nick[len-1] = '\0';
            cc->nickname = nick;
	} else {
	    cc->nickname = NULL;
	}
    }
    if (context) {
	/* trust */
	nssTrust = nssCryptoContext_FindTrustForCertificate(context, c);
	if (!nssTrust) {
	    /* chicken and egg issue:
	     *
	     * c->issuer and c->serial are empty at this point, but
	     * nssTrustDomain_FindTrustForCertificate use them to look up
	     * up the trust object, so we point them to cc->derIssuer and
	     * cc->serialNumber.
	     *
	     * Our caller will fill these in with proper arena copies when we
	     * return. */
	    c->issuer.data = cc->derIssuer.data;
	    c->issuer.size = cc->derIssuer.len;
	    c->serial.data = cc->serialNumber.data;
	    c->serial.size = cc->serialNumber.len;
	    nssTrust = nssTrustDomain_FindTrustForCertificate(context->td, c);
	}
	if (nssTrust) {
            trust = cert_trust_from_stan_trust(nssTrust, cc->arena);
            if (trust) {
                /* we should destroy cc->trust before replacing it, but it's
                   allocated in cc->arena, so memory growth will occur on each
                   refresh */
                CERT_LockCertTrust(cc);
                cc->trust = trust;
                CERT_UnlockCertTrust(cc);
            }
	    nssTrust_Destroy(nssTrust);
	}
    } else if (instance) {
	/* slot */
	if (cc->slot != instance->token->pk11slot) {
	    if (cc->slot) {
		PK11_FreeSlot(cc->slot);
	    }
	    cc->slot = PK11_ReferenceSlot(instance->token->pk11slot);
	}
	cc->ownSlot = PR_TRUE;
	/* pkcs11ID */
	cc->pkcs11ID = instance->handle;
	/* trust */
	trust = nssTrust_GetCERTCertTrustForCert(c, cc);
        if (trust) {
            /* we should destroy cc->trust before replacing it, but it's
               allocated in cc->arena, so memory growth will occur on each
               refresh */
            CERT_LockCertTrust(cc);
            cc->trust = trust;
            CERT_UnlockCertTrust(cc);
        }
	nssCryptokiObject_Destroy(instance);
    } 
    /* database handle is now the trust domain */
    cc->dbhandle = c->object.trustDomain;
    /* subjectList ? */
    /* istemp and isperm are supported in NSS 3.4 */
    cc->istemp = PR_FALSE; /* CERT_NewTemp will override this */
    cc->isperm = PR_TRUE;  /* by default */
    /* pointer back */
    cc->nssCertificate = c;
    if (trust) {
	/* force the cert type to be recomputed to include trust info */
	PRUint32 nsCertType = cert_ComputeCertType(cc);

	/* Assert that it is safe to cast &cc->nsCertType to "PRInt32 *" */
	PORT_Assert(sizeof(cc->nsCertType) == sizeof(PRInt32));
	PR_ATOMIC_SET((PRInt32 *)&cc->nsCertType, nsCertType);
    }
}