diff options
author | Rob Austein <sra@hactrn.net> | 2006-08-16 05:56:52 +0000 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2006-08-16 05:56:52 +0000 |
commit | e8f93a484d9640c8c439e46a42cb878d7c2ea1de (patch) | |
tree | 86095029018da2f75acd91ad1ccc2f033a6b15f4 /openssl | |
parent | 3b0de4f4e2037f15b435bdfafe06abccd20389c6 (diff) |
Rewrite address extention path validation to work bottom up, using
cached extensions.
svn path=/openssl/trunk/crypto/x509v3/v3_addr.c; revision=159
Diffstat (limited to 'openssl')
-rw-r--r-- | openssl/trunk/crypto/x509v3/v3_addr.c | 111 | ||||
-rw-r--r-- | openssl/trunk/crypto/x509v3/v3err.c | 1 | ||||
-rw-r--r-- | openssl/trunk/crypto/x509v3/x509v3.h | 1 |
3 files changed, 50 insertions, 63 deletions
diff --git a/openssl/trunk/crypto/x509v3/v3_addr.c b/openssl/trunk/crypto/x509v3/v3_addr.c index dfd77608..131aeffb 100644 --- a/openssl/trunk/crypto/x509v3/v3_addr.c +++ b/openssl/trunk/crypto/x509v3/v3_addr.c @@ -949,91 +949,76 @@ static int addr_contains(IPAddressOrRanges *parent, */ int v3_addr_validate_path(X509_STORE_CTX *ctx) { - IPAddrBlocks *parent = NULL, *child = NULL; - int i, j, has_ext, ret = 1; + IPAddrBlocks *child = NULL; + int i, j, ret = 1; X509 *x; assert(ctx->verify_cb); /* - * Start with the ancestral cert. It can't inherit anything. + * Start with the target certificate. If it doesn't have the + * extension, we're done. */ - i = sk_X509_num(ctx->chain) - 1; - x = sk_X509_value(ctx->chain, i); + x = sk_X509_value(ctx->chain, 0); assert(x != NULL); - parent = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL); - has_ext = parent != NULL; - if (has_ext) { - for (j = 0; j < sk_IPAddressFamily_num(parent); j++) { - IPAddressFamily *fp = sk_IPAddressFamily_value(parent, j); - assert(fp != NULL && fp->ipAddressChoice != NULL); - if (fp->ipAddressChoice->type == IPAddressChoice_inherit) { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - goto done; /* callback insisted on continuing */ - } - } - sk_IPAddressFamily_set_cmp_func(parent, IPAddressFamily_cmp); + if (x->rfc3779_addr == NULL) + goto done; + + /* + * Has extension, need to check the whole chain. This requires a + * scratch stack, initially populated with a copy of the target + * certificate's extension. + */ + sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp); + if ((child = sk_IPAddressFamily_dup(x->rfc3779_addr)) == NULL) { + X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH, ERR_R_MALLOC_FAILURE); + goto done; } /* - * Now walk down the chain. No cert may list resources that its + * Now walk up the chain. No cert may list resources that its * parent doesn't list. */ - while (--i >= 0) { + for (i = 1; i < sk_X509_num(ctx->chain); i++) { x = sk_X509_value(ctx->chain, i); assert(x != NULL); - assert(child == NULL); - child = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL); - if (child == NULL) { - has_ext = 0; - } else if (!has_ext) { + if (x->rfc3779_addr == NULL) { validation_err(X509_V_ERR_UNNESTED_RESOURCE); - has_ext = 1; /* callback insists on continuing */ + continue; } - - if (has_ext) { - /* - * Clean out address families that child doesn't use. - * (Need to do this before modifying child....) - */ - sk_IPAddressFamily_set_cmp_func(child, IPAddressFamily_cmp); - for (j = 0; j < sk_IPAddressFamily_num(parent); j++) { - IPAddressFamily *fp = sk_IPAddressFamily_value(parent, j); - if (sk_IPAddressFamily_find(child, fp) < 0) { - IPAddressFamily_free(fp); - sk_IPAddressFamily_delete(parent, j); - --j; - } - } - /* - * Check all remaining address families in child. - */ - for (j = 0; j < sk_IPAddressFamily_num(child); j++) { - IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); - int k = sk_IPAddressFamily_find(parent, fc); - if (k < 0) + sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, IPAddressFamily_cmp); + for (j = 0; j < sk_IPAddressFamily_num(child); j++) { + IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); + int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc); + IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, k); + if (fp == NULL) { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } else if (fp->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) { + if (fc->ipAddressChoice->type == IPAddressChoice_inherit || + addr_contains(fp->ipAddressChoice->u.addressesOrRanges, + fc->ipAddressChoice->u.addressesOrRanges, + length_from_afi(afi_from_addressfamily(fc)))) + sk_IPAddressFamily_set(child, j, fp); + else validation_err(X509_V_ERR_UNNESTED_RESOURCE); - if (k >= 0 && - fc->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) { - IPAddressFamily *fp = sk_IPAddressFamily_value(parent, k); - if (!addr_contains(fp->ipAddressChoice->u.addressesOrRanges, - fc->ipAddressChoice->u.addressesOrRanges, - length_from_afi(afi_from_addressfamily(fc)))) - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - IPAddressFamily_free(fp); - sk_IPAddressFamily_set(parent, k, fc); - sk_IPAddressFamily_delete(child, j); - --j; - } } } - sk_IPAddressFamily_pop_free(child, IPAddressFamily_free); - child = NULL; + } + + /* + * Trust anchor can't inherit. + */ + if (x->rfc3779_addr != NULL) { + for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) { + IPAddressFamily *fp = sk_IPAddressFamily_value(x->rfc3779_addr, j); + if (fp->ipAddressChoice->type == IPAddressChoice_inherit && + sk_IPAddressFamily_find(child, fp) >= 0) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } } done: - sk_IPAddressFamily_pop_free(parent, IPAddressFamily_free); - sk_IPAddressFamily_pop_free(child, IPAddressFamily_free); + sk_IPAddressFamily_free(child); return ret; } diff --git a/openssl/trunk/crypto/x509v3/v3err.c b/openssl/trunk/crypto/x509v3/v3err.c index 04073ca6..2393e8c2 100644 --- a/openssl/trunk/crypto/x509v3/v3err.c +++ b/openssl/trunk/crypto/x509v3/v3err.c @@ -116,6 +116,7 @@ static ERR_STRING_DATA X509V3_str_functs[]= {ERR_FUNC(X509V3_F_V2I_POLICY_CONSTRAINTS), "V2I_POLICY_CONSTRAINTS"}, {ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS), "V2I_POLICY_MAPPINGS"}, {ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT), "V2I_SUBJECT_ALT"}, +{ERR_FUNC(X509V3_F_V3_ADDR_VALIDATE_PATH), "v3_addr_validate_path"}, {ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION), "V3_GENERIC_EXTENSION"}, {ERR_FUNC(X509V3_F_X509V3_ADD1_I2D), "X509V3_add1_i2d"}, {ERR_FUNC(X509V3_F_X509V3_ADD_VALUE), "X509V3_add_value"}, diff --git a/openssl/trunk/crypto/x509v3/x509v3.h b/openssl/trunk/crypto/x509v3/x509v3.h index ee642a44..44faf17f 100644 --- a/openssl/trunk/crypto/x509v3/x509v3.h +++ b/openssl/trunk/crypto/x509v3/x509v3.h @@ -788,6 +788,7 @@ void ERR_load_X509V3_strings(void); #define X509V3_F_V2I_POLICY_CONSTRAINTS 146 #define X509V3_F_V2I_POLICY_MAPPINGS 145 #define X509V3_F_V2I_SUBJECT_ALT 154 +#define X509V3_F_V3_ADDR_VALIDATE_PATH 160 #define X509V3_F_V3_GENERIC_EXTENSION 116 #define X509V3_F_X509V3_ADD1_I2D 140 #define X509V3_F_X509V3_ADD_VALUE 105 |