summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralexei.volkov.bugs%sun.com <devnull@localhost>2008-03-15 02:15:36 +0000
committeralexei.volkov.bugs%sun.com <devnull@localhost>2008-03-15 02:15:36 +0000
commit437cc1cc06563e247746921f90b77351e18fb0c0 (patch)
tree9a8d85dd1356a3d8fc9f467c82790fc13de61b09
parent5741e4dbc313d0ecce564041cd68d640b5f5da97 (diff)
downloadnss-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.h5
-rw-r--r--security/nss/lib/certdb/certdb.c53
-rw-r--r--security/nss/lib/certdb/certi.h11
-rw-r--r--security/nss/lib/certhigh/certvfypkix.c8
-rw-r--r--security/nss/lib/pki/pki3hack.c9
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 *