From f5a10d5cc19215ab22be55b4a2ee1e41bd38fb14 Mon Sep 17 00:00:00 2001 From: Wangchong Zhou Date: Fri, 28 Oct 2022 11:47:50 +0800 Subject: [PATCH] Check for private key existence before calling eddsa sign functions Fixes #19524 Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/19525) --- .../implementations/signature/eddsa_sig.c | 8 ++ test/evp_extra_test.c | 76 ++++++++++++++++++- 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/providers/implementations/signature/eddsa_sig.c b/providers/implementations/signature/eddsa_sig.c index 0229dd74d66..f678e64cf8d 100644 --- a/providers/implementations/signature/eddsa_sig.c +++ b/providers/implementations/signature/eddsa_sig.c @@ -161,6 +161,10 @@ int ed25519_digest_sign(void *vpeddsactx, unsigned char *sigret, ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } + if (edkey->privkey == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); + return 0; + } #ifdef S390X_EC_ASM if (S390X_CAN_SIGN(ED25519)) { if (s390x_ed25519_digestsign(edkey, sigret, tbs, tbslen) == 0) { @@ -198,6 +202,10 @@ int ed448_digest_sign(void *vpeddsactx, unsigned char *sigret, ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; } + if (edkey->privkey == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); + return 0; + } #ifdef S390X_EC_ASM if (S390X_CAN_SIGN(ED448)) { if (s390x_ed448_digestsign(edkey, sigret, tbs, tbslen) == 0) { diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c index 3115c2d5b2a..113a7e9f8b0 100644 --- a/test/evp_extra_test.c +++ b/test/evp_extra_test.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "testutil.h" #include "internal/nelem.h" #include "internal/sizes.h" @@ -4622,11 +4623,13 @@ static int test_ecx_short_keys(int tst) EVP_PKEY *pkey; - pkey = EVP_PKEY_new_raw_private_key(ecxnids[tst], NULL, &ecxkeydata, 1); + pkey = EVP_PKEY_new_raw_private_key_ex(testctx, OBJ_nid2sn(ecxnids[tst]), + NULL, &ecxkeydata, 1); if (!TEST_ptr_null(pkey)) { EVP_PKEY_free(pkey); return 0; } + return 1; } @@ -4647,6 +4650,73 @@ const OPTIONS *test_get_options(void) return options; } +#ifndef OPENSSL_NO_EC +/* Test that trying to sign with a public key errors out gracefully */ +static int test_ecx_not_private_key(int tst) +{ + EVP_PKEY *pkey = NULL; + + const unsigned char msg[] = { 0x00, 0x01, 0x02, 0x03 }; + int testresult = 0; + EVP_MD_CTX *ctx = NULL; + unsigned char *mac = NULL; + size_t maclen = 0; + unsigned char *pubkey; + size_t pubkeylen; + + switch (keys[tst].type) { + case NID_X25519: + case NID_X448: + return TEST_skip("signing not supported for X25519/X448"); + } + + /* Check if this algorithm supports public keys */ + if (keys[tst].pub == NULL) + return TEST_skip("no public key present"); + + pubkey = (unsigned char *)keys[tst].pub; + pubkeylen = strlen(keys[tst].pub); + + pkey = EVP_PKEY_new_raw_public_key_ex(testctx, OBJ_nid2sn(keys[tst].type), + NULL, pubkey, pubkeylen); + if (!TEST_ptr(pkey)) + goto err; + + if (!TEST_ptr(ctx = EVP_MD_CTX_new())) + goto err; + + if (EVP_DigestSignInit(ctx, NULL, NULL, NULL, pkey) != 1) + goto check_err; + + if (EVP_DigestSign(ctx, NULL, &maclen, msg, sizeof(msg)) != 1) + goto check_err; + + if (!TEST_ptr(mac = OPENSSL_malloc(maclen))) + goto err; + + if (!TEST_int_eq(EVP_DigestSign(ctx, mac, &maclen, msg, sizeof(msg)), 0)) + goto err; + + check_err: + /* + * Currently only EVP_DigestSign will throw PROV_R_NOT_A_PRIVATE_KEY, + * but we relax the check to allow error also thrown by + * EVP_DigestSignInit and EVP_DigestSign. + */ + if (ERR_GET_REASON(ERR_peek_error()) == PROV_R_NOT_A_PRIVATE_KEY) { + testresult = 1; + ERR_clear_error(); + } + + err: + EVP_MD_CTX_free(ctx); + OPENSSL_free(mac); + EVP_PKEY_free(pkey); + + return testresult; +} +#endif /* OPENSSL_NO_EC */ + int setup_tests(void) { OPTION_CHOICE o; @@ -4782,6 +4852,10 @@ int setup_tests(void) ADD_ALL_TESTS(test_ecx_short_keys, OSSL_NELEM(ecxnids)); +#ifndef OPENSSL_NO_EC + ADD_ALL_TESTS(test_ecx_not_private_key, OSSL_NELEM(keys)); +#endif + return 1; } -- 2.47.3