Refactor PEM_read_bio_{PrivateKey,Parameters,DHparams}#2746
Refactor PEM_read_bio_{PrivateKey,Parameters,DHparams}#2746levitte wants to merge 2 commits intoopenssl:masterfrom
Conversation
|
This seems like it might make it harder for #1700 to achieve its goal of using memory from the secure heap for the temporary buffer used while reading private keys from disk. |
|
Not really, but the proper place would be to introduce secure heap in |
|
I just added some code in #2011 that adds support for finer control of loaders. With that, the following diff should provide fairly good support for what you do in #1700, no? diff --git a/crypto/store/loader_file.c b/crypto/store/loader_file.c
index 9d7e860dec..b59ecf6113 100644
--- a/crypto/store/loader_file.c
+++ b/crypto/store/loader_file.c
@@ -551,6 +551,8 @@ struct store_loader_ctx_st {
is_pem,
is_dir
} type;
+#define FILE_FLAG_SECMEM (1<<0)
+ unsigned int flags;
union {
struct { /* Used with is_raw and is_pem */
BIO *file;
@@ -737,6 +739,36 @@ static STORE_LOADER_CTX *file_open(const char *scheme, const char *user,
return NULL;
}
+int file_ctrl(STORE_LOADER_CTX *ctx, int cmd, va_list args)
+{
+ int ret = 1;
+
+ switch (cmd) {
+ case 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:
+ STOREerr(STORE_F_FILE_CTRL, ERR_R_PASSED_INVALID_ARGUMENT);
+ ret = 0;
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
static STORE_INFO *file_load_try_decode(STORE_LOADER_CTX *ctx,
const char *pem_name,
const char *pem_header,
@@ -862,12 +894,22 @@ static STORE_INFO *file_load_try_repeat(STORE_LOADER_CTX *ctx,
return result;
}
+static void pem_free_flag(char *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_flags(bp, pem_name, pem_header, data, len,
+ PEM_FLAG_SECURE);
+ : PEM_read_bio(bp, pem_name, pem_header, data, len);
if (i <= 0)
return 0;
@@ -881,9 +923,9 @@ static int file_read_pem(BIO *bp, char **pem_name, char **pem_header,
ui_data)
|| !PEM_do_header(&cipher, *data, len, file_get_pem_pass,
&pass_data)) {
- OPENSSL_free(*pem_name);
- OPENSSL_free(*pem_header);
- OPENSSL_free(*data);
+ pem_free_flag(*pem_name, secure);
+ pem_free_flag(*pem_header, secure);
+ pem_free_flag(*data, secure);
*pem_name = NULL;
*pem_header = NULL;
*data = NULL;
@@ -1064,7 +1106,8 @@ static STORE_INFO *file_load(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))
goto err;
} else {
if (!file_read_asn1(ctx->_.file.file, &data, &len))
@@ -1075,9 +1118,9 @@ static STORE_INFO *file_load(STORE_LOADER_CTX *ctx,
ui_method, ui_data, &matchcount);
err:
- 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));
/* We bail out on ambiguity */
diff --git a/include/openssl/store.h b/include/openssl/store.h
index e73b1df01b..f8ee6cd5be 100644
--- a/include/openssl/store.h
+++ b/include/openssl/store.h
@@ -70,6 +70,8 @@ int STORE_ctrl(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 STORE_C_USE_SECMEM 1
/* Where custom commands start */
# define STORE_C_CUSTOM_START 100
|
|
To finalize support in this PR: diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c
index 01b9828534..8b9d014a8e 100644
--- a/crypto/pem/pem_pkey.c
+++ b/crypto/pem/pem_pkey.c
@@ -38,6 +38,13 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
if ((ctx = store_attach_pem_bio(bp, ui_method, u)) == NULL)
goto err;
+#ifndef OPENSSL_NO_SECURE_HEAP
+ {
+ int on = 1;
+ if (STORE_ctrl(ctx, STORE_C_USE_SECMEM, &on))
+ goto err;
+ }
+#endif
while ((info = STORE_load(ctx)) != NULL
&& STORE_INFO_get_type(info) != STORE_INFO_UNSPECIFIED) {
@@ -88,6 +95,13 @@ EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
if ((ctx = store_attach_pem_bio(bp, UI_null(), NULL)) == NULL)
goto err;
+#ifndef OPENSSL_NO_SECURE_HEAP
+ {
+ int on = 1;
+ if (STORE_ctrl(ctx, STORE_C_USE_SECMEM, &on))
+ goto err;
+ }
+#endif
while ((info = STORE_load(ctx)) != NULL
&& STORE_INFO_get_type(info) != STORE_INFO_UNSPECIFIED) {
@@ -171,6 +185,13 @@ DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u)
if ((ctx = store_attach_pem_bio(bp, ui_method, u)) == NULL)
goto err;
+#ifndef OPENSSL_NO_SECURE_HEAP
+ {
+ int on = 1;
+ if (STORE_ctrl(ctx, STORE_C_USE_SECMEM, &on))
+ goto err;
+ }
+#endif
while ((info = STORE_load(ctx)) != NULL
&& STORE_INFO_get_type(info) != STORE_INFO_UNSPECIFIED) { |
|
Note: I haven't tested those diffs |
649a277 to
cd25258
Compare
0b038f1 to
f1869df
Compare
14e4413 to
3be3b04
Compare
3be3b04 to
c281833
Compare
c281833 to
14c38e5
Compare
14c38e5 to
fd96afe
Compare
fd96afe to
815a3be
Compare
815a3be to
27bc94e
Compare
a022b4f to
dc0b767
Compare
dc0b767 to
318c5f5
Compare
|
Needs a rebase |
They now go through internal STORE routines to do their job.
Domain parameters are public data, so secure heap is unnecessary for them
318c5f5 to
da1015e
Compare
|
Rebased and fixups added |
They now go through internal STORE routines to do their job. Reviewed-by: Matt Caswell <[email protected]> (Merged from #2746)
|
Merged. 1427d33 Refactor PEM_read_bio_{PrivateKey,Parameters,DHparams} |
They now go through internal STORE routines to do their job.
Just like #2696 and #2697, this PR will not build correctly until #3542, #2745 and #3483 have been approved and merged.