summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Mraz <tomas@openssl.org>2021-12-21 12:26:05 +0100
committerTomas Mraz <tomas@openssl.org>2022-01-03 10:35:36 +0100
commitef65bbb96352650bf9ce4ff46c60c71d9f138d08 (patch)
tree270797af463fb7cbbb4395cb722bde80963ae31e
parent9f6841e9d8964943cf5f616543750cee85c4911c (diff)
Compensate for UI method always adding NUL termination
The UI method always adds NUL termination and we need to compensate for that when using it from a pem_password_cb because the buffer used in pem_password_cb does not account for that and the returned password should be able fill the whole buffer. Fixes #16601 Reviewed-by: Ben Kaduk <kaduk@mit.edu> (Merged from https://github.com/openssl/openssl/pull/17320)
-rw-r--r--crypto/passphrase.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/crypto/passphrase.c b/crypto/passphrase.c
index d61e249440..cb1bc66958 100644
--- a/crypto/passphrase.c
+++ b/crypto/passphrase.c
@@ -109,7 +109,8 @@ int ossl_pw_disable_passphrase_caching(struct ossl_passphrase_data_st *data)
* UI_METHOD processor. It differs from UI_UTIL_read_pw() like this:
*
* 1. It constructs a prompt on its own, based on |prompt_info|.
- * 2. It allocates a buffer for verification on its own.
+ * 2. It allocates a buffer for password and verification on its own
+ * to compensate for NUL terminator in UI password strings.
* 3. It raises errors.
* 4. It reports back the length of the prompted pass phrase.
*/
@@ -117,8 +118,8 @@ static int do_ui_passphrase(char *pass, size_t pass_size, size_t *pass_len,
const char *prompt_info, int verify,
const UI_METHOD *ui_method, void *ui_data)
{
- char *prompt = NULL, *vpass = NULL;
- int prompt_idx = -1, verify_idx = -1;
+ char *prompt = NULL, *ipass = NULL, *vpass = NULL;
+ int prompt_idx = -1, verify_idx = -1, res;
UI *ui = NULL;
int ret = 0;
@@ -145,9 +146,16 @@ static int do_ui_passphrase(char *pass, size_t pass_size, size_t *pass_len,
goto end;
}
+ /* Get a buffer for verification prompt */
+ ipass = OPENSSL_zalloc(pass_size + 1);
+ if (ipass == NULL) {
+ ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
+ goto end;
+ }
+
prompt_idx = UI_add_input_string(ui, prompt,
UI_INPUT_FLAG_DEFAULT_PWD,
- pass, 0, pass_size - 1) - 1;
+ ipass, 0, pass_size) - 1;
if (prompt_idx < 0) {
ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB);
goto end;
@@ -155,15 +163,15 @@ static int do_ui_passphrase(char *pass, size_t pass_size, size_t *pass_len,
if (verify) {
/* Get a buffer for verification prompt */
- vpass = OPENSSL_zalloc(pass_size);
+ vpass = OPENSSL_zalloc(pass_size + 1);
if (vpass == NULL) {
ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE);
goto end;
}
verify_idx = UI_add_verify_string(ui, prompt,
UI_INPUT_FLAG_DEFAULT_PWD,
- vpass, 0, pass_size - 1,
- pass) - 1;
+ vpass, 0, pass_size,
+ ipass) - 1;
if (verify_idx < 0) {
ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB);
goto end;
@@ -178,13 +186,20 @@ static int do_ui_passphrase(char *pass, size_t pass_size, size_t *pass_len,
ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB);
break;
default:
- *pass_len = (size_t)UI_get_result_length(ui, prompt_idx);
+ res = UI_get_result_length(ui, prompt_idx);
+ if (res < 0) {
+ ERR_raise(ERR_LIB_CRYPTO, ERR_R_UI_LIB);
+ break;
+ }
+ *pass_len = (size_t)res;
+ memcpy(pass, ipass, *pass_len);
ret = 1;
break;
}
end:
- OPENSSL_free(vpass);
+ OPENSSL_clear_free(vpass, pass_size + 1);
+ OPENSSL_clear_free(ipass, pass_size + 1);
OPENSSL_free(prompt);
UI_free(ui);
return ret;