The branch master has been updated via 4d2d4b4bc1a8515fa5c17906393458a7beef5422 (commit) via 05814be8d647ec3056866c13e68c4b48c788ec23 (commit) via 07f65429c34cb581484371f7d45cb83815f95484 (commit) from b59b2f93a165f9e4ad6ed15ca8b22ff29296297f (commit)
- Log ----------------------------------------------------------------- commit 4d2d4b4bc1a8515fa5c17906393458a7beef5422 Author: Tomas Mraz <to...@openssl.org> Date: Tue May 25 09:59:06 2021 +0200 OSSL_DECODER_from_bio: Report an unsupported error when there is none When nothing was decoded and there is no error on the stack report something. Fixes #15442 Reviewed-by: Paul Dale <pa...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15441) commit 05814be8d647ec3056866c13e68c4b48c788ec23 Author: Tomas Mraz <to...@openssl.org> Date: Tue May 25 09:58:35 2021 +0200 Add negative test cases for PEM_read_bio_PrivateKey Reviewed-by: Paul Dale <pa...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15441) commit 07f65429c34cb581484371f7d45cb83815f95484 Author: Tomas Mraz <to...@openssl.org> Date: Mon May 24 18:47:45 2021 +0200 Fix possible infinite loop in pem_read_bio_key_decoder() There could be an infinite loop if no read happened. Fixes #15426 Reviewed-by: Paul Dale <pa...@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15441) ----------------------------------------------------------------------- Summary of changes: crypto/encode_decode/decoder_lib.c | 5 +++-- crypto/pem/pem_pkey.c | 9 ++++++++- test/evp_extra_test2.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c index c7eac0eddd..022c1d56e2 100644 --- a/crypto/encode_decode/decoder_lib.c +++ b/crypto/encode_decode/decoder_lib.c @@ -87,9 +87,10 @@ int OSSL_DECODER_from_bio(OSSL_DECODER_CTX *ctx, BIO *in) const char *input_structure = ctx->input_structure != NULL ? ctx->input_structure : ""; - if (BIO_eof(in) == 0 /* Prevent spurious decoding error */) + if (BIO_eof(in) == 0 || ERR_peek_error() == 0) + /* Prevent spurious decoding error */ ERR_raise_data(ERR_LIB_OSSL_DECODER, ERR_R_UNSUPPORTED, - "Not supported for the data to decode.%s%s%s%s%s%s", + "No supported data to decode. %s%s%s%s%s%s", spaces, input_type_label, input_type, comma, input_structure_label, input_structure); ok = 0; diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c index adbf8bcfe7..becf7e277c 100644 --- a/crypto/pem/pem_pkey.c +++ b/crypto/pem/pem_pkey.c @@ -36,6 +36,11 @@ static EVP_PKEY *pem_read_bio_key_decoder(BIO *bp, EVP_PKEY **x, { EVP_PKEY *pkey = NULL; OSSL_DECODER_CTX *dctx = NULL; + int pos, newpos; + + if ((pos = BIO_tell(bp)) < 0) + /* We can depend on BIO_tell() thanks to the BIO_f_readbuffer() */ + return NULL; dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "PEM", NULL, NULL, selection, libctx, propq); @@ -50,8 +55,10 @@ static EVP_PKEY *pem_read_bio_key_decoder(BIO *bp, EVP_PKEY **x, goto err; while (!OSSL_DECODER_from_bio(dctx, bp) || pkey == NULL) - if (BIO_eof(bp) != 0) + if (BIO_eof(bp) != 0 || (newpos = BIO_tell(bp)) < 0 || newpos <= pos) goto err; + else + pos = newpos; if (!evp_keymgmt_util_has(pkey, selection)) { EVP_PKEY_free(pkey); diff --git a/test/evp_extra_test2.c b/test/evp_extra_test2.c index 3f7edac278..e480ae9555 100644 --- a/test/evp_extra_test2.c +++ b/test/evp_extra_test2.c @@ -414,6 +414,41 @@ static int test_d2i_PrivateKey_ex(int testid) return ok; } +static int test_PEM_read_bio_negative(int testid) +{ + int ok = 0; + OSSL_PROVIDER *provider = NULL; + BIO *key_bio = NULL; + EVP_PKEY *pkey = NULL; + + if (!TEST_ptr(key_bio = BIO_new_mem_buf(keydata[testid].kder, keydata[testid].size))) + goto err; + ERR_clear_error(); + if (!TEST_ptr_null(pkey = PEM_read_bio_PrivateKey(key_bio, NULL, NULL, NULL))) + goto err; + if (!TEST_int_ne(ERR_peek_error(), 0)) + goto err; + if (!TEST_ptr(provider = OSSL_PROVIDER_load(NULL, "default"))) + goto err; + if (!TEST_int_ge(BIO_seek(key_bio, 0), 0)) + goto err; + ERR_clear_error(); + if (!TEST_ptr_null(pkey = PEM_read_bio_PrivateKey(key_bio, NULL, NULL, NULL))) + goto err; + if (!TEST_int_ne(ERR_peek_error(), 0)) + goto err; + + ok = 1; + + err: + test_openssl_errors(); + EVP_PKEY_free(pkey); + BIO_free(key_bio); + OSSL_PROVIDER_unload(provider); + + return ok; +} + static int do_fromdata_key_is_equal(const OSSL_PARAM params[], const EVP_PKEY *expected, const char *type) { @@ -807,6 +842,7 @@ int setup_tests(void) #ifndef OPENSSL_NO_DES ADD_TEST(test_pkcs8key_nid_bio); #endif + ADD_ALL_TESTS(test_PEM_read_bio_negative, OSSL_NELEM(keydata)); return 1; }