From 533b9cb6fe0524c31a25d947f525c859b4c84ff9 Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Wed, 6 Aug 2014 01:54:01 +0000
Subject: Add support for loading the public/private key from memory, rather
 than directly from file.

---
 src/lib/libressl/ressl.c          | 82 ++++++++++++++++++++++++++++++++++-----
 src/lib/libressl/ressl.h          |  6 ++-
 src/lib/libressl/ressl_config.c   | 16 +++++++-
 src/lib/libressl/ressl_internal.h |  6 ++-
 4 files changed, 97 insertions(+), 13 deletions(-)

(limited to 'src/lib')

diff --git a/src/lib/libressl/ressl.c b/src/lib/libressl/ressl.c
index f026da52b5..01d1610e3f 100644
--- a/src/lib/libressl/ressl.c
+++ b/src/lib/libressl/ressl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ressl.c,v 1.10 2014/08/05 12:46:16 jsing Exp $ */
+/* $OpenBSD: ressl.c,v 1.11 2014/08/06 01:54:01 jsing Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -21,6 +21,11 @@
 #include <stdlib.h>
 #include <unistd.h>
 
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+
 #include <ressl.h>
 #include "ressl_internal.h"
 
@@ -97,21 +102,78 @@ ressl_configure(struct ressl *ctx, struct ressl_config *config)
 int
 ressl_configure_keypair(struct ressl *ctx)
 {
-	if (SSL_CTX_use_certificate_file(ctx->ssl_ctx, ctx->config->cert_file,
-	    SSL_FILETYPE_PEM) != 1) {
-		ressl_set_error(ctx, "failed to load certificate");
-		return (1);
+	EVP_PKEY *pkey = NULL;
+	X509 *cert = NULL;
+	BIO *bio = NULL;
+
+	if (ctx->config->cert_mem != NULL) {
+		if ((bio = BIO_new_mem_buf(ctx->config->cert_mem,
+		    ctx->config->cert_len)) == NULL) {
+			ressl_set_error(ctx, "failed to create buffer");
+			goto err;
+		}
+		if ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) {
+			ressl_set_error(ctx, "failed to read certificate");
+			goto err;
+		}
+		if (SSL_CTX_use_certificate(ctx->ssl_ctx, cert) != 1) {
+			ressl_set_error(ctx, "failed to load certificate");
+			goto err;
+		}
+		BIO_free(bio);
+		bio = NULL;
+		X509_free(cert);
+		cert = NULL;
 	}
-	if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx, ctx->config->key_file,
-	    SSL_FILETYPE_PEM) != 1) {
-		ressl_set_error(ctx, "failed to load private key");
-		return (1);
+	if (ctx->config->key_mem != NULL) {
+		if ((bio = BIO_new_mem_buf(ctx->config->key_mem,
+		    ctx->config->key_len)) == NULL) {
+			ressl_set_error(ctx, "failed to create buffer");
+			goto err;
+		}
+		if ((pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL,
+		    NULL)) == NULL) {
+			ressl_set_error(ctx, "failed to read private key");
+			goto err;
+		}
+		if (SSL_CTX_use_PrivateKey(ctx->ssl_ctx, pkey) != 1) {
+			ressl_set_error(ctx, "failed to load private key");
+			goto err;
+		}
+		BIO_free(bio);
+		bio = NULL;
+		EVP_PKEY_free(pkey);
+		pkey = NULL;
 	}
+
+	if (ctx->config->cert_file != NULL) {
+		if (SSL_CTX_use_certificate_file(ctx->ssl_ctx,
+		    ctx->config->cert_file, SSL_FILETYPE_PEM) != 1) {
+			ressl_set_error(ctx, "failed to load certificate file");
+			goto err;
+		}
+	}
+	if (ctx->config->key_file != NULL) {
+		if (SSL_CTX_use_PrivateKey_file(ctx->ssl_ctx,
+		    ctx->config->key_file, SSL_FILETYPE_PEM) != 1) {
+			ressl_set_error(ctx, "failed to load private key file");
+			goto err;
+		}
+	}
+
 	if (SSL_CTX_check_private_key(ctx->ssl_ctx) != 1) {
 		ressl_set_error(ctx, "private/public key mismatch");
-		return (1);
+		goto err;
 	}
+
 	return (0);
+
+err:
+	EVP_PKEY_free(pkey);
+	X509_free(cert);
+	BIO_free(bio);
+
+	return (1);
 }
 
 void
diff --git a/src/lib/libressl/ressl.h b/src/lib/libressl/ressl.h
index b9ae809be4..0b437c4ad9 100644
--- a/src/lib/libressl/ressl.h
+++ b/src/lib/libressl/ressl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ressl.h,v 1.10 2014/08/05 12:46:16 jsing Exp $ */
+/* $OpenBSD: ressl.h,v 1.11 2014/08/06 01:54:01 jsing Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -34,8 +34,12 @@ void ressl_config_free(struct ressl_config *config);
 void ressl_config_set_ca_file(struct ressl_config *config, char *ca_file);
 void ressl_config_set_ca_path(struct ressl_config *config, char *ca_path);
 void ressl_config_set_cert_file(struct ressl_config *config, char *cert_file);
+void ressl_config_set_cert_mem(struct ressl_config *config, char *cert,
+    size_t len);
 void ressl_config_set_ciphers(struct ressl_config *config, char *ciphers);
 void ressl_config_set_key_file(struct ressl_config *config, char *key_file);
+void ressl_config_set_key_mem(struct ressl_config *config, char *key,
+    size_t len);
 void ressl_config_set_verify_depth(struct ressl_config *config,
     int verify_depth);
 
diff --git a/src/lib/libressl/ressl_config.c b/src/lib/libressl/ressl_config.c
index 60307d66b3..133ef81b02 100644
--- a/src/lib/libressl/ressl_config.c
+++ b/src/lib/libressl/ressl_config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ressl_config.c,v 1.6 2014/08/05 12:46:16 jsing Exp $ */
+/* $OpenBSD: ressl_config.c,v 1.7 2014/08/06 01:54:01 jsing Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -69,6 +69,13 @@ ressl_config_set_cert_file(struct ressl_config *config, char *cert_file)
 	config->cert_file = cert_file;
 }
 
+void
+ressl_config_set_cert_mem(struct ressl_config *config, char *cert, size_t len)
+{
+	config->cert_mem = cert;
+	config->cert_len = len;
+}
+
 void
 ressl_config_set_ciphers(struct ressl_config *config, char *ciphers)
 {
@@ -81,6 +88,13 @@ ressl_config_set_key_file(struct ressl_config *config, char *key_file)
 	config->key_file = key_file;
 }
 
+void
+ressl_config_set_key_mem(struct ressl_config *config, char *key, size_t len)
+{
+	config->key_mem = key;
+	config->key_len = len;
+}
+
 void
 ressl_config_set_verify_depth(struct ressl_config *config, int verify_depth)
 {
diff --git a/src/lib/libressl/ressl_internal.h b/src/lib/libressl/ressl_internal.h
index b7158bce9a..3f667526ad 100644
--- a/src/lib/libressl/ressl_internal.h
+++ b/src/lib/libressl/ressl_internal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ressl_internal.h,v 1.8 2014/08/05 12:46:16 jsing Exp $ */
+/* $OpenBSD: ressl_internal.h,v 1.9 2014/08/06 01:54:01 jsing Exp $ */
 /*
  * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
@@ -29,8 +29,12 @@ struct ressl_config {
 	const char *ca_file;
 	const char *ca_path;
 	const char *cert_file;
+	char *cert_mem;
+	size_t cert_len;
 	const char *ciphers;
 	const char *key_file;
+	char *key_mem;
+	size_t key_len;
 	int verify;
 	int verify_depth;
 };
-- 
cgit v1.2.3-55-g6feb