[Spice-devel] [PATCH spice-gtk 2/2] channel: learn to load certificate from memory
Marc-André Lureau
marcandre.lureau at gmail.com
Mon Nov 19 12:52:02 PST 2012
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!
---
gtk/spice-channel.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 61 insertions(+), 8 deletions(-)
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;
--
1.7.11.7
More information about the Spice-devel
mailing list