mirror of
https://github.com/openssl/openssl.git
synced 2024-11-27 05:21:51 +08:00
Fix Edge Cases in Password Callback Handling
Fixes #8441: Modify the password callback handling to reserve one byte in the buffer for a null terminator, ensuring compatibility with legacy behavior that puts a terminating null byte at the end. Additionally, validate the length returned by the callback to ensure it does not exceed the given buffer size. If the returned length is too large, the process now stops gracefully with an appropriate error, enhancing robustness by preventing crashes from out-of-bounds access. Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/25330)
This commit is contained in:
parent
fa6ae88a47
commit
5387b71acb
@ -173,7 +173,7 @@ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
|
|||||||
X509_SIG *p8 = NULL;
|
X509_SIG *p8 = NULL;
|
||||||
int klen;
|
int klen;
|
||||||
EVP_PKEY *ret;
|
EVP_PKEY *ret;
|
||||||
char psbuf[PEM_BUFSIZE];
|
char psbuf[PEM_BUFSIZE + 1]; /* reserve one byte at the end */
|
||||||
|
|
||||||
p8 = d2i_PKCS8_bio(bp, NULL);
|
p8 = d2i_PKCS8_bio(bp, NULL);
|
||||||
if (p8 == NULL)
|
if (p8 == NULL)
|
||||||
@ -182,7 +182,7 @@ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
|
|||||||
klen = cb(psbuf, PEM_BUFSIZE, 0, u);
|
klen = cb(psbuf, PEM_BUFSIZE, 0, u);
|
||||||
else
|
else
|
||||||
klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
|
klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
|
||||||
if (klen < 0) {
|
if (klen < 0 || klen > PEM_BUFSIZE) {
|
||||||
ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ);
|
ERR_raise(ERR_LIB_PEM, PEM_R_BAD_PASSWORD_READ);
|
||||||
X509_SIG_free(p8);
|
X509_SIG_free(p8);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -105,14 +105,18 @@ static int ui_read(UI *ui, UI_STRING *uis)
|
|||||||
switch (UI_get_string_type(uis)) {
|
switch (UI_get_string_type(uis)) {
|
||||||
case UIT_PROMPT:
|
case UIT_PROMPT:
|
||||||
{
|
{
|
||||||
char result[PEM_BUFSIZE + 1];
|
int len;
|
||||||
|
char result[PEM_BUFSIZE + 1]; /* reserve one byte at the end */
|
||||||
const struct pem_password_cb_data *data =
|
const struct pem_password_cb_data *data =
|
||||||
UI_method_get_ex_data(UI_get_method(ui), ui_method_data_index);
|
UI_method_get_ex_data(UI_get_method(ui), ui_method_data_index);
|
||||||
int maxsize = UI_get_result_maxsize(uis);
|
int maxsize = UI_get_result_maxsize(uis);
|
||||||
int len = data->cb(result,
|
|
||||||
maxsize > PEM_BUFSIZE ? PEM_BUFSIZE : maxsize,
|
|
||||||
data->rwflag, UI_get0_user_data(ui));
|
|
||||||
|
|
||||||
|
if (maxsize > PEM_BUFSIZE)
|
||||||
|
maxsize = PEM_BUFSIZE;
|
||||||
|
len = data->cb(result, maxsize, data->rwflag,
|
||||||
|
UI_get0_user_data(ui));
|
||||||
|
if (len > maxsize)
|
||||||
|
return -1;
|
||||||
if (len >= 0)
|
if (len >= 0)
|
||||||
result[len] = '\0';
|
result[len] = '\0';
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user