Esempio n. 1
0
static void match_nickname(const void *k, void *v, void *a)
{
    PRStatus nssrv;
    NSSCertificate *c;
    NSSUTF8 *nickname;
    nssList *subjectList = (nssList *)v;
    struct nickname_template_str *nt = (struct nickname_template_str *)a;
    nssrv = nssList_GetArray(subjectList, (void **)&c, 1);
    nickname = nssCertificate_GetNickname(c, NULL);
    if (nssrv == PR_SUCCESS && nickname &&
         nssUTF8_Equal(nickname, nt->nickname, &nssrv)) 
    {
	nt->subjectList = subjectList;
    }
}
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);
}
Esempio n. 3
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;
}
Esempio n. 4
0
SECStatus
__CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname,
                         CERTCertTrust *trust)
{
    NSSUTF8 *stanNick;
    PK11SlotInfo *slot;
    NSSToken *internal;
    NSSCryptoContext *context;
    nssCryptokiObject *permInstance;
    NSSCertificate *c = STAN_GetNSSCertificate(cert);
    nssCertificateStoreTrace lockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
    nssCertificateStoreTrace unlockTrace = { NULL, NULL, PR_FALSE, PR_FALSE };
    SECStatus rv;
    PRStatus ret;

    if (c == NULL) {
        CERT_MapStanError();
        return SECFailure;
    }

    context = c->object.cryptoContext;
    if (!context) {
        PORT_SetError(SEC_ERROR_ADDING_CERT);
        return SECFailure; /* wasn't a temp cert */
    }
    stanNick = nssCertificate_GetNickname(c, NULL);
    if (stanNick && nickname && strcmp(nickname, stanNick) != 0) {
        /* different: take the new nickname */
        cert->nickname = NULL;
        nss_ZFreeIf(stanNick);
        stanNick = NULL;
    }
    if (!stanNick && nickname) {
        /* Either there was no nickname yet, or we have a new nickname */
        stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, NULL);
    } /* else: old stanNick is identical to new nickname */
    /* Delete the temp instance */
    nssCertificateStore_Lock(context->certStore, &lockTrace);
    nssCertificateStore_RemoveCertLOCKED(context->certStore, c);
    nssCertificateStore_Unlock(context->certStore, &lockTrace, &unlockTrace);
    c->object.cryptoContext = NULL;
    /* Import the perm instance onto the internal token */
    slot = PK11_GetInternalKeySlot();
    internal = PK11Slot_GetNSSToken(slot);
    permInstance = nssToken_ImportCertificate(
        internal, NULL, NSSCertificateType_PKIX, &c->id, stanNick, &c->encoding,
        &c->issuer, &c->subject, &c->serial, cert->emailAddr, PR_TRUE);
    nss_ZFreeIf(stanNick);
    stanNick = NULL;
    PK11_FreeSlot(slot);
    if (!permInstance) {
        if (NSS_GetError() == NSS_ERROR_INVALID_CERTIFICATE) {
            PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL);
        }
        return SECFailure;
    }
    nssPKIObject_AddInstance(&c->object, permInstance);
    nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1);
    /* reset the CERTCertificate fields */
    cert->nssCertificate = NULL;
    cert = STAN_GetCERTCertificateOrRelease(c); /* should return same pointer */
    if (!cert) {
        CERT_MapStanError();
        return SECFailure;
    }
    cert->istemp = PR_FALSE;
    cert->isperm = PR_TRUE;
    if (!trust) {
        return SECSuccess;
    }
    ret = STAN_ChangeCertTrust(cert, trust);
    rv = SECSuccess;
    if (ret != PR_SUCCESS) {
        rv = SECFailure;
        CERT_MapStanError();
    }
    return rv;
}