]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
pem_read_bio_key: Add passphrase caching to avoid asking for password twice
authorTomas Mraz <tomas@openssl.org>
Tue, 29 Jun 2021 14:24:59 +0000 (16:24 +0200)
committerTomas Mraz <tomas@openssl.org>
Fri, 2 Jul 2021 13:33:34 +0000 (15:33 +0200)
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15949)

crypto/pem/pem_pkey.c

index 4a029daa950e44c31f19cff4971db8c07d5227ea..f9346486dd2f19010deb6562d3f8e64194fb5ea5 100644 (file)
@@ -11,7 +11,6 @@
 #define OPENSSL_SUPPRESS_DEPRECATED
 
 #include <stdio.h>
-#include "internal/cryptlib.h"
 #include <openssl/buffer.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
@@ -22,6 +21,8 @@
 #include <openssl/dh.h>
 #include <openssl/decoder.h>
 #include <openssl/ui.h>
+#include "internal/cryptlib.h"
+#include "internal/passphrase.h"
 #include "crypto/asn1.h"
 #include "crypto/x509.h"
 #include "crypto/evp.h"
@@ -208,9 +209,10 @@ static EVP_PKEY *pem_read_bio_key(BIO *bp, EVP_PKEY **x,
                                   const char *propq,
                                   int selection)
 {
-    EVP_PKEY *ret;
+    EVP_PKEY *ret = NULL;
     BIO *new_bio = NULL;
     int pos;
+    struct ossl_passphrase_data_st pwdata = { 0 };
 
     if ((pos = BIO_tell(bp)) < 0) {
         new_bio = BIO_new(BIO_f_readbuffer());
@@ -220,17 +222,28 @@ static EVP_PKEY *pem_read_bio_key(BIO *bp, EVP_PKEY **x,
         pos = BIO_tell(bp);
     }
 
+    if (cb == NULL)
+        cb = PEM_def_callback;
+
+    if (!ossl_pw_set_pem_password_cb(&pwdata, cb, u)
+        || !ossl_pw_enable_passphrase_caching(&pwdata))
+        goto err;
+
     ERR_set_mark();
-    ret = pem_read_bio_key_decoder(bp, x, cb, u, libctx, propq, selection);
+    ret = pem_read_bio_key_decoder(bp, x, ossl_pw_pem_password, &pwdata,
+                                   libctx, propq, selection);
     if (ret == NULL
         && (BIO_seek(bp, pos) < 0
-            || (ret = pem_read_bio_key_legacy(bp, x, cb, u,
+            || (ret = pem_read_bio_key_legacy(bp, x,
+                                              ossl_pw_pem_password, &pwdata,
                                               libctx, propq,
                                               selection)) == NULL))
         ERR_clear_last_mark();
     else
         ERR_pop_to_mark();
 
+ err:
+    ossl_pw_clear_passphrase_data(&pwdata);
     if (new_bio != NULL) {
         BIO_pop(new_bio);
         BIO_free(new_bio);