From: David Woodhouse Date: Tue, 1 May 2018 08:50:50 +0000 (+0100) Subject: Validate DTLS server certificate X-Git-Tag: v0.91~13 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=8cad5e9f575fa2a8936c5f697eb7d878965bfbba;p=pidgin-chime.git Validate DTLS server certificate 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. --- diff --git a/chime/chime-call-audio.h b/chime/chime-call-audio.h index ddd5a8f..b29c4a0 100644 --- a/chime/chime-call-audio.h +++ b/chime/chime-call-audio.h @@ -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; diff --git a/chime/chime-call-transport.c b/chime/chime-call-transport.c index 6f6ee18..b174409 100644 --- a/chime/chime-call-transport.c +++ b/chime/chime-call-transport.c @@ -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;