summaryrefslogtreecommitdiffstats
path: root/crypto/evp
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2021-01-19 11:36:24 +0000
committerMatt Caswell <matt@openssl.org>2021-01-22 09:30:45 +0000
commit5060cd5f3ed14a2dc4764cc1e042f76af6b44664 (patch)
tree5e8a40c6d75ac52d8f41fad6bd8d716811fcaeb0 /crypto/evp
parentef161e7b8f61ea588c654c9600bde80b2e07588f (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/evp')
-rw-r--r--crypto/evp/p_lib.c37
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;