diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-03-22 09:00:09 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-03-23 11:38:37 +0100 |
commit | 96bb0aad1f3f24d0812a426951c04df6a1a61332 (patch) | |
tree | a2545dd763f603a13745018fe3a74ad35c87f3c8 | |
parent | 41af39b816fa26493c4f2268255430e4a7d794b6 (diff) | |
download | gnutls-96bb0aad1f3f24d0812a426951c04df6a1a61332.tar.gz |
Introduced GNUTLS_DT_IP_ADDRESS
This allows verifying an IP address using gnutls_certificate_verify_peers()
or gnutls_x509_trust_list_verify_crt2().
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r-- | lib/includes/gnutls/gnutls.h.in | 8 | ||||
-rw-r--r-- | lib/x509/verify-high.c | 37 |
2 files changed, 38 insertions, 7 deletions
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in index 8e26a122a7..31a1fdcbe2 100644 --- a/lib/includes/gnutls/gnutls.h.in +++ b/lib/includes/gnutls/gnutls.h.in @@ -1417,6 +1417,7 @@ void gnutls_session_set_verify_function(gnutls_session_t session, gnutls_certifi * @GNUTLS_DT_UNKNOWN: Unknown data type. * @GNUTLS_DT_DNS_HOSTNAME: The data contain a null-terminated DNS hostname; the hostname will be * matched using the RFC6125 rules. + * @GNUTLS_DT_IP_ADDRESS: The data contain a raw IP address (4 or 16 bytes) - since 3.6.0 * @GNUTLS_DT_RFC822NAME: The data contain a null-terminated email address; the email will be * matched against the RFC822Name field of the certificate, or the EMAIL DN component if the * former isn't available. Prior to matching the email address will be converted to ACE @@ -1426,13 +1427,16 @@ void gnutls_session_set_verify_function(gnutls_session_t session, gnutls_certifi * * Enumeration of different typed-data options. They are used as input to certificate * verification functions to provide information about the name and purpose of the - * certificate. Only a single option of a type can be provided to the relevant functions. + * certificate. Only a single option of a type can be provided to the relevant functions + * (i.e., options %GNUTLS_DT_DNS_HOSTNAME, %GNUTLS_DT_IP_ADDRESS and + * %GNUTLS_DT_RFC822NAME cannot be combined). */ typedef enum { GNUTLS_DT_UNKNOWN = 0, GNUTLS_DT_DNS_HOSTNAME = 1, GNUTLS_DT_KEY_PURPOSE_OID = 2, - GNUTLS_DT_RFC822NAME = 3 + GNUTLS_DT_RFC822NAME = 3, + GNUTLS_DT_IP_ADDRESS = 4 } gnutls_vdata_types_t; typedef struct { diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c index 1749d49b10..9d9d0956cd 100644 --- a/lib/x509/verify-high.c +++ b/lib/x509/verify-high.c @@ -1202,7 +1202,7 @@ gnutls_x509_trust_list_verify_crt(gnutls_x509_trust_list_t list, * flags. * * Additional verification parameters are possible via the @data types; the - * acceptable types are %GNUTLS_DT_DNS_HOSTNAME and %GNUTLS_DT_KEY_PURPOSE_OID. + * acceptable types are %GNUTLS_DT_DNS_HOSTNAME, %GNUTLS_DT_IP_ADDRESS and %GNUTLS_DT_KEY_PURPOSE_OID. * The former accepts as data a null-terminated hostname, and the latter a null-terminated * object identifier (e.g., %GNUTLS_KP_TLS_WWW_SERVER). * If a DNS hostname is provided then this function will compare @@ -1237,6 +1237,8 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list, gnutls_x509_crt_t sorted[DEFAULT_MAX_VERIFY_DEPTH]; const char *hostname = NULL, *purpose = NULL, *email = NULL; unsigned hostname_size = 0; + unsigned have_set_name = 0; + gnutls_datum_t ip = {NULL, 0}; if (cert_list == NULL || cert_list_size < 1) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); @@ -1247,10 +1249,22 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list, if (data[i].size > 0) { hostname_size = data[i].size; } - if (email != NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + if (have_set_name != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + have_set_name = 1; + } else if (data[i].type == GNUTLS_DT_IP_ADDRESS) { + if (data[i].size > 0) { + ip.data = data[i].data; + ip.size = data[i].size; + } + + if (have_set_name != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + have_set_name = 1; } else if (data[i].type == GNUTLS_DT_RFC822NAME) { email = (void*)data[i].data; - if (hostname != NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + + if (have_set_name != 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + have_set_name = 1; } else if (data[i].type == GNUTLS_DT_KEY_PURPOSE_OID) { purpose = (void*)data[i].data; } @@ -1349,15 +1363,28 @@ gnutls_x509_trust_list_verify_crt2(gnutls_x509_trust_list_t list, if (hostname) { ret = gnutls_x509_crt_check_hostname2(cert_list[0], hostname, flags); - if (ret == 0) + if (ret == 0) { + gnutls_assert(); *voutput |= GNUTLS_CERT_UNEXPECTED_OWNER|GNUTLS_CERT_INVALID; + } + } + + if (ip.data) { + ret = + gnutls_x509_crt_check_ip(cert_list[0], ip.data, ip.size, flags); + if (ret == 0) { + gnutls_assert(); + *voutput |= GNUTLS_CERT_UNEXPECTED_OWNER|GNUTLS_CERT_INVALID; + } } if (email) { ret = gnutls_x509_crt_check_email(cert_list[0], email, 0); - if (ret == 0) + if (ret == 0) { + gnutls_assert(); *voutput |= GNUTLS_CERT_UNEXPECTED_OWNER|GNUTLS_CERT_INVALID; + } } /* CRL checks follow */ |