[glib-networking/mcatanzaro/identity: 2/2] gnutls: remove manual identity verification code
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/mcatanzaro/identity: 2/2] gnutls: remove manual identity verification code
- Date: Fri, 25 Jun 2021 16:22:09 +0000 (UTC)
commit ffb66818621f8b5ebba3da3252e94e858c826324
Author: Michael Catanzaro <mcatanzaro redhat com>
Date: Fri Jun 25 10:56:17 2021 -0500
gnutls: remove manual identity verification code
Currently GTlsDatabase and GTlsConnection both rely on GnuTLS to verify
the peer identity, but GTlsCertificate does it manually. There's no good
reason for this.
tls/gnutls/gtlscertificate-gnutls.c | 100 +++++++++++-------------------------
tls/gnutls/gtlscertificate-gnutls.h | 5 +-
tls/gnutls/gtlsdatabase-gnutls.c | 35 ++-----------
3 files changed, 37 insertions(+), 103 deletions(-)
---
diff --git a/tls/gnutls/gtlscertificate-gnutls.c b/tls/gnutls/gtlscertificate-gnutls.c
index 7d9a1ff..0461974 100644
--- a/tls/gnutls/gtlscertificate-gnutls.c
+++ b/tls/gnutls/gtlscertificate-gnutls.c
@@ -510,6 +510,7 @@ g_tls_certificate_gnutls_verify (GTlsCertificate *cert,
guint num_certs, i;
gnutls_x509_crt_t *chain;
GTlsCertificateFlags gtls_flags;
+ GError *error = NULL;
cert_gnutls = G_TLS_CERTIFICATE_GNUTLS (cert);
num_certs = 0;
@@ -554,7 +555,14 @@ g_tls_certificate_gnutls_verify (GTlsCertificate *cert,
g_free (chain);
if (identity)
- gtls_flags |= g_tls_certificate_gnutls_verify_identity (G_TLS_CERTIFICATE_GNUTLS (cert), identity);
+ {
+ gtls_flags |= g_tls_certificate_gnutls_verify_identity (G_TLS_CERTIFICATE_GNUTLS (cert), identity,
&error);
+ if (error)
+ {
+ g_warning ("Error verifying TLS certificate: %s", error->message);
+ g_error_free (error);
+ }
+ }
return gtls_flags;
}
@@ -772,88 +780,40 @@ g_tls_certificate_gnutls_convert_flags (guint gnutls_flags)
return gtls_flags;
}
-static gboolean
-verify_identity_hostname (GTlsCertificateGnutls *gnutls,
- GSocketConnectable *identity)
+GTlsCertificateFlags
+g_tls_certificate_gnutls_verify_identity (GTlsCertificateGnutls *gnutls,
+ GSocketConnectable *identity,
+ GError **error)
{
+ GTlsCertificateFlags result = 0;
const char *hostname;
+ char *free_hostname = NULL;
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;
-
- return gnutls_x509_crt_check_hostname (gnutls->cert, hostname);
-}
-
-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;
-
- 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);
-
- for (i = 0; ret >= 0; i++)
+ else if (G_IS_INET_SOCKET_ADDRESS (identity))
{
- char san[500];
- size_t san_size;
+ GInetAddress *addr;
- san_size = sizeof (san);
- ret = gnutls_x509_crt_get_subject_alt_name (gnutls->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;
- }
- }
+ addr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (identity));
+ hostname = free_hostname = g_inet_address_to_string (addr);
+ }
+ else
+ {
+ g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
+ _("Cannot verify peer identity of unexpected type %s"), G_OBJECT_TYPE_NAME (identity));
+ return G_TLS_CERTIFICATE_BAD_IDENTITY;
}
- 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;
+ g_assert (hostname);
+ if (!gnutls_x509_crt_check_hostname (gnutls->cert, hostname))
+ result |= G_TLS_CERTIFICATE_BAD_IDENTITY;
- /* FIXME: check sRVName and uniformResourceIdentifier
- * subjectAltNames, if appropriate for @identity.
- */
+ g_free (free_hostname);
- return G_TLS_CERTIFICATE_BAD_IDENTITY;
+ return result;
}
void
diff --git a/tls/gnutls/gtlscertificate-gnutls.h b/tls/gnutls/gtlscertificate-gnutls.h
index 838f7db..257e1ec 100644
--- a/tls/gnutls/gtlscertificate-gnutls.h
+++ b/tls/gnutls/gtlscertificate-gnutls.h
@@ -56,8 +56,9 @@ void g_tls_certificate_gnutls_copy_free (gnutls_pc
unsigned int pcert_length,
gnutls_privkey_t pkey);
-GTlsCertificateFlags g_tls_certificate_gnutls_verify_identity (GTlsCertificateGnutls *gnutls,
- GSocketConnectable *identity);
+GTlsCertificateFlags g_tls_certificate_gnutls_verify_identity (GTlsCertificateGnutls *gnutls,
+ GSocketConnectable *identity,
+ GError **error);
GTlsCertificateFlags g_tls_certificate_gnutls_convert_flags (guint gnutls_flags);
diff --git a/tls/gnutls/gtlsdatabase-gnutls.c b/tls/gnutls/gtlsdatabase-gnutls.c
index 1bd1a8a..e418157 100644
--- a/tls/gnutls/gtlsdatabase-gnutls.c
+++ b/tls/gnutls/gtlsdatabase-gnutls.c
@@ -492,8 +492,6 @@ g_tls_database_gnutls_verify_chain (GTlsDatabase *database,
GTlsCertificateFlags result;
guint gnutls_result;
CertificateChain *gnutls_chain;
- const char *hostname = NULL;
- char *free_hostname = NULL;
int gerr;
g_return_val_if_fail (G_IS_TLS_CERTIFICATE_GNUTLS (chain),
@@ -521,35 +519,10 @@ g_tls_database_gnutls_verify_chain (GTlsDatabase *database,
result = g_tls_certificate_gnutls_convert_flags (gnutls_result);
- 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 if (G_IS_INET_SOCKET_ADDRESS (identity))
- {
- GInetAddress *addr;
-
- addr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (identity));
- hostname = free_hostname = g_inet_address_to_string (addr);
- }
-
- if (hostname)
- {
- if (!gnutls_x509_crt_check_hostname (gnutls_chain->chain[0], hostname))
- result |= G_TLS_CERTIFICATE_BAD_IDENTITY;
- g_free (free_hostname);
- }
- else if (identity)
- {
- /* If identity is NULL, then the application has requested that we not
- * verify identity. But if the application passes an identity of a
- * type we don't expect, then the application surely expects it to be
- * used, so we'd better not fail silently.
- */
- g_set_error (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
- _("Cannot verify peer identity of unexpected type %s"), G_OBJECT_TYPE_NAME (identity));
- result |= G_TLS_CERTIFICATE_BAD_IDENTITY;
- }
+ if (identity)
+ result |= g_tls_certificate_gnutls_verify_identity (G_TLS_CERTIFICATE_GNUTLS (chain),
+ identity,
+ error);
certificate_chain_free (gnutls_chain);
return result;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]