summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-03-22 09:00:09 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-03-23 11:38:37 +0100
commit96bb0aad1f3f24d0812a426951c04df6a1a61332 (patch)
treea2545dd763f603a13745018fe3a74ad35c87f3c8
parent41af39b816fa26493c4f2268255430e4a7d794b6 (diff)
downloadgnutls-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.in8
-rw-r--r--lib/x509/verify-high.c37
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 */