From 54e84b7b0133ff4d3c3853968575495de15f84f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=9Aled=C5=BA?= Date: Wed, 22 Nov 2023 19:18:40 +0100 Subject: [PATCH] Accept self-signed certificates. --- c_src/ex_dtls/native.c | 34 ++++++++++++++++++++++++++-------- lib/ex_dtls.ex | 1 + test/integration_test.exs | 1 + 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/c_src/ex_dtls/native.c b/c_src/ex_dtls/native.c index b8b24ac..4481430 100644 --- a/c_src/ex_dtls/native.c +++ b/c_src/ex_dtls/native.c @@ -96,7 +96,9 @@ UNIFEX_TERM do_init(UnifexEnv *env, char *mode_str, int dtls_srtp, } if (verify_peer == 1) { - SSL_CTX_set_verify(state->ssl_ctx, SSL_VERIFY_PEER, verify_cb); + SSL_CTX_set_verify(state->ssl_ctx, + SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_PEER, + verify_cb); } state->pkey = pkey; @@ -402,18 +404,34 @@ UNIFEX_TERM handle_timeout(UnifexEnv *env, State *state) { static void ssl_info_cb(const SSL *ssl, int where, int ret) { UNIFEX_UNUSED(ssl); - UNIFEX_UNUSED(ret); + UNIFEX_MAYBE_UNUSED(ret); + if (where & SSL_CB_ALERT) { - DEBUG("DTLS alert occurred."); + const char *type = SSL_alert_type_string(ret); + const char *type_long = SSL_alert_type_string_long(ret); + const char *desc = SSL_alert_desc_string(ret); + const char *desc_long = SSL_alert_desc_string_long(ret); + + UNIFEX_MAYBE_UNUSED(type); + UNIFEX_MAYBE_UNUSED(type_long); + UNIFEX_MAYBE_UNUSED(desc); + UNIFEX_MAYBE_UNUSED(desc_long); + + DEBUG("DTLS alert occurred, where: %d, ret: %d, type: %s, type_long: %s, " + "desc: %s, desc_long: %s", + where, ret, type, type_long, desc, desc_long); } } static int verify_cb(int preverify_ok, X509_STORE_CTX *ctx) { - // TODO implement this callback - UNIFEX_UNUSED(preverify_ok); - UNIFEX_UNUSED(ctx); - DEBUG("Verify callback, preverify_ok: %d", preverify_ok); - return 1; + int err = X509_STORE_CTX_get_error(ctx); + + if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) { + // accept self-signed certs + return 1; + } else { + return preverify_ok; + } } static int read_pending_data(UnifexPayload *gen_packets, int pending_data_len, diff --git a/lib/ex_dtls.ex b/lib/ex_dtls.ex index 266d3b1..b348320 100644 --- a/lib/ex_dtls.ex +++ b/lib/ex_dtls.ex @@ -48,6 +48,7 @@ defmodule ExDTLS do * `cert` - certificate to use in this SSL context. Must correspond to `pkey`. If both `pkey` and `cert` are not passed `ExDTLS` will generate key and certificate on its own. * `verify_peer` - `true` if peer's certificate should be verified. + Default OpenSSL verification is performed except that self-signed certificates are also accepted. Note that if `verify_peer` is `false`, `get_peer_cert/1` called on `ExDTLS` working in the server mode, will always return `nil`. Defaults to `false`. """ diff --git a/test/integration_test.exs b/test/integration_test.exs index 8525843..3b55faa 100644 --- a/test/integration_test.exs +++ b/test/integration_test.exs @@ -1,6 +1,7 @@ defmodule ExDTLS.IntegrationTest do use ExUnit.Case, async: true + @tag :debug test "dtls_srtp" do rx_dtls = ExDTLS.init(mode: :server, dtls_srtp: true, verify_peer: true) tx_dtls = ExDTLS.init(mode: :client, dtls_srtp: true, verify_peer: true)