From 7852f588a651ee30256678a23a6162a3b2fb822f Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Mon, 27 Feb 2017 14:30:00 +0100 Subject: [PATCH] Make it possible to tell the file loader to use secure memory Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/3483) --- crypto/err/openssl.txt | 1 + crypto/store/loader_file.c | 58 +++++++++++++++++++++++++++++++----- crypto/store/store_err.c | 1 + doc/man3/OSSL_STORE_open.pod | 19 ++++++++++-- include/openssl/store.h | 2 ++ include/openssl/storeerr.h | 1 + 6 files changed, 73 insertions(+), 9 deletions(-) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index e5393022b5..d62957727d 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -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 diff --git a/crypto/store/loader_file.c b/crypto/store/loader_file.c index ea2ec8b7d6..8c8b81eb74 100644 --- a/crypto/store/loader_file.c +++ b/crypto/store/loader_file.c @@ -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, diff --git a/crypto/store/store_err.c b/crypto/store/store_err.c index 681c9ffa28..8f1a9be195 100644 --- a/crypto/store/store_err.c +++ b/crypto/store/store_err.c @@ -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"}, diff --git a/doc/man3/OSSL_STORE_open.pod b/doc/man3/OSSL_STORE_open.pod index 9a054436d4..14ce9d2867 100644 --- a/doc/man3/OSSL_STORE_open.pod +++ b/doc/man3/OSSL_STORE_open.pod @@ -58,8 +58,23 @@ OSSL_STORE_load() to manipulate or drop the value to be returned. OSSL_STORE_ctrl() takes a B, and command number B 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 + +Controls if the loader should attempt to use secure memory for any +allocated B and its contents. +This control expects one argument, a pointer to an B 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, tries to load the next available object and return it wrapped with B. diff --git a/include/openssl/store.h b/include/openssl/store.h index d3947dfc0f..c6948f223d 100644 --- a/include/openssl/store.h +++ b/include/openssl/store.h @@ -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 diff --git a/include/openssl/storeerr.h b/include/openssl/storeerr.h index 1e0d23c6bd..a049726a3d 100644 --- a/include/openssl/storeerr.h +++ b/include/openssl/storeerr.h @@ -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 -- GitLab