[openssl] master update

beldmit at gmail.com beldmit at gmail.com
Thu Sep 17 08:14:13 UTC 2020


The branch master has been updated
       via  3f96b687f7d27a32f37f7c6b4fdee45dae685b38 (commit)
       via  7fc6168b6f5d0f696b610a88004ef79ed0eaa2ba (commit)
       via  d8025f4ac002f6de775a8c3c7936036d0722eed6 (commit)
       via  b0002eb09ac744d0c702c85648b2517e214580ea (commit)
       via  b8e5622809d3b3f61c4a615e51f5a8fd492ee23f (commit)
      from  067a3057c3aab0cdd9a3cdb13c2e0000f69a4170 (commit)


- Log -----------------------------------------------------------------
commit 3f96b687f7d27a32f37f7c6b4fdee45dae685b38
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Sep 14 16:30:50 2020 +0100

    Document 2 newly added functions
    
    Adds documentation for EVP_PKEY_get0_first_alg_name() and
    EVP_KEYMGMT_get0_first_name().
    
    Reviewed-by: Dmitry Belyavskiy <beldmit at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/12850)

commit 7fc6168b6f5d0f696b610a88004ef79ed0eaa2ba
Author: Matt Caswell <matt at openssl.org>
Date:   Mon Sep 14 16:13:54 2020 +0100

    Test HMAC output from the dgst CLI
    
    We run two HMAC operations on the same file and confirm that both provide
    us with the expected values.
    
    Reviewed-by: Dmitry Belyavskiy <beldmit at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/12850)

commit d8025f4ac002f6de775a8c3c7936036d0722eed6
Author: Matt Caswell <matt at openssl.org>
Date:   Sun Sep 13 11:09:20 2020 +0100

    Correctly display the signing/hmac algorithm in the dgst app
    
    In OpenSSL 1.1.1 doing an HMAC operation with (say) SHA1 would produce
    output like this:
    
    HMAC-SHA1(README.md)= 553154e4c0109ddc320bb495735906ad7135c2f1
    
    Prior to this change master would instead display this like so:
    
    SHA1(README.md)= 553154e4c0109ddc320bb495735906ad7135c2f1
    
    The problem is that dgst was using EVP_PKEY_asn1_get0_info() to get
    the algorithm name from the EVP_PKEY. This doesn't work with provider
    based keys. Instead we introduce a new EVP_PKEY_get0_first_alg_name()
    function, and an equivalent EVP_KEYMGMT_get0_first_name() function.
    
    Reviewed-by: Dmitry Belyavskiy <beldmit at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/12850)

commit b0002eb09ac744d0c702c85648b2517e214580ea
Author: Matt Caswell <matt at openssl.org>
Date:   Fri Sep 11 16:47:53 2020 +0100

    Redirect EVP_DigestInit to EVP_DigestSignInit_ex if appropriate
    
    Prior to OpenSSL 3.0 calling EVP_DigestInit_ex() on an mdctx previously
    initialised with EVP_DigestSignInit() would retain information about the
    key, and re-initialise for another sign operation. To emulate that we
    redirect calls to EVP_DigestInit() to EVP_DigestSignInit_ex() if
    appropriate.
    
    Reviewed-by: Dmitry Belyavskiy <beldmit at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/12850)

commit b8e5622809d3b3f61c4a615e51f5a8fd492ee23f
Author: Matt Caswell <matt at openssl.org>
Date:   Thu Sep 10 14:46:41 2020 +0100

    Don't send -1 as the length of the hmac key
    
    The dgst app was using an undocumented behaviour in the
    EVP_PKEY_new_raw_private_key() function when setting a key length for
    a MAC. The old EVP_PKEY to MAC bridge, probably by accident, converts a
    -1 length to a strlen() call, by virtue of the fact that it eventually
    calls ASN1_STRING_set() which has this feature.
    
    As noted above this is undocumented, and unexpected since the len
    parameter to EVP_PKEY_new_raw_private_key() is an unsigned value (size_t).
    In the old bridge it was later (silently) cast to an int, and therefore
    the original -1 value was restored. This only works because sizeof(int) <=
    sizeof(size_t). If we ever run on a platform where sizeof(int) >
    sizeof(size_t) then it would have failed. The behaviour also doesn't hold
    for EVP_PKEY_new_raw_private_key() in general - only when the old MAC
    bridge was in use.
    
    Rather than restore the original behaviour I think it is best to simply
    fix the dgst app to not assume it exists. We should not bake in this
    backwards and inconsistent behaviour.
    
    Fixes #12837
    
    Reviewed-by: Dmitry Belyavskiy <beldmit at gmail.com>
    (Merged from https://github.com/openssl/openssl/pull/12850)

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

Summary of changes:
 apps/dgst.c                 | 12 ++++--------
 crypto/evp/digest.c         | 19 +++++++++++++++++++
 crypto/evp/evp_pkey.c       | 17 +++++++++++++++++
 crypto/evp/keymgmt_meth.c   |  5 +++++
 doc/man3/EVP_KEYMGMT.pod    | 11 +++++++++++
 doc/man3/EVP_PKEY_is_a.pod  | 16 +++++++++++++++-
 include/openssl/evp.h       |  3 +++
 test/recipes/20-test_dgst.t | 16 +++++++++++++++-
 util/libcrypto.num          |  2 ++
 9 files changed, 91 insertions(+), 10 deletions(-)

diff --git a/apps/dgst.c b/apps/dgst.c
index 0bbde71d4b..650115b468 100644
--- a/apps/dgst.c
+++ b/apps/dgst.c
@@ -319,7 +319,8 @@ int dgst_main(int argc, char **argv)
 
     if (hmac_key != NULL) {
         sigkey = EVP_PKEY_new_raw_private_key(EVP_PKEY_HMAC, impl,
-                                              (unsigned char *)hmac_key, -1);
+                                              (unsigned char *)hmac_key,
+                                              strlen(hmac_key));
         if (sigkey == NULL)
             goto end;
     }
@@ -405,13 +406,8 @@ int dgst_main(int argc, char **argv)
     } else {
         const char *sig_name = NULL;
         if (!out_bin) {
-            if (sigkey != NULL) {
-                const EVP_PKEY_ASN1_METHOD *ameth;
-                ameth = EVP_PKEY_get0_asn1(sigkey);
-                if (ameth)
-                    EVP_PKEY_asn1_get0_info(NULL, NULL,
-                                            NULL, NULL, &sig_name, ameth);
-            }
+            if (sigkey != NULL)
+                sig_name = EVP_PKEY_get0_first_alg_name(sigkey);
         }
         ret = 0;
         for (i = 0; i < argc; i++) {
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index a177abdb67..fb29ab5f08 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -140,6 +140,25 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
     ENGINE *tmpimpl = NULL;
 #endif
 
+#if !defined(FIPS_MODULE)
+    if (ctx->pctx != NULL
+            && EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx)
+            && ctx->pctx->op.sig.sigprovctx != NULL) {
+        /*
+         * Prior to OpenSSL 3.0 calling EVP_DigestInit_ex() on an mdctx
+         * previously initialised with EVP_DigestSignInit() would retain
+         * information about the key, and re-initialise for another sign
+         * operation. So in that case we redirect to EVP_DigestSignInit()
+         */
+        if (ctx->pctx->operation == EVP_PKEY_OP_SIGNCTX)
+            return EVP_DigestSignInit(ctx, NULL, type, impl, NULL);
+        if (ctx->pctx->operation == EVP_PKEY_OP_VERIFYCTX)
+            return EVP_DigestVerifyInit(ctx, NULL, type, impl, NULL);
+        EVPerr(0, EVP_R_UPDATE_ERROR);
+        return 0;
+    }
+#endif
+
     EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
 
     if (ctx->provctx != NULL) {
diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c
index d435c86087..f31d1d68f8 100644
--- a/crypto/evp/evp_pkey.c
+++ b/crypto/evp/evp_pkey.c
@@ -163,3 +163,20 @@ int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
         return 1;
     return 0;
 }
+
+const char *EVP_PKEY_get0_first_alg_name(const EVP_PKEY *key)
+{
+    const EVP_PKEY_ASN1_METHOD *ameth;
+    const char *name = NULL;
+
+    if (key->keymgmt != NULL)
+        return EVP_KEYMGMT_get0_first_name(key->keymgmt);
+
+    /* Otherwise fallback to legacy */
+    ameth = EVP_PKEY_get0_asn1(key);
+    if (ameth != NULL)
+        EVP_PKEY_asn1_get0_info(NULL, NULL,
+                                NULL, NULL, &name, ameth);
+
+    return name;
+}
diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c
index 1459b64f0e..5453ceadda 100644
--- a/crypto/evp/keymgmt_meth.c
+++ b/crypto/evp/keymgmt_meth.c
@@ -249,6 +249,11 @@ int EVP_KEYMGMT_number(const EVP_KEYMGMT *keymgmt)
     return keymgmt->name_id;
 }
 
+const char *EVP_KEYMGMT_get0_first_name(const EVP_KEYMGMT *keymgmt)
+{
+    return evp_first_name(keymgmt->prov, keymgmt->name_id);
+}
+
 int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name)
 {
     return evp_is_a(keymgmt->prov, keymgmt->name_id, NULL, name);
diff --git a/doc/man3/EVP_KEYMGMT.pod b/doc/man3/EVP_KEYMGMT.pod
index 8e7afc6a22..d06b9ba369 100644
--- a/doc/man3/EVP_KEYMGMT.pod
+++ b/doc/man3/EVP_KEYMGMT.pod
@@ -9,6 +9,7 @@ EVP_KEYMGMT_free,
 EVP_KEYMGMT_provider,
 EVP_KEYMGMT_is_a,
 EVP_KEYMGMT_number,
+EVP_KEYMGMT_get0_first_name,
 EVP_KEYMGMT_do_all_provided,
 EVP_KEYMGMT_names_do_all,
 EVP_KEYMGMT_gettable_params,
@@ -29,6 +30,8 @@ EVP_KEYMGMT_gen_settable_params
  const OSSL_PROVIDER *EVP_KEYMGMT_provider(const EVP_KEYMGMT *keymgmt);
  int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name);
  int EVP_KEYMGMT_number(const EVP_KEYMGMT *keymgmt);
+ const char *EVP_KEYMGMT_get0_first_name(const EVP_KEYMGMT *keymgmt);
+
  void EVP_KEYMGMT_do_all_provided(OPENSSL_CTX *libctx,
                                   void (*fn)(EVP_KEYMGMT *keymgmt, void *arg),
                                   void *arg);
@@ -69,6 +72,12 @@ algorithm that's identifiable with I<name>.
 EVP_KEYMGMT_number() returns the internal dynamic number assigned to
 the I<keymgmt>.
 
+EVP_KEYMGMT_get0_first_name() returns the first algorithm name that is found for
+the given I<keymgmt>. Note that the I<keymgmt> may have multiple synonyms
+associated with it. In this case it is undefined which one will be returned.
+Ownership of the returned string is retained by the I<keymgmt> object and should
+not be freed by the caller.
+
 EVP_KEYMGMT_names_do_all() traverses all names for the I<keymgmt>, and
 calls I<fn> with each name and I<data>.
 
@@ -111,6 +120,8 @@ otherwise 0.
 
 EVP_KEYMGMT_number() returns an integer.
 
+EVP_KEYMGMT_get0_first_name() returns the name that is found or NULL on error.
+
 EVP_KEYMGMT_gettable_params(), EVP_KEYMGMT_settable_params() and
 EVP_KEYMGMT_gen_settable_params() return a constant B<OSSL_PARAM> array or
 NULL on error.
diff --git a/doc/man3/EVP_PKEY_is_a.pod b/doc/man3/EVP_PKEY_is_a.pod
index cfce3de5da..efc72ea110 100644
--- a/doc/man3/EVP_PKEY_is_a.pod
+++ b/doc/man3/EVP_PKEY_is_a.pod
@@ -2,7 +2,7 @@
 
 =head1 NAME
 
-EVP_PKEY_is_a, EVP_PKEY_can_sign
+EVP_PKEY_is_a, EVP_PKEY_can_sign, EVP_PKEY_get0_first_alg_name
 - key type and capabilities functions
 
 =head1 SYNOPSIS
@@ -11,6 +11,8 @@ EVP_PKEY_is_a, EVP_PKEY_can_sign
 
  int EVP_PKEY_is_a(const EVP_PKEY *pkey, const char *name);
  int EVP_PKEY_can_sign(const EVP_PKEY *pkey);
+ const char *EVP_PKEY_get0_first_alg_name(const EVP_PKEY *key);
+
 
 =head1 DESCRIPTION
 
@@ -20,6 +22,12 @@ EVP_PKEY_can_sign() checks if the functionality for the key type of
 I<pkey> supports signing.  No other check is done, such as whether
 I<pkey> contains a private key.
 
+EVP_PKEY_get0_first_alg_name() returns the first algorithm name that is found
+for the given I<pkey>. Note that the I<pkey> may have multiple synonyms
+associated with it. In this case it is undefined which one will be returned.
+Ownership of the returned string is retained by the I<pkey> object and should
+not be freed by the caller.
+
 =head1 RETURN VALUES
 
 EVP_PKEY_is_a() returns 1 if I<pkey> has the key type I<name>,
@@ -28,6 +36,8 @@ otherwise 0.
 EVP_PKEY_can_sign() returns 1 if the I<pkey> key type functionality
 supports signing, otherwise 0.
 
+EVP_PKEY_get0_first_alg_name() returns the name that is found or NULL on error.
+
 =head1 EXAMPLES
 
 =head2 EVP_PKEY_is_a()
@@ -60,6 +70,10 @@ this as an crude example:
      }
      /* Sign something... */
 
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
 =head1 COPYRIGHT
 
 Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 4d0cc9d560..ff97198542 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1496,6 +1496,8 @@ int EVP_PKEY_CTX_set1_id(EVP_PKEY_CTX *ctx, const void *id, int len);
 int EVP_PKEY_CTX_get1_id(EVP_PKEY_CTX *ctx, void *id);
 int EVP_PKEY_CTX_get1_id_len(EVP_PKEY_CTX *ctx, size_t *id_len);
 
+const char *EVP_PKEY_get0_first_alg_name(const EVP_PKEY *key);
+
 # define EVP_PKEY_OP_UNDEFINED           0
 # define EVP_PKEY_OP_PARAMGEN            (1<<1)
 # define EVP_PKEY_OP_KEYGEN              (1<<2)
@@ -1573,6 +1575,7 @@ EVP_KEYMGMT *EVP_KEYMGMT_fetch(OPENSSL_CTX *ctx, const char *algorithm,
 int EVP_KEYMGMT_up_ref(EVP_KEYMGMT *keymgmt);
 void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt);
 const OSSL_PROVIDER *EVP_KEYMGMT_provider(const EVP_KEYMGMT *keymgmt);
+const char *EVP_KEYMGMT_get0_first_name(const EVP_KEYMGMT *keymgmt);
 int EVP_KEYMGMT_number(const EVP_KEYMGMT *keymgmt);
 int EVP_KEYMGMT_is_a(const EVP_KEYMGMT *keymgmt, const char *name);
 void EVP_KEYMGMT_do_all_provided(OPENSSL_CTX *libctx,
diff --git a/test/recipes/20-test_dgst.t b/test/recipes/20-test_dgst.t
index 0b7ab2d5d1..9dcf6d31a2 100644
--- a/test/recipes/20-test_dgst.t
+++ b/test/recipes/20-test_dgst.t
@@ -17,7 +17,7 @@ use OpenSSL::Test::Utils;
 
 setup("test_dgst");
 
-plan tests => 5;
+plan tests => 6;
 
 sub tsignverify {
     my $testtext = shift;
@@ -102,3 +102,17 @@ SKIP: {
                     srctop_file("test","tested448pub.pem"));
     };
 }
+
+subtest "HMAC generation with `dgst` CLI" => sub {
+    plan tests => 2;
+
+    my $testdata = srctop_file('test', 'data.txt');
+    #HMAC the data twice to check consistency
+    my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-hmac', '123456',
+                            $testdata, $testdata]), capture => 1);
+    chomp(@hmacdata);
+    my $expected = qr/HMAC-SHA256\([^\)]*data.txt\)= 6f12484129c4a761747f13d8234a1ff0e074adb34e9e9bf3a155c391b97b9a7c/;
+    ok($hmacdata[0] =~ $expected, "HMAC: Check HMAC value is as expected ($hmacdata[0]) vs ($expected)");
+    ok($hmacdata[1] =~ $expected,
+       "HMAC: Check second HMAC value is consistent with the first ($hmacdata[1]) vs ($expected)");
+};
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 6070b570a5..a1b8ce0be1 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -5280,3 +5280,5 @@ EVP_PKEY_CTX_get1_id_len                ?	3_0_0	EXIST::FUNCTION:
 CMS_AuthEnvelopedData_create            ?	3_0_0	EXIST::FUNCTION:CMS
 CMS_AuthEnvelopedData_create_with_libctx ?	3_0_0	EXIST::FUNCTION:CMS
 EVP_PKEY_CTX_set_ec_param_enc           ?	3_0_0	EXIST::FUNCTION:EC
+EVP_PKEY_get0_first_alg_name            ?	3_0_0	EXIST::FUNCTION:
+EVP_KEYMGMT_get0_first_name             ?	3_0_0	EXIST::FUNCTION:


More information about the openssl-commits mailing list