[glib-networking] gnutls: Fix up GTlsCertificateFlags handling
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking] gnutls: Fix up GTlsCertificateFlags handling
- Date: Wed, 8 Dec 2010 15:40:34 +0000 (UTC)
commit dc8510f338b74315387bbbfdd07f2661196d1ef1
Author: Dan Winship <danw gnome org>
Date: Tue Dec 7 23:10:23 2010 +0100
gnutls: Fix up GTlsCertificateFlags handling
If a certificate isn't signed by a known CA, gnutls won't bother
checking some of the other things (eg, expiration). But callers
might be planning to do the CA check themselves, in which case we
need to do the other checks anyway. So do that.
tls/gnutls/gtlscertificate-gnutls.c | 52 +++++++++++++++++++-----------
tls/gnutls/gtlsclientconnection-gnutls.c | 2 -
tls/gnutls/gtlsconnection-gnutls.c | 23 ++++++++-----
tls/gnutls/gtlsconnection-gnutls.h | 1 -
tls/gnutls/gtlsserverconnection-gnutls.c | 2 -
5 files changed, 47 insertions(+), 33 deletions(-)
---
diff --git a/tls/gnutls/gtlscertificate-gnutls.c b/tls/gnutls/gtlscertificate-gnutls.c
index 29e992f..68b6e2d 100644
--- a/tls/gnutls/gtlscertificate-gnutls.c
+++ b/tls/gnutls/gtlscertificate-gnutls.c
@@ -285,10 +285,10 @@ g_tls_certificate_gnutls_verify (GTlsCertificate *cert,
GTlsCertificate *trusted_ca)
{
GTlsCertificateGnutls *cert_gnutls;
- int status;
- guint gnutls_flags, num_certs, i, num_cas;
- gnutls_x509_crt_t *chain, ca;
+ guint num_certs, i;
+ gnutls_x509_crt_t *chain;
GTlsCertificateFlags gtls_flags;
+ time_t t, now;
cert_gnutls = G_TLS_CERTIFICATE_GNUTLS (cert);
for (num_certs = 0; cert_gnutls; cert_gnutls = cert_gnutls->priv->issuer)
@@ -300,28 +300,42 @@ g_tls_certificate_gnutls_verify (GTlsCertificate *cert,
if (trusted_ca)
{
- cert_gnutls = G_TLS_CERTIFICATE_GNUTLS (trusted_ca);
- ca = cert_gnutls->priv->cert;
- num_cas = 1;
+ gnutls_x509_crt_t ca;
+ guint gnutls_flags;
+ int status;
+
+ ca = G_TLS_CERTIFICATE_GNUTLS (trusted_ca)->priv->cert;
+ status = gnutls_x509_crt_list_verify (chain, num_certs,
+ &ca, 1,
+ NULL, 0,
+ GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT,
+ &gnutls_flags);
+ if (status != 0)
+ {
+ g_free (chain);
+ return G_TLS_CERTIFICATE_GENERIC_ERROR;
+ }
+
+ gtls_flags = g_tls_certificate_gnutls_convert_flags (gnutls_flags);
}
- else
+
+ /* We have to check these ourselves since gnutls_x509_crt_list_verify
+ * won't bother if it gets an UNKNOWN_CA.
+ */
+ now = time (NULL);
+ for (i = 0; i < num_certs; i++)
{
- ca = NULL;
- num_cas = 0;
+ t = gnutls_x509_crt_get_activation_time (chain[i]);
+ if (t == (time_t) -1 || t > now)
+ gtls_flags |= G_TLS_CERTIFICATE_NOT_ACTIVATED;
+
+ t = gnutls_x509_crt_get_expiration_time (chain[i]);
+ if (t == (time_t) -1 || t < now)
+ gtls_flags |= G_TLS_CERTIFICATE_EXPIRED;
}
- status = gnutls_x509_crt_list_verify (chain, num_certs,
- &ca, num_cas,
- NULL, 0,
- GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT,
- &gnutls_flags);
g_free (chain);
- if (status != 0)
- return G_TLS_CERTIFICATE_GENERIC_ERROR;
-
- gtls_flags = g_tls_certificate_gnutls_convert_flags (gnutls_flags);
-
if (identity)
gtls_flags |= g_tls_certificate_gnutls_verify_identity (G_TLS_CERTIFICATE_GNUTLS (cert), identity);
diff --git a/tls/gnutls/gtlsclientconnection-gnutls.c b/tls/gnutls/gtlsclientconnection-gnutls.c
index 476a60b..5b2fb95 100644
--- a/tls/gnutls/gtlsclientconnection-gnutls.c
+++ b/tls/gnutls/gtlsclientconnection-gnutls.c
@@ -256,8 +256,6 @@ g_tls_client_connection_gnutls_verify_peer (GTlsConnectionGnutls *conn_gnutls,
GTlsClientConnectionGnutls *gnutls = G_TLS_CLIENT_CONNECTION_GNUTLS (conn_gnutls);
gboolean accepted;
- *errors = g_tls_connection_gnutls_validate_peer (conn_gnutls);
-
if (gnutls->priv->server_identity)
{
*errors |= g_tls_certificate_gnutls_verify_identity (G_TLS_CERTIFICATE_GNUTLS (peer_certificate),
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index de25e4d..6239890 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -442,15 +442,6 @@ g_tls_connection_gnutls_get_certificate (GTlsConnectionGnutls *gnutls,
st->ncerts = 0;
}
-GTlsCertificateFlags
-g_tls_connection_gnutls_validate_peer (GTlsConnectionGnutls *gnutls)
-{
- int status;
-
- status = gnutls_certificate_verify_peers (gnutls->priv->session);
- return g_tls_certificate_gnutls_convert_flags (status);
-}
-
static void
begin_gnutls_io (GTlsConnectionGnutls *gnutls,
gboolean blocking,
@@ -865,6 +856,20 @@ handshake_internal (GTlsConnectionGnutls *gnutls,
if (peer_certificate)
{
+ int status;
+
+ status = gnutls_certificate_verify_peers (gnutls->priv->session);
+ peer_certificate_errors = g_tls_certificate_gnutls_convert_flags (status);
+ if (peer_certificate_errors)
+ {
+ /* gnutls_certificate_verify_peers() bails out on the first
+ * error, which may be G_TLS_CERTIFICATE_UNKNOWN_CA, but the
+ * caller may be planning to check that part themselves. So
+ * call g_tls_certificate_verify() to get any other errors.
+ */
+ peer_certificate_errors |= g_tls_certificate_verify (peer_certificate, NULL, NULL);
+ }
+
if (!G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->verify_peer (gnutls, peer_certificate, &peer_certificate_errors))
{
g_object_unref (peer_certificate);
diff --git a/tls/gnutls/gtlsconnection-gnutls.h b/tls/gnutls/gtlsconnection-gnutls.h
index 0e54df8..fff49af 100644
--- a/tls/gnutls/gtlsconnection-gnutls.h
+++ b/tls/gnutls/gtlsconnection-gnutls.h
@@ -53,7 +53,6 @@ gnutls_certificate_credentials g_tls_connection_gnutls_get_credentials (GTlsConn
gnutls_session g_tls_connection_gnutls_get_session (GTlsConnectionGnutls *connection);
void g_tls_connection_gnutls_get_certificate (GTlsConnectionGnutls *gnutls,
gnutls_retr_st *st);
-GTlsCertificateFlags g_tls_connection_gnutls_validate_peer (GTlsConnectionGnutls *gnutls);
gssize g_tls_connection_gnutls_read (GTlsConnectionGnutls *gnutls,
void *buffer,
diff --git a/tls/gnutls/gtlsserverconnection-gnutls.c b/tls/gnutls/gtlsserverconnection-gnutls.c
index 6e9a8bd..e374b63 100644
--- a/tls/gnutls/gtlsserverconnection-gnutls.c
+++ b/tls/gnutls/gtlsserverconnection-gnutls.c
@@ -174,8 +174,6 @@ g_tls_server_connection_gnutls_verify_peer (GTlsConnectionGnutls *gnutls,
GTlsCertificate *peer_certificate,
GTlsCertificateFlags *errors)
{
- *errors = g_tls_connection_gnutls_validate_peer (G_TLS_CONNECTION_GNUTLS (gnutls));
-
return g_tls_connection_emit_accept_certificate (G_TLS_CONNECTION (gnutls),
peer_certificate, *errors);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]