[glib-networking] gnutls: refactor and extend IP altname check
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking] gnutls: refactor and extend IP altname check
- Date: Mon, 21 Jul 2014 16:29:37 +0000 (UTC)
commit f60379d2e1d64999c04d0f213def319de66be3a3
Author: Dan Winship <danw gnome org>
Date: Mon Jul 21 12:27:34 2014 -0400
gnutls: refactor and extend IP altname check
Refactor g_tls_certificate_gnutls_verify_identity() and extend the IP
address altname code to handle GInetSocketAddress identities as well.
Extend tls/tests/certificate.c to check that case as well, and also
check that incorrect IP addresses (as GNetworkAddress or
GInetSocketAddress) fail to verify.
tls/gnutls/gtlscertificate-gnutls.c | 104 +++++++++++++++++++++--------------
tls/tests/certificate.c | 17 +++++-
2 files changed, 78 insertions(+), 43 deletions(-)
---
diff --git a/tls/gnutls/gtlscertificate-gnutls.c b/tls/gnutls/gtlscertificate-gnutls.c
index ba6b5d2..c513233 100644
--- a/tls/gnutls/gtlscertificate-gnutls.c
+++ b/tls/gnutls/gtlscertificate-gnutls.c
@@ -540,63 +540,83 @@ g_tls_certificate_gnutls_convert_flags (guint gnutls_flags)
return gtls_flags;
}
-GTlsCertificateFlags
-g_tls_certificate_gnutls_verify_identity (GTlsCertificateGnutls *gnutls,
- GSocketConnectable *identity)
+static gboolean
+verify_identity_hostname (GTlsCertificateGnutls *gnutls,
+ GSocketConnectable *identity)
{
const char *hostname;
- GInetAddress *addr;
if (G_IS_NETWORK_ADDRESS (identity))
hostname = g_network_address_get_hostname (G_NETWORK_ADDRESS (identity));
else if (G_IS_NETWORK_SERVICE (identity))
hostname = g_network_service_get_domain (G_NETWORK_SERVICE (identity));
else
- hostname = NULL;
+ return FALSE;
- if (!hostname)
- return G_TLS_CERTIFICATE_BAD_IDENTITY;
+ return gnutls_x509_crt_check_hostname (gnutls->priv->cert, hostname);
+}
- if (gnutls_x509_crt_check_hostname (gnutls->priv->cert, hostname))
- return 0;
+static gboolean
+verify_identity_ip (GTlsCertificateGnutls *gnutls,
+ GSocketConnectable *identity)
+{
+ GInetAddress *addr;
+ int i, ret = 0;
+ gsize addr_size;
+ const guint8 *addr_bytes;
+
+ if (G_IS_INET_SOCKET_ADDRESS (identity))
+ addr = g_object_ref (g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (identity)));
+ else {
+ const char *hostname;
+
+ if (G_IS_NETWORK_ADDRESS (identity))
+ hostname = g_network_address_get_hostname (G_NETWORK_ADDRESS (identity));
+ else if (G_IS_NETWORK_SERVICE (identity))
+ hostname = g_network_service_get_domain (G_NETWORK_SERVICE (identity));
+ else
+ return FALSE;
- if (!g_hostname_is_ip_address (hostname))
- return G_TLS_CERTIFICATE_BAD_IDENTITY;
+ addr = g_inet_address_new_from_string (hostname);
+ if (!addr)
+ return FALSE;
+ }
+
+ addr_bytes = g_inet_address_to_bytes (addr);
+ addr_size = g_inet_address_get_native_size (addr);
- addr = g_inet_address_new_from_string (hostname);
- if (addr)
+ for (i = 0; ret >= 0; i++)
{
- int i, ret = 0;
- gsize addr_size;
- const guint8 *addr_bytes;
-
- addr_bytes = g_inet_address_to_bytes (addr);
- addr_size = g_inet_address_get_native_size (addr);
-
- /* Here we only add an additional check to support IP addresses. */
- for (i = 0; ret >= 0; i++)
- {
- char san[500];
- size_t san_size;
-
- san_size = sizeof (san);
- ret = gnutls_x509_crt_get_subject_alt_name (gnutls->priv->cert, i,
- san, &san_size, NULL);
-
- if ((ret == GNUTLS_SAN_IPADDRESS) && (addr_size == san_size))
- {
- /* Let's check if found a matching IP. */
- if (memcmp (addr_bytes, san, addr_size) == 0)
- {
- g_object_unref (addr);
- return 0;
- }
- }
- }
-
- g_object_unref (addr);
+ char san[500];
+ size_t san_size;
+
+ san_size = sizeof (san);
+ ret = gnutls_x509_crt_get_subject_alt_name (gnutls->priv->cert, i,
+ san, &san_size, NULL);
+
+ if ((ret == GNUTLS_SAN_IPADDRESS) && (addr_size == san_size))
+ {
+ if (memcmp (addr_bytes, san, addr_size) == 0)
+ {
+ g_object_unref (addr);
+ return TRUE;
+ }
+ }
}
+ g_object_unref (addr);
+ return FALSE;
+}
+
+GTlsCertificateFlags
+g_tls_certificate_gnutls_verify_identity (GTlsCertificateGnutls *gnutls,
+ GSocketConnectable *identity)
+{
+ if (verify_identity_hostname (gnutls, identity))
+ return 0;
+ else if (verify_identity_ip (gnutls, identity))
+ return 0;
+
/* FIXME: check sRVName and uniformResourceIdentifier
* subjectAltNames, if appropriate for @identity.
*/
diff --git a/tls/tests/certificate.c b/tls/tests/certificate.c
index 56be9e1..6ba85d9 100644
--- a/tls/tests/certificate.c
+++ b/tls/tests/certificate.c
@@ -308,6 +308,7 @@ test_verify_certificate_good (TestVerify *test,
gconstpointer data)
{
GSocketConnectable *identity;
+ GSocketAddress *addr;
GTlsCertificateFlags errors;
errors = g_tls_certificate_verify (test->cert, test->identity, test->anchor);
@@ -320,6 +321,11 @@ test_verify_certificate_good (TestVerify *test,
errors = g_tls_certificate_verify (test->cert, identity, test->anchor);
g_assert_cmpuint (errors, ==, 0);
g_object_unref (identity);
+
+ addr = g_inet_socket_address_new_from_string ("192.168.1.10", 80);
+ errors = g_tls_certificate_verify (test->cert, G_SOCKET_CONNECTABLE (addr), test->anchor);
+ g_assert_cmpuint (errors, ==, 0);
+ g_object_unref (addr);
}
static void
@@ -328,13 +334,22 @@ test_verify_certificate_bad_identity (TestVerify *test,
{
GSocketConnectable *identity;
GTlsCertificateFlags errors;
+ GSocketAddress *addr;
identity = g_network_address_new ("other.example.com", 80);
-
errors = g_tls_certificate_verify (test->cert, identity, test->anchor);
g_assert_cmpuint (errors, ==, G_TLS_CERTIFICATE_BAD_IDENTITY);
+ g_object_unref (identity);
+ identity = g_network_address_new ("127.0.0.1", 80);
+ errors = g_tls_certificate_verify (test->cert, identity, test->anchor);
+ g_assert_cmpuint (errors, ==, G_TLS_CERTIFICATE_BAD_IDENTITY);
g_object_unref (identity);
+
+ addr = g_inet_socket_address_new_from_string ("127.0.0.1", 80);
+ errors = g_tls_certificate_verify (test->cert, G_SOCKET_CONNECTABLE (addr), test->anchor);
+ g_assert_cmpuint (errors, ==, G_TLS_CERTIFICATE_BAD_IDENTITY);
+ g_object_unref (addr);
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]