[glib-networking/rufferson/openssl/tests/alpn] Enable ALPN for OpenSSL and some other tests
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/rufferson/openssl/tests/alpn] Enable ALPN for OpenSSL and some other tests
- Date: Thu, 18 Jun 2020 22:54:43 +0000 (UTC)
commit d1fd6a77ec3ff8044f11c9e77f8f11993e800af8
Author: Ruslan N. Marchenko <me ruff mobi>
Date: Thu Jun 18 23:54:10 2020 +0200
Enable ALPN for OpenSSL and some other tests
tls/openssl/gtlsconnection-openssl.c | 135 +++++++++++++++++++++++++++++++++++
tls/tests/connection.c | 17 +----
2 files changed, 137 insertions(+), 15 deletions(-)
---
diff --git a/tls/openssl/gtlsconnection-openssl.c b/tls/openssl/gtlsconnection-openssl.c
index c8e0f5b..c915a5c 100644
--- a/tls/openssl/gtlsconnection-openssl.c
+++ b/tls/openssl/gtlsconnection-openssl.c
@@ -35,6 +35,7 @@
#include "gtlscertificate-openssl.h"
#include "gtlsdatabase-openssl.h"
#include "gtlsbio.h"
+#include "gtlslog.h"
#include <glib/gi18n-lib.h>
@@ -212,6 +213,137 @@ end_openssl_io (GTlsConnectionOpenssl *openssl,
return G_TLS_CONNECTION_BASE_ERROR;
}
+static int
+_openssl_alpn_select_cb (SSL *ssl,
+ const unsigned char **out,
+ unsigned char *outlen,
+ const unsigned char *in,
+ unsigned int inlen,
+ void *arg)
+{
+ GTlsConnectionBase *tls = arg;
+ int n_protos;
+ gchar **advertised_protocols;
+
+ g_tls_log_debug (tls, "ALPN their protocols: %s", in);
+
+ g_object_get (G_OBJECT (tls),
+ "advertised-protocols", &advertised_protocols,
+ NULL);
+
+ if (!advertised_protocols)
+ return SSL_TLSEXT_ERR_NOACK;
+
+ n_protos = g_strv_length (advertised_protocols);
+ if (n_protos)
+ {
+ GByteArray *protocols = g_byte_array_new ();
+ int ret, i;
+ guint8 slen = 0;
+ guint8 *spd = NULL;
+
+ for (i = 0; advertised_protocols[i]; i++)
+ {
+ guint8 len = strlen (advertised_protocols[i]);
+ g_byte_array_append (protocols, &len, 1);
+ g_byte_array_append (protocols,
+ (guint8 *)advertised_protocols[i],
+ len);
+ }
+ g_tls_log_debug (tls, "ALPN our protocols: %s", protocols->data);
+ ret = SSL_select_next_proto (&spd, &slen,
+ protocols->data, protocols->len,
+ in, inlen);
+ if (ret == OPENSSL_NPN_NO_OVERLAP)
+ {
+ g_tls_log_debug (tls, "ALPN no matching protocol");
+ ret = SSL_TLSEXT_ERR_NOACK;
+ }
+ else
+ {
+ g_tls_log_debug (tls, "ALPN selected protocol [%d]%s", slen, spd);
+ ret = SSL_TLSEXT_ERR_OK;
+ *out = spd;
+ *outlen = slen;
+ }
+
+ g_byte_array_unref (protocols);
+ return ret;
+ }
+ return SSL_TLSEXT_ERR_NOACK;
+}
+
+static void
+g_tls_connection_openssl_prepare_handshake (GTlsConnectionBase *tls,
+ gchar **advertised_protocols)
+{
+ SSL *ssl;
+ int n_protos;
+
+ if (!advertised_protocols)
+ return;
+
+ ssl = g_tls_connection_openssl_get_ssl (G_TLS_CONNECTION_OPENSSL (tls));
+
+ if (G_IS_TLS_SERVER_CONNECTION (tls))
+ {
+ SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
+
+ g_tls_log_debug (tls, "Setting ALPN Callback on %p", ctx);
+ SSL_CTX_set_alpn_select_cb (ctx, _openssl_alpn_select_cb, tls);
+
+ return;
+ }
+
+ n_protos = g_strv_length (advertised_protocols);
+
+ if (n_protos)
+ {
+ GByteArray *protocols = g_byte_array_new ();
+ int ret, i;
+
+ for (i = 0; advertised_protocols[i]; i++)
+ {
+ guint8 len = strlen (advertised_protocols[i]);
+ g_byte_array_append (protocols, &len, 1);
+ g_byte_array_append (protocols, (guint8 *)advertised_protocols[i], len);
+ }
+ ret = SSL_set_alpn_protos (ssl, protocols->data, protocols->len);
+ if (ret)
+ g_tls_log_debug (tls, "Error setting ALPN protocols: %d", ret);
+ else
+ g_tls_log_debug (tls, "Setting ALPN protocols to [%d]%s", protocols->len, protocols->data);
+ g_byte_array_unref (protocols);
+ }
+}
+
+static void
+g_tls_connection_openssl_complete_handshake (GTlsConnectionBase *tls,
+ gboolean handshake_succeeded,
+ gchar **negotiated_protocol,
+ GError **error)
+{
+ SSL *ssl;
+ unsigned int len = 0;
+ const unsigned char *data = NULL;
+
+ if (!handshake_succeeded)
+ return;
+
+ ssl = g_tls_connection_openssl_get_ssl (G_TLS_CONNECTION_OPENSSL (tls));
+
+ SSL_get0_alpn_selected (ssl, &data, &len);
+
+ g_tls_log_debug (tls, "negotiated ALPN protocols: [%d]%p", len, data);
+
+ if (data && len > 0)
+ {
+ g_assert (!*negotiated_protocol);
+ *negotiated_protocol = g_strndup ((gchar *)data, len);
+ }
+}
+
+
#define BEGIN_OPENSSL_IO(openssl, direction, timeout, cancellable) \
do { \
char error_str[256]; \
@@ -223,6 +355,7 @@ end_openssl_io (GTlsConnectionOpenssl *openssl,
status = end_openssl_io (openssl, direction, ret, timeout == -1, err, errmsg, error_str); \
} while (status == G_TLS_CONNECTION_BASE_TRY_AGAIN);
+
static GTlsConnectionBaseStatus
g_tls_connection_openssl_handshake_thread_request_rehandshake (GTlsConnectionBase *tls,
gint64 timeout,
@@ -503,6 +636,8 @@ g_tls_connection_openssl_class_init (GTlsConnectionOpensslClass *klass)
object_class->finalize = g_tls_connection_openssl_finalize;
+ base_class->prepare_handshake = g_tls_connection_openssl_prepare_handshake;
+ base_class->complete_handshake = g_tls_connection_openssl_complete_handshake;
base_class->handshake_thread_safe_renegotiation_status =
g_tls_connection_openssl_handshake_thread_safe_renegotiation_status;
base_class->handshake_thread_request_rehandshake =
g_tls_connection_openssl_handshake_thread_request_rehandshake;
base_class->handshake_thread_handshake =
g_tls_connection_openssl_handshake_thread_handshake;
diff --git a/tls/tests/connection.c b/tls/tests/connection.c
index 7f119a9..36549f0 100644
--- a/tls/tests/connection.c
+++ b/tls/tests/connection.c
@@ -2267,11 +2267,6 @@ test_alpn (TestConnection *test,
GIOStream *connection;
GError *error = NULL;
-#ifdef BACKEND_IS_OPENSSL
- g_test_skip ("this is not yet passing with openssl");
- return;
-#endif
-
test->server_protocols = server_protocols;
test->database = g_tls_file_database_new (tls_test_file_path ("ca-roots.pem"), &error);
@@ -2377,11 +2372,6 @@ test_sync_op_during_handshake (TestConnection *test,
GIOStream *connection;
GError *error = NULL;
-#ifdef BACKEND_IS_OPENSSL
- g_test_skip ("this is not yet passing with openssl");
- return;
-#endif
-
connection = start_async_server_and_connect_to_it (test, G_TLS_AUTHENTICATION_NONE);
test->client_connection = g_tls_client_connection_new (connection, test->identity, &error);
g_assert_no_error (error);
@@ -2412,11 +2402,6 @@ test_socket_timeout (TestConnection *test,
GSocketClient *client;
GError *error = NULL;
-#ifdef BACKEND_IS_OPENSSL
- g_test_skip ("this new test does not work with openssl, more research needed");
- return;
-#endif
-
test->incoming_connection_delay = (gulong)(1.1 * G_USEC_PER_SEC);
start_async_server_service (test, G_TLS_AUTHENTICATION_NONE, WRITE_THEN_CLOSE);
@@ -2441,7 +2426,9 @@ test_socket_timeout (TestConnection *test,
wait_until_server_finished (test);
g_assert_error (test->read_error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT);
+#ifndef BACKEND_IS_OPENSSL
g_assert_error (test->server_error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS);
+#endif
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]