[openssl] master update
Matt Caswell
matt at openssl.org
Fri Oct 11 11:19:34 UTC 2019
The branch master has been updated
via 59d0e6c8964c07d7e46c9989735cd1486250b330 (commit)
via 72df8f8825d54a7f1be48cc9035f4e3a86f639b4 (commit)
via bc3a1377366b2465cebfb61032c1e864c6bbf665 (commit)
from 7c3ccd7fc823b5580f862c0e35dd7962fd2ae0f0 (commit)
- Log -----------------------------------------------------------------
commit 59d0e6c8964c07d7e46c9989735cd1486250b330
Author: Matt Caswell <matt at openssl.org>
Date: Mon Oct 7 18:21:39 2019 +0100
Add a test for EVP_Digest[Sign|Verify]* with a BIO MD
If an EVP_MD_CTX is initialised with EVP_DigestSignInit_ex() or
EVP_DigestVerifyInit_ex() it should work with an MD BIO to provide
the "Updates". Test that this is the case.
Reviewed-by: Richard Levitte <levitte at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10116)
commit 72df8f8825d54a7f1be48cc9035f4e3a86f639b4
Author: Matt Caswell <matt at openssl.org>
Date: Mon Oct 7 17:47:04 2019 +0100
Support calling EVP_DigestUpdate instead of EVP_Digest[Sign|Verify]Update
Prior to OpenSSL 3.0 EVP_Digest[Sign|Verify|Update were just macros for
EVP_DigestUpdate. They are now separate functions. Unfortunately some
code assumes that EVP_Digest[Sign|Verify]Update is interchangeable with
EVP_DigestUpdate. For example the dgst app uses an MD bio which always
calls EVP_DigestUpdate(). However the dgst app supports signing instead
of digesting and may initialise with EVP_DigestSignInit_ex() instead of
just EVP_DigestInit().
We now detect these differences and redirect to the correct function
where appropriate.
Fixes #10114
Reviewed-by: Richard Levitte <levitte at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10116)
commit bc3a1377366b2465cebfb61032c1e864c6bbf665
Author: Matt Caswell <matt at openssl.org>
Date: Mon Oct 7 17:45:25 2019 +0100
Don't use internal knowledge about EVP_MD_CTX in and MD BIO
There is no need for us to be diving inside the EVP_MD_CTX in the
implementation of an MD BIO. We can just use public APIs. By doing this
certain calls (such as getting the MD out of the BIO were not working
correctly) where providers are in use.
Reviewed-by: Richard Levitte <levitte at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10116)
-----------------------------------------------------------------------
Summary of changes:
crypto/evp/bio_md.c | 9 +--
crypto/evp/build.info | 5 +-
crypto/evp/digest.c | 18 ++++++
crypto/evp/m_sigver.c | 6 +-
test/evp_extra_test.c | 150 ++++++++++++++++++++++++++++++++++++++++++++------
5 files changed, 163 insertions(+), 25 deletions(-)
diff --git a/crypto/evp/bio_md.c b/crypto/evp/bio_md.c
index 8d502d0bf7..aca177e9da 100644
--- a/crypto/evp/bio_md.c
+++ b/crypto/evp/bio_md.c
@@ -9,11 +9,8 @@
#include <stdio.h>
#include <errno.h>
-#include "internal/cryptlib.h"
#include <openssl/buffer.h>
#include <openssl/evp.h>
-#include "crypto/evp.h"
-#include "evp_local.h"
#include "internal/bio.h"
/*
@@ -148,7 +145,7 @@ static long md_ctrl(BIO *b, int cmd, long num, void *ptr)
switch (cmd) {
case BIO_CTRL_RESET:
if (BIO_get_init(b))
- ret = EVP_DigestInit_ex(ctx, ctx->digest, NULL);
+ ret = EVP_DigestInit_ex(ctx, EVP_MD_CTX_md(ctx), NULL);
else
ret = 0;
if (ret > 0)
@@ -157,7 +154,7 @@ static long md_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_C_GET_MD:
if (BIO_get_init(b)) {
ppmd = ptr;
- *ppmd = ctx->digest;
+ *ppmd = EVP_MD_CTX_md(ctx);
} else
ret = 0;
break;
@@ -223,7 +220,7 @@ static int md_gets(BIO *bp, char *buf, int size)
ctx = BIO_get_data(bp);
- if (size < ctx->digest->md_size)
+ if (size < EVP_MD_CTX_size(ctx))
return 0;
if (EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &ret) <= 0)
diff --git a/crypto/evp/build.info b/crypto/evp/build.info
index 94f033bbc1..aef0031d3d 100644
--- a/crypto/evp/build.info
+++ b/crypto/evp/build.info
@@ -1,6 +1,7 @@
LIBS=../../libcrypto
$COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c cmeth_lib.c evp_utils.c \
- mac_lib.c mac_meth.c keymgmt_meth.c keymgmt_lib.c kdf_lib.c kdf_meth.c
+ mac_lib.c mac_meth.c keymgmt_meth.c keymgmt_lib.c kdf_lib.c kdf_meth.c \
+ m_sigver.c
SOURCE[../../libcrypto]=$COMMON\
encode.c evp_key.c evp_cnf.c \
e_des.c e_bf.c e_idea.c e_des3.c e_camellia.c\
@@ -13,7 +14,7 @@ SOURCE[../../libcrypto]=$COMMON\
c_allc.c c_alld.c bio_ok.c \
evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c pbe_scrypt.c \
pkey_kdf.c \
- e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c \
+ e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c \
e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \
e_chacha20_poly1305.c \
pkey_mac.c exchange.c \
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index fa1dfa7303..5ff43fdd64 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -285,6 +285,24 @@ int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
if (count == 0)
return 1;
+ if (ctx->pctx != NULL
+ && EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx->pctx)
+ && ctx->pctx->op.sig.sigprovctx != NULL) {
+ /*
+ * Prior to OpenSSL 3.0 EVP_DigestSignUpdate() and
+ * EVP_DigestVerifyUpdate() were just macros for EVP_DigestUpdate().
+ * Some code calls EVP_DigestUpdate() directly even when initialised
+ * with EVP_DigestSignInit_ex() or EVP_DigestVerifyInit_ex(), so we
+ * detect that and redirect to the correct EVP_Digest*Update() function
+ */
+ if (ctx->pctx->operation == EVP_PKEY_OP_SIGNCTX)
+ return EVP_DigestSignUpdate(ctx, data, count);
+ if (ctx->pctx->operation == EVP_PKEY_OP_VERIFYCTX)
+ return EVP_DigestVerifyUpdate(ctx, data, count);
+ EVPerr(EVP_F_EVP_DIGESTUPDATE, EVP_R_UPDATE_ERROR);
+ return 0;
+ }
+
if (ctx->digest == NULL || ctx->digest->prov == NULL)
goto legacy;
diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
index 85272c9516..7912c8dd59 100644
--- a/crypto/evp/m_sigver.c
+++ b/crypto/evp/m_sigver.c
@@ -16,6 +16,8 @@
#include "internal/provider.h"
#include "evp_local.h"
+#ifndef FIPS_MODE
+
static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen)
{
EVPerr(EVP_F_UPDATE, EVP_R_ONLY_ONESHOT_SUPPORTED);
@@ -220,6 +222,7 @@ int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
{
return do_sigver_init(ctx, pctx, type, NULL, NULL, e, pkey, NULL, 1);
}
+#endif /* FIPS_MDOE */
int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
{
@@ -255,7 +258,7 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
return EVP_DigestUpdate(ctx, data, dsize);
}
-
+#ifndef FIPS_MODE
int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
size_t *siglen)
{
@@ -397,3 +400,4 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
return -1;
return EVP_DigestVerifyFinal(ctx, sigret, siglen);
}
+#endif /* FIPS_MODE */
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index d7f63f0247..3a843e6a43 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -84,6 +84,51 @@ static const unsigned char kExampleRSAKeyDER[] = {
0x2d, 0x86, 0x9d, 0xa5, 0x20, 0x1b, 0xe5, 0xdf,
};
+/*
+* kExampleDSAKeyDER is a DSA private key in ASN.1, DER format. Of course, you
+ * should never use this key anywhere but in an example.
+ */
+static const unsigned char kExampleDSAKeyDER[] = {
+ 0x30, 0x82, 0x01, 0xba, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0x9a,
+ 0x05, 0x6d, 0x33, 0xcd, 0x5d, 0x78, 0xa1, 0xbb, 0xcb, 0x7d, 0x5b, 0x8d,
+ 0xb4, 0xcc, 0xbf, 0x03, 0x99, 0x64, 0xde, 0x38, 0x78, 0x06, 0x15, 0x2f,
+ 0x86, 0x26, 0x77, 0xf3, 0xb1, 0x85, 0x00, 0xed, 0xfc, 0x28, 0x3a, 0x42,
+ 0x4d, 0xab, 0xab, 0xdf, 0xbc, 0x9c, 0x16, 0xd0, 0x22, 0x50, 0xd1, 0x38,
+ 0xdd, 0x3f, 0x64, 0x05, 0x9e, 0x68, 0x7a, 0x1e, 0xf1, 0x56, 0xbf, 0x1e,
+ 0x2c, 0xc5, 0x97, 0x2a, 0xfe, 0x7a, 0x22, 0xdc, 0x6c, 0x68, 0xb8, 0x2e,
+ 0x06, 0xdb, 0x41, 0xca, 0x98, 0xd8, 0x54, 0xc7, 0x64, 0x48, 0x24, 0x04,
+ 0x20, 0xbc, 0x59, 0xe3, 0x6b, 0xea, 0x7e, 0xfc, 0x7e, 0xc5, 0x4e, 0xd4,
+ 0xd8, 0x3a, 0xed, 0xcd, 0x5d, 0x99, 0xb8, 0x5c, 0xa2, 0x8b, 0xbb, 0x0b,
+ 0xac, 0xe6, 0x8e, 0x25, 0x56, 0x22, 0x3a, 0x2d, 0x3a, 0x56, 0x41, 0x14,
+ 0x1f, 0x1c, 0x8f, 0x53, 0x46, 0x13, 0x85, 0x02, 0x15, 0x00, 0x98, 0x7e,
+ 0x92, 0x81, 0x88, 0xc7, 0x3f, 0x70, 0x49, 0x54, 0xf6, 0x76, 0xb4, 0xa3,
+ 0x9e, 0x1d, 0x45, 0x98, 0x32, 0x7f, 0x02, 0x81, 0x80, 0x69, 0x4d, 0xef,
+ 0x55, 0xff, 0x4d, 0x59, 0x2c, 0x01, 0xfa, 0x6a, 0x38, 0xe0, 0x70, 0x9f,
+ 0x9e, 0x66, 0x8e, 0x3e, 0x8c, 0x52, 0x22, 0x9d, 0x15, 0x7e, 0x3c, 0xef,
+ 0x4c, 0x7a, 0x61, 0x26, 0xe0, 0x2b, 0x81, 0x3f, 0xeb, 0xaf, 0x35, 0x38,
+ 0x8d, 0xfe, 0xed, 0x46, 0xff, 0x5f, 0x03, 0x9b, 0x81, 0x92, 0xe7, 0x6f,
+ 0x76, 0x4f, 0x1d, 0xd9, 0xbb, 0x89, 0xc9, 0x3e, 0xd9, 0x0b, 0xf9, 0xf4,
+ 0x78, 0x11, 0x59, 0xc0, 0x1d, 0xcd, 0x0e, 0xa1, 0x6f, 0x15, 0xf1, 0x4d,
+ 0xc1, 0xc9, 0x22, 0xed, 0x8d, 0xad, 0x67, 0xc5, 0x4b, 0x95, 0x93, 0x86,
+ 0xa6, 0xaf, 0x8a, 0xee, 0x06, 0x89, 0x2f, 0x37, 0x7e, 0x64, 0xaa, 0xf6,
+ 0xe7, 0xb1, 0x5a, 0x0a, 0x93, 0x95, 0x5d, 0x3e, 0x53, 0x9a, 0xde, 0x8a,
+ 0xc2, 0x95, 0x45, 0x81, 0xbe, 0x5c, 0x2f, 0xc2, 0xb2, 0x92, 0x58, 0x19,
+ 0x72, 0x80, 0xe9, 0x79, 0xa1, 0x02, 0x81, 0x80, 0x07, 0xd7, 0x62, 0xff,
+ 0xdf, 0x1a, 0x3f, 0xed, 0x32, 0xd4, 0xd4, 0x88, 0x7b, 0x2c, 0x63, 0x7f,
+ 0x97, 0xdc, 0x44, 0xd4, 0x84, 0xa2, 0xdd, 0x17, 0x16, 0x85, 0x13, 0xe0,
+ 0xac, 0x51, 0x8d, 0x29, 0x1b, 0x75, 0x9a, 0xe4, 0xe3, 0x8a, 0x92, 0x69,
+ 0x09, 0x03, 0xc5, 0x68, 0xae, 0x5e, 0x94, 0xfe, 0xc9, 0x92, 0x6c, 0x07,
+ 0xb4, 0x1e, 0x64, 0x62, 0x87, 0xc6, 0xa4, 0xfd, 0x0d, 0x5f, 0xe5, 0xf9,
+ 0x1b, 0x4f, 0x85, 0x5f, 0xae, 0xf3, 0x11, 0xe5, 0x18, 0xd4, 0x4d, 0x79,
+ 0x9f, 0xc4, 0x79, 0x26, 0x04, 0x27, 0xf0, 0x0b, 0xee, 0x2b, 0x86, 0x9f,
+ 0x86, 0x61, 0xe6, 0x51, 0xce, 0x04, 0x9b, 0x5d, 0x6b, 0x34, 0x43, 0x8c,
+ 0x85, 0x3c, 0xf1, 0x51, 0x9b, 0x08, 0x23, 0x1b, 0xf5, 0x7e, 0x33, 0x12,
+ 0xea, 0xab, 0x1f, 0xb7, 0x2d, 0xe2, 0x5f, 0xe6, 0x97, 0x99, 0xb5, 0x45,
+ 0x16, 0x5b, 0xc3, 0x41, 0x02, 0x14, 0x61, 0xbf, 0x51, 0x60, 0xcf, 0xc8,
+ 0xf1, 0x8c, 0x82, 0x97, 0xf2, 0xf4, 0x19, 0xba, 0x2b, 0xf3, 0x16, 0xbe,
+ 0x40, 0x48
+};
+
/*
* kExampleBadRSAKeyDER is an RSA private key in ASN.1, DER format. The private
* components are not correct.
@@ -377,6 +422,31 @@ end:
return ret;
}
+static EVP_PKEY *load_example_dsa_key(void)
+{
+ EVP_PKEY *ret = NULL;
+ const unsigned char *derp = kExampleDSAKeyDER;
+ EVP_PKEY *pkey = NULL;
+ DSA *dsa = NULL;
+
+ if (!TEST_true(d2i_DSAPrivateKey(&dsa, &derp, sizeof(kExampleDSAKeyDER))))
+ return NULL;
+
+ if (!TEST_ptr(pkey = EVP_PKEY_new())
+ || !TEST_true(EVP_PKEY_set1_DSA(pkey, dsa)))
+ goto end;
+
+ ret = pkey;
+ pkey = NULL;
+
+end:
+ EVP_PKEY_free(pkey);
+ DSA_free(dsa);
+
+ return ret;
+}
+
+
static int test_EVP_Enveloped(void)
{
int ret = 0;
@@ -420,24 +490,56 @@ err:
return ret;
}
-
-static int test_EVP_DigestSignInit(void)
+/*
+ * Test 0: Standard calls to EVP_DigestSignInit/Update/Final (RSA)
+ * Test 1: Standard calls to EVP_DigestSignInit/Update/Final (DSA)
+ * Test 2: Use an MD BIO to do the Update calls instead (RSA)
+ * Test 3: Use an MD BIO to do the Update calls instead (DSA)
+ */
+static int test_EVP_DigestSignInit(int tst)
{
int ret = 0;
EVP_PKEY *pkey = NULL;
unsigned char *sig = NULL;
size_t sig_len = 0;
- EVP_MD_CTX *md_ctx, *md_ctx_verify = NULL;
+ EVP_MD_CTX *md_ctx = NULL, *md_ctx_verify = NULL;
+ EVP_MD_CTX *a_md_ctx = NULL, *a_md_ctx_verify = NULL;
+ BIO *mdbio = NULL, *membio = NULL;
+ size_t written;
+
+ if (tst >= 2) {
+ membio = BIO_new(BIO_s_mem());
+ mdbio = BIO_new(BIO_f_md());
+ if (!TEST_ptr(membio) || !TEST_ptr(mdbio))
+ goto out;
+ BIO_push(mdbio, membio);
+ if (!TEST_int_gt(BIO_get_md_ctx(mdbio, &md_ctx), 0))
+ goto out;
+ } else {
+ if (!TEST_ptr(a_md_ctx = md_ctx = EVP_MD_CTX_new())
+ || !TEST_ptr(a_md_ctx_verify = md_ctx_verify = EVP_MD_CTX_new()))
+ goto out;
+ }
- if (!TEST_ptr(md_ctx = EVP_MD_CTX_new())
- || !TEST_ptr(md_ctx_verify = EVP_MD_CTX_new())
- || !TEST_ptr(pkey = load_example_rsa_key()))
- goto out;
+ if (tst == 0 || tst == 2) {
+ if (!TEST_ptr(pkey = load_example_rsa_key()))
+ goto out;
+ } else {
+ if (!TEST_ptr(pkey = load_example_dsa_key()))
+ goto out;
+ }
- if (!TEST_true(EVP_DigestSignInit(md_ctx, NULL, EVP_sha256(), NULL, pkey))
- || !TEST_true(EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg))))
+ if (!TEST_true(EVP_DigestSignInit(md_ctx, NULL, EVP_sha256(), NULL, pkey)))
goto out;
+ if (tst >= 2) {
+ if (!BIO_write_ex(mdbio, kMsg, sizeof(kMsg), &written))
+ goto out;
+ } else {
+ if (!TEST_true(EVP_DigestSignUpdate(md_ctx, kMsg, sizeof(kMsg))))
+ goto out;
+ }
+
/* Determine the size of the signature. */
if (!TEST_true(EVP_DigestSignFinal(md_ctx, NULL, &sig_len))
|| !TEST_size_t_eq(sig_len, (size_t)EVP_PKEY_size(pkey)))
@@ -447,19 +549,35 @@ static int test_EVP_DigestSignInit(void)
|| !TEST_true(EVP_DigestSignFinal(md_ctx, sig, &sig_len)))
goto out;
+ if (tst >= 2) {
+ if (!TEST_int_gt(BIO_reset(mdbio), 0)
+ || !TEST_int_gt(BIO_get_md_ctx(mdbio, &md_ctx_verify), 0))
+ goto out;
+ }
+
/* Ensure that the signature round-trips. */
if (!TEST_true(EVP_DigestVerifyInit(md_ctx_verify, NULL, EVP_sha256(),
- NULL, pkey))
- || !TEST_true(EVP_DigestVerifyUpdate(md_ctx_verify,
- kMsg, sizeof(kMsg)))
- || !TEST_true(EVP_DigestVerifyFinal(md_ctx_verify, sig, sig_len)))
+ NULL, pkey)))
+ goto out;
+
+ if (tst >= 2) {
+ if (!BIO_write_ex(mdbio, kMsg, sizeof(kMsg), &written))
+ goto out;
+ } else {
+ if (!TEST_true(EVP_DigestVerifyUpdate(md_ctx_verify, kMsg,
+ sizeof(kMsg))))
+ goto out;
+ }
+ if (!TEST_true(EVP_DigestVerifyFinal(md_ctx_verify, sig, sig_len)))
goto out;
ret = 1;
out:
- EVP_MD_CTX_free(md_ctx);
- EVP_MD_CTX_free(md_ctx_verify);
+ BIO_free(membio);
+ BIO_free(mdbio);
+ EVP_MD_CTX_free(a_md_ctx);
+ EVP_MD_CTX_free(a_md_ctx_verify);
EVP_PKEY_free(pkey);
OPENSSL_free(sig);
@@ -1220,7 +1338,7 @@ static int test_EVP_PKEY_CTX_get_set_params(void)
int setup_tests(void)
{
- ADD_TEST(test_EVP_DigestSignInit);
+ ADD_ALL_TESTS(test_EVP_DigestSignInit, 4);
ADD_TEST(test_EVP_DigestVerifyInit);
ADD_TEST(test_EVP_Enveloped);
ADD_ALL_TESTS(test_d2i_AutoPrivateKey, OSSL_NELEM(keydata));
More information about the openssl-commits
mailing list