Re: [External] : Re: BIO_read() crash
On Mon, Dec 05, 2022 at 11:31:18AM -0800, Thomas Dwyer III wrote: > Why does EVP_get_digestbyname("md4") return non-NULL if the legacy provider > isn't loaded? Similarly, why does it return non-NULL for "md5" after doing > EVP_set_default_properties(NULL, "fips=yes")? This seems unintuitive. Legacy > code that does not know about EVP_MD_fetch() checks the return value of > EVP_get_digestbyname(). Isn't that where the error should be detected? Why > let it get all the way to BIO_set_md() (or EVP_DigestInit() or whatever) > before the error is detected? To do so would introduce a time-of-check/time-of-use race, as the set of providers available may change in the intervening period. -Ben
Re: [External] : Re: BIO_read() crash
Why does EVP_get_digestbyname("md4") return non-NULL if the legacy provider isn't loaded? Similarly, why does it return non-NULL for "md5" after doing EVP_set_default_properties(NULL, "fips=yes")? This seems unintuitive. Legacy code that does not know about EVP_MD_fetch() checks the return value of EVP_get_digestbyname(). Isn't that where the error should be detected? Why let it get all the way to BIO_set_md() (or EVP_DigestInit() or whatever) before the error is detected? Tom.III || On 12/5/22 02:24, Tomas Mraz wrote: Hi, there is an error in your code - see my comment below. On Mon, 2022-12-05 at 08:45 +, Zhongyan Wang wrote: ... md = EVP_get_digestbyname(dgst); if (!md) { printf("Error EVP_get_digestbyname %s\n", dgst); goto err_exit; } in = BIO_new_file(datain, "rb"); if (!in) { printf("Error BIO_new_file %s\n", datain); goto err_exit; } out = BIO_new(BIO_s_mem()); if (!out) { printf("Error BIO_new out\n"); goto err_exit; } rbio = in; bmd = BIO_new(BIO_f_md()); if (!bmd){ printf("Error BIO_new bmd\n"); goto err_exit; } BIO_set_md(bmd, md); You do not check the return value here. This call will return <= 0 return value in case the legacy provider is not loaded.
Re: BIO_read() crash
Hi, there is an error in your code - see my comment below. On Mon, 2022-12-05 at 08:45 +, Zhongyan Wang wrote: ... > md = EVP_get_digestbyname(dgst); > if (!md) { > printf("Error EVP_get_digestbyname %s\n", dgst); > goto err_exit; > } > > in = BIO_new_file(datain, "rb"); > if (!in) { > printf("Error BIO_new_file %s\n", datain); > goto err_exit; > } > > out = BIO_new(BIO_s_mem()); > if (!out) { > printf("Error BIO_new out\n"); > goto err_exit; > } > > rbio = in; > > bmd = BIO_new(BIO_f_md()); > if (!bmd){ > printf("Error BIO_new bmd\n"); > goto err_exit; > } > > BIO_set_md(bmd, md); You do not check the return value here. This call will return <= 0 return value in case the legacy provider is not loaded. -- Tomáš Mráz, OpenSSL
BIO_read() crash
Hi team, I find a segment fault in BIO_read() on openssl 3.0 about calculate digest with BIO using md4 algorithm. This is my test code, put it in a.c, build & run, it will crash. If don't load legacy provider: 1. Set dgst = "md4", EVP_get_digestbyname(dgst) won't return NULL, but a non-NULL object. If use EVP_MD_fetch(NULL, dgst, NULL) instead, it will return NULL. 2. When call BIO_read(), this program crashes. If load legacy provider, this program works ok. #include #include #include #include #include #include #include #include int main() { EVP_MD *md = NULL; const char *datain = "a.c"; const int BUF_SIZE = 8192; char *buff = NULL; char *ptr = NULL; const char *dgst = "md4"; int ret = 0, len = 0, i = 0; BIO *in = NULL, *out = NULL, *bmd = NULL, *rbio = NULL, *err; if ((err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(err, stderr, BIO_NOCLOSE|BIO_FP_TEXT); md = EVP_get_digestbyname(dgst); if (!md) { printf("Error EVP_get_digestbyname %s\n", dgst); goto err_exit; } in = BIO_new_file(datain, "rb"); if (!in) { printf("Error BIO_new_file %s\n", datain); goto err_exit; } out = BIO_new(BIO_s_mem()); if (!out) { printf("Error BIO_new out\n"); goto err_exit; } rbio = in; bmd = BIO_new(BIO_f_md()); if (!bmd){ printf("Error BIO_new bmd\n"); goto err_exit; } BIO_set_md(bmd, md); rbio = BIO_push(bmd, rbio); buff = (char *)malloc(BUF_SIZE); if (!buff) { printf("Error malloc\n"); goto err_exit; } for (;;) { ret = BIO_read(rbio, buff, BUF_SIZE); /* this call will segment fault */ if (ret <= 0) break; } len = BIO_gets(rbio, buff, BUF_SIZE); len = BIO_write(out, buff, len); if (!BIO_flush(out)) { printf("Error BIO_flush\n"); goto err_exit; } len = BIO_get_mem_data(out, ); printf("digest success, len=%d\n", len); for (i = 0; i < len; i++) printf("%d ", ptr[i]); printf("\n"); err_exit: ERR_print_errors(err); if (in) BIO_free(in); if (out) BIO_free_all(out); if (err) BIO_free(err); if (bmd) BIO_free(bmd); if (buff) free(buff); if (md) EVP_MD_free(md); ERR_clear_error(); return 0; } - Rocket Software, Inc. and subsidiaries ? 77 Fourth Avenue, Waltham MA 02451 ? Main Office Toll Free Number: +1 855.577.4323 Contact Customer Support: https://my.rocketsoftware.com/RocketCommunity/RCEmailSupport Unsubscribe from Marketing Messages/Manage Your Subscription Preferences - http://www.rocketsoftware.com/manage-your-email-preferences Privacy Policy - http://www.rocketsoftware.com/company/legal/privacy-policy This communication and any attachments may contain confidential information of Rocket Software, Inc. All unauthorized use, disclosure or distribution is prohibited. If you are not the intended recipient, please notify Rocket Software immediately and destroy all copies of this communication. Thank you.