diff --git a/CHANGES b/CHANGES index 5dca9e0f4e01c6f1344420af1e8182f726f46c9c..319340774471ed2128f2662f960ffaefc1036d45 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,18 @@ Changes between 0.9.5 and 0.9.5a [XX XXX 2000] + *) Add compatability options to the purpose and trust code. The + purpose X509_PURPOSE_ANY is "any purpose" which automatically + accepts a certificate or CA, this was the previous behaviour, + with all the associated security issues. + + X509_TRUST_COMPAT is the old trust behaviour: only and + automatically trust self signed roots in certificate store. A + new trust setting X509_TRUST_DEFAULT is used to specify that + a purpose has no associated trust setting and it should instead + use the value in the default purpose. + [Steve Henson] + *) Fix the PKCS#8 DSA private key code so it decodes keys again and fix a memory leak. [Steve Henson] diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h index d3336d9cebbe57e6fa852c3862cf2aca08212513..0192272e7c1d188996f82187c65df7b50fc438ad 100644 --- a/crypto/x509/x509.h +++ b/crypto/x509/x509.h @@ -284,7 +284,9 @@ DECLARE_STACK_OF(X509_TRUST) /* standard trust ids */ -#define X509_TRUST_ANY 1 +#define X509_TRUST_DEFAULT -1 /* Only valid in purpose settings */ + +#define X509_TRUST_COMPAT 1 #define X509_TRUST_SSL_CLIENT 2 #define X509_TRUST_SSL_SERVER 3 #define X509_TRUST_EMAIL 4 diff --git a/crypto/x509/x509_trs.c b/crypto/x509/x509_trs.c index 9f7d67952db8f33476e2b5a8116e9996d73e8224..c779aaf94d614746626de4ee8cd3d05938d2f4a5 100644 --- a/crypto/x509/x509_trs.c +++ b/crypto/x509/x509_trs.c @@ -65,7 +65,7 @@ static int tr_cmp(X509_TRUST **a, X509_TRUST **b); static void trtable_free(X509_TRUST *p); static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags); -static int trust_any(X509_TRUST *trust, X509 *x, int flags); +static int trust_compat(X509_TRUST *trust, X509 *x, int flags); static int obj_trust(int id, X509 *x, int flags); static int (*default_trust)(int id, X509 *x, int flags) = obj_trust; @@ -76,7 +76,7 @@ static int (*default_trust)(int id, X509 *x, int flags) = obj_trust; */ static X509_TRUST trstandard[] = { -{X509_TRUST_ANY, 0, trust_any, "Any", 0, NULL}, +{X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL}, {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth, NULL}, {X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Client", NID_server_auth, NULL}, {X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, NULL}, @@ -107,8 +107,8 @@ int X509_check_trust(X509 *x, int id, int flags) X509_TRUST *pt; int idx; if(id == -1) return 1; - if(!(idx = X509_TRUST_get_by_id(id))) - return default_trust(id, x, flags); + idx = X509_TRUST_get_by_id(id); + if(idx == -1) return default_trust(id, x, flags); pt = X509_TRUST_get0(idx); return pt->check_trust(pt, x, flags); } @@ -230,6 +230,11 @@ static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags) /* we don't have any trust settings: for compatibility * we return trusted if it is self signed */ + return trust_compat(trust, x, flags); +} + +static int trust_compat(X509_TRUST *trust, X509 *x, int flags) +{ X509_check_purpose(x, -1, 0); if(x->ex_flags & EXFLAG_SS) return X509_TRUST_TRUSTED; else return X509_TRUST_UNTRUSTED; @@ -257,7 +262,3 @@ static int obj_trust(int id, X509 *x, int flags) return X509_TRUST_UNTRUSTED; } -static int trust_any(X509_TRUST *trust, X509 *x, int flags) -{ - return X509_TRUST_TRUSTED; -} diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 8563f65695148ec9fdefc56057d99c50c9eca0c6..3ddb2303d3809a31eb5cf351d75891f00fb5d7ef 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -771,18 +771,25 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, if(!purpose) purpose = def_purpose; /* If we have a purpose then check it is valid */ if(purpose) { + X509_PURPOSE *ptmp; idx = X509_PURPOSE_get_by_id(purpose); if(idx == -1) { X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, X509_R_UNKNOWN_PURPOSE_ID); return 0; } - /* If trust not set then get from purpose default */ - if(!trust) { - X509_PURPOSE *ptmp; + ptmp = X509_PURPOSE_get0(idx); + if(ptmp->trust == X509_TRUST_DEFAULT) { + idx = X509_PURPOSE_get_by_id(def_purpose); + if(idx == -1) { + X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, + X509_R_UNKNOWN_PURPOSE_ID); + return 0; + } ptmp = X509_PURPOSE_get0(idx); - trust = ptmp->trust; } + /* If trust not set then get from purpose default */ + if(!trust) trust = ptmp->trust; } if(trust) { idx = X509_TRUST_get_by_id(trust); diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c index b7494ebcd56890ec5d15db9bf11918de98d1176a..5594a1d64f9b257479e11bc4d941910eff37294c 100644 --- a/crypto/x509v3/v3_purp.c +++ b/crypto/x509v3/v3_purp.c @@ -71,6 +71,7 @@ static int purpose_smime(X509 *x, int ca); static int check_purpose_smime_sign(X509_PURPOSE *xp, X509 *x, int ca); static int check_purpose_smime_encrypt(X509_PURPOSE *xp, X509 *x, int ca); static int check_purpose_crl_sign(X509_PURPOSE *xp, X509 *x, int ca); +static int no_check(X509_PURPOSE *xp, X509 *x, int ca); static int xp_cmp(X509_PURPOSE **a, X509_PURPOSE **b); static void xptable_free(X509_PURPOSE *p); @@ -81,7 +82,8 @@ static X509_PURPOSE xstandard[] = { {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL}, {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, "S/MIME signing", "smimesign", NULL}, {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL}, - {X509_PURPOSE_CRL_SIGN, X509_TRUST_ANY, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL}, + {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, "CRL signing", "crlsign", NULL}, + {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", NULL}, }; #define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE)) @@ -454,3 +456,8 @@ static int check_purpose_crl_sign(X509_PURPOSE *xp, X509 *x, int ca) if(ku_reject(x, KU_CRL_SIGN)) return 0; return 1; } + +static int no_check(X509_PURPOSE *xp, X509 *x, int ca) +{ + return 1; +} diff --git a/crypto/x509v3/x509v3.h b/crypto/x509v3/x509v3.h index fe01755797b65f2f2e4d9289b0b4724d6c677491..ce715dfa737c12a5c4e87717c70e8263633e6039 100644 --- a/crypto/x509v3/x509v3.h +++ b/crypto/x509v3/x509v3.h @@ -344,9 +344,10 @@ typedef struct x509_purpose_st { #define X509_PURPOSE_SMIME_SIGN 4 #define X509_PURPOSE_SMIME_ENCRYPT 5 #define X509_PURPOSE_CRL_SIGN 6 +#define X509_PURPOSE_ANY 7 #define X509_PURPOSE_MIN 1 -#define X509_PURPOSE_MAX 6 +#define X509_PURPOSE_MAX 7 DECLARE_STACK_OF(X509_PURPOSE)