diff options
author | Christophe Fergeau <cfergeau@redhat.com> | 2014-06-04 11:46:54 +0200 |
---|---|---|
committer | Christophe Fergeau <cfergeau@redhat.com> | 2014-08-13 15:32:07 +0200 |
commit | 0f491306d22a1f27ea84876efd613509458ad945 (patch) | |
tree | b1eb33805610a8101a62df8f0e43095aadfb8ef0 | |
parent | 07814eedb7c002ced35a6699db5f617dccb5498c (diff) |
gnutlsgnutls
-rw-r--r-- | gtk/spice-channel.c | 79 |
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) { |