[Spice-commits] 2 commits - gtk/spice-channel.c gtk/spice-session.c gtk/spice-session-priv.h
Marc-André Lureau
elmarco at kemper.freedesktop.org
Thu Nov 22 10:11:39 PST 2012
gtk/spice-channel.c | 69 +++++++++++++++++++++++++++++++++++++++++------
gtk/spice-session-priv.h | 2 +
gtk/spice-session.c | 46 +++++++++++++++++++++++++++++--
3 files changed, 107 insertions(+), 10 deletions(-)
New commits:
commit 1625aef30129d1961bead56bfcc1727ed46d1df3
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Mon Nov 19 21:47:41 2012 +0100
channel: learn to load certificate from memory
Sadly, OpenSSL doesn't provide a way to load certificate from memory,
but all the functions necessary to do so are actually public, so we
can implement our own version and avoid files, how awesome!
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
index fea46d7..500935a 100644
--- a/gtk/spice-channel.c
+++ b/gtk/spice-channel.c
@@ -2087,6 +2087,64 @@ static gboolean spice_channel_delayed_unref(gpointer data)
return FALSE;
}
+static X509_LOOKUP_METHOD spice_x509_mem_lookup = {
+ "spice_x509_mem_lookup",
+ 0
+};
+
+static int spice_channel_load_ca(SpiceChannel *channel)
+{
+ SpiceChannelPrivate *c = channel->priv;
+ STACK_OF(X509_INFO) *inf;
+ X509_INFO *itmp;
+ X509_LOOKUP *lookup;
+ BIO *in;
+ int i, count = 0;
+ guint8 *ca;
+ guint size;
+ const gchar *ca_file;
+
+ g_return_val_if_fail(c->ctx != NULL, 0);
+
+ lookup = X509_STORE_add_lookup(c->ctx->cert_store, &spice_x509_mem_lookup);
+ ca_file = spice_session_get_ca_file(c->session);
+ spice_session_get_ca(c->session, &ca, &size);
+
+ CHANNEL_DEBUG(channel, "Load CA, file: %s, data: %p", ca_file, ca);
+ g_warn_if_fail(ca_file || ca);
+
+ if (ca != NULL) {
+ in = BIO_new_mem_buf(ca, size);
+ inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
+ BIO_free(in);
+
+ for (i = 0; i < sk_X509_INFO_num(inf); i++) {
+ itmp = sk_X509_INFO_value(inf, i);
+ if (itmp->x509) {
+ X509_STORE_add_cert(lookup->store_ctx, itmp->x509);
+ count++;
+ }
+ if (itmp->crl) {
+ X509_STORE_add_crl(lookup->store_ctx, itmp->crl);
+ count++;
+ }
+ }
+
+ sk_X509_INFO_pop_free(inf, X509_INFO_free);
+ }
+
+ if (ca_file != NULL) {
+ int rc = SSL_CTX_load_verify_locations(c->ctx, ca_file, NULL);
+ if (rc != 1)
+ g_warning("loading ca certs from %s failed", ca_file);
+ else
+ count++;
+ }
+
+ return count;
+}
+
+
/* coroutine context */
static void *spice_channel_coroutine(void *data)
{
@@ -2142,14 +2200,9 @@ reconnect:
verify = spice_session_get_verify(c->session);
if (verify &
(SPICE_SESSION_VERIFY_SUBJECT | SPICE_SESSION_VERIFY_HOSTNAME)) {
- const gchar *ca_file = spice_session_get_ca_file (c->session);
-
- g_warn_if_fail(ca_file != NULL);
- CHANNEL_DEBUG(channel, "CA file: %s", ca_file);
- rc = SSL_CTX_load_verify_locations(c->ctx, ca_file, NULL);
-
- if (rc != 1) {
- g_warning("loading ca certs from %s failed", ca_file);
+ 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;
commit caeb29b507996b9e70e10c568ed5c85deeddda11
Author: Marc-André Lureau <marcandre.lureau at redhat.com>
Date: Thu Nov 22 19:05:52 2012 +0100
Add SpiceSession:ca property
diff --git a/gtk/spice-session-priv.h b/gtk/spice-session-priv.h
index 13345b4..804658d 100644
--- a/gtk/spice-session-priv.h
+++ b/gtk/spice-session-priv.h
@@ -40,6 +40,7 @@ struct _SpiceSessionPrivate {
char *ca_file;
char *ciphers;
GByteArray *pubkey;
+ GByteArray *ca;
char *cert_subject;
guint verify;
gboolean read_only;
@@ -135,6 +136,7 @@ const gchar* spice_session_get_host(SpiceSession *session);
const gchar* spice_session_get_cert_subject(SpiceSession *session);
const gchar* spice_session_get_ciphers(SpiceSession *session);
const gchar* spice_session_get_ca_file(SpiceSession *session);
+void spice_session_get_ca(SpiceSession *session, guint8 **ca, guint *size);
void spice_session_set_caches_hints(SpiceSession *session,
uint32_t pci_ram_size,
diff --git a/gtk/spice-session.c b/gtk/spice-session.c
index 526d05b..85cc14d 100644
--- a/gtk/spice-session.c
+++ b/gtk/spice-session.c
@@ -103,6 +103,7 @@ enum {
PROP_GLZ_WINDOW_SIZE,
PROP_UUID,
PROP_NAME,
+ PROP_CA,
};
/* signals */
@@ -233,8 +234,8 @@ spice_session_finalize(GObject *gobject)
spice_session_images_clear(session);
glz_decoder_window_destroy(s->glz_window);
- if (s->pubkey)
- g_byte_array_unref(s->pubkey);
+ g_clear_pointer(&s->pubkey, g_byte_array_unref);
+ g_clear_pointer(&s->ca, g_byte_array_unref);
/* Chain up to the parent class */
if (G_OBJECT_CLASS(spice_session_parent_class)->finalize)
@@ -437,6 +438,9 @@ static void spice_session_get_property(GObject *gobject,
case PROP_PUBKEY:
g_value_set_boxed(value, s->pubkey);
break;
+ case PROP_CA:
+ g_value_set_boxed(value, s->ca);
+ break;
case PROP_CERT_SUBJECT:
g_value_set_string(value, s->cert_subject);
break;
@@ -596,6 +600,10 @@ static void spice_session_set_property(GObject *gobject,
case PROP_GLZ_WINDOW_SIZE:
s->glz_window_size = g_value_get_int(value);
break;
+ case PROP_CA:
+ g_clear_pointer(&s->ca, g_byte_array_unref);
+ s->ca = g_value_dup_boxed(value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
break;
@@ -950,6 +958,27 @@ static void spice_session_class_init(SpiceSessionClass *klass)
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
+ * SpiceSession:ca:
+ *
+ * CA certificates in PEM format. The text data can contain
+ * several CA certificates identified by:
+ *
+ * -----BEGIN CERTIFICATE-----
+ * ... (CA certificate in base64 encoding) ...
+ * -----END CERTIFICATE-----
+ *
+ * Since: 0.15
+ **/
+ g_object_class_install_property
+ (gobject_class, PROP_CA,
+ g_param_spec_boxed("ca",
+ "CA",
+ "The CA certificates data",
+ G_TYPE_BYTE_ARRAY,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
* SpiceSession::channel-new:
* @session: the session that emitted the signal
* @channel: the new #SpiceChannel
@@ -1772,6 +1801,19 @@ void spice_session_get_pubkey(SpiceSession *session, guint8 **pubkey, guint *siz
}
G_GNUC_INTERNAL
+void spice_session_get_ca(SpiceSession *session, guint8 **ca, guint *size)
+{
+ SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session);
+
+ g_return_if_fail(s != NULL);
+ g_return_if_fail(ca != NULL);
+ g_return_if_fail(size != NULL);
+
+ *ca = s->ca ? s->ca->data : NULL;
+ *size = s->ca ? s->ca->len : 0;
+}
+
+G_GNUC_INTERNAL
guint spice_session_get_verify(SpiceSession *session)
{
SpiceSessionPrivate *s = SPICE_SESSION_GET_PRIVATE(session);
More information about the Spice-commits
mailing list