From: Matt Caswell Date: Wed, 29 Dec 2021 16:39:11 +0000 (+0000) Subject: Add a test for a custom digest created via EVP_MD_meth_new() X-Git-Tag: openssl-3.2.0-alpha1~3103 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fbbe7202eba9fba243c18513f4f0316dafb3496d;p=thirdparty%2Fopenssl.git Add a test for a custom digest created via EVP_MD_meth_new() We check that the init and cleanup functions for the custom method are called as expected. Based on an original reproducer by Dmitry Belyavsky from issue #17149. Reviewed-by: Dmitry Belyavskiy (Merged from https://github.com/openssl/openssl/pull/17255) --- diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c index 7f191c43a99..05af89379f4 100644 --- a/test/evp_extra_test.c +++ b/test/evp_extra_test.c @@ -4179,6 +4179,90 @@ static int test_evp_md_cipher_meth(void) return testresult; } +typedef struct { + int data; +} custom_dgst_ctx; + +static int custom_md_init_called = 0; +static int custom_md_cleanup_called = 0; + +static int custom_md_init(EVP_MD_CTX *ctx) +{ + custom_dgst_ctx *p = EVP_MD_CTX_md_data(ctx); + + if (p == NULL) + return 0; + + custom_md_init_called++; + return 1; +} + +static int custom_md_cleanup(EVP_MD_CTX *ctx) +{ + custom_dgst_ctx *p = EVP_MD_CTX_md_data(ctx); + + if (p == NULL) + /* Nothing to do */ + return 1; + + custom_md_cleanup_called++; + return 1; +} + +static int test_custom_md_meth(void) +{ + EVP_MD_CTX *mdctx = NULL; + EVP_MD *tmp = NULL; + char mess[] = "Test Message\n"; + unsigned char md_value[EVP_MAX_MD_SIZE]; + unsigned int md_len; + int testresult = 0; + int nid; + + /* + * We are testing deprecated functions. We don't support a non-default + * library context in this test. + */ + if (testctx != NULL) + return 1; + + custom_md_init_called = custom_md_cleanup_called = 0; + + nid = OBJ_create("1.3.6.1.4.1.16604.998866.1", "custom-md", "custom-md"); + if (!TEST_int_ne(nid, NID_undef)) + goto err; + tmp = EVP_MD_meth_new(nid, NID_undef); + if (!TEST_ptr(tmp)) + goto err; + + if (!TEST_true(EVP_MD_meth_set_init(tmp, custom_md_init)) + || !TEST_true(EVP_MD_meth_set_cleanup(tmp, custom_md_cleanup)) + || !TEST_true(EVP_MD_meth_set_app_datasize(tmp, + sizeof(custom_dgst_ctx)))) + goto err; + + mdctx = EVP_MD_CTX_new(); + if (!TEST_ptr(mdctx) + /* + * Initing our custom md and then initing another md should + * result in the init and cleanup functions of the custom md + * from being called. + */ + || !TEST_true(EVP_DigestInit_ex(mdctx, tmp, NULL)) + || !TEST_true(EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL)) + || !TEST_true(EVP_DigestUpdate(mdctx, mess, strlen(mess))) + || !TEST_true(EVP_DigestFinal_ex(mdctx, md_value, &md_len)) + || !TEST_int_eq(custom_md_init_called, 1) + || !TEST_int_eq(custom_md_cleanup_called, 1)) + goto err; + + testresult = 1; + err: + EVP_MD_CTX_free(mdctx); + EVP_MD_meth_free(tmp); + return testresult; +} + # ifndef OPENSSL_NO_DYNAMIC_ENGINE /* Test we can create a signature keys with an associated ENGINE */ static int test_signatures_with_engine(int tst) @@ -4473,6 +4557,7 @@ int setup_tests(void) #ifndef OPENSSL_NO_DEPRECATED_3_0 ADD_ALL_TESTS(test_custom_pmeth, 12); ADD_TEST(test_evp_md_cipher_meth); + ADD_TEST(test_custom_md_meth); # ifndef OPENSSL_NO_DYNAMIC_ENGINE /* Tests only support the default libctx */