diff options
author | Matt Caswell <matt@openssl.org> | 2021-01-19 11:36:24 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2021-01-22 09:30:45 +0000 |
commit | 5060cd5f3ed14a2dc4764cc1e042f76af6b44664 (patch) | |
tree | 5e8a40c6d75ac52d8f41fad6bd8d716811fcaeb0 /crypto | |
parent | ef161e7b8f61ea588c654c9600bde80b2e07588f (diff) |
Ensure legacy_asn1_ctrl_to_param can handle MDs not in the OBJ database
The legacy_asn1_ctrl_to_param implementation of
ASN1_PKEY_CTRL_DEFAULT_MD_NID calls EVP_PKEY_get_default_digest_name()
which returns an mdname. Previously we were using OBJ_sn2nid/OBJ_ln2nid
to lookup that name in the OBJ database. However we might get an md name
back that only exists in the namemap, not in the OBJ database. In that
case we need to check the various aliases for the name, to see if one of
those matches the name we are looking for.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13899)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/evp/p_lib.c | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index cc5a612748..66487054ae 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -16,6 +16,7 @@ #include <stdio.h> #include "internal/cryptlib.h" #include "internal/refcount.h" +#include "internal/namemap.h" #include <openssl/bn.h> #include <openssl/err.h> #include <openssl/objects.h> @@ -1153,6 +1154,18 @@ int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, pctx); } +static void find_md_nid(const char *mdname, void *data) +{ + int *nid = (int *)data; + + if (*nid != NID_undef) + return; + + *nid = OBJ_sn2nid(mdname); + if (*nid == NID_undef) + *nid = OBJ_ln2nid(mdname); +} + static int legacy_asn1_ctrl_to_param(EVP_PKEY *pkey, int op, int arg1, void *arg2) { @@ -1166,11 +1179,27 @@ static int legacy_asn1_ctrl_to_param(EVP_PKEY *pkey, int op, sizeof(mdname)); if (rv > 0) { - int nid; + int mdnum; + OSSL_LIB_CTX *libctx = ossl_provider_libctx(pkey->keymgmt->prov); + /* Make sure the MD is in the namemap if available */ + EVP_MD *md = EVP_MD_fetch(libctx, mdname, NULL); + OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx); + int nid = NID_undef; - nid = OBJ_sn2nid(mdname); - if (nid == NID_undef) - nid = OBJ_ln2nid(mdname); + /* + * The only reason to fetch the MD was to make sure it is in the + * namemap. We can immediately free it. + */ + EVP_MD_free(md); + mdnum = ossl_namemap_name2num(namemap, mdname); + if (mdnum == 0) + return 0; + + /* + * We have the namemap number - now we need to find the + * associated nid + */ + ossl_namemap_doall_names(namemap, mdnum, find_md_nid, &nid); *(int *)arg2 = nid; } return rv; |