summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgnacio Casal Quinteiro <qignacio@amazon.com>2019-05-10 16:07:29 +0200
committerMichael Catanzaro <mcatanzaro@posteo.net>2019-05-15 14:02:30 +0000
commitab412072d871c7a199acb51259b47b0cfd951134 (patch)
tree2025146ffd253652a07f43f3ced617f129bef6c6
parenta34d1f644380bbccdc2bbc9d85245b079eb2e274 (diff)
downloadglib-networking-ab412072d871c7a199acb51259b47b0cfd951134.tar.gz
openssl: go back to verify peer certificate after handshake
The SSL_set_verify callback is only called if the verify method is called and openssl seems to call this only for the client
-rw-r--r--tls/openssl/gtlsconnection-openssl.c67
1 files changed, 21 insertions, 46 deletions
diff --git a/tls/openssl/gtlsconnection-openssl.c b/tls/openssl/gtlsconnection-openssl.c
index eed8c25..6957f84 100644
--- a/tls/openssl/gtlsconnection-openssl.c
+++ b/tls/openssl/gtlsconnection-openssl.c
@@ -42,8 +42,6 @@ typedef struct _GTlsConnectionOpensslPrivate
{
BIO *bio;
- GTlsCertificate *peer_certificate;
-
gboolean shutting_down;
} GTlsConnectionOpensslPrivate;
@@ -54,19 +52,6 @@ G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GTlsConnectionOpenssl, g_tls_connection_openss
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
g_tls_connection_openssl_initable_iface_init))
-static void
-g_tls_connection_openssl_finalize (GObject *object)
-{
- GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (object);
- GTlsConnectionOpensslPrivate *priv;
-
- priv = g_tls_connection_openssl_get_instance_private (openssl);
-
- g_clear_object (&priv->peer_certificate);
-
- G_OBJECT_CLASS (g_tls_connection_openssl_parent_class)->finalize (object);
-}
-
static GTlsConnectionBaseStatus
end_openssl_io (GTlsConnectionOpenssl *openssl,
GIOCondition direction,
@@ -249,41 +234,30 @@ g_tls_connection_openssl_request_rehandshake (GTlsConnectionBase *tls,
static GTlsCertificate *
g_tls_connection_openssl_retrieve_peer_certificate (GTlsConnectionBase *tls)
{
- GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
- GTlsConnectionOpensslPrivate *priv;
-
- priv = g_tls_connection_openssl_get_instance_private (openssl);
-
- return g_object_ref (priv->peer_certificate);
-}
-
-static int
-handshake_thread_verify_certificate_cb (int preverify_ok,
- X509_STORE_CTX *x509_ctx)
-{
- GTlsConnectionOpenssl *openssl;
- GTlsConnectionOpensslPrivate *priv;
- SSL *ssl;
X509 *peer;
STACK_OF (X509) *certs;
+ GTlsCertificateOpenssl *chain;
+ SSL *ssl;
- ssl = X509_STORE_CTX_get_ex_data (x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx ());
- openssl = g_tls_connection_openssl_get_connection_from_ssl (ssl);
- g_return_val_if_fail (G_IS_TLS_CONNECTION_OPENSSL (openssl), 0);
-
- priv = g_tls_connection_openssl_get_instance_private (openssl);
+ ssl = g_tls_connection_openssl_get_ssl (G_TLS_CONNECTION_OPENSSL (tls));
- peer = X509_STORE_CTX_get_current_cert (x509_ctx);
+ peer = SSL_get_peer_certificate (ssl);
if (peer == NULL)
- return 0;
+ return NULL;
- certs = X509_STORE_CTX_get_chain (x509_ctx);
+ certs = SSL_get_peer_cert_chain (ssl);
if (certs == NULL)
- return 0;
+ {
+ X509_free (peer);
+ return NULL;
+ }
- priv->peer_certificate = G_TLS_CERTIFICATE (g_tls_certificate_openssl_build_chain (peer, certs));
+ chain = g_tls_certificate_openssl_build_chain (peer, certs);
+ X509_free (peer);
+ if (!chain)
+ return NULL;
- return g_tls_connection_base_handshake_thread_verify_certificate (G_TLS_CONNECTION_BASE (openssl));
+ return G_TLS_CERTIFICATE (chain);
}
static GTlsConnectionBaseStatus
@@ -304,6 +278,12 @@ g_tls_connection_openssl_handshake_thread_handshake (GTlsConnectionBase *tls,
END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, status,
_("Error performing TLS handshake"), error);
+ if (ret > 0)
+ {
+ if (!g_tls_connection_base_handshake_thread_verify_certificate (G_TLS_CONNECTION_BASE (openssl)))
+ return G_TLS_CONNECTION_BASE_ERROR;
+ }
+
return status;
}
@@ -445,11 +425,8 @@ g_tls_connection_openssl_close (GTlsConnectionBase *tls,
static void
g_tls_connection_openssl_class_init (GTlsConnectionOpensslClass *klass)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GTlsConnectionBaseClass *base_class = G_TLS_CONNECTION_BASE_CLASS (klass);
- gobject_class->finalize = g_tls_connection_openssl_finalize;
-
base_class->request_rehandshake = g_tls_connection_openssl_request_rehandshake;
base_class->handshake_thread_handshake = g_tls_connection_openssl_handshake_thread_handshake;
base_class->retrieve_peer_certificate = g_tls_connection_openssl_retrieve_peer_certificate;
@@ -488,8 +465,6 @@ g_tls_connection_openssl_initable_init (GInitable *initable,
}
SSL_set_ex_data (ssl, data_index, openssl);
- SSL_set_verify (ssl, SSL_VERIFY_PEER, handshake_thread_verify_certificate_cb);
-
priv->bio = g_tls_bio_new (base_io_stream);
SSL_set_bio (ssl, priv->bio, priv->bio);