diff options
author | Tomas Mraz <tomas@openssl.org> | 2021-12-21 12:26:05 +0100 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2022-01-03 10:35:36 +0100 |
commit | ef65bbb96352650bf9ce4ff46c60c71d9f138d08 (patch) | |
tree | 270797af463fb7cbbb4395cb722bde80963ae31e /crypto | |
parent | 9f6841e9d8964943cf5f616543750cee85c4911c (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)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/passphrase.c | 33 |
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; |