diff options
author | alexei.volkov.bugs%sun.com <devnull@localhost> | 2008-03-15 02:15:36 +0000 |
---|---|---|
committer | alexei.volkov.bugs%sun.com <devnull@localhost> | 2008-03-15 02:15:36 +0000 |
commit | 437cc1cc06563e247746921f90b77351e18fb0c0 (patch) | |
tree | 9a8d85dd1356a3d8fc9f467c82790fc13de61b09 | |
parent | 5741e4dbc313d0ecce564041cd68d640b5f5da97 (diff) | |
download | nss-hg-437cc1cc06563e247746921f90b77351e18fb0c0.tar.gz |
390381 - libpkix rejects cert chain when root CA cert has no basic constraints.
Main patch(by Nelson). r=rrelyea
-rw-r--r-- | security/nss/lib/certdb/cert.h | 5 | ||||
-rw-r--r-- | security/nss/lib/certdb/certdb.c | 53 | ||||
-rw-r--r-- | security/nss/lib/certdb/certi.h | 11 | ||||
-rw-r--r-- | security/nss/lib/certhigh/certvfypkix.c | 8 | ||||
-rw-r--r-- | security/nss/lib/pki/pki3hack.c | 9 |
5 files changed, 53 insertions, 33 deletions
diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h index fb46a33d0..a62b2c872 100644 --- a/security/nss/lib/certdb/cert.h +++ b/security/nss/lib/certdb/cert.h @@ -1515,11 +1515,6 @@ extern SECItem * CERT_GetSPKIDigest(PRArenaPool *arena, const CERTCertificate *cert, SECOidTag digestAlg, SECItem *fill); -/* - * fill in nsCertType field of the cert based on the cert extension - */ -extern SECStatus cert_GetCertType(CERTCertificate *cert); - SECStatus CERT_CheckCRL(CERTCertificate* cert, CERTCertificate* issuer, SECItem* dp, int64 t, void* wincx); diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c index 373a09aec..37f0dd62c 100644 --- a/security/nss/lib/certdb/certdb.c +++ b/security/nss/lib/certdb/certdb.c @@ -559,18 +559,30 @@ findOIDinOIDSeqByTagNum(CERTOidSequence *seq, SECOidTag tagnum) SECStatus cert_GetCertType(CERTCertificate *cert) { + PRUint32 nsCertType; + + if (cert->nsCertType) { + /* once set, no need to recalculate */ + return SECSuccess; + } + nsCertType = cert_ComputeCertType(cert); + + /* Assert that it is safe to cast &cert->nsCertType to "PRInt32 *" */ + PORT_Assert(sizeof(cert->nsCertType) == sizeof(PRInt32)); + PR_AtomicSet((PRInt32 *)&cert->nsCertType, nsCertType); + return SECSuccess; +} + +PRUint32 +cert_ComputeCertType(CERTCertificate *cert) +{ SECStatus rv; SECItem tmpitem; SECItem encodedExtKeyUsage; CERTOidSequence *extKeyUsage = NULL; PRBool basicConstraintPresent = PR_FALSE; CERTBasicConstraints basicConstraint; - unsigned int nsCertType = 0; - - if (cert->nsCertType) { - /* once set, no need to recalculate */ - return SECSuccess; - } + PRUint32 nsCertType = 0; tmpitem.data = NULL; CERT_FindNSCertTypeExtension(cert, &tmpitem); @@ -677,22 +689,20 @@ cert_GetCertType(CERTCertificate *cert) nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; } } else { - /* if no extension, then allow any ssl or email (no ca or object - * signing) - */ - nsCertType = NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER | - NS_CERT_TYPE_EMAIL; - + /* If no NS Cert Type extension and no EKU extension, then */ + nsCertType = 0; + if (CERT_IsCACert(cert, &nsCertType)) + nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; /* if the basic constraint extension says the cert is a CA, then allow SSL CA and EMAIL CA and Status Responder */ - if ((basicConstraintPresent == PR_TRUE) - && (basicConstraint.isCA)) { - nsCertType |= NS_CERT_TYPE_SSL_CA; - nsCertType |= NS_CERT_TYPE_EMAIL_CA; - nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; - } else if (CERT_IsCACert(cert, NULL) == PR_TRUE) { - nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER; + if (basicConstraintPresent && basicConstraint.isCA ) { + nsCertType |= (NS_CERT_TYPE_SSL_CA | + NS_CERT_TYPE_EMAIL_CA | + EXT_KEY_USAGE_STATUS_RESPONDER); } + /* allow any ssl or email (no ca or object signing. */ + nsCertType |= NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER | + NS_CERT_TYPE_EMAIL; /* if the cert is a fortezza CA cert, then allow SSL CA and EMAIL CA */ if (fortezzaIsCA(cert)) { @@ -707,10 +717,7 @@ cert_GetCertType(CERTCertificate *cert) if (extKeyUsage != NULL) { CERT_DestroyOidSequence(extKeyUsage); } - /* Assert that it is safe to cast &cert->nsCertType to "PRInt32 *" */ - PORT_Assert(sizeof(cert->nsCertType) == sizeof(PRInt32)); - PR_AtomicSet((PRInt32 *)&cert->nsCertType, nsCertType); - return(SECSuccess); + return nsCertType; } /* diff --git a/security/nss/lib/certdb/certi.h b/security/nss/lib/certdb/certi.h index b79def467..1a9606b25 100644 --- a/security/nss/lib/certdb/certi.h +++ b/security/nss/lib/certdb/certi.h @@ -292,5 +292,16 @@ SECStatus cert_InitLocks(void); SECStatus cert_DestroyLocks(void); +/* + * fill in nsCertType field of the cert based on the cert extension + */ +extern SECStatus cert_GetCertType(CERTCertificate *cert); + +/* + * compute and return the value of nsCertType for cert, but do not + * update the CERTCertificate. + */ +extern PRUint32 cert_ComputeCertType(CERTCertificate *cert); + #endif /* _CERTI_H_ */ diff --git a/security/nss/lib/certhigh/certvfypkix.c b/security/nss/lib/certhigh/certvfypkix.c index c2b1b799d..87b01fb95 100644 --- a/security/nss/lib/certhigh/certvfypkix.c +++ b/security/nss/lib/certhigh/certvfypkix.c @@ -405,11 +405,9 @@ cert_ProcessingParamsSetKuAndEku( plContext), PKIX_COMCERTSELPARAMSSETEXTKEYUSAGEFAILED); -/* Enable the following call when bug 390381 is fixed. - * PKIX_CHECK( - * PKIX_PL_EkuChecker_Create(procParams, plContext), - * PKIX_EKUCHECKERINITIALIZEFAILED); - */ + PKIX_CHECK( + PKIX_PL_EkuChecker_Create(procParams, plContext), + PKIX_EKUCHECKERINITIALIZEFAILED); cleanup: PKIX_DECREF(extKeyUsage); diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c index ea5d9db06..33eb61684 100644 --- a/security/nss/lib/pki/pki3hack.c +++ b/security/nss/lib/pki/pki3hack.c @@ -70,6 +70,7 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$"; #include "certdb.h" #include "certt.h" #include "cert.h" +#include "certi.h" #include "pk11func.h" #include "pkistore.h" #include "secmod.h" @@ -810,6 +811,14 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced 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_AtomicSet((PRInt32 *)&cc->nsCertType, nsCertType); + } } static CERTCertificate * |