From 589963f79e114256d895173d7edba9adae1978bd Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Wed, 11 Feb 2015 12:18:56 -0800 Subject: Multiple verifier reference identities. (Imported from upstream's 8abffa4a73fcbf6536e0a42d736ed9211a8204ea, 9624b50d51de25bb2e3a72e81fe45032d80ea5c2 and 41e3ebd5abacfdf98461cdeb6fa97a4175b7aad3.) Change-Id: Ic9099eb5704b19b4500229e89351371cc6184f9d --- crypto/x509/vpm_int.h | 2 +- crypto/x509/x509_vfy.c | 17 +++++++++- crypto/x509/x509_vpm.c | 88 +++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 97 insertions(+), 10 deletions(-) (limited to 'crypto') diff --git a/crypto/x509/vpm_int.h b/crypto/x509/vpm_int.h index dd33f883..6b670af5 100644 --- a/crypto/x509/vpm_int.h +++ b/crypto/x509/vpm_int.h @@ -60,7 +60,7 @@ struct X509_VERIFY_PARAM_ID_st { - unsigned char *host; /* If not NULL hostname to match */ + STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */ unsigned int hostflags; /* Flags to control matching features */ unsigned char *email; /* If not NULL email address to match */ size_t emaillen; diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 1650b77a..29a25455 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -704,12 +704,27 @@ static int check_id_error(X509_STORE_CTX *ctx, int errcode) return ctx->verify_cb(0, ctx); } +static int check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id) + { + size_t i; + size_t n = sk_OPENSSL_STRING_num(id->hosts); + unsigned char *name; + + for (i = 0; i < n; ++i) + { + name = (unsigned char *)sk_OPENSSL_STRING_value(id->hosts, i); + if (X509_check_host(x, name, strlen((const char*) name), id->hostflags) > 0) + return 1; + } + return n == 0; + } + static int check_id(X509_STORE_CTX *ctx) { X509_VERIFY_PARAM *vpm = ctx->param; X509_VERIFY_PARAM_ID *id = vpm->id; X509 *x = ctx->cert; - if (id->host && X509_check_host(x, id->host, strlen((const char*) id->host), id->hostflags) <= 0) + if (id->hosts && check_hosts(x, id) <= 0) { if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH)) return 0; diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c index 7f646d82..d3266379 100644 --- a/crypto/x509/x509_vpm.c +++ b/crypto/x509/x509_vpm.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,59 @@ /* X509_VERIFY_PARAM functions */ +#define SET_HOST 0 +#define ADD_HOST 1 + +static char *str_copy(char *s) { return OPENSSL_strdup(s); } +static void str_free(char *s) { OPENSSL_free(s); } + +#define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free) + +static int int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode, + const unsigned char *name, size_t namelen) + { + char *copy; + + /* + * Refuse names with embedded NUL bytes. + * XXX: Do we need to push an error onto the error stack? + */ + if (name && memchr(name, '\0', namelen)) + return 0; + + if (mode == SET_HOST && id->hosts) + { + string_stack_free(id->hosts); + id->hosts = NULL; + } + if (name == NULL || namelen == 0) + return 1; + + copy = BUF_strndup((char *)name, namelen); + if (copy == NULL) + return 0; + + if (id->hosts == NULL && + (id->hosts = sk_OPENSSL_STRING_new_null()) == NULL) + { + OPENSSL_free(copy); + return 0; + } + + if (!sk_OPENSSL_STRING_push(id->hosts, copy)) + { + OPENSSL_free(copy); + if (sk_OPENSSL_STRING_num(id->hosts) == 0) + { + sk_OPENSSL_STRING_free(id->hosts); + id->hosts = NULL; + } + return 0; + } + + return 1; + } + static void x509_verify_param_zero(X509_VERIFY_PARAM *param) { X509_VERIFY_PARAM_ID *paramid; @@ -84,10 +138,10 @@ static void x509_verify_param_zero(X509_VERIFY_PARAM *param) param->policies = NULL; } paramid = param->id; - if (paramid->host) + if (paramid->hosts) { - OPENSSL_free(paramid->host); - paramid->host = NULL; + string_stack_free(paramid->hosts); + paramid->hosts = NULL; } if (paramid->email) { @@ -231,11 +285,23 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, return 0; } - if (test_x509_verify_param_copy_id(host, NULL)) + /* Copy the host flags if and only if we're copying the host list */ + if (test_x509_verify_param_copy_id(hosts, NULL)) { - if (!X509_VERIFY_PARAM_set1_host(dest, id->host, strlen((const char*) id->host))) - return 0; - dest->id->hostflags = id->hostflags; + if (dest->id->hosts) + { + string_stack_free(dest->id->hosts); + dest->id->hosts = NULL; + } + if (id->hosts) + { + dest->id->hosts = + sk_OPENSSL_STRING_deep_copy(id->hosts, + str_copy, str_free); + if (dest->id->hosts == NULL) + return 0; + dest->id->hostflags = id->hostflags; + } } if (test_x509_verify_param_copy_id(email, NULL)) @@ -395,7 +461,13 @@ int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, const unsigned char *name, size_t namelen) { - return int_x509_param_set1(¶m->id->host, NULL, name, namelen); + return int_x509_param_set_hosts(param->id, SET_HOST, name, namelen); + } + +int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const unsigned char *name, size_t namelen) + { + return int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen); } void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, -- cgit v1.2.3