summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Fergeau <cfergeau@redhat.com>2014-06-04 11:46:54 +0200
committerChristophe Fergeau <cfergeau@redhat.com>2014-08-13 15:32:07 +0200
commit0f491306d22a1f27ea84876efd613509458ad945 (patch)
treeb1eb33805610a8101a62df8f0e43095aadfb8ef0
parent07814eedb7c002ced35a6699db5f617dccb5498c (diff)
gnutlsgnutls
-rw-r--r--gtk/spice-channel.c79
1 files changed, 78 insertions, 1 deletions
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index c5d3661..e57fdbe 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -2238,6 +2238,7 @@ static int spice_channel_load_ca(SpiceChannel *channel)
gnutls_datum_t ca_data;
g_return_val_if_fail(c->ctx != NULL, 0);
+ //g_return_val_if_fail(channel->priv->tls_ca != NULL, 0);
rc = gnutls_certificate_allocate_credentials (&channel->priv->tls_ca);
if (rc != GNUTLS_E_SUCCESS) {
@@ -2640,7 +2641,7 @@ spice_channel_gnutls_verify_hostname (SpiceChannel *channel)
gnutls_strerror(rc));
goto end;
}
- g_warning("got subject!! %d %s", cert_subject.size, (char *)cert_subject.data);
+ // g_warning("got subject!! %d %s", cert_subject.size, (char *)cert_subject.data);
subject_datum.data = (unsigned char *)subject;
subject_datum.size = strlen(subject);
if (!spice_channel_gnutls_compare_rfc4514(&cert_subject, &subject_datum)) {
@@ -2663,6 +2664,82 @@ end:
return verified;
}
+static gboolean
+spice_channel_gnutls_verify(SpiceChannel *channel)
+{
+ unsigned int failed_verifications = 0
+ /* FIXME: if spice_channel_load_ca is not called, the connection
+ * will have no trusted CAs */
+ /* FIXME: could be done as soon as the options are set on SpiceSession
+ * since with GNUTLS the truststore is global */
+ verify = spice_session_get_verify(c->session);
+ if (verify & (SPICE_SESSION_VERIFY_SUBJECT | SPICE_SESSION_VERIFY_HOSTNAME)) {
+ rc = spice_channel_load_ca(channel);
+ if (rc == 0) {
+ g_warning("no cert loaded");
+ if (verify & SPICE_SESSION_VERIFY_PUBKEY) {
+ g_warning("only pubkey active");
+ verify = SPICE_SESSION_VERIFY_PUBKEY;
+ } else {
+ return FALSE;
+ }
+ }
+ }
+
+/* TODO Accept self-signed certificate if VERIFY_PUBKEY is set */
+/* -> PUBKEY is only used during migration to older RHEL versions,
+ * let's assume we have a --spice-ca-cert in this case, at worse
+ * we can reuse the same one as the first connection
+ */
+ if (verify & SPICE_SESSION_VERIFY_PUBKEY)
+ if (verify_pubkey(cert, v->pubkey, v->pubkey_size))
+ return TRUE;
+ else
+ failed_verifications |= SPICE_SESSION_VERIFY_PUBKEY;
+ }
+
+ if (!preverify_ok) {
+ err = X509_STORE_CTX_get_error(ctx);
+ depth = X509_STORE_CTX_get_error_depth(ctx);
+ spice_warning("Error in server certificate verification: %s (num=%d:depth%d:%s)",
+ X509_verify_cert_error_string(err), err, depth, buf);
+ return FALSE;
+ }
+ if (!v->all_preverify_ok) {
+ return FALSE;
+ }
+
+ if (verify & SPICE_SESSION_VERIFY_SUBJECT) {
+ if (verify_subject(cert, v))
+ return TRUE;
+ else
+ failed_verifications |= SPICE_SESSION_VERIFY_SUBJECT;
+ } else if (verify & SPICE_SESSION_VERIFY_HOSTNAME) {
+ if (verify_hostname(cert, v->hostname))
+ return TRUE;
+ else
+ failed_verifications |= SPICE_SESSION_VERIFY_HOSTNAME;
+ }
+
+ /* If we reach this code, this means all the tests failed, thus
+ * verification failed
+ */
+ if (failed_verifications & SPICE_SESSION_VERIFY_PUBKEY)
+ spice_warning("ssl: pubkey verification failed");
+
+ if (failed_verifications & SPICE_SESSION_VERIFY_HOSTNAME)
+ spice_warning("ssl: hostname '%s' verification failed", v->hostname);
+
+ if (failed_verifications & SPICE_SESSION_VERIFY_SUBJECT)
+ spice_warning("ssl: subject '%s' verification failed", v->subject);
+
+ spice_warning("ssl: verification failed");
+
+ return 0;
+
+ return TRUE;
+}
+
/* coroutine context */
static void *spice_channel_coroutine(void *data)
{