diff options
Diffstat (limited to 'src/crypto/x509v3/v3_purp.c')
-rw-r--r-- | src/crypto/x509v3/v3_purp.c | 88 |
1 files changed, 20 insertions, 68 deletions
diff --git a/src/crypto/x509v3/v3_purp.c b/src/crypto/x509v3/v3_purp.c index 324de85a..03270377 100644 --- a/src/crypto/x509v3/v3_purp.c +++ b/src/crypto/x509v3/v3_purp.c @@ -80,7 +80,6 @@ static void x509v3_cache_extensions(X509 *x); -static int check_ssl_ca(const X509 *x); static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca); static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, @@ -562,39 +561,20 @@ static void x509v3_cache_extensions(X509 *x) CRYPTO_MUTEX_unlock_write(&x->lock); } -/* - * CA checks common to all purposes return codes: 0 not a CA 1 is a CA 2 - * basicConstraints absent so "maybe" a CA 3 basicConstraints absent but self - * signed V1. 4 basicConstraints absent but keyUsage present and keyCertSign - * asserted. - */ - +/* check_ca returns one if |x| should be considered a CA certificate and zero + * otherwise. */ static int check_ca(const X509 *x) { /* keyUsage if present should allow cert signing */ if (ku_reject(x, KU_KEY_CERT_SIGN)) return 0; - if (x->ex_flags & EXFLAG_BCONS) { - if (x->ex_flags & EXFLAG_CA) - return 1; - /* If basicConstraints says not a CA then say so */ - else - return 0; - } else { - /* we support V1 roots for... uh, I don't really know why. */ - if ((x->ex_flags & V1_ROOT) == V1_ROOT) - return 3; - /* - * If key usage present it must have certSign so tolerate it - */ - else if (x->ex_flags & EXFLAG_KUSAGE) - return 4; - /* Older certificates could have Netscape-specific CA types */ - else if (x->ex_flags & EXFLAG_NSCERT && x->ex_nscert & NS_ANY_CA) - return 5; - /* can this still be regarded a CA certificate? I doubt it */ - return 0; + /* Version 1 certificates are considered CAs and don't have extensions. */ + if ((x->ex_flags & V1_ROOT) == V1_ROOT) { + return 1; } + /* Otherwise, it's only a CA if basicConstraints says so. */ + return ((x->ex_flags & EXFLAG_BCONS) && + (x->ex_flags & EXFLAG_CA)); } int X509_check_ca(X509 *x) @@ -603,27 +583,13 @@ int X509_check_ca(X509 *x) return check_ca(x); } -/* Check SSL CA: common checks for SSL client and server */ -static int check_ssl_ca(const X509 *x) -{ - int ca_ret; - ca_ret = check_ca(x); - if (!ca_ret) - return 0; - /* check nsCertType if present */ - if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA) - return ca_ret; - else - return 0; -} - static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, int ca) { if (xku_reject(x, XKU_SSL_CLIENT)) return 0; if (ca) - return check_ssl_ca(x); + return check_ca(x); /* We need to do digital signatures or key agreement */ if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT)) return 0; @@ -647,7 +613,7 @@ static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, if (xku_reject(x, XKU_SSL_SERVER | XKU_SGC)) return 0; if (ca) - return check_ssl_ca(x); + return check_ca(x); if (ns_reject(x, NS_SSL_SERVER)) return 0; @@ -671,29 +637,23 @@ static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, return ret; } -/* common S/MIME checks */ +/* purpose_smime returns one if |x| is a valid S/MIME leaf (|ca| is zero) or CA + * (|ca| is one) certificate, and zero otherwise. */ static int purpose_smime(const X509 *x, int ca) { if (xku_reject(x, XKU_SMIME)) return 0; if (ca) { - int ca_ret; - ca_ret = check_ca(x); - if (!ca_ret) - return 0; /* check nsCertType if present */ - if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) - return ca_ret; - else - return 0; + if ((x->ex_flags & EXFLAG_NSCERT) && + (x->ex_nscert & NS_SMIME_CA) == 0) { + return 0; + } + + return check_ca(x); } if (x->ex_flags & EXFLAG_NSCERT) { - if (x->ex_nscert & NS_SMIME) - return 1; - /* Workaround for some buggy certificates */ - if (x->ex_nscert & NS_SSL_CLIENT) - return 2; - return 0; + return (x->ex_nscert & NS_SMIME) == NS_SMIME; } return 1; } @@ -726,11 +686,7 @@ static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, int ca) { if (ca) { - int ca_ret; - if ((ca_ret = check_ca(x)) != 2) - return ca_ret; - else - return 0; + return check_ca(x); } if (ku_reject(x, KU_CRL_SIGN)) return 0; @@ -744,10 +700,6 @@ static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) { - /* - * Must be a valid CA. Should we really support the "I don't know" value - * (2)? - */ if (ca) return check_ca(x); /* leaf certificate is checked in OCSP_verify() */ |