[glib-networking] Use gnutls_certificate_set_retrieve_function2()
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking] Use gnutls_certificate_set_retrieve_function2()
- Date: Mon, 5 Mar 2018 02:40:21 +0000 (UTC)
commit c158d7f51284a6f5ac50f0b02a833893b69509fa
Author: Michael Catanzaro <mcatanzaro igalia com>
Date: Mon Feb 26 13:18:41 2018 -0600
Use gnutls_certificate_set_retrieve_function2()
The GnuTLS manual says this is significantly more efficient than using
gnutls_certificate_set_retrieve_function(). It certainly is a bit safer.
It's easy to forget to initialize a member of the gnutls_retr2_st, but
harder to forget about function parameters.
https://bugzilla.gnome.org/show_bug.cgi?id=793712
tls/gnutls/gtlscertificate-gnutls-pkcs11.c | 28 ++++++++-----
tls/gnutls/gtlscertificate-gnutls.c | 59 +++++++++++++++++++---------
tls/gnutls/gtlscertificate-gnutls.h | 13 ++++--
tls/gnutls/gtlsclientconnection-gnutls.c | 47 +++++++++++-----------
tls/gnutls/gtlsconnection-gnutls.c | 22 +++++++---
tls/gnutls/gtlsconnection-gnutls.h | 5 ++-
tls/gnutls/gtlsserverconnection-gnutls.c | 33 +++++++++-------
7 files changed, 128 insertions(+), 79 deletions(-)
---
diff --git a/tls/gnutls/gtlscertificate-gnutls-pkcs11.c b/tls/gnutls/gtlscertificate-gnutls-pkcs11.c
index ae02982..58c7e4f 100644
--- a/tls/gnutls/gtlscertificate-gnutls-pkcs11.c
+++ b/tls/gnutls/gtlscertificate-gnutls-pkcs11.c
@@ -115,31 +115,37 @@ g_tls_certificate_gnutls_pkcs11_init (GTlsCertificateGnutlsPkcs11 *self)
static void
g_tls_certificate_gnutls_pkcs11_copy (GTlsCertificateGnutls *gnutls,
const gchar *interaction_id,
- gnutls_retr2_st *st)
+ gnutls_pcert_st **pcert,
+ unsigned int *pcert_length,
+ gnutls_privkey_t *pkey)
{
GTlsCertificateGnutlsPkcs11 *self = G_TLS_CERTIFICATE_GNUTLS_PKCS11 (gnutls);
gchar *uri;
- st->key.x509 = NULL;
-
/* Let the base class copy certificate in */
G_TLS_CERTIFICATE_GNUTLS_CLASS (g_tls_certificate_gnutls_pkcs11_parent_class)->copy (gnutls,
interaction_id,
- st);
-
- /* This is the allocation behavior we expect from base class */
- g_assert (st->deinit_all);
+ pcert,
+ pcert_length,
+ pkey);
/* If the base class somehow put a key in, then respect that */
- if (st->key.x509 == NULL)
+ if (*pkey == NULL)
{
uri = g_tls_certificate_gnutls_pkcs11_build_private_key_uri (self, interaction_id);
if (uri != NULL)
{
- gnutls_pkcs11_privkey_init (&st->key.pkcs11);
- gnutls_pkcs11_privkey_import_url (st->key.pkcs11, uri, GNUTLS_PKCS11_URL_GENERIC);
- st->key_type = GNUTLS_PRIVKEY_PKCS11;
+ gnutls_pkcs11_privkey_t pkcs11_privkey;
+ gnutls_privkey_t privkey;
+
+ gnutls_pkcs11_privkey_init (&pkcs11_privkey);
+ gnutls_pkcs11_privkey_import_url (pkcs11_privkey, uri, GNUTLS_PKCS11_URL_GENERIC);
g_free (uri);
+
+ gnutls_privkey_init (&privkey);
+ gnutls_privkey_import_pkcs11 (privkey, pkcs11_privkey, GNUTLS_PRIVKEY_IMPORT_COPY);
+ *pkey = privkey;
+ gnutls_pkcs11_privkey_deinit (pkcs11_privkey);
}
}
}
diff --git a/tls/gnutls/gtlscertificate-gnutls.c b/tls/gnutls/gtlscertificate-gnutls.c
index 95b8093..d5545b3 100644
--- a/tls/gnutls/gtlscertificate-gnutls.c
+++ b/tls/gnutls/gtlscertificate-gnutls.c
@@ -389,11 +389,11 @@ g_tls_certificate_gnutls_verify (GTlsCertificate *cert,
static void
g_tls_certificate_gnutls_real_copy (GTlsCertificateGnutls *gnutls,
const gchar *interaction_id,
- gnutls_retr2_st *st)
+ gnutls_pcert_st **pcert,
+ unsigned int *pcert_length,
+ gnutls_privkey_t *pkey)
{
GTlsCertificateGnutls *chain;
- gnutls_x509_crt_t cert;
- gnutls_datum_t data;
guint num_certs = 0;
size_t size = 0;
int status;
@@ -409,15 +409,18 @@ g_tls_certificate_gnutls_real_copy (GTlsCertificateGnutls *gnutls,
chain = priv->issuer;
}
- st->ncerts = 0;
- st->cert_type = GNUTLS_CRT_X509;
- st->cert.x509 = gnutls_malloc (sizeof (gnutls_x509_crt_t) * num_certs);
+ *pcert_length = 0;
+ *pcert = gnutls_malloc (sizeof (gnutls_pcert_st) * num_certs);
+ if (*pcert == NULL)
+ g_error ("%s: out of memory", __FUNCTION__);
/* Now do the actual copy of the whole chain. */
chain = gnutls;
while (chain != NULL)
{
GTlsCertificateGnutlsPrivate *priv = g_tls_certificate_gnutls_get_instance_private (chain);
+ gnutls_x509_crt_t cert;
+ gnutls_datum_t data;
gnutls_x509_crt_export (priv->cert, GNUTLS_X509_FMT_DER,
NULL, &size);
@@ -431,8 +434,9 @@ g_tls_certificate_gnutls_real_copy (GTlsCertificateGnutls *gnutls,
g_warn_if_fail (status == 0);
g_free (data.data);
- st->cert.x509[st->ncerts] = cert;
- st->ncerts++;
+ gnutls_pcert_import_x509 (*pcert + *pcert_length, cert, 0);
+ gnutls_x509_crt_deinit (cert);
+ (*pcert_length)++;
chain = priv->issuer;
}
@@ -442,14 +446,22 @@ g_tls_certificate_gnutls_real_copy (GTlsCertificateGnutls *gnutls,
if (priv->key != NULL)
{
- gnutls_x509_privkey_init (&st->key.x509);
- gnutls_x509_privkey_cpy (st->key.x509, priv->key);
- }
+ gnutls_x509_privkey_t x509_privkey;
+ gnutls_privkey_t privkey;
- st->key_type = GNUTLS_PRIVKEY_X509;
- }
+ gnutls_x509_privkey_init (&x509_privkey);
+ gnutls_x509_privkey_cpy (x509_privkey, priv->key);
- st->deinit_all = TRUE;
+ gnutls_privkey_init (&privkey);
+ gnutls_privkey_import_x509 (privkey, x509_privkey, GNUTLS_PRIVKEY_IMPORT_COPY);
+ *pkey = privkey;
+ gnutls_x509_privkey_deinit (x509_privkey);
+ }
+ else
+ {
+ *pkey = NULL;
+ }
+ }
}
static void
@@ -524,14 +536,23 @@ g_tls_certificate_gnutls_has_key (GTlsCertificateGnutls *gnutls)
}
void
-g_tls_certificate_gnutls_copy (GTlsCertificateGnutls *gnutls,
- const gchar *interaction_id,
- gnutls_retr2_st *st)
+g_tls_certificate_gnutls_copy (GTlsCertificateGnutls *gnutls,
+ const gchar *interaction_id,
+ gnutls_pcert_st **pcert,
+ unsigned int *pcert_length,
+ gnutls_privkey_t *pkey)
{
g_return_if_fail (G_IS_TLS_CERTIFICATE_GNUTLS (gnutls));
- g_return_if_fail (st != NULL);
+ g_return_if_fail (pcert != NULL);
+ g_return_if_fail (pcert_length != NULL);
+ g_return_if_fail (pkey != NULL);
g_return_if_fail (G_TLS_CERTIFICATE_GNUTLS_GET_CLASS (gnutls)->copy);
- G_TLS_CERTIFICATE_GNUTLS_GET_CLASS (gnutls)->copy (gnutls, interaction_id, st);
+
+ G_TLS_CERTIFICATE_GNUTLS_GET_CLASS (gnutls)->copy (gnutls,
+ interaction_id,
+ pcert,
+ pcert_length,
+ pkey);
}
static const struct {
diff --git a/tls/gnutls/gtlscertificate-gnutls.h b/tls/gnutls/gtlscertificate-gnutls.h
index a6450ec..569b3db 100644
--- a/tls/gnutls/gtlscertificate-gnutls.h
+++ b/tls/gnutls/gtlscertificate-gnutls.h
@@ -26,6 +26,7 @@
#define __G_TLS_CERTIFICATE_GNUTLS_H__
#include <gio/gio.h>
+#include <gnutls/abstract.h>
#include <gnutls/gnutls.h>
G_BEGIN_DECLS
@@ -40,7 +41,9 @@ struct _GTlsCertificateGnutlsClass
void (*copy) (GTlsCertificateGnutls *gnutls,
const gchar *interaction_id,
- gnutls_retr2_st *st);
+ gnutls_pcert_st **pcert,
+ unsigned int *pcert_length,
+ gnutls_privkey_t *pkey);
};
GTlsCertificate * g_tls_certificate_gnutls_new (const gnutls_datum_t *datum,
@@ -54,9 +57,11 @@ void g_tls_certificate_gnutls_set_data (GTlsCerti
const gnutls_x509_crt_t g_tls_certificate_gnutls_get_cert (GTlsCertificateGnutls *gnutls);
gboolean g_tls_certificate_gnutls_has_key (GTlsCertificateGnutls *gnutls);
-void g_tls_certificate_gnutls_copy (GTlsCertificateGnutls *gnutls,
- const gchar *interaction_id,
- gnutls_retr2_st *st);
+void g_tls_certificate_gnutls_copy (GTlsCertificateGnutls *gnutls,
+ const gchar
*interaction_id,
+ gnutls_pcert_st **pcert,
+ unsigned int *pcert_length,
+ gnutls_privkey_t *pkey);
GTlsCertificateFlags g_tls_certificate_gnutls_verify_identity (GTlsCertificateGnutls *gnutls,
GSocketConnectable *identity);
diff --git a/tls/gnutls/gtlsclientconnection-gnutls.c b/tls/gnutls/gtlsclientconnection-gnutls.c
index f0fa94e..a32ea43 100644
--- a/tls/gnutls/gtlsclientconnection-gnutls.c
+++ b/tls/gnutls/gtlsclientconnection-gnutls.c
@@ -66,12 +66,14 @@ static void g_tls_client_connection_gnutls_initable_interface_init (GInitabl
static void g_tls_client_connection_gnutls_client_connection_interface_init (GTlsClientConnectionInterface
*iface);
static void g_tls_client_connection_gnutls_dtls_client_connection_interface_init
(GDtlsClientConnectionInterface *iface);
-static int g_tls_client_connection_gnutls_retrieve_function (gnutls_session_t session,
- const gnutls_datum_t *req_ca_rdn,
- int nreqs,
- const gnutls_pk_algorithm_t *pk_algos,
- int pk_algos_length,
- gnutls_retr2_st *st);
+static int g_tls_client_connection_gnutls_retrieve_function (gnutls_session_t session,
+ const gnutls_datum_t *req_ca_rdn,
+ int nreqs,
+ const gnutls_pk_algorithm_t *pk_algos,
+ int pk_algos_length,
+ gnutls_pcert_st **pcert,
+ unsigned int *pcert_length,
+ gnutls_privkey_t *pkey);
static GInitableIface *g_tls_client_connection_gnutls_parent_initable_iface;
@@ -90,7 +92,7 @@ g_tls_client_connection_gnutls_init (GTlsClientConnectionGnutls *gnutls)
gnutls_certificate_credentials_t creds;
creds = g_tls_connection_gnutls_get_credentials (G_TLS_CONNECTION_GNUTLS (gnutls));
- gnutls_certificate_set_retrieve_function (creds, g_tls_client_connection_gnutls_retrieve_function);
+ gnutls_certificate_set_retrieve_function2 (creds, g_tls_client_connection_gnutls_retrieve_function);
}
static const gchar *
@@ -291,12 +293,14 @@ g_tls_client_connection_gnutls_set_property (GObject *object,
}
static int
-g_tls_client_connection_gnutls_retrieve_function (gnutls_session_t session,
- const gnutls_datum_t *req_ca_rdn,
- int nreqs,
- const gnutls_pk_algorithm_t *pk_algos,
- int pk_algos_length,
- gnutls_retr2_st *st)
+g_tls_client_connection_gnutls_retrieve_function (gnutls_session_t session,
+ const gnutls_datum_t *req_ca_rdn,
+ int nreqs,
+ const gnutls_pk_algorithm_t *pk_algos,
+ int pk_algos_length,
+ gnutls_pcert_st **pcert,
+ unsigned int *pcert_length,
+ gnutls_privkey_t *pkey)
{
GTlsClientConnectionGnutls *gnutls = gnutls_transport_get_ptr (session);
GTlsConnectionGnutls *conn = G_TLS_CONNECTION_GNUTLS (gnutls);
@@ -321,15 +325,15 @@ g_tls_client_connection_gnutls_retrieve_function (gnutls_session_t s
gnutls->accepted_cas = accepted_cas;
g_object_notify (G_OBJECT (gnutls), "accepted-cas");
- g_tls_connection_gnutls_get_certificate (conn, st);
+ g_tls_connection_gnutls_get_certificate (conn, pcert, pcert_length, pkey);
- if (st->ncerts == 0)
+ if (*pcert_length == 0)
{
g_clear_error (&gnutls->cert_error);
if (g_tls_connection_gnutls_request_certificate (conn, &gnutls->cert_error))
- g_tls_connection_gnutls_get_certificate (conn, st);
+ g_tls_connection_gnutls_get_certificate (conn, pcert, pcert_length, pkey);
- if (st->ncerts == 0)
+ if (*pcert_length == 0)
{
/* If there is still no client certificate, this connection will
* probably fail, but no reason to give up: let's try anyway.
@@ -339,13 +343,10 @@ g_tls_client_connection_gnutls_retrieve_function (gnutls_session_t s
}
}
- g_assert (st->key_type == GNUTLS_PRIVKEY_X509 ||
- st->key_type == GNUTLS_PRIVKEY_PKCS11);
- if ((st->key_type == GNUTLS_PRIVKEY_X509 && st->key.x509 == NULL) ||
- (st->key_type == GNUTLS_PRIVKEY_PKCS11 && st->key.pkcs11 == NULL))
+ if (*pkey == NULL)
{
- /* No private key. GnuTLS expects it to be non-null if ncerts is nonzero,
- * so we have to abort now.
+ /* No private key. GnuTLS expects it to be non-null if pcert_length is
+ * nonzero, so we have to abort now.
*/
gnutls->requested_cert_missing = TRUE;
return -1;
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index 6aa17bc..ce89dfb 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -652,20 +652,28 @@ g_tls_connection_gnutls_get_session (GTlsConnectionGnutls *gnutls)
}
void
-g_tls_connection_gnutls_get_certificate (GTlsConnectionGnutls *gnutls,
- gnutls_retr2_st *st)
+g_tls_connection_gnutls_get_certificate (GTlsConnectionGnutls *gnutls,
+ gnutls_pcert_st **pcert,
+ unsigned int *pcert_length,
+ gnutls_privkey_t *pkey)
{
GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
GTlsCertificate *cert;
- st->cert_type = GNUTLS_CRT_X509;
- st->ncerts = 0;
-
cert = g_tls_connection_get_certificate (G_TLS_CONNECTION (gnutls));
if (cert)
- g_tls_certificate_gnutls_copy (G_TLS_CERTIFICATE_GNUTLS (cert),
- priv->interaction_id, st);
+ {
+ g_tls_certificate_gnutls_copy (G_TLS_CERTIFICATE_GNUTLS (cert),
+ priv->interaction_id,
+ pcert, pcert_length, pkey);
+ }
+ else
+ {
+ *pcert = NULL;
+ *pcert_length = 0;
+ *pkey = NULL;
+ }
}
typedef enum {
diff --git a/tls/gnutls/gtlsconnection-gnutls.h b/tls/gnutls/gtlsconnection-gnutls.h
index 4c623c2..71c69cd 100644
--- a/tls/gnutls/gtlsconnection-gnutls.h
+++ b/tls/gnutls/gtlsconnection-gnutls.h
@@ -26,6 +26,7 @@
#define __G_TLS_CONNECTION_GNUTLS_H__
#include <gio/gio.h>
+#include <gnutls/abstract.h>
#include <gnutls/gnutls.h>
G_BEGIN_DECLS
@@ -49,7 +50,9 @@ gnutls_certificate_credentials_t g_tls_connection_gnutls_get_credentials (GTlsCo
gnutls_session_t g_tls_connection_gnutls_get_session (GTlsConnectionGnutls *connection);
void g_tls_connection_gnutls_get_certificate (GTlsConnectionGnutls *gnutls,
- gnutls_retr2_st *st);
+ gnutls_pcert_st **pcert,
+ unsigned int *pcert_length,
+ gnutls_privkey_t *pkey);
gboolean g_tls_connection_gnutls_request_certificate (GTlsConnectionGnutls *gnutls,
GError **error);
diff --git a/tls/gnutls/gtlsserverconnection-gnutls.c b/tls/gnutls/gtlsserverconnection-gnutls.c
index 8e323b3..7c38b87 100644
--- a/tls/gnutls/gtlsserverconnection-gnutls.c
+++ b/tls/gnutls/gtlsserverconnection-gnutls.c
@@ -51,12 +51,14 @@ static void g_tls_server_connection_gnutls_initable_interface_init (GInitabl
static void g_tls_server_connection_gnutls_server_connection_interface_init (GTlsServerConnectionInterface
*iface);
-static int g_tls_server_connection_gnutls_retrieve_function (gnutls_session_t session,
- const gnutls_datum_t *req_ca_rdn,
- int nreqs,
- const gnutls_pk_algorithm_t *pk_algos,
- int pk_algos_length,
- gnutls_retr2_st *st);
+static int g_tls_server_connection_gnutls_retrieve_function (gnutls_session_t session,
+ const gnutls_datum_t *req_ca_rdn,
+ int nreqs,
+ const gnutls_pk_algorithm_t *pk_algos,
+ int pk_algos_length,
+ gnutls_pcert_st **pcert,
+ unsigned int *pcert_length,
+ gnutls_privkey_t *pkey);
static int g_tls_server_connection_gnutls_db_store (void *user_data,
gnutls_datum_t key,
@@ -83,7 +85,7 @@ g_tls_server_connection_gnutls_init (GTlsServerConnectionGnutls *gnutls)
gnutls_certificate_credentials_t creds;
creds = g_tls_connection_gnutls_get_credentials (G_TLS_CONNECTION_GNUTLS (gnutls));
- gnutls_certificate_set_retrieve_function (creds, g_tls_server_connection_gnutls_retrieve_function);
+ gnutls_certificate_set_retrieve_function2 (creds, g_tls_server_connection_gnutls_retrieve_function);
}
static gboolean
@@ -154,14 +156,17 @@ g_tls_server_connection_gnutls_set_property (GObject *object,
}
static int
-g_tls_server_connection_gnutls_retrieve_function (gnutls_session_t session,
- const gnutls_datum_t *req_ca_rdn,
- int nreqs,
- const gnutls_pk_algorithm_t *pk_algos,
- int pk_algos_length,
- gnutls_retr2_st *st)
+g_tls_server_connection_gnutls_retrieve_function (gnutls_session_t session,
+ const gnutls_datum_t *req_ca_rdn,
+ int nreqs,
+ const gnutls_pk_algorithm_t *pk_algos,
+ int pk_algos_length,
+ gnutls_pcert_st **pcert,
+ unsigned int *pcert_length,
+ gnutls_privkey_t *pkey)
{
- g_tls_connection_gnutls_get_certificate (gnutls_transport_get_ptr (session), st);
+ g_tls_connection_gnutls_get_certificate (gnutls_transport_get_ptr (session),
+ pcert, pcert_length, pkey);
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]