Make it possible to tell the file loader to use secure memory
authorRichard Levitte <levitte@openssl.org>
Mon, 27 Feb 2017 13:30:00 +0000 (14:30 +0100)
committerRichard Levitte <levitte@openssl.org>
Thu, 29 Jun 2017 17:19:40 +0000 (19:19 +0200)
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3483)

crypto/err/openssl.txt
crypto/store/loader_file.c
crypto/store/store_err.c
doc/man3/OSSL_STORE_open.pod
include/openssl/store.h
include/openssl/storeerr.h

index e5393022b5be7c0482554fec34e89b3b31deddcb..d62957727de456e4ec6ae9e1d30343c9ca9d928a 100644 (file)
@@ -724,6 +724,7 @@ OCSP_F_OCSP_REQUEST_SIGN:110:OCSP_request_sign
 OCSP_F_OCSP_REQUEST_VERIFY:116:OCSP_request_verify
 OCSP_F_OCSP_RESPONSE_GET1_BASIC:111:OCSP_response_get1_basic
 OCSP_F_PARSE_HTTP_LINE1:118:parse_http_line1
+OSSL_STORE_F_FILE_CTRL:129:file_ctrl
 OSSL_STORE_F_FILE_GET_PASS:118:file_get_pass
 OSSL_STORE_F_FILE_LOAD:119:file_load
 OSSL_STORE_F_FILE_LOAD_TRY_DECODE:124:file_load_try_decode
index ea2ec8b7d6cb7e815754adee31592c1ac2f3c0fe..8c8b81eb74a3cc7743501267bce47154e08caf6e 100644 (file)
@@ -623,6 +623,8 @@ struct ossl_store_loader_ctx_st {
         is_dir
     } type;
     int errcnt;
+#define FILE_FLAG_SECMEM         (1<<0)
+    unsigned int flags;
     union {
         struct {                 /* Used with is_raw and is_pem */
             BIO *file;
@@ -767,6 +769,37 @@ static OSSL_STORE_LOADER_CTX *file_open(const OSSL_STORE_LOADER *loader,
     return NULL;
 }
 
+static int file_ctrl(OSSL_STORE_LOADER_CTX *ctx, int cmd, va_list args)
+{
+    int ret = 1;
+
+    switch (cmd) {
+    case OSSL_STORE_C_USE_SECMEM:
+        {
+            int on = *(va_arg(args, int *));
+
+            switch (on) {
+            case 0:
+                ctx->flags &= ~FILE_FLAG_SECMEM;
+                break;
+            case 1:
+                ctx->flags |= FILE_FLAG_SECMEM;
+                break;
+            default:
+                OSSL_STOREerr(OSSL_STORE_F_FILE_CTRL,
+                              ERR_R_PASSED_INVALID_ARGUMENT);
+                ret = 0;
+                break;
+            }
+        }
+        break;
+    default:
+        break;
+    }
+
+    return ret;
+}
+
 static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx,
                                              const char *pem_name,
                                              const char *pem_header,
@@ -879,12 +912,22 @@ static OSSL_STORE_INFO *file_load_try_repeat(OSSL_STORE_LOADER_CTX *ctx,
     return result;
 }
 
+static void pem_free_flag(void *pem_data, int secure)
+{
+    if (secure)
+        OPENSSL_secure_free(pem_data);
+    else
+        OPENSSL_free(pem_data);
+}
 static int file_read_pem(BIO *bp, char **pem_name, char **pem_header,
                          unsigned char **data, long *len,
                          const UI_METHOD *ui_method,
-                         void *ui_data)
+                         void *ui_data, int secure)
 {
-    int i = PEM_read_bio(bp, pem_name, pem_header, data, len);
+    int i = secure
+        ? PEM_read_bio_ex(bp, pem_name, pem_header, data, len,
+                          PEM_FLAG_SECURE | PEM_FLAG_EAY_COMPATIBLE)
+        : PEM_read_bio(bp, pem_name, pem_header, data, len);
 
     if (i <= 0)
         return 0;
@@ -1029,7 +1072,8 @@ static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
             matchcount = -1;
             if (ctx->type == is_pem) {
                 if (!file_read_pem(ctx->_.file.file, &pem_name, &pem_header,
-                                   &data, &len, ui_method, ui_data)) {
+                                   &data, &len, ui_method, ui_data,
+                                   (ctx->flags & FILE_FLAG_SECMEM) != 0)) {
                     ctx->errcnt++;
                     goto endloop;
                 }
@@ -1074,9 +1118,9 @@ static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
                 ctx->errcnt++;
 
          endloop:
-            OPENSSL_free(pem_name);
-            OPENSSL_free(pem_header);
-            OPENSSL_free(data);
+            pem_free_flag(pem_name, (ctx->flags & FILE_FLAG_SECMEM) != 0);
+            pem_free_flag(pem_header, (ctx->flags & FILE_FLAG_SECMEM) != 0);
+            pem_free_flag(data, (ctx->flags & FILE_FLAG_SECMEM) != 0);
         } while (matchcount == 0 && !file_eof(ctx) && !file_error(ctx));
 
         /* We bail out on ambiguity */
@@ -1119,7 +1163,7 @@ static OSSL_STORE_LOADER file_loader =
         "file",
         NULL,
         file_open,
-        NULL,
+        file_ctrl,
         file_load,
         file_eof,
         file_error,
index 681c9ffa284dcea4cc04637f8c8c588499214ad0..8f1a9be195edc455dd89e8a30c32651aae5f9ecb 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef OPENSSL_NO_ERR
 
 static const ERR_STRING_DATA OSSL_STORE_str_functs[] = {
+    {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_CTRL, 0), "file_ctrl"},
     {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_GET_PASS, 0),
      "file_get_pass"},
     {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_LOAD, 0), "file_load"},
index 9a054436d4c3846875b9d9d87c3a7740d8ba68fe..14ce9d28672dc8df6b1816c3703fc2a2eda9b86e 100644 (file)
@@ -58,8 +58,23 @@ OSSL_STORE_load() to manipulate or drop the value to be returned.
 
 OSSL_STORE_ctrl() takes a B<OSSL_STORE_CTX>, and command number B<cmd> and
 more arguments not specified here.
-The available command numbers and arguments they each take depends on
-the loader that's used and is documented together with that loader.
+The available loader specific command numbers and arguments they each
+take depends on the loader that's used and is documented together with
+that loader.
+
+There are also global controls available:
+
+=over 4
+
+=item B<OSSL_STORE_C_USE_SECMEM>
+
+Controls if the loader should attempt to use secure memory for any
+allocated B<OSSL_STORE_INFO> and its contents.
+This control expects one argument, a pointer to an B<int> that is expected to
+have the value 1 (yes) or 0 (no).
+Any other value is an error.
+
+=back
 
 OSSL_STORE_load() takes a B<OSSL_STORE_CTX>, tries to load the next available
 object and return it wrapped with  B<OSSL_STORE_INFO>.
index d3947dfc0f98ab33146c927e5e126cb28a0778ef..c6948f223d09f6cfdd29c4e82ea397bafda6b283 100644 (file)
@@ -62,6 +62,8 @@ int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ... /* args */);
 /*
  * Common ctrl commands that different loaders may choose to support.
  */
+/* int on = 0 or 1; STORE_ctrl(ctx, STORE_C_USE_SECMEM, &on); */
+# define OSSL_STORE_C_USE_SECMEM      1
 /* Where custom commands start */
 # define OSSL_STORE_C_CUSTOM_START    100
 
index 1e0d23c6bdacaa7b5f61e203999aaccae296552a..a049726a3d964c2995dbf63e24360d2ffd95597c 100644 (file)
@@ -22,6 +22,7 @@ int ERR_load_OSSL_STORE_strings(void);
 /*
  * OSSL_STORE function codes.
  */
+# define OSSL_STORE_F_FILE_CTRL                           129
 # define OSSL_STORE_F_FILE_GET_PASS                       118
 # define OSSL_STORE_F_FILE_LOAD                           119
 # define OSSL_STORE_F_FILE_LOAD_TRY_DECODE                124