Add support for loading the public/private key from memory, rather than
authorjsing <jsing@openbsd.org>
Wed, 6 Aug 2014 01:54:01 +0000 (01:54 +0000)
committerjsing <jsing@openbsd.org>
Wed, 6 Aug 2014 01:54:01 +0000 (01:54 +0000)
directly from file.

lib/libressl/ressl.c
lib/libressl/ressl.h
lib/libressl/ressl_config.c
lib/libressl/ressl_internal.h

index f026da5..01d1610 100644 (file)
@@ -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>
  *
 #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
index b9ae809..0b437c4 100644 (file)
@@ -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);
 
index 60307d6..133ef81 100644 (file)
@@ -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)
 {
index b7158bc..3f66752 100644 (file)
@@ -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;
 };