Am 10.02.20 um 18:59 schrieb Mateusz Markowicz via Openvpn-devel: > when using "--verify-x509-name [hostname] name" hostname will now be > accepted > also when matched against one of the X509v3 Subject Alternative Name IP > or DNS > entries (instead of just Subject's CN). > > see also: https://github.com/OpenVPN/openvpn/pull/136/ > > Signed-off-by: Mateusz Markowicz <[email protected] > <mailto:[email protected]>>
If this should have a chance of being included it needs to cover mbed
TLS as well.
Also documentation in the man page is missing.
> ---
> src/openvpn/options.c | 4 +++
> src/openvpn/ssl_verify.c | 18 +++++++++++---
> src/openvpn/ssl_verify.h | 1 +
> src/openvpn/ssl_verify_backend.h | 7 ++++++
> src/openvpn/ssl_verify_mbedtls.c | 11 +++++++++
> src/openvpn/ssl_verify_openssl.c | 42 ++++++++++++++++++++++++++++++++
> 6 files changed, 80 insertions(+), 3 deletions(-)
>
> diff --git a/src/openvpn/options.c b/src/openvpn/options.c
> index 173a1eea..438dfff0 100644
> --- a/src/openvpn/options.c
> +++ b/src/openvpn/options.c
> @@ -8144,6 +8144,10 @@ add_option(struct options *options,
> {
> type = VERIFY_X509_SUBJECT_RDN_PREFIX;
> }
> + else if (streq(p[2], "subject-alt-name"))
> + {
> + type = VERIFY_X509_SAN;
> + }
> else
> {
> msg(msglevel, "unknown X.509 name type: %s", p[2]);
> diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c
> index 65188d23..6480b5eb 100644
> --- a/src/openvpn/ssl_verify.c
> +++ b/src/openvpn/ssl_verify.c
> @@ -390,15 +390,27 @@ verify_peer_cert(const struct tls_options *opt,
> openvpn_x509_cert_t *peer_cert,
> /* verify X509 name or username against --verify-x509-[user]name */
> if (opt->verify_x509_type != VERIFY_X509_NONE)
> {
> - if ( (opt->verify_x509_type == VERIFY_X509_SUBJECT_DN
> + bool match;
> + if (opt->verify_x509_type == VERIFY_X509_SAN)
> + {
> + bool have_alt_names;
> + match = x509v3_is_host_in_alternative_names(peer_cert,
> opt->verify_x509_name, &have_alt_names)
> + || (!have_alt_names &&
> strcmp(opt->verify_x509_name, common_name) == 0);
I know that this technically correct C but setting a variable in the
first part of via & and then using it in the second part feels like not
good style. I would rather like too a bit more verbose and less clever
code that is easier to understand.
> + }
> + else
> + {
> + match = (opt->verify_x509_type == VERIFY_X509_SUBJECT_DN
> && strcmp(opt->verify_x509_name, subject) == 0)
> || (opt->verify_x509_type == VERIFY_X509_SUBJECT_RDN
> && strcmp(opt->verify_x509_name, common_name) == 0)
> || (opt->verify_x509_type == VERIFY_X509_SUBJECT_RDN_PREFIX
> && strncmp(opt->verify_x509_name, common_name,
> - strlen(opt->verify_x509_name)) == 0) )
> + strlen(opt->verify_x509_name)) == 0);
> + }
> +
> + if (match)
> {
> - msg(D_HANDSHAKE, "VERIFY X509NAME OK: %s", subject);
> + msg(D_HANDSHAKE, "VERIFY X509NAME OK: %s",
> opt->verify_x509_name);
This changes the log message. If you want to verify that the cert prefix
with OVPN-client or something you don't get to see what certificate you
accepted anymore. If you want to log opt->verify_x509_name that needs to
be in addition.
> }
> else
> {
> diff --git a/src/openvpn/ssl_verify.h b/src/openvpn/ssl_verify.h
> index c54b89a6..1295e76b 100644
> --- a/src/openvpn/ssl_verify.h
> +++ b/src/openvpn/ssl_verify.h
> @@ -64,6 +64,7 @@ struct cert_hash_set {
> #define VERIFY_X509_SUBJECT_DN 1
> #define VERIFY_X509_SUBJECT_RDN 2
> #define VERIFY_X509_SUBJECT_RDN_PREFIX 3
> +#define VERIFY_X509_SAN 4
>
> #define TLS_AUTHENTICATION_SUCCEEDED 0
> #define TLS_AUTHENTICATION_FAILED 1
> diff --git a/src/openvpn/ssl_verify_backend.h
> b/src/openvpn/ssl_verify_backend.h
> index d6b31bfa..927a5a29 100644
> --- a/src/openvpn/ssl_verify_backend.h
> +++ b/src/openvpn/ssl_verify_backend.h
> @@ -268,4 +268,11 @@ result_t x509_write_pem(FILE *peercert_file,
> openvpn_x509_cert_t *peercert);
> */
> bool tls_verify_crl_missing(const struct tls_options *opt);
>
> +/**
> + * Return true iff {host} was found in {cert} Subject Alternative Names
> DNS or IP entries.
> + * If {has_alt_names} != NULL it'll return true iff Subject Alternative
> Names were defined
> + * for {cert}.
> + */
> +bool x509v3_is_host_in_alternative_names(openvpn_x509_cert_t *cert,
> const char *host, bool *has_alt_names);
> +
> #endif /* SSL_VERIFY_BACKEND_H_ */
> diff --git a/src/openvpn/ssl_verify_mbedtls.c
> b/src/openvpn/ssl_verify_mbedtls.c
> index fd31bbbd..2f2e04be 100644
> --- a/src/openvpn/ssl_verify_mbedtls.c
> +++ b/src/openvpn/ssl_verify_mbedtls.c
> @@ -245,6 +245,17 @@ x509_get_subject(mbedtls_x509_crt *cert, struct
> gc_arena *gc)
> return subject;
> }
>
> +bool
> +x509v3_is_host_in_alternative_names(mbedtls_x509_crt *cert, const char
> *host, bool *has_alt_names)
> +{
> + msg(M_WARN, "Missing support for subject alternative names in
> mbedtls.");
> + if (has_alt_names != NULL)
> + {
> + *has_alt_names = false;
> + }
> + return false;
> +}
*has_alt_names = (has_alt_names != NULL);
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Openvpn-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openvpn-devel
