Add internal functions to fetch PEM data from an opened BIO
authorRichard Levitte <levitte@openssl.org>
Tue, 6 Dec 2016 13:41:33 +0000 (14:41 +0100)
committerRichard Levitte <levitte@openssl.org>
Thu, 29 Jun 2017 17:25:39 +0000 (19:25 +0200)
store_attach_pem_bio() creates a STORE_CTX with the 'file' scheme
loader backend in PEM reading mode on an already opened BIO.
store_detach_pem_bio() detaches the STORE_CTX from the BIO and
destroys it (without destroying the BIO).

These two functions can be used in place of STORE_open() and
STORE_close(), and are present as internal support for other OpenSSL
functions.

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2745)

crypto/err/openssl.txt
crypto/include/internal/store_int.h [new file with mode: 0644]
crypto/store/loader_file.c
crypto/store/store_err.c
crypto/store/store_lib.c
crypto/store/store_locl.h
include/openssl/storeerr.h

index d629577..87aea05 100644 (file)
@@ -730,6 +730,9 @@ OSSL_STORE_F_FILE_LOAD:119:file_load
 OSSL_STORE_F_FILE_LOAD_TRY_DECODE:124:file_load_try_decode
 OSSL_STORE_F_FILE_NAME_TO_URI:126:file_name_to_uri
 OSSL_STORE_F_FILE_OPEN:120:file_open
+OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO:127:ossl_store_attach_pem_bio
+OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT:128:\
+       ossl_store_file_attach_pem_bio_int
 OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT:100:ossl_store_get0_loader_int
 OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT:101:OSSL_STORE_INFO_get1_CERT
 OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL:102:OSSL_STORE_INFO_get1_CRL
diff --git a/crypto/include/internal/store_int.h b/crypto/include/internal/store_int.h
new file mode 100644 (file)
index 0000000..9966aef
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_STORE_INT_H
+# define HEADER_STORE_INT_H
+
+# include <openssl/bio.h>
+# include <openssl/store.h>
+# include <openssl/ui.h>
+
+# ifdef  __cplusplus
+extern "C" {
+# endif
+
+/*
+ * Two functions to read PEM data off an already opened BIO.  To be used
+ * instead of OSSLSTORE_open() and OSSLSTORE_close().  Everything is done
+ * as usual with OSSLSTORE_load() and OSSLSTORE_eof().
+ */
+OSSL_STORE_CTX *ossl_store_attach_pem_bio(BIO *bp, const UI_METHOD *ui_method,
+                                          void *ui_data);
+int ossl_store_detach_pem_bio(OSSL_STORE_CTX *ctx);
+
+# ifdef  __cplusplus
+}
+# endif
+#endif
index 8c8b81e..2b0f213 100644 (file)
@@ -25,6 +25,7 @@
 #include "internal/asn1_int.h"
 #include "internal/o_dir.h"
 #include "internal/cryptlib.h"
+#include "internal/store_int.h"
 #include "store_locl.h"
 
 #include "e_os.h"
@@ -800,6 +801,23 @@ static int file_ctrl(OSSL_STORE_LOADER_CTX *ctx, int cmd, va_list args)
     return ret;
 }
 
+/* Internal function to decode an already opened PEM file */
+OSSL_STORE_LOADER_CTX *ossl_store_file_attach_pem_bio_int(BIO *bp)
+{
+    OSSL_STORE_LOADER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    if (ctx == NULL) {
+        OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT,
+                      ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+
+    ctx->_.file.file = bp;
+    ctx->type = is_pem;
+
+    return ctx;
+}
+
 static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx,
                                              const char *pem_name,
                                              const char *pem_header,
@@ -1158,6 +1176,12 @@ static int file_close(OSSL_STORE_LOADER_CTX *ctx)
     return 1;
 }
 
+int ossl_store_file_detach_pem_bio_int(OSSL_STORE_LOADER_CTX *ctx)
+{
+    OSSL_STORE_LOADER_CTX_free(ctx);
+    return 1;
+}
+
 static OSSL_STORE_LOADER file_loader =
     {
         "file",
index 8f1a9be..aad643b 100644 (file)
@@ -23,6 +23,10 @@ static const ERR_STRING_DATA OSSL_STORE_str_functs[] = {
     {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_NAME_TO_URI, 0),
      "file_name_to_uri"},
     {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_OPEN, 0), "file_open"},
+    {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO, 0),
+     "ossl_store_attach_pem_bio"},
+    {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT, 0),
+     "ossl_store_file_attach_pem_bio_int"},
     {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT, 0),
      "ossl_store_get0_loader_int"},
     {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT, 0),
index 2c8ce86..d5bb8b8 100644 (file)
@@ -14,6 +14,7 @@
 #include <openssl/err.h>
 #include <openssl/store.h>
 #include "internal/thread_once.h"
+#include "internal/store_int.h"
 #include "store_locl.h"
 
 struct ossl_store_ctx_st {
@@ -407,3 +408,46 @@ char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info)
         return info->_.embedded.pem_name;
     return NULL;
 }
+
+OSSL_STORE_CTX *ossl_store_attach_pem_bio(BIO *bp, const UI_METHOD *ui_method,
+                                          void *ui_data)
+{
+    OSSL_STORE_CTX *ctx = NULL;
+    const OSSL_STORE_LOADER *loader = NULL;
+    OSSL_STORE_LOADER_CTX *loader_ctx = NULL;
+
+    if ((loader = ossl_store_get0_loader_int("file")) == NULL
+        || ((loader_ctx = ossl_store_file_attach_pem_bio_int(bp)) == NULL))
+        goto done;
+    if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
+        OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO,
+                     ERR_R_MALLOC_FAILURE);
+        goto done;
+    }
+
+    ctx->loader = loader;
+    ctx->loader_ctx = loader_ctx;
+    loader_ctx = NULL;
+    ctx->ui_method = ui_method;
+    ctx->ui_data = ui_data;
+    ctx->post_process = NULL;
+    ctx->post_process_data = NULL;
+
+ done:
+    if (loader_ctx != NULL)
+        /*
+         * We ignore a returned error because we will return NULL anyway in
+         * this case, so if something goes wrong when closing, that'll simply
+         * just add another entry on the error stack.
+         */
+        (void)loader->close(loader_ctx);
+    return ctx;
+}
+
+int ossl_store_detach_pem_bio(OSSL_STORE_CTX *ctx)
+{
+    int loader_ret = ossl_store_file_detach_pem_bio_int(ctx->loader_ctx);
+
+    OPENSSL_free(ctx);
+    return loader_ret;
+}
index a954c57..789d332 100644 (file)
@@ -92,3 +92,11 @@ void ossl_store_destroy_loaders_int(void);
 
 int ossl_store_init_once(void);
 int ossl_store_file_loader_init(void);
+
+/*-
+ *  'file' scheme stuff
+ *  -------------------
+ */
+
+OSSL_STORE_LOADER_CTX *ossl_store_file_attach_pem_bio_int(BIO *bp);
+int ossl_store_file_detach_pem_bio_int(OSSL_STORE_LOADER_CTX *ctx);
index a049726..4e0818d 100644 (file)
@@ -28,6 +28,8 @@ int ERR_load_OSSL_STORE_strings(void);
 # define OSSL_STORE_F_FILE_LOAD_TRY_DECODE                124
 # define OSSL_STORE_F_FILE_NAME_TO_URI                    126
 # define OSSL_STORE_F_FILE_OPEN                           120
+# define OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO           127
+# define OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT  128
 # define OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT          100
 # define OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT           101
 # define OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL            102