[openssl] master update

Richard Levitte levitte at openssl.org
Fri Jan 17 08:00:44 UTC 2020


The branch master has been updated
       via  e4a1d0230016d090ba78bc7092384315f85b0e72 (commit)
      from  9bb3e5fd87905e3e9f5f7edcc2e22d98360510ab (commit)


- Log -----------------------------------------------------------------
commit e4a1d0230016d090ba78bc7092384315f85b0e72
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Jan 15 01:04:37 2020 +0100

    Modify EVP_CIPHER_is_a() and EVP_MD_is_a() to handle legacy methods too
    
    These functions would only handle provided methods, but there are
    cases where the caller just passes along a received method without
    knowing the underlying method tech, so might pass along a legacy
    method.  We therefore need to have them handle this case as well so
    they don't cause any unnecessary surprises.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10845)

-----------------------------------------------------------------------

Summary of changes:
 crypto/core_namemap.c        |  2 +-
 crypto/evp/evp_fetch.c       |  8 +++++++-
 crypto/evp/evp_lib.c         | 15 ++++++---------
 crypto/evp/evp_local.h       |  3 ++-
 crypto/evp/exchange.c        |  2 +-
 crypto/evp/kdf_lib.c         |  2 +-
 crypto/evp/keymgmt_meth.c    |  2 +-
 crypto/evp/mac_lib.c         |  2 +-
 crypto/evp/pmeth_fn.c        |  2 +-
 crypto/evp/signature.c       |  2 +-
 doc/man3/EVP_DigestInit.pod  |  5 +++++
 doc/man3/EVP_EncryptInit.pod |  4 ++++
 test/namemap_internal_test.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
 13 files changed, 76 insertions(+), 18 deletions(-)

diff --git a/crypto/core_namemap.c b/crypto/core_namemap.c
index 9a9d1a5748..4723604ee3 100644
--- a/crypto/core_namemap.c
+++ b/crypto/core_namemap.c
@@ -294,7 +294,7 @@ int ossl_namemap_add_names(OSSL_NAMEMAP *namemap, int number,
         if (number == 0) {
             number = this_number;
         } else if (this_number != number) {
-            ERR_raise_data(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR,
+            ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
                            "Got number %d when expecting %d",
                            this_number, number);
             return 0;
diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c
index db47981013..5bf825d62b 100644
--- a/crypto/evp/evp_fetch.c
+++ b/crypto/evp/evp_fetch.c
@@ -381,11 +381,17 @@ const char *evp_first_name(OSSL_PROVIDER *prov, int name_id)
     return ossl_namemap_num2name(namemap, name_id, 0);
 }
 
-int evp_is_a(OSSL_PROVIDER *prov, int number, const char *name)
+int evp_is_a(OSSL_PROVIDER *prov, int number,
+             const char *legacy_name, const char *name)
 {
+    /*
+     * For a |prov| that is NULL, the library context will be NULL
+     */
     OPENSSL_CTX *libctx = ossl_provider_library_context(prov);
     OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
 
+    if (prov == NULL)
+        number = ossl_namemap_name2num(namemap, legacy_name);
     return ossl_namemap_name2num(namemap, name) == number;
 }
 
diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c
index 3c2083148e..2b51267179 100644
--- a/crypto/evp/evp_lib.c
+++ b/crypto/evp/evp_lib.c
@@ -532,14 +532,9 @@ int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx)
 
 int EVP_CIPHER_is_a(const EVP_CIPHER *cipher, const char *name)
 {
-#ifndef FIPS_MODE
-    if (cipher->prov == NULL) {
-        int nid = EVP_CIPHER_nid(cipher);
-
-        return nid == OBJ_sn2nid(name) || nid == OBJ_ln2nid(name);
-    }
-#endif
-    return evp_is_a(cipher->prov, cipher->name_id, name);
+    if (cipher->prov != NULL)
+        return evp_is_a(cipher->prov, cipher->name_id, NULL, name);
+    return evp_is_a(NULL, 0, EVP_CIPHER_name(cipher), name);
 }
 
 int EVP_CIPHER_number(const EVP_CIPHER *cipher)
@@ -578,7 +573,9 @@ int EVP_CIPHER_mode(const EVP_CIPHER *cipher)
 
 int EVP_MD_is_a(const EVP_MD *md, const char *name)
 {
-    return evp_is_a(md->prov, md->name_id, name);
+    if (md->prov != NULL)
+        return evp_is_a(md->prov, md->name_id, NULL, name);
+    return evp_is_a(NULL, 0, EVP_MD_name(md), name);
 }
 
 int EVP_MD_number(const EVP_MD *md)
diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h
index 71051a6587..de73267c98 100644
--- a/crypto/evp/evp_local.h
+++ b/crypto/evp/evp_local.h
@@ -270,7 +270,8 @@ void evp_pkey_ctx_free_old_ops(EVP_PKEY_CTX *ctx);
 
 /* OSSL_PROVIDER * is only used to get the library context */
 const char *evp_first_name(OSSL_PROVIDER *prov, int name_id);
-int evp_is_a(OSSL_PROVIDER *prov, int number, const char *name);
+int evp_is_a(OSSL_PROVIDER *prov, int number,
+             const char *legacy_name, const char *name);
 void evp_names_do_all(OSSL_PROVIDER *prov, int number,
                       void (*fn)(const char *name, void *data),
                       void *data);
diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c
index ade1dc373d..56896390e0 100644
--- a/crypto/evp/exchange.c
+++ b/crypto/evp/exchange.c
@@ -380,7 +380,7 @@ int EVP_KEYEXCH_number(const EVP_KEYEXCH *keyexch)
 
 int EVP_KEYEXCH_is_a(const EVP_KEYEXCH *keyexch, const char *name)
 {
-    return evp_is_a(keyexch->prov, keyexch->name_id, name);
+    return evp_is_a(keyexch->prov, keyexch->name_id, NULL, name);
 }
 
 void EVP_KEYEXCH_do_all_provided(OPENSSL_CTX *libctx,
diff --git a/crypto/evp/kdf_lib.c b/crypto/evp/kdf_lib.c
index 5ddf8560d2..84dc910858 100644
--- a/crypto/evp/kdf_lib.c
+++ b/crypto/evp/kdf_lib.c
@@ -90,7 +90,7 @@ int EVP_KDF_number(const EVP_KDF *kdf)
 
 int EVP_KDF_is_a(const EVP_KDF *kdf, const char *name)
 {
-    return evp_is_a(kdf->prov, kdf->name_id, name);
+    return evp_is_a(kdf->prov, kdf->name_id, NULL, name);
 }
 
 const OSSL_PROVIDER *EVP_KDF_provider(const EVP_KDF *kdf)
diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c
index 6318ddd3fb..03d1686cf3 100644
--- a/crypto/evp/keymgmt_meth.c
+++ b/crypto/evp/keymgmt_meth.c
@@ -212,7 +212,7 @@ int EVP_KEYMGMT_number(const EVP_KEYMGMT *keymgmt)
 
 int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name)
 {
-    return evp_is_a(keymgmt->prov, keymgmt->name_id, name);
+    return evp_is_a(keymgmt->prov, keymgmt->name_id, NULL, name);
 }
 
 void EVP_KEYMGMT_do_all_provided(OPENSSL_CTX *libctx,
diff --git a/crypto/evp/mac_lib.c b/crypto/evp/mac_lib.c
index 07ed1c8749..bf52aaff8c 100644
--- a/crypto/evp/mac_lib.c
+++ b/crypto/evp/mac_lib.c
@@ -165,7 +165,7 @@ int EVP_MAC_number(const EVP_MAC *mac)
 
 int EVP_MAC_is_a(const EVP_MAC *mac, const char *name)
 {
-    return evp_is_a(mac->prov, mac->name_id, name);
+    return evp_is_a(mac->prov, mac->name_id, NULL, name);
 }
 
 void EVP_MAC_names_do_all(const EVP_MAC *mac,
diff --git a/crypto/evp/pmeth_fn.c b/crypto/evp/pmeth_fn.c
index 31422baa4c..aa226fcc7b 100644
--- a/crypto/evp/pmeth_fn.c
+++ b/crypto/evp/pmeth_fn.c
@@ -393,7 +393,7 @@ EVP_ASYM_CIPHER *EVP_ASYM_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
 
 int EVP_ASYM_CIPHER_is_a(const EVP_ASYM_CIPHER *cipher, const char *name)
 {
-    return evp_is_a(cipher->prov, cipher->name_id, name);
+    return evp_is_a(cipher->prov, cipher->name_id, NULL, name);
 }
 
 int EVP_ASYM_CIPHER_number(const EVP_ASYM_CIPHER *cipher)
diff --git a/crypto/evp/signature.c b/crypto/evp/signature.c
index 119cd322a3..1cef4649ed 100644
--- a/crypto/evp/signature.c
+++ b/crypto/evp/signature.c
@@ -289,7 +289,7 @@ EVP_SIGNATURE *EVP_SIGNATURE_fetch(OPENSSL_CTX *ctx, const char *algorithm,
 
 int EVP_SIGNATURE_is_a(const EVP_SIGNATURE *signature, const char *name)
 {
-    return evp_is_a(signature->prov, signature->name_id, name);
+    return evp_is_a(signature->prov, signature->name_id, NULL, name);
 }
 
 int EVP_SIGNATURE_number(const EVP_SIGNATURE *signature)
diff --git a/doc/man3/EVP_DigestInit.pod b/doc/man3/EVP_DigestInit.pod
index 01da721d56..ef40ae49f8 100644
--- a/doc/man3/EVP_DigestInit.pod
+++ b/doc/man3/EVP_DigestInit.pod
@@ -248,6 +248,11 @@ be initialized.
 Returns 1 if I<md> is an implementation of an algorithm that's
 identifiable with I<name>, otherwise 0.
 
+If I<md> is a legacy digest (it's the return value from the likes of
+EVP_sha256() rather than the result of an EVP_MD_fetch()), only cipher
+names registered with the default library context (see
+L<OPENSSL_CTX(3)>) will be considered.
+
 =item EVP_MD_number()
 
 Returns the internal dynamic number assigned to the I<md>.  This is
diff --git a/doc/man3/EVP_EncryptInit.pod b/doc/man3/EVP_EncryptInit.pod
index a008d0f6f6..5dc60a0801 100644
--- a/doc/man3/EVP_EncryptInit.pod
+++ b/doc/man3/EVP_EncryptInit.pod
@@ -338,6 +338,10 @@ B<NID_undef>.
 
 EVP_CIPHER_is_a() returns 1 if I<cipher> is an implementation of an
 algorithm that's identifiable with I<name>, otherwise 0.
+If I<cipher> is a legacy cipher (it's the return value from the likes
+of EVP_aes128() rather than the result of an EVP_CIPHER_fetch()), only
+cipher names registered with the default library context (see
+L<OPENSSL_CTX(3)>) will be considered.
 
 EVP_CIPHER_number() returns the internal dynamic number assigned to
 the I<cipher>.  This is only useful with fetched B<EVP_CIPHER>s.
diff --git a/test/namemap_internal_test.c b/test/namemap_internal_test.c
index 263364adbd..1d4a657ac6 100644
--- a/test/namemap_internal_test.c
+++ b/test/namemap_internal_test.c
@@ -108,6 +108,49 @@ static int test_cipherbyname(void)
     return 1;
 }
 
+/*
+ * Test that EVP_CIPHER_is_a() responds appropriately, even for ciphers that
+ * are entirely legacy.
+ */
+static int test_cipher_is_a(void)
+{
+    EVP_CIPHER *fetched = EVP_CIPHER_fetch(NULL, "AES-256-CCM", NULL);
+    int rv = 1;
+
+    if (!TEST_ptr_ne(fetched, NULL))
+        return 0;
+    if (!TEST_true(EVP_CIPHER_is_a(fetched, "id-aes256-CCM"))
+        || !TEST_false(EVP_CIPHER_is_a(fetched, "AES-128-GCM")))
+        rv = 0;
+    if (!TEST_true(EVP_CIPHER_is_a(EVP_aes_256_gcm(), "AES-256-GCM"))
+        || !TEST_false(EVP_CIPHER_is_a(EVP_aes_256_gcm(), "AES-128-CCM")))
+        rv = 0;
+
+    EVP_CIPHER_free(fetched);
+    return rv;
+}
+
+/*
+ * Test that EVP_MD_is_a() responds appropriately, even for MDs that are
+ * entirely legacy.
+ */
+static int test_digest_is_a(void)
+{
+    EVP_MD *fetched = EVP_MD_fetch(NULL, "SHA2-512", NULL);
+    int rv = 1;
+
+    if (!TEST_ptr_ne(fetched, NULL))
+        return 0;
+    if (!TEST_true(EVP_MD_is_a(fetched, "SHA512"))
+        || !TEST_false(EVP_MD_is_a(fetched, "SHA1")))
+        rv = 0;
+    if (!TEST_true(EVP_MD_is_a(EVP_sha256(), "SHA2-256"))
+        || !TEST_false(EVP_MD_is_a(EVP_sha256(), "SHA3-256")))
+        rv = 0;
+
+    EVP_MD_free(fetched);
+    return rv;
+}
 
 int setup_tests(void)
 {
@@ -115,5 +158,7 @@ int setup_tests(void)
     ADD_TEST(test_namemap_stored);
     ADD_TEST(test_digestbyname);
     ADD_TEST(test_cipherbyname);
+    ADD_TEST(test_digest_is_a);
+    ADD_TEST(test_cipher_is_a);
     return 1;
 }


More information about the openssl-commits mailing list