]> www.infradead.org Git - pidgin-chime.git/commitdiff
Validate DTLS server certificate
authorDavid Woodhouse <dwmw2@infradead.org>
Tue, 1 May 2018 08:50:50 +0000 (09:50 +0100)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Tue, 1 May 2018 09:37:34 +0000 (10:37 +0100)
Hm, it really shouldn't be so easy to forget this. There really is a case
to be made that you should get GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR by
default *unless* you set up verification. Fail safe, not open.

chime/chime-call-audio.h
chime/chime-call-transport.c

index ddd5a8ffc87188946ad774c6058425e71cd2be95..b29c4a043b216d8624b121132716a12e63ee44ca 100644 (file)
@@ -50,6 +50,7 @@ struct _ChimeCallAudio {
        GSocket *dtls_sock;
        GSource *dtls_source;
        gnutls_session_t dtls_sess;
+       gchar *dtls_hostname;
        gnutls_certificate_credentials_t dtls_cred;
        GCancellable *cancel;
 
index 6f6ee181f7a68c0e9d1b9e93d2d09989f6f1b665..b1744093fce19a6b935cf818b0b63db5c310d76d 100644 (file)
@@ -394,6 +394,9 @@ static gboolean dtls_src_cb(GDatagramBased *dgram, GIOCondition condition, Chime
                }
 
                if (ret) {
+                       chime_debug("DTLS failed (%d): %s\n",
+                                   gnutls_session_get_verify_cert_status(audio->dtls_sess),
+                                   gnutls_strerror(ret));
                        gnutls_deinit(audio->dtls_sess);
                        audio->dtls_sess = NULL;
                        g_source_destroy(audio->dtls_source);
@@ -451,26 +454,29 @@ static void connect_dtls(ChimeCallAudio *audio, GSocket *s)
        gnutls_init(&audio->dtls_sess, GNUTLS_CLIENT|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK);
        gnutls_set_default_priority(audio->dtls_sess);
        gnutls_session_set_ptr(audio->dtls_sess, audio);
-
-       /* We can't rely on the length argument to gnutls_server_name_set().
-          https://bugs.launchpad.net/ubuntu/+bug/1762710 */
-       gchar *hostname = g_strdup(chime_call_get_media_host(audio->call));
-       if (!hostname)
-               goto err;
-       char *colon = strrchr(hostname, ':');
-       if (!colon) {
-               g_free(hostname);
-               goto err;
-       }
-       *colon = 0;
-       gnutls_server_name_set(audio->dtls_sess, GNUTLS_NAME_DNS, hostname, colon - hostname);
-       g_free(hostname);
-
        if (!audio->dtls_cred) {
                gnutls_certificate_allocate_credentials(&audio->dtls_cred);
                gnutls_certificate_set_x509_system_trust(audio->dtls_cred);
        }
        gnutls_credentials_set(audio->dtls_sess, GNUTLS_CRD_CERTIFICATE, audio->dtls_cred);
+
+       if (!audio->dtls_hostname) {
+               gchar *hostname = g_strdup(chime_call_get_media_host(audio->call));
+               if (!hostname)
+                       goto err;
+               char *colon = strrchr(hostname, ':');
+               if (!colon) {
+                       g_free(hostname);
+                       goto err;
+               }
+               *colon = 0;
+               audio->dtls_hostname = hostname;
+       }
+       /* We can't rely on the length argument to gnutls_server_name_set().
+          https://bugs.launchpad.net/ubuntu/+bug/1762710 */
+       gnutls_server_name_set(audio->dtls_sess, GNUTLS_NAME_DNS, audio->dtls_hostname, strlen(audio->dtls_hostname));
+       gnutls_session_set_verify_cert(audio->dtls_sess, audio->dtls_hostname, 0);
+
        gnutls_transport_set_ptr(audio->dtls_sess, audio);
        gnutls_transport_set_push_function (audio->dtls_sess,
                                            g_tls_connection_gnutls_push_func);
@@ -623,6 +629,11 @@ void chime_call_transport_disconnect(ChimeCallAudio *audio, gboolean hangup)
                g_clear_object(&audio->dtls_sock);
        }
 
+       if (audio->dtls_hostname) {
+               g_free(audio->dtls_hostname);
+               audio->dtls_hostname = NULL;
+       }
+
        if (audio->timeout_source) {
                g_source_remove(audio->timeout_source);
                audio->timeout_source = 0;