Skip to content

Commit

Permalink
evp_get_digest/cipherbyname_ex(): Try to fetch if not found
Browse files Browse the repository at this point in the history
If the name is not found in namemap, we need
to try to fetch the algorithm and query the
namemap again.

Fixes openssl#19338

Reviewed-by: Neil Horman <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
Reviewed-by: Shane Lontis <[email protected]>
(Merged from openssl#24940)

(cherry picked from commit 454ca90)
  • Loading branch information
t8m committed Jul 31, 2024
1 parent 4910b0b commit 1484101
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 5 deletions.
34 changes: 30 additions & 4 deletions crypto/evp/names.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ const EVP_CIPHER *evp_get_cipherbyname_ex(OSSL_LIB_CTX *libctx,
const EVP_CIPHER *cp;
OSSL_NAMEMAP *namemap;
int id;
int do_retry = 1;

if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS, NULL))
return NULL;
Expand All @@ -94,9 +95,21 @@ const EVP_CIPHER *evp_get_cipherbyname_ex(OSSL_LIB_CTX *libctx,
*/

namemap = ossl_namemap_stored(libctx);
retry:
id = ossl_namemap_name2num(namemap, name);
if (id == 0)
return NULL;
if (id == 0) {
EVP_CIPHER *fetched_cipher;

/* Try to fetch it because the name might not be known yet. */
if (!do_retry)
return NULL;
do_retry = 0;
ERR_set_mark();
fetched_cipher = EVP_CIPHER_fetch(libctx, name, NULL);
EVP_CIPHER_free(fetched_cipher);
ERR_pop_to_mark();
goto retry;
}

if (!ossl_namemap_doall_names(namemap, id, cipher_from_name, &cp))
return NULL;
Expand Down Expand Up @@ -124,6 +137,7 @@ const EVP_MD *evp_get_digestbyname_ex(OSSL_LIB_CTX *libctx, const char *name)
const EVP_MD *dp;
OSSL_NAMEMAP *namemap;
int id;
int do_retry = 1;

if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_DIGESTS, NULL))
return NULL;
Expand All @@ -140,9 +154,21 @@ const EVP_MD *evp_get_digestbyname_ex(OSSL_LIB_CTX *libctx, const char *name)
*/

namemap = ossl_namemap_stored(libctx);
retry:
id = ossl_namemap_name2num(namemap, name);
if (id == 0)
return NULL;
if (id == 0) {
EVP_MD *fetched_md;

/* Try to fetch it because the name might not be known yet. */
if (!do_retry)
return NULL;
do_retry = 0;
ERR_set_mark();
fetched_md = EVP_MD_fetch(libctx, name, NULL);
EVP_MD_free(fetched_md);
ERR_pop_to_mark();
goto retry;
}

if (!ossl_namemap_doall_names(namemap, id, digest_from_name, &dp))
return NULL;
Expand Down
6 changes: 5 additions & 1 deletion test/build.info
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ IF[{- !$disabled{tests} -}]
exptest pbetest localetest evp_pkey_ctx_new_from_name \
evp_pkey_provided_test evp_test evp_extra_test evp_extra_test2 \
evp_fetch_prov_test evp_libctx_test ossl_store_test \
v3nametest v3ext punycode_test \
v3nametest v3ext punycode_test evp_byname_test \
crltest danetest bad_dtls_test lhash_test sparse_array_test \
conf_include_test params_api_test params_conversion_test \
constant_time_test verify_extra_test clienthellotest \
Expand Down Expand Up @@ -305,6 +305,10 @@ IF[{- !$disabled{tests} -}]
INCLUDE[punycode_test]=../include ../apps/include
DEPEND[punycode_test]=../libcrypto.a libtestutil.a

SOURCE[evp_byname_test]=evp_byname_test.c
INCLUDE[evp_byname_test]=../include ../apps/include
DEPEND[evp_byname_test]=../libcrypto libtestutil.a

SOURCE[stack_test]=stack_test.c
INCLUDE[stack_test]=../include ../apps/include
DEPEND[stack_test]=../libcrypto libtestutil.a
Expand Down
40 changes: 40 additions & 0 deletions test/evp_byname_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <openssl/evp.h>
#include "testutil.h"

static int test_evp_get_digestbyname(void)
{
const EVP_MD *md;

if (!TEST_ptr(md = EVP_get_digestbyname("SHA2-256")))
return 0;
return 1;
}

static int test_evp_get_cipherbyname(void)
{
const EVP_CIPHER *cipher;

if (!TEST_ptr(cipher = EVP_get_cipherbyname("AES-256-WRAP")))
return 0;
return 1;
}

int setup_tests(void)
{
ADD_TEST(test_evp_get_digestbyname);
ADD_TEST(test_evp_get_cipherbyname);
return 1;
}
16 changes: 16 additions & 0 deletions test/recipes/30-test_evp_byname.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#! /usr/bin/env perl
# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the Apache License 2.0 (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html

use strict;
use OpenSSL::Test;
use OpenSSL::Test::Simple;
use OpenSSL::Test::Utils;

setup("test_evp_byname");

simple_test("test_evp_byname", "evp_byname_test");

0 comments on commit 1484101

Please sign in to comment.