提交 55a6250f 编写于 作者: V Viktor Dukhovni

Skip CN DNS name constraint checks when not needed

Only check the CN against DNS name contraints if the
`X509_CHECK_FLAG_NEVER_CHECK_SUBJECT` flag is not set, and either the
certificate has no DNS subject alternative names or the
`X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT` flag is set.

Add pertinent documentation, and touch up some stale text about
name checks and DANE.
Reviewed-by: NMatt Caswell <matt@openssl.org>
Reviewed-by: NTim Hudson <tjh@openssl.org>
上级 d02d80b2
...@@ -560,6 +560,27 @@ static int check_chain_extensions(X509_STORE_CTX *ctx) ...@@ -560,6 +560,27 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
return 1; return 1;
} }
static int has_san_id(X509 *x, int gtype)
{
int i;
int ret = 0;
GENERAL_NAMES *gs = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
if (gs == NULL)
return 0;
for (i = 0; i < sk_GENERAL_NAME_num(gs); i++) {
GENERAL_NAME *g = sk_GENERAL_NAME_value(gs, i);
if (g->type == gtype) {
ret = 1;
break;
}
}
GENERAL_NAMES_free(gs);
return ret;
}
static int check_name_constraints(X509_STORE_CTX *ctx) static int check_name_constraints(X509_STORE_CTX *ctx)
{ {
int i; int i;
...@@ -658,7 +679,12 @@ static int check_name_constraints(X509_STORE_CTX *ctx) ...@@ -658,7 +679,12 @@ static int check_name_constraints(X509_STORE_CTX *ctx)
int rv = NAME_CONSTRAINTS_check(x, nc); int rv = NAME_CONSTRAINTS_check(x, nc);
/* If EE certificate check commonName too */ /* If EE certificate check commonName too */
if (rv == X509_V_OK && i == 0) if (rv == X509_V_OK && i == 0
&& (ctx->param->hostflags
& X509_CHECK_FLAG_NEVER_CHECK_SUBJECT) == 0
&& ((ctx->param->hostflags
& X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT) != 0
|| !has_san_id(x, GEN_DNS)))
rv = NAME_CONSTRAINTS_check_CN(x, nc); rv = NAME_CONSTRAINTS_check_CN(x, nc);
switch (rv) { switch (rv) {
......
...@@ -299,9 +299,9 @@ int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) ...@@ -299,9 +299,9 @@ int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc)
static int cn2dnsid(ASN1_STRING *cn, unsigned char **dnsid, size_t *idlen) static int cn2dnsid(ASN1_STRING *cn, unsigned char **dnsid, size_t *idlen)
{ {
int utf8_length; /* Return type of ASN1_STRING_to_UTF8 */ int utf8_length;
int i;
unsigned char *utf8_value; unsigned char *utf8_value;
int i;
int isdnsname = 0; int isdnsname = 0;
/* Don't leave outputs uninitialized */ /* Don't leave outputs uninitialized */
...@@ -337,8 +337,10 @@ static int cn2dnsid(ASN1_STRING *cn, unsigned char **dnsid, size_t *idlen) ...@@ -337,8 +337,10 @@ static int cn2dnsid(ASN1_STRING *cn, unsigned char **dnsid, size_t *idlen)
--utf8_length; --utf8_length;
/* Reject *embedded* NULs */ /* Reject *embedded* NULs */
if ((size_t)utf8_length != strlen((char *)utf8_value)) if ((size_t)utf8_length != strlen((char *)utf8_value)) {
return X509_V_ERR_UNSPECIFIED; OPENSSL_free(utf8_value);
return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX;
}
/* /*
* XXX: Deviation from strict DNS name syntax, also check names with '_' * XXX: Deviation from strict DNS name syntax, also check names with '_'
...@@ -389,14 +391,12 @@ static int cn2dnsid(ASN1_STRING *cn, unsigned char **dnsid, size_t *idlen) ...@@ -389,14 +391,12 @@ static int cn2dnsid(ASN1_STRING *cn, unsigned char **dnsid, size_t *idlen)
} }
/* /*
* Check CN against DNS-ID name constraints, provided no DNS-ID * Check CN against DNS-ID name constraints.
* subjectAlternativeName values are present in the certificate.
*/ */
int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc) int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc)
{ {
int r, i; int r, i;
GENERAL_NAMES *gens = NULL; X509_NAME *nm = X509_get_subject_name(x);
X509_NAME *nm;
ASN1_STRING stmp; ASN1_STRING stmp;
GENERAL_NAME gntmp; GENERAL_NAME gntmp;
...@@ -405,21 +405,6 @@ int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc) ...@@ -405,21 +405,6 @@ int NAME_CONSTRAINTS_check_CN(X509 *x, NAME_CONSTRAINTS *nc)
gntmp.type = GEN_DNS; gntmp.type = GEN_DNS;
gntmp.d.dNSName = &stmp; gntmp.d.dNSName = &stmp;
gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
if (gens != NULL) {
for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
GENERAL_NAME *gen = sk_GENERAL_NAME_value(gens, i);
if (gen->type == GEN_DNS) {
GENERAL_NAMES_free(gens);
return X509_V_OK;
}
}
GENERAL_NAMES_free(gens);
}
nm = X509_get_subject_name(x);
/* Process any commonName attributes in subject name */ /* Process any commonName attributes in subject name */
for (i = -1;;) { for (i = -1;;) {
......
...@@ -56,7 +56,7 @@ is cleared or freed, or a renegotiation takes place. Applications ...@@ -56,7 +56,7 @@ is cleared or freed, or a renegotiation takes place. Applications
must not free the return value. must not free the return value.
SSL clients are advised to use these functions in preference to SSL clients are advised to use these functions in preference to
explicitly calling L<X509_check_host(3)>. Hostname checks are out explicitly calling L<X509_check_host(3)>. Hostname checks may be out
of scope with the RFC7671 DANE-EE(3) certificate usage, and the of scope with the RFC7671 DANE-EE(3) certificate usage, and the
internal check will be suppressed as appropriate when DANE is internal check will be suppressed as appropriate when DANE is
enabled. enabled.
......
...@@ -133,14 +133,29 @@ B<name> clearing any previously specified host name or names. If ...@@ -133,14 +133,29 @@ B<name> clearing any previously specified host name or names. If
B<name> is NULL, or empty the list of hostnames is cleared, and 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> name checks are not performed on the peer certificate. If B<name>
is NUL-terminated, B<namelen> may be zero, otherwise B<namelen> 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, must be set to the length of B<name>.
When a hostname is specified,
certificate verification automatically invokes L<X509_check_host(3)> certificate verification automatically invokes L<X509_check_host(3)>
with flags equal to the B<flags> argument given to with flags equal to the B<flags> argument given to
X509_VERIFY_PARAM_set_hostflags() (default zero). Applications X509_VERIFY_PARAM_set_hostflags() (default zero). Applications
are strongly advised to use this interface in preference to explicitly are strongly advised to use this interface in preference to explicitly
calling L<X509_check_host(3)>, hostname checks are out of scope calling L<X509_check_host(3)>, hostname checks may be out of scope
with the DANE-EE(3) certificate usage, and the internal check will with the DANE-EE(3) certificate usage, and the internal check will
be suppressed as appropriate when DANE support is added to OpenSSL. be suppressed as appropriate when DANE verification is enabled.
When the subject CommonName will not be ignored, whether as a result of the
B<X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT> host flag, or because no DNS subject
alternative names are present in the certificate, any DNS name constraints in
issuer certificates apply to the subject CommonName as well as the subject
alternative name extension.
When the subject CommonName will be ignored, whether as a result of the
B<X509_CHECK_FLAG_NEVER_CHECK_SUBJECT> host flag, or because some DNS subject
alternative names are present in the certificate, DNS name constraints in
issuer certificates will not be applied to the subject DN.
As described in X509_check_host(3) the B<X509_CHECK_FLAG_NEVER_CHECK_SUBJECT>
flag takes precendence over the B<X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT> flag.
X509_VERIFY_PARAM_get_hostflags() returns any host flags previously set via a X509_VERIFY_PARAM_get_hostflags() returns any host flags previously set via a
call to X509_VERIFY_PARAM_set_hostflags(). call to X509_VERIFY_PARAM_set_hostflags().
......
...@@ -93,6 +93,9 @@ consider the subject DN even if the certificate contains no subject alternative ...@@ -93,6 +93,9 @@ consider the subject DN even if the certificate contains no subject alternative
names of the right type (DNS name or email address as appropriate); the default names of the right type (DNS name or email address as appropriate); the default
is to use the subject DN when no corresponding subject alternative names are is to use the subject DN when no corresponding subject alternative names are
present. present.
If both B<X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT> and
B<X509_CHECK_FLAG_NEVER_CHECK_SUBJECT> are specified, the latter takes
precedence and the subject DN is not checked for matching names.
If set, B<X509_CHECK_FLAG_NO_WILDCARDS> disables wildcard If set, B<X509_CHECK_FLAG_NO_WILDCARDS> disables wildcard
expansion; this only applies to B<X509_check_host>. expansion; this only applies to B<X509_check_host>.
...@@ -128,9 +131,9 @@ NULs. ...@@ -128,9 +131,9 @@ NULs.
Applications are encouraged to use X509_VERIFY_PARAM_set1_host() Applications are encouraged to use X509_VERIFY_PARAM_set1_host()
rather than explicitly calling L<X509_check_host(3)>. Host name rather than explicitly calling L<X509_check_host(3)>. Host name
checks are out of scope with the DANE-EE(3) certificate usage, checks may be out of scope with the DANE-EE(3) certificate usage,
and the internal checks will be suppressed as appropriate when and the internal checks will be suppressed as appropriate when
DANE support is added to OpenSSL. DANE support is enabled.
=head1 SEE ALSO =head1 SEE ALSO
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册