summaryrefslogtreecommitdiffstats
path: root/test/evp_extra_test.c
diff options
context:
space:
mode:
authorMatt Caswell <matt@openssl.org>2021-10-07 14:15:47 +0100
committerMatt Caswell <matt@openssl.org>2021-10-22 08:44:59 +0100
commit1974be5912fc10c4f589c328063aba7a09d3aa93 (patch)
tree03f05cca7e7d4fb02856e7397ab1ed46a0e8194b /test/evp_extra_test.c
parent55398b354f55955a1f504f591b8cf64a559a5793 (diff)
Test short buffers
Test that calling EVP_DigestSign(), EVP_DigestSignFinal(), EVP_PKEY_sign(), EVP_PKEY_get_raw_private_key(), or EVP_PKEY_get_raw_public_key() with a short output buffer results in a failure. Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/16789) (cherry picked from commit 15ff7d7c2569a1aceaf6e85b61aee62422628fc9)
Diffstat (limited to 'test/evp_extra_test.c')
-rw-r--r--test/evp_extra_test.c157
1 files changed, 133 insertions, 24 deletions
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index baa93beb11..33c5a5b7e6 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -600,6 +600,14 @@ static EVP_PKEY *load_example_dsa_key(void)
}
#endif
+#ifndef OPENSSL_NO_EC
+static EVP_PKEY *load_example_ec_key(void)
+{
+ return load_example_key("EC", kExampleECKeyDER,
+ sizeof(kExampleECKeyDER));
+}
+#endif
+
#ifndef OPENSSL_NO_DEPRECATED_3_0
# ifndef OPENSSL_NO_DH
static EVP_PKEY *load_example_dh_key(void)
@@ -610,12 +618,6 @@ static EVP_PKEY *load_example_dh_key(void)
# endif
# ifndef OPENSSL_NO_EC
-static EVP_PKEY *load_example_ec_key(void)
-{
- return load_example_key("EC", kExampleECKeyDER,
- sizeof(kExampleECKeyDER));
-}
-
static EVP_PKEY *load_example_ed25519_key(void)
{
return load_example_key("ED25519", kExampleED25519KeyDER,
@@ -979,6 +981,66 @@ static int test_EC_priv_only_legacy(void)
# endif /* OPENSSL_NO_DEPRECATED_3_0 */
#endif /* OPENSSL_NO_EC */
+static int test_EVP_PKEY_sign(int tst)
+{
+ int ret = 0;
+ EVP_PKEY *pkey = NULL;
+ unsigned char *sig = NULL;
+ size_t sig_len = 0, shortsig_len = 1;
+ EVP_PKEY_CTX *ctx = NULL;
+ unsigned char tbs[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
+ 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13
+ };
+
+ if (tst == 0 ) {
+ if (!TEST_ptr(pkey = load_example_rsa_key()))
+ goto out;
+ } else if (tst == 1) {
+#ifndef OPENSSL_NO_DSA
+ if (!TEST_ptr(pkey = load_example_dsa_key()))
+ goto out;
+#else
+ ret = 1;
+ goto out;
+#endif
+ } else {
+#ifndef OPENSSL_NO_EC
+ if (!TEST_ptr(pkey = load_example_ec_key()))
+ goto out;
+#else
+ ret = 1;
+ goto out;
+#endif
+ }
+
+ ctx = EVP_PKEY_CTX_new_from_pkey(testctx, pkey, NULL);
+ if (!TEST_ptr(ctx)
+ || !TEST_int_gt(EVP_PKEY_sign_init(ctx), 0)
+ || !TEST_int_gt(EVP_PKEY_sign(ctx, NULL, &sig_len, tbs,
+ sizeof(tbs)), 0))
+ goto out;
+ sig = OPENSSL_malloc(sig_len);
+ if (!TEST_ptr(sig)
+ /* Test sending a signature buffer that is too short is rejected */
+ || !TEST_int_le(EVP_PKEY_sign(ctx, sig, &shortsig_len, tbs,
+ sizeof(tbs)), 0)
+ || !TEST_int_gt(EVP_PKEY_sign(ctx, sig, &sig_len, tbs, sizeof(tbs)),
+ 0)
+ /* Test the signature round-trips */
+ || !TEST_int_gt(EVP_PKEY_verify_init(ctx), 0)
+ || !TEST_int_gt(EVP_PKEY_verify(ctx, sig, sig_len, tbs, sizeof(tbs)),
+ 0))
+ goto out;
+
+ ret = 1;
+ out:
+ EVP_PKEY_CTX_free(ctx);
+ OPENSSL_free(sig);
+ EVP_PKEY_free(pkey);
+ return ret;
+}
+
/*
* n = 0 => test using legacy cipher
* n = 1 => test using fetched cipher
@@ -1047,13 +1109,19 @@ err:
* Test 6: Use an MD BIO to do the Update calls instead (RSA)
* Test 7: Use an MD BIO to do the Update calls instead (DSA)
* Test 8: Use an MD BIO to do the Update calls instead (HMAC)
+ * Test 9: Use EVP_DigestSign (Implicit fetch digest, RSA, short sig)
+ * Test 10: Use EVP_DigestSign (Implicit fetch digest, DSA, short sig)
+ * Test 11: Use EVP_DigestSign (Implicit fetch digest, HMAC, short sig)
+ * Test 12: Use EVP_DigestSign (Implicit fetch digest, RSA)
+ * Test 13: Use EVP_DigestSign (Implicit fetch digest, DSA)
+ * Test 14: Use EVP_DigestSign (Implicit fetch digest, HMAC)
*/
static int test_EVP_DigestSignInit(int tst)
{
int ret = 0;
EVP_PKEY *pkey = NULL;
unsigned char *sig = NULL, *sig2 = NULL;
- size_t sig_len = 0, sig2_len = 0;
+ size_t sig_len = 0, sig2_len = 0, shortsig_len = 1;
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;
@@ -1064,7 +1132,7 @@ static int test_EVP_DigestSignInit(int tst)
if (nullprov != NULL)
return TEST_skip("Test does not support a non-default library context");
- if (tst >= 6) {
+ if (tst >= 6 && tst <= 8) {
membio = BIO_new(BIO_s_mem());
mdbio = BIO_new(BIO_f_md());
if (!TEST_ptr(membio) || !TEST_ptr(mdbio))
@@ -1078,10 +1146,10 @@ static int test_EVP_DigestSignInit(int tst)
goto out;
}
- if (tst == 0 || tst == 3 || tst == 6) {
+ if (tst % 3 == 0) {
if (!TEST_ptr(pkey = load_example_rsa_key()))
goto out;
- } else if (tst == 1 || tst == 4 || tst == 7) {
+ } else if (tst % 3 == 1) {
#ifndef OPENSSL_NO_DSA
if (!TEST_ptr(pkey = load_example_dsa_key()))
goto out;
@@ -1102,26 +1170,54 @@ static int test_EVP_DigestSignInit(int tst)
if (!TEST_true(EVP_DigestSignInit(md_ctx, NULL, md, NULL, pkey)))
goto out;
- if (tst >= 6) {
+ if (tst >= 6 && tst <= 8) {
if (!BIO_write_ex(mdbio, kMsg, sizeof(kMsg), &written))
goto out;
- } else {
+ } else if (tst < 6) {
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_ptr(sig = OPENSSL_malloc(sig_len))
- || !TEST_true(EVP_DigestSignFinal(md_ctx, sig, &sig_len)))
- goto out;
+ if (tst >= 9) {
+ /* Determine the size of the signature. */
+ if (!TEST_true(EVP_DigestSign(md_ctx, NULL, &sig_len, kMsg,
+ sizeof(kMsg)))
+ || !TEST_ptr(sig = OPENSSL_malloc(sig_len)))
+ goto out;
+ if (tst <= 11) {
+ /* Test that supply a short sig buffer fails */
+ if (!TEST_false(EVP_DigestSign(md_ctx, sig, &shortsig_len, kMsg,
+ sizeof(kMsg))))
+ goto out;
+ /*
+ * We end here because once EVP_DigestSign() has failed you should
+ * not call it again without re-initing the ctx
+ */
+ ret = 1;
+ goto out;
+ }
+ if (!TEST_true(EVP_DigestSign(md_ctx, sig, &sig_len, kMsg,
+ sizeof(kMsg))))
+ goto out;
+ } else {
+ /* Determine the size of the signature. */
+ if (!TEST_true(EVP_DigestSignFinal(md_ctx, NULL, &sig_len))
+ || !TEST_ptr(sig = OPENSSL_malloc(sig_len))
+ /*
+ * Trying to create a signature with a deliberately short
+ * buffer should fail.
+ */
+ || !TEST_false(EVP_DigestSignFinal(md_ctx, sig, &shortsig_len))
+ || !TEST_true(EVP_DigestSignFinal(md_ctx, sig, &sig_len)))
+ goto out;
+ }
/*
* Ensure that the signature round-trips (Verification isn't supported for
* HMAC via EVP_DigestVerify*)
*/
- if (tst != 2 && tst != 5 && tst != 8) {
- if (tst >= 6) {
+ if (tst % 3 != 2) {
+ if (tst >= 6 && tst <= 8) {
if (!TEST_int_gt(BIO_reset(mdbio), 0)
|| !TEST_int_gt(BIO_get_md_ctx(mdbio, &md_ctx_verify), 0))
goto out;
@@ -1131,7 +1227,7 @@ static int test_EVP_DigestSignInit(int tst)
NULL, pkey)))
goto out;
- if (tst >= 6) {
+ if (tst >= 6 && tst <= 8) {
if (!TEST_true(BIO_write_ex(mdbio, kMsg, sizeof(kMsg), &written)))
goto out;
} else {
@@ -1806,7 +1902,7 @@ static int test_set_get_raw_keys_int(int tst, int pub, int uselibctx)
int ret = 0;
unsigned char buf[80];
unsigned char *in;
- size_t inlen, len = 0;
+ size_t inlen, len = 0, shortlen = 1;
EVP_PKEY *pkey;
/* Check if this algorithm supports public keys */
@@ -1856,8 +1952,20 @@ static int test_set_get_raw_keys_int(int tst, int pub, int uselibctx)
|| !TEST_int_eq(EVP_PKEY_eq(pkey, pkey), 1)
|| (!pub && !TEST_true(EVP_PKEY_get_raw_private_key(pkey, NULL, &len)))
|| (pub && !TEST_true(EVP_PKEY_get_raw_public_key(pkey, NULL, &len)))
- || !TEST_true(len == inlen)
- || (!pub && !TEST_true(EVP_PKEY_get_raw_private_key(pkey, buf, &len)))
+ || !TEST_true(len == inlen))
+ goto done;
+ if (tst != 1) {
+ /*
+ * Test that supplying a buffer that is too small fails. Doesn't apply
+ * to HMAC with a zero length key
+ */
+ if ((!pub && !TEST_false(EVP_PKEY_get_raw_private_key(pkey, buf,
+ &shortlen)))
+ || (pub && !TEST_false(EVP_PKEY_get_raw_public_key(pkey, buf,
+ &shortlen))))
+ goto done;
+ }
+ if ((!pub && !TEST_true(EVP_PKEY_get_raw_private_key(pkey, buf, &len)))
|| (pub && !TEST_true(EVP_PKEY_get_raw_public_key(pkey, buf, &len)))
|| !TEST_mem_eq(in, inlen, buf, len))
goto done;
@@ -4033,9 +4141,10 @@ int setup_tests(void)
}
ADD_TEST(test_EVP_set_default_properties);
- ADD_ALL_TESTS(test_EVP_DigestSignInit, 9);
+ ADD_ALL_TESTS(test_EVP_DigestSignInit, 15);
ADD_TEST(test_EVP_DigestVerifyInit);
ADD_TEST(test_EVP_Digest);
+ ADD_ALL_TESTS(test_EVP_PKEY_sign, 3);
ADD_ALL_TESTS(test_EVP_Enveloped, 2);
ADD_ALL_TESTS(test_d2i_AutoPrivateKey, OSSL_NELEM(keydata));
ADD_TEST(test_privatekey_to_pkcs8);