Multiple verifier reference identities.
Implemented as STACK_OF(OPENSSL_STRING).
(cherry picked from commit 8abffa4a73
)
This commit is contained in:
parent
7f7e11ee5c
commit
449d864515
@ -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;
|
||||
|
@ -719,12 +719,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)
|
||||
{
|
||||
int i;
|
||||
int 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, 0, 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, 0, id->hostflags) <= 0)
|
||||
if (id->hosts && !check_hosts(x, id) <= 0)
|
||||
{
|
||||
if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
|
||||
return 0;
|
||||
|
@ -560,6 +560,8 @@ 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);
|
||||
int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
|
||||
const unsigned char *name, size_t namelen);
|
||||
void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
|
||||
unsigned int flags);
|
||||
int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
|
||||
|
@ -69,6 +69,63 @@
|
||||
|
||||
/* X509_VERIFY_PARAM functions */
|
||||
|
||||
#define SET_HOST 0
|
||||
#define ADD_HOST 1
|
||||
|
||||
static char *str_copy(const 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, except perhaps as final byte.
|
||||
* XXX: Do we need to push an error onto the error stack?
|
||||
*/
|
||||
if (namelen == 0)
|
||||
namelen = name ? strlen((char *)name) : 0;
|
||||
else if (name && memchr(name, '\0', namelen > 1 ? namelen-1 : namelen))
|
||||
return 0;
|
||||
if (name && name[namelen-1] == '\0')
|
||||
--namelen;
|
||||
|
||||
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;
|
||||
@ -87,10 +144,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)
|
||||
{
|
||||
@ -234,11 +291,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, 0))
|
||||
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))
|
||||
@ -398,7 +467,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,
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
X509_VERIFY_PARAM_set_flags, X509_VERIFY_PARAM_clear_flags, X509_VERIFY_PARAM_get_flags, X509_VERIFY_PARAM_set_purpose, X509_VERIFY_PARAM_set_trust, X509_VERIFY_PARAM_set_depth, X509_VERIFY_PARAM_get_depth, X509_VERIFY_PARAM_set_time, X509_VERIFY_PARAM_add0_policy, X509_VERIFY_PARAM_set1_policies, X509_VERIFY_PARAM_set1_host, X509_VERIFY_PARAM_set_hostflags, X509_VERIFY_PARAM_set1_email, X509_VERIFY_PARAM_set1_ip, X509_VERIFY_PARAM_set1_ip_asc - X509 verification parameters
|
||||
X509_VERIFY_PARAM_set_flags, X509_VERIFY_PARAM_clear_flags, X509_VERIFY_PARAM_get_flags, X509_VERIFY_PARAM_set_purpose, X509_VERIFY_PARAM_set_trust, X509_VERIFY_PARAM_set_depth, X509_VERIFY_PARAM_get_depth, X509_VERIFY_PARAM_set_time, X509_VERIFY_PARAM_add0_policy, X509_VERIFY_PARAM_set1_policies, X509_VERIFY_PARAM_set1_host, X509_VERIFY_PARAM_add1_host, X509_VERIFY_PARAM_set_hostflags, X509_VERIFY_PARAM_set1_email, X509_VERIFY_PARAM_set1_ip, X509_VERIFY_PARAM_set1_ip_asc - X509 verification parameters
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
@ -28,6 +28,8 @@ X509_VERIFY_PARAM_set_flags, X509_VERIFY_PARAM_clear_flags, X509_VERIFY_PARAM_ge
|
||||
|
||||
int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
|
||||
const unsigned char *name, size_t namelen);
|
||||
int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param,
|
||||
const unsigned char *name, size_t namelen);
|
||||
void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param,
|
||||
unsigned int flags);
|
||||
int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
|
||||
@ -72,16 +74,26 @@ X509_VERIFY_PARAM_set_depth() sets the maximum verification depth to B<depth>.
|
||||
That is the maximum number of untrusted CA certificates that can appear in a
|
||||
chain.
|
||||
|
||||
X509_VERIFY_PARAM_set1_host() sets the expected DNS hostname to B<name>. If
|
||||
B<name> is NUL-terminated, B<namelen> may be zero, otherwise B<namelen> must
|
||||
be set to the length of B<name>. When a hostname is specified, certificate
|
||||
verification automatically invokes L<X509_check_host(3)> with flags equal to
|
||||
the B<flags> argument given to B<X509_VERIFY_PARAM_set_hostflags()> (default
|
||||
zero). Applications are strongly advised to use this interface in preference
|
||||
to explicitly calling L<X509_check_host(3)>, hostname checks are
|
||||
out of scope with the DANE-EE(3) certificate usage, and the internal
|
||||
check will be suppressed as appropriate when DANE support is added
|
||||
to OpenSSL.
|
||||
X509_VERIFY_PARAM_set1_host() sets the expected DNS hostname to
|
||||
B<name> clearing any previously specified host name or names. If
|
||||
B<name> is NULL, or empty the list of hostnames is cleared, and
|
||||
name checks are not performed on the peer certificate. If B<name>
|
||||
is NUL-terminated, B<namelen> may be zero, otherwise B<namelen>
|
||||
must be set to the length of B<name>. When a hostname is specified,
|
||||
certificate verification automatically invokes L<X509_check_host(3)>
|
||||
with flags equal to the B<flags> argument given to
|
||||
B<X509_VERIFY_PARAM_set_hostflags()> (default zero). Applications
|
||||
are strongly advised to use this interface in preference to explicitly
|
||||
calling L<X509_check_host(3)>, hostname checks are out of scope
|
||||
with the DANE-EE(3) certificate usage, and the internal check will
|
||||
be suppressed as appropriate when DANE support is added to OpenSSL.
|
||||
|
||||
X509_VERIFY_PARAM_add1_host() adds B<name> as an additional reference
|
||||
identifer that can match the peer's certificate. Any previous names
|
||||
set via X509_VERIFY_PARAM_set1_host() or X509_VERIFY_PARAM_add1_host()
|
||||
are retained, no change is made if B<name> is NULL or empty. When
|
||||
multiple names are configured, the peer is considered verified when
|
||||
any name matches.
|
||||
|
||||
X509_VERIFY_PARAM_set1_email() sets the expected RFC822 email address to
|
||||
B<email>. If B<email> is NUL-terminated, B<emaillen> may be zero, otherwise
|
||||
|
@ -109,6 +109,7 @@ X509_check_ip_asc() can also return -2 if the IP address string is malformed.
|
||||
|
||||
L<SSL_get_verify_result(3)|SSL_get_verify_result(3)>,
|
||||
L<X509_VERIFY_PARAM_set1_host(3)|X509_VERIFY_PARAM_set1_host(3)>,
|
||||
L<X509_VERIFY_PARAM_add1_host(3)|X509_VERIFY_PARAM_add1_host(3)>,
|
||||
L<X509_VERIFY_PARAM_set1_email(3)|X509_VERIFY_PARAM_set1_email(3)>,
|
||||
L<X509_VERIFY_PARAM_set1_ip(3)|X509_VERIFY_PARAM_set1_ip(3)>,
|
||||
L<X509_VERIFY_PARAM_set1_ipasc(3)|X509_VERIFY_PARAM_set1_ipasc(3)>
|
||||
|
Loading…
Reference in New Issue
Block a user