Bug 813857: Make certificate trust flags thread safe.

r=rrelyea


git-svn-id: svn://10.0.0.236/trunk@264626 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
ryan.sleevi%gmail.com 2013-01-07 04:11:52 +00:00
parent 4eac635e00
commit 04bb52c2f6
10 changed files with 101 additions and 79 deletions

View File

@ -477,8 +477,7 @@ listCerts(CERTCertDBHandle *handle, char *name, char *email, PK11SlotInfo *slot,
}
rv = SECSuccess;
} else {
rv = SEC_PrintCertificateAndTrust(the_cert, "Certificate",
the_cert->trust);
rv = SEC_PrintCertificateAndTrust(the_cert, "Certificate", NULL);
if (rv != SECSuccess) {
SECU_PrintError(progName, "problem printing certificate");
}
@ -516,8 +515,7 @@ listCerts(CERTCertDBHandle *handle, char *name, char *email, PK11SlotInfo *slot,
rv = SECFailure;
}
} else {
rv = SEC_PrintCertificateAndTrust(the_cert, "Certificate",
the_cert->trust);
rv = SEC_PrintCertificateAndTrust(the_cert, "Certificate", NULL);
if (rv != SECSuccess) {
SECU_PrintError(progName, "problem printing certificate");
}

View File

@ -2143,7 +2143,7 @@ printflags(char *trusts, unsigned int flags)
SECStatus
SECU_PrintCertNickname(CERTCertListNode *node, void *data)
{
CERTCertTrust *trust;
CERTCertTrust trust;
CERTCertificate* cert;
FILE *out;
char trusts[30];
@ -2165,13 +2165,12 @@ SECU_PrintCertNickname(CERTCertListNode *node, void *data)
name = "(NULL)";
}
trust = cert->trust;
if (trust) {
printflags(trusts, trust->sslFlags);
if (CERT_GetCertTrust(cert, &trust) == SECSuccess) {
printflags(trusts, trust.sslFlags);
PORT_Strcat(trusts, ",");
printflags(trusts, trust->emailFlags);
printflags(trusts, trust.emailFlags);
PORT_Strcat(trusts, ",");
printflags(trusts, trust->objectSigningFlags);
printflags(trusts, trust.objectSigningFlags);
} else {
PORT_Memcpy(trusts,",,",3);
}
@ -3068,6 +3067,7 @@ SEC_PrintCertificateAndTrust(CERTCertificate *cert,
{
SECStatus rv;
SECItem data;
CERTCertTrust certTrust;
data.data = cert->derCert.data;
data.len = cert->derCert.len;
@ -3080,8 +3080,8 @@ SEC_PrintCertificateAndTrust(CERTCertificate *cert,
if (trust) {
SECU_PrintTrustFlags(stdout, trust,
"Certificate Trust Flags", 1);
} else if (cert->trust) {
SECU_PrintTrustFlags(stdout, cert->trust,
} else if (CERT_GetCertTrust(cert, &certTrust) == SECSuccess) {
SECU_PrintTrustFlags(stdout, &certTrust,
"Certificate Trust Flags", 1);
}
@ -3463,6 +3463,7 @@ SECU_FindCrlIssuer(CERTCertDBHandle *dbhandle, SECItem* subject,
{
CERTCertificate *issuerCert = NULL;
CERTCertList *certList = NULL;
CERTCertTrust trust;
if (!subject) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@ -3481,7 +3482,7 @@ SECU_FindCrlIssuer(CERTCertDBHandle *dbhandle, SECItem* subject,
/* check cert CERTCertTrust data is allocated, check cert
usage extension, check that cert has pkey in db. Select
the first (newest) user cert */
if (cert->trust &&
if (CERT_GetCertTrust(cert, &trust) == SECSuccess &&
CERT_CheckCertUsage(cert, KU_CRL_SIGN) == SECSuccess &&
CERT_IsUserCert(cert)) {

View File

@ -492,6 +492,7 @@ do_list_certs(const char *progName, int log)
CERTCertList *list;
CERTCertList *sorted;
CERTCertListNode *node;
CERTCertTrust trust;
int i;
list = PK11_ListCerts(PK11CertListUnique, NULL);
@ -543,10 +544,10 @@ do_list_certs(const char *progName, int log)
commonName = CERT_GetCommonName(&cert->subject);
appendString(commonName?commonName:"*NoName*");
PORT_Free(commonName);
if (cert->trust) {
appendFlags(cert->trust->sslFlags);
appendFlags(cert->trust->emailFlags);
appendFlags(cert->trust->objectSigningFlags);
if (CERT_GetCertTrust(cert, &trust) == SECSuccess) {
appendFlags(trust.sslFlags);
appendFlags(trust.emailFlags);
appendFlags(trust.objectSigningFlags);
}
}
CERT_DestroyCertList(list);

View File

@ -5,7 +5,7 @@
/*
* Certificate handling code
*
* $Id: certdb.c,v 1.123 2012-04-25 14:49:26 gerv%gerv.net Exp $
* $Id: certdb.c,v 1.124 2013-01-07 04:11:50 ryan.sleevi%gmail.com Exp $
*/
#include "nssilock.h"
@ -2051,35 +2051,38 @@ cert_Version(CERTCertificate *cert)
static unsigned int
cert_ComputeTrustOverrides(CERTCertificate *cert, unsigned int cType)
{
CERTCertTrust *trust = cert->trust;
CERTCertTrust trust;
SECStatus rv = SECFailure;
if (trust && (trust->sslFlags |
trust->emailFlags |
trust->objectSigningFlags)) {
rv = CERT_GetCertTrust(cert, &trust);
if (trust->sslFlags & (CERTDB_TERMINAL_RECORD|CERTDB_TRUSTED))
if (rv == SECSuccess && (trust.sslFlags |
trust.emailFlags |
trust.objectSigningFlags)) {
if (trust.sslFlags & (CERTDB_TERMINAL_RECORD|CERTDB_TRUSTED))
cType |= NS_CERT_TYPE_SSL_SERVER|NS_CERT_TYPE_SSL_CLIENT;
if (trust->sslFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA))
if (trust.sslFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA))
cType |= NS_CERT_TYPE_SSL_CA;
#if defined(CERTDB_NOT_TRUSTED)
if (trust->sslFlags & CERTDB_NOT_TRUSTED)
if (trust.sslFlags & CERTDB_NOT_TRUSTED)
cType &= ~(NS_CERT_TYPE_SSL_SERVER|NS_CERT_TYPE_SSL_CLIENT|
NS_CERT_TYPE_SSL_CA);
#endif
if (trust->emailFlags & (CERTDB_TERMINAL_RECORD|CERTDB_TRUSTED))
if (trust.emailFlags & (CERTDB_TERMINAL_RECORD|CERTDB_TRUSTED))
cType |= NS_CERT_TYPE_EMAIL;
if (trust->emailFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA))
if (trust.emailFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA))
cType |= NS_CERT_TYPE_EMAIL_CA;
#if defined(CERTDB_NOT_TRUSTED)
if (trust->emailFlags & CERTDB_NOT_TRUSTED)
if (trust.emailFlags & CERTDB_NOT_TRUSTED)
cType &= ~(NS_CERT_TYPE_EMAIL|NS_CERT_TYPE_EMAIL_CA);
#endif
if (trust->objectSigningFlags & (CERTDB_TERMINAL_RECORD|CERTDB_TRUSTED))
if (trust.objectSigningFlags & (CERTDB_TERMINAL_RECORD|CERTDB_TRUSTED))
cType |= NS_CERT_TYPE_OBJECT_SIGNING;
if (trust->objectSigningFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA))
if (trust.objectSigningFlags & (CERTDB_VALID_CA|CERTDB_TRUSTED_CA))
cType |= NS_CERT_TYPE_OBJECT_SIGNING_CA;
#if defined(CERTDB_NOT_TRUSTED)
if (trust->objectSigningFlags & CERTDB_NOT_TRUSTED)
if (trust.objectSigningFlags & CERTDB_NOT_TRUSTED)
cType &= ~(NS_CERT_TYPE_OBJECT_SIGNING|
NS_CERT_TYPE_OBJECT_SIGNING_CA);
#endif
@ -2818,10 +2821,14 @@ loser:
PRBool CERT_IsUserCert(CERTCertificate* cert)
{
if ( cert->trust &&
((cert->trust->sslFlags & CERTDB_USER ) ||
(cert->trust->emailFlags & CERTDB_USER ) ||
(cert->trust->objectSigningFlags & CERTDB_USER )) ) {
CERTCertTrust trust;
SECStatus rv = SECFailure;
rv = CERT_GetCertTrust(cert, &trust);
if (rv == SECSuccess &&
((trust.sslFlags & CERTDB_USER ) ||
(trust.emailFlags & CERTDB_USER ) ||
(trust.objectSigningFlags & CERTDB_USER )) ) {
return PR_TRUE;
} else {
return PR_FALSE;

View File

@ -240,9 +240,7 @@ CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert,
SECStatus rv = SECSuccess;
PRStatus ret;
CERT_LockCertTrust(cert);
ret = STAN_ChangeCertTrust(cert, trust);
CERT_UnlockCertTrust(cert);
if (ret != PR_SUCCESS) {
rv = SECFailure;
CERT_MapStanError();

View File

@ -542,17 +542,15 @@ CollectDistNames( CERTCertificate *cert, SECItem *k, void *data)
{
CERTDistNames *names;
PRBool saveit = PR_FALSE;
CERTCertTrust *trust;
CERTCertTrust trust;
dnameNode *node;
int len;
names = (CERTDistNames *)data;
if ( cert->trust ) {
trust = cert->trust;
if ( CERT_GetCertTrust(cert, &trust) == SECSuccess ) {
/* only collect names of CAs trusted for issuing SSL clients */
if ( trust->sslFlags & CERTDB_TRUSTED_CLIENT_CA ) {
if ( trust.sslFlags & CERTDB_TRUSTED_CLIENT_CA ) {
saveit = PR_TRUE;
}
}

View File

@ -328,6 +328,7 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
int certsListLen = 16;
int namesCount = 0;
PRBool subjectCertIsSelfIssued;
CERTCertTrust issuerTrust;
if (revoked) {
*revoked = PR_FALSE;
@ -528,7 +529,7 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
LOG_ERROR(log,subjectCert,count,0);
}
if ( issuerCert->trust ) {
if ( CERT_GetCertTrust(issuerCert, &issuerTrust) == SECSuccess) {
/* we have some trust info, but this does NOT imply that this
* cert is actually trusted for any purpose. The cert may be
* explicitly UNtrusted. We won't know until we examine the
@ -552,7 +553,7 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
}
}
flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType);
flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType);
if (( flags & requiredFlags ) == requiredFlags) {
/* we found a trusted one, so return */
rv = rvFinal;
@ -574,7 +575,7 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
* certUsageAnyCA or certUsageStatusResponder. */
for (trustType = trustSSL; trustType < trustTypeNone;
trustType++) {
flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType);
flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType);
if ((flags & requiredFlags) == requiredFlags) {
rv = rvFinal;
goto done;
@ -588,7 +589,7 @@ cert_VerifyCertChainOld(CERTCertDBHandle *handle, CERTCertificate *cert,
* untrusted */
for (trustType = trustSSL; trustType < trustTypeNone;
trustType++) {
flags = SEC_GET_TRUST_FLAGS(issuerCert->trust, trustType);
flags = SEC_GET_TRUST_FLAGS(&issuerTrust, trustType);
/* is it explicitly distrusted? */
if ((flags & CERTDB_TERMINAL_RECORD) &&
((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0)) {
@ -729,6 +730,7 @@ CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
unsigned int requiredCAKeyUsage;
unsigned int requiredFlags;
CERTCertificate *issuerCert;
CERTCertTrust certTrust;
if (CERT_KeyUsageAndTypeForCertUsage(certUsage, PR_TRUE,
@ -794,7 +796,7 @@ CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
isca = PR_TRUE;
}
if ( cert->trust ) {
if ( CERT_GetCertTrust(cert, &certTrust) == SECSuccess ) {
/* we have some trust info, but this does NOT imply that this
* cert is actually trusted for any purpose. The cert may be
* explicitly UNtrusted. We won't know until we examine the
@ -823,7 +825,7 @@ CERT_VerifyCACertForUsage(CERTCertDBHandle *handle, CERTCertificate *cert,
/*
* check the trust params of the issuer
*/
flags = SEC_GET_TRUST_FLAGS(cert->trust, trustType);
flags = SEC_GET_TRUST_FLAGS(&certTrust, trustType);
if ( ( flags & requiredFlags ) == requiredFlags) {
/* we found a trusted one, so return */
rv = rvFinal;
@ -915,16 +917,17 @@ cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
unsigned int *failedFlags, PRBool *trusted)
{
unsigned int flags;
CERTCertTrust trust;
*failedFlags = 0;
*trusted = PR_FALSE;
/* check trust flags to see if this cert is directly trusted */
if ( cert->trust ) {
if ( CERT_GetCertTrust(cert, &trust) == SECSuccess ) {
switch ( certUsage ) {
case certUsageSSLClient:
case certUsageSSLServer:
flags = cert->trust->sslFlags;
flags = trust.sslFlags;
/* is the cert directly trusted or not trusted ? */
if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
@ -940,7 +943,7 @@ cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
break;
case certUsageSSLServerWithStepUp:
/* XXX - step up certs can't be directly trusted, only distrust */
flags = cert->trust->sslFlags;
flags = trust.sslFlags;
if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
* authoritative */
if (( flags & CERTDB_TRUSTED ) == 0) {
@ -951,7 +954,7 @@ cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
}
break;
case certUsageSSLCA:
flags = cert->trust->sslFlags;
flags = trust.sslFlags;
if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
* authoritative */
if (( flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA) ) == 0) {
@ -963,7 +966,7 @@ cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
break;
case certUsageEmailSigner:
case certUsageEmailRecipient:
flags = cert->trust->emailFlags;
flags = trust.emailFlags;
if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
* authoritative */
if ( flags & CERTDB_TRUSTED ) { /* trust this cert */
@ -978,7 +981,7 @@ cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
break;
case certUsageObjectSigner:
flags = cert->trust->objectSigningFlags;
flags = trust.objectSigningFlags;
if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
* authoritative */
@ -993,21 +996,21 @@ cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
break;
case certUsageVerifyCA:
case certUsageStatusResponder:
flags = cert->trust->sslFlags;
flags = trust.sslFlags;
/* is the cert directly trusted or not trusted ? */
if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) ==
( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) {
*trusted = PR_TRUE;
return SECSuccess;
}
flags = cert->trust->emailFlags;
flags = trust.emailFlags;
/* is the cert directly trusted or not trusted ? */
if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) ==
( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) {
*trusted = PR_TRUE;
return SECSuccess;
}
flags = cert->trust->objectSigningFlags;
flags = trust.objectSigningFlags;
/* is the cert directly trusted or not trusted ? */
if ( ( flags & ( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) ==
( CERTDB_VALID_CA | CERTDB_TRUSTED_CA ) ) {
@ -1018,7 +1021,7 @@ cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
case certUsageAnyCA:
case certUsageUserCertImport:
/* do we distrust these certs explicitly */
flags = cert->trust->sslFlags;
flags = trust.sslFlags;
if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
* authoritative */
if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) {
@ -1026,7 +1029,7 @@ cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
return SECFailure;
}
}
flags = cert->trust->emailFlags;
flags = trust.emailFlags;
if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
* authoritative */
if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) {
@ -1036,7 +1039,7 @@ cert_CheckLeafTrust(CERTCertificate *cert, SECCertUsage certUsage,
}
/* fall through */
case certUsageProtectedObjectSigner:
flags = cert->trust->objectSigningFlags;
flags = trust.objectSigningFlags;
if ( flags & CERTDB_TERMINAL_RECORD) { /* the trust record is
* authoritative */
if ((flags & (CERTDB_TRUSTED|CERTDB_TRUSTED_CA)) == 0) {
@ -1387,6 +1390,7 @@ CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName,
{
CERTCertList *certList = NULL;
CERTCertificate *cert = NULL;
CERTCertTrust certTrust;
unsigned int requiredTrustFlags;
SECTrustType requiredTrustType;
unsigned int flags;
@ -1428,10 +1432,10 @@ CERT_FindMatchingCert(CERTCertDBHandle *handle, SECItem *derName,
if ( ( owner == certOwnerCA ) && preferTrusted &&
( requiredTrustType != trustTypeNone ) ) {
if ( cert->trust == NULL ) {
if ( CERT_GetCertTrust(cert, &certTrust) != SECSuccess ) {
flags = 0;
} else {
flags = SEC_GET_TRUST_FLAGS(cert->trust, requiredTrustType);
flags = SEC_GET_TRUST_FLAGS(&certTrust, requiredTrustType);
}
if ( ( flags & requiredTrustFlags ) != requiredTrustFlags ) {

View File

@ -324,7 +324,6 @@ PK11_MakeCertFromHandle(PK11SlotInfo *slot,CK_OBJECT_HANDLE certID,
if (trust == NULL)
goto loser;
PORT_Memset(trust,0, sizeof(CERTCertTrust));
cert->trust = trust;
if(! pk11_HandleTrustObject(slot, cert, trust) ) {
unsigned int type;
@ -365,6 +364,10 @@ PK11_MakeCertFromHandle(PK11SlotInfo *slot,CK_OBJECT_HANDLE certID,
trust->emailFlags |= CERTDB_USER;
/* trust->objectSigningFlags |= CERTDB_USER; */
}
CERT_LockCertTrust(cert);
cert->trust = trust;
CERT_UnlockCertTrust(cert);
return cert;
loser:
@ -1410,6 +1413,7 @@ pk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipien
NSSCMSRecipient *ri = NULL;
int i;
PRBool tokenRescanDone = PR_FALSE;
CERTCertTrust trust;
for (i=0; (ri = recipientlist[i]) != NULL; i++) {
CERTCertificate *cert = NULL;
@ -1490,8 +1494,8 @@ pk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipien
}
if (cert) {
/* this isn't our cert */
if ((cert->trust == NULL) ||
((cert->trust->emailFlags & CERTDB_USER) != CERTDB_USER)) {
if (CERT_GetCertTrust(cert, &trust) != SECSuccess ||
((trust.emailFlags & CERTDB_USER) != CERTDB_USER)) {
CERT_DestroyCertificate(cert);
continue;
}
@ -1550,6 +1554,7 @@ pk11_FindCertObjectByRecipient(PK11SlotInfo *slot,
SEC_PKCS7RecipientInfo **rip, void *pwarg)
{
SEC_PKCS7RecipientInfo *ri = NULL;
CERTCertTrust trust;
int i;
for (i=0; (ri = recipientArray[i]) != NULL; i++) {
@ -1559,8 +1564,8 @@ pk11_FindCertObjectByRecipient(PK11SlotInfo *slot,
pwarg);
if (cert) {
/* this isn't our cert */
if ((cert->trust == NULL) ||
((cert->trust->emailFlags & CERTDB_USER) != CERTDB_USER)) {
if (CERT_GetCertTrust(cert, &trust) != SECSuccess ||
((trust.emailFlags & CERTDB_USER) != CERTDB_USER)) {
CERT_DestroyCertificate(cert);
continue;
}
@ -2260,9 +2265,10 @@ PK11_FortezzaHasKEA(CERTCertificate *cert)
{
/* look at the subject and see if it is a KEA for MISSI key */
SECOidData *oid;
CERTCertTrust trust;
if ((cert->trust == NULL) ||
((cert->trust->sslFlags & CERTDB_USER) != CERTDB_USER)) {
if (CERT_GetCertTrust(cert, &trust) != SECSuccess ||
((trust.sslFlags & CERTDB_USER) != CERTDB_USER)) {
return PR_FALSE;
}

View File

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifdef DEBUG
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.110 $ $Date: 2012-12-12 19:22:40 $";
static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.111 $ $Date: 2013-01-07 04:11:51 $";
#endif /* DEBUG */
/*
@ -805,7 +805,9 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced
/* 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);
}
@ -826,7 +828,9 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced
/* 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);
}
@ -853,6 +857,7 @@ stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate)
{
nssDecodedCert *dc = NULL;
CERTCertificate *cc = NULL;
CERTCertTrust certTrust;
nssPKIObject_Lock(&c->object);
@ -887,14 +892,18 @@ stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate)
}
if (!cc->nssCertificate || forceUpdate) {
fill_CERTCertificateFields(c, cc, forceUpdate);
} else if (!cc->trust && !c->object.cryptoContext) {
} 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:
@ -1086,6 +1095,7 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
NSSTrust *nssTrust;
NSSArena *arena;
CERTCertTrust *oldTrust;
CERTCertTrust *newTrust;
nssListIterator *tokens;
PRBool moving_object;
nssCryptokiObject *newInstance;
@ -1101,12 +1111,15 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust)
return PR_SUCCESS;
} else {
/* take over memory already allocated in cc's arena */
cc->trust = oldTrust;
newTrust = oldTrust;
}
} else {
cc->trust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
newTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust));
}
memcpy(cc->trust, trust, 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;

View File

@ -5,7 +5,7 @@
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* $Id: ssl3con.c,v 1.195 2012-11-15 18:49:01 wtc%google.com Exp $ */
/* $Id: ssl3con.c,v 1.196 2013-01-07 04:11:52 ryan.sleevi%gmail.com Exp $ */
/* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */
@ -8342,7 +8342,6 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
PRInt32 size;
SECStatus rv;
PRBool isServer = (PRBool)(!!ss->sec.isServer);
PRBool trusted = PR_FALSE;
PRBool isTLS;
SSL3AlertDescription desc;
int errCode = SSL_ERROR_RX_MALFORMED_CERTIFICATE;
@ -8459,9 +8458,6 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto ambiguous_err;
}
if (c->cert->trust)
trusted = PR_TRUE;
c->next = NULL;
if (lastCert) {
lastCert->next = c;