From 24cbd83f22068353ad26954c16c9fbe8dfc13e53 Mon Sep 17 00:00:00 2001 From: xujing Date: Tue, 29 Oct 2024 14:18:24 +0800 Subject: [PATCH] Support sm2p256v1 of ECDSA and sm3 of hash --- ...t-sm2p256v1-of-ECDSA-and-sm3-of-hash.patch | 251 ++++++++++++++ ...-Add-ECDSA-support-to-digest_openssl.patch | 263 +++++++++++++++ backport-Allow-signing-with-ECDSA-keys.patch | 29 ++ ...r-use-the-low-level-API-in-openssl-3.patch | 138 ++++++++ backport-Support-ECDSA-in-key-parsing.patch | 78 +++++ backport-Support-NIST-P-521.patch | 52 +++ ...PKEY_verify-to-verify-DSA-signatures.patch | 316 ++++++++++++++++++ rpm.spec | 12 +- 8 files changed, 1138 insertions(+), 1 deletion(-) create mode 100644 Support-sm2p256v1-of-ECDSA-and-sm3-of-hash.patch create mode 100644 backport-Add-ECDSA-support-to-digest_openssl.patch create mode 100644 backport-Allow-signing-with-ECDSA-keys.patch create mode 100644 backport-No-longer-use-the-low-level-API-in-openssl-3.patch create mode 100644 backport-Support-ECDSA-in-key-parsing.patch create mode 100644 backport-Support-NIST-P-521.patch create mode 100644 backport-Use-EVP_PKEY_verify-to-verify-DSA-signatures.patch diff --git a/Support-sm2p256v1-of-ECDSA-and-sm3-of-hash.patch b/Support-sm2p256v1-of-ECDSA-and-sm3-of-hash.patch new file mode 100644 index 0000000..38f80d2 --- /dev/null +++ b/Support-sm2p256v1-of-ECDSA-and-sm3-of-hash.patch @@ -0,0 +1,251 @@ +From 32ab7eb58556d41df302af8166a77f2f2bf38754 Mon Sep 17 00:00:00 2001 +From: xujing +Date: Wed, 18 Sep 2024 15:57:34 +0800 +Subject: [PATCH] Support sm2p256v1 of ECDSA and sm3 of hash + +--- + include/rpm/rpmcrypto.h | 1 + + include/rpm/rpmpgp.h | 2 ++ + macros.in | 4 +++ + rpmio/digest_libgcrypt.c | 6 ++++ + rpmio/digest_openssl.c | 69 +++++++++++++++++++++++++++++++++++++++- + rpmio/rpmpgp_internal.c | 1 + + rpmio/rpmpgpval.h | 1 + + sign/rpmsignfiles.c | 4 +++ + 8 files changed, 87 insertions(+), 1 deletion(-) + +diff --git a/include/rpm/rpmcrypto.h b/include/rpm/rpmcrypto.h +index 69d329f..ef36e7a 100644 +--- a/include/rpm/rpmcrypto.h ++++ b/include/rpm/rpmcrypto.h +@@ -27,6 +27,7 @@ typedef enum rpmHashAlgo_e { + RPM_HASH_SHA384 = 9, /*!< SHA384 */ + RPM_HASH_SHA512 = 10, /*!< SHA512 */ + RPM_HASH_SHA224 = 11, /*!< SHA224 */ ++ RPM_HASH_SM3 = 109, /*!< SM3, the definition is the same as that of libgcrypt */ + } rpmHashAlgo; + + /** \ingroup rpmcrypto +diff --git a/include/rpm/rpmpgp.h b/include/rpm/rpmpgp.h +index a3238a6..0d46941 100644 +--- a/include/rpm/rpmpgp.h ++++ b/include/rpm/rpmpgp.h +@@ -274,6 +274,7 @@ typedef enum pgpHashAlgo_e { + PGPHASHALGO_SHA384 = 9, /*!< SHA384 */ + PGPHASHALGO_SHA512 = 10, /*!< SHA512 */ + PGPHASHALGO_SHA224 = 11, /*!< SHA224 */ ++ PGPHASHALGO_SM3 = 109, /*!< SM3, the definition is the same as that of libgcrypt */ + } pgpHashAlgo; + + /** \ingroup rpmpgp +@@ -290,6 +291,7 @@ typedef enum pgpCurveId_e { + PGPCURVE_BRAINPOOL_P512R1 = 5, /*!< brainpoolP512r1 */ + PGPCURVE_ED25519 = 6, /*!< Ed25519 */ + PGPCURVE_CURVE25519 = 7, /*!< Curve25519 */ ++ PGPCURVE_SM2P256V1 = 8, /*!< sm2p256v1 */ + } pgpCurveId; + + /** \ingroup rpmpgp +diff --git a/macros.in b/macros.in +index 11c70be..1b05672 100644 +--- a/macros.in ++++ b/macros.in +@@ -597,6 +597,10 @@ package or when debugging this package.\ + -sbo %{shescape:%{?__signature_filename}} \ + %{?__plaintext_filename:-- %{shescape:%{__plaintext_filename}}} + ++# The sm3 hash algorithm and sm2p256v1 encryption and decryption algorithm ++# in ECDSA are disabled by default. ++%_enable_sm2p256v1_sm3_algo 0 ++ + #============================================================================== + # ---- Transaction macros. + # Macro(s) used to parameterize transactions. +diff --git a/rpmio/digest_libgcrypt.c b/rpmio/digest_libgcrypt.c +index 7a75d2d..d14cc52 100644 +--- a/rpmio/digest_libgcrypt.c ++++ b/rpmio/digest_libgcrypt.c +@@ -42,6 +42,9 @@ size_t rpmDigestLength(int hashalgo) + return 28; + case RPM_HASH_SHA256: + return 32; ++ case RPM_HASH_SM3: ++ if (rpmExpandNumeric("%{?_enable_sm2p256v1_sm3_algo}")) ++ return 32; + case RPM_HASH_SHA384: + return 48; + case RPM_HASH_SHA512: +@@ -66,6 +69,9 @@ static int hashalgo2gcryalgo(int hashalgo) + return GCRY_MD_SHA384; + case RPM_HASH_SHA512: + return GCRY_MD_SHA512; ++ case RPM_HASH_SM3: ++ if (rpmExpandNumeric("%{?_enable_sm2p256v1_sm3_algo}")) ++ return GCRY_MD_SM3; + default: + return 0; + } +diff --git a/rpmio/digest_openssl.c b/rpmio/digest_openssl.c +index eb9fbaa..92b8113 100644 +--- a/rpmio/digest_openssl.c ++++ b/rpmio/digest_openssl.c +@@ -9,6 +9,7 @@ + #include + + #include ++#include + #include "rpmio/rpmpgp_internal.h" + + +@@ -188,6 +189,10 @@ static const EVP_MD *getEVPMD(int hashalgo) + case RPM_HASH_SHA224: + return EVP_sha224(); + ++ case RPM_HASH_SM3: ++ if (rpmExpandNumeric("%{?_enable_sm2p256v1_sm3_algo}")) ++ return EVP_sm3(); ++ + default: + return EVP_md_null(); + } +@@ -837,6 +842,14 @@ static int constructECDSASigningKey(struct pgpDigKeyECDSA_s *key, int curve) + OSSL_PARAM_END + }; + key->evp_pkey = construct_pkey_from_param(EVP_PKEY_EC, params); ++ } else if (curve == PGPCURVE_SM2P256V1 && ++ rpmExpandNumeric("%{?_enable_sm2p256v1_sm3_algo}")) { ++ OSSL_PARAM params[] = { ++ OSSL_PARAM_utf8_string("group", "SM2", 3), ++ OSSL_PARAM_octet_string("pub", key->q, key->qlen), ++ OSSL_PARAM_END ++ }; ++ key->evp_pkey = construct_pkey_from_param(EVP_PKEY_SM2, params); + } + return key->evp_pkey ? 1 : 0; + #else +@@ -950,6 +963,46 @@ static void pgpFreeSigECDSA(pgpDigAlg pgpsig) + free(pgpsig->data); + } + ++/* Source of zin information refer to https://datatracker.ietf.org/doc/html/draft-shen-sm2-ecdsa-02.html#appendix-D */ ++const unsigned char zin_default[] = { ++ 0x00, 0x80, /* id length */ ++ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, ++ 0x35, 0x36, 0x37, 0x38, /* default id: 1234567812345678 */ ++ 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, ++ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, /* sm2 a */ ++ 0x28, 0xe9, 0xfa, 0x9e, 0x9d, 0x9f, 0x5e, 0x34, 0x4d, 0x5a, 0x9e, 0x4b, ++ 0xcf, 0x65, 0x09, 0xa7, 0xf3, 0x97, 0x89, 0xf5, 0x15, 0xab, 0x8f, 0x92, ++ 0xdd, 0xbc, 0xbd, 0x41, 0x4d, 0x94, 0x0e, 0x93, /* sm2 b */ ++ 0x32, 0xc4, 0xae, 0x2c, 0x1f, 0x19, 0x81, 0x19, 0x5f, 0x99, 0x04, 0x46, ++ 0x6a, 0x39, 0xc9, 0x94, 0x8f, 0xe3, 0x0b, 0xbf, 0xf2, 0x66, 0x0b, 0xe1, ++ 0x71, 0x5a, 0x45, 0x89, 0x33, 0x4c, 0x74, 0xc7, /* sm2 x */ ++ 0xbc, 0x37, 0x36, 0xa2, 0xf4, 0xf6, 0x77, 0x9c, 0x59, 0xbd, 0xce, 0xe3, ++ 0x6b, 0x69, 0x21, 0x53, 0xd0, 0xa9, 0x87, 0x7c, 0xc6, 0x2a, 0x47, 0x40, ++ 0x02, 0xdf, 0x32, 0xe5, 0x21, 0x39, 0xf0, 0xa0 /* sm2 y */ ++}; ++ ++static int calculate_sm2_hash(struct pgpDigKeyECDSA_s *key, uint8_t *msg, size_t msglen, uint8_t *hash) ++{ ++ unsigned char z[32]; ++ ++ EVP_MD_CTX *ctx = EVP_MD_CTX_new(); ++ ++ EVP_DigestInit(ctx, EVP_sm3()); ++ EVP_DigestUpdate(ctx, zin_default, sizeof(zin_default)); ++ EVP_DigestUpdate(ctx, key->q + 1, key->qlen - 1); ++ EVP_DigestFinal_ex(ctx, z, NULL); ++ ++ EVP_DigestInit(ctx, EVP_sm3()); ++ EVP_DigestUpdate(ctx, z, sizeof(z)); ++ EVP_DigestUpdate(ctx, msg, msglen); ++ EVP_DigestFinal_ex(ctx, hash, NULL); ++ ++ EVP_MD_CTX_free(ctx); ++ ++ return 0; ++} ++ + static int pgpVerifySigECDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, + uint8_t *hash, size_t hashlen, int hash_algo) + { +@@ -959,6 +1012,8 @@ static int pgpVerifySigECDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, + unsigned char *xsig = NULL; /* signature encoded for X509 */ + size_t xsig_len = 0; + EVP_PKEY_CTX *pkey_ctx = NULL; ++ uint8_t *hash_to_use = hash; ++ uint8_t sm2_hash[32] = { 0 }; + + if (!constructECDSASigningKey(key, pgpkey->curve)) + goto done; +@@ -974,7 +1029,16 @@ static int pgpVerifySigECDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, + if (EVP_PKEY_verify_init(pkey_ctx) != 1) + goto done; + +- if (EVP_PKEY_verify(pkey_ctx, xsig, xsig_len, hash, hashlen) == 1) ++ if (pgpkey->curve == PGPCURVE_SM2P256V1) { ++ if (rpmExpandNumeric("%{?_enable_sm2p256v1_sm3_algo}")) { ++ calculate_sm2_hash(key, hash, hashlen, sm2_hash); ++ hash_to_use = sm2_hash; ++ } else { ++ goto done; ++ } ++ } ++ ++ if (EVP_PKEY_verify(pkey_ctx, xsig, xsig_len, hash_to_use, hashlen) == 1) + { + /* Success */ + rc = 0; +@@ -1109,6 +1173,9 @@ static int pgpSupportedCurve(int algo, int curve) + return 1; + if (algo == PGPPUBKEYALGO_ECDSA && curve == PGPCURVE_NIST_P_521) + return 1; ++ if (algo == PGPPUBKEYALGO_ECDSA && curve == PGPCURVE_SM2P256V1 && ++ rpmExpandNumeric("%{?_enable_sm2p256v1_sm3_algo}")) ++ return 1; + return 0; + } + +diff --git a/rpmio/rpmpgp_internal.c b/rpmio/rpmpgp_internal.c +index 8b845b7..0960057 100644 +--- a/rpmio/rpmpgp_internal.c ++++ b/rpmio/rpmpgp_internal.c +@@ -537,6 +537,7 @@ static uint8_t curve_oids[] = { + PGPCURVE_BRAINPOOL_P512R1, 0x09, 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0d, + PGPCURVE_ED25519, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01, + PGPCURVE_CURVE25519, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01, ++ PGPCURVE_SM2P256V1, 0x08, 0x2a, 0x81, 0x1c, 0xcf, 0x55, 0x1, 0x82, 0x2d, + 0, + }; + +diff --git a/rpmio/rpmpgpval.h b/rpmio/rpmpgpval.h +index ad8ed08..b8b7cb4 100644 +--- a/rpmio/rpmpgpval.h ++++ b/rpmio/rpmpgpval.h +@@ -77,6 +77,7 @@ static struct pgpValTbl_s const pgpHashTbl[] = { + { PGPHASHALGO_SHA384, "SHA384" }, + { PGPHASHALGO_SHA512, "SHA512" }, + { PGPHASHALGO_SHA224, "SHA224" }, ++ { PGPHASHALGO_SM3, "SM3" }, + { -1, "Unknown hash algorithm" }, + }; + +diff --git a/sign/rpmsignfiles.c b/sign/rpmsignfiles.c +index 80ef233..fa20bf6 100644 +--- a/sign/rpmsignfiles.c ++++ b/sign/rpmsignfiles.c +@@ -19,6 +19,10 @@ + + #define MAX_SIGNATURE_LENGTH 1024 + ++/* ++ * Currently, we do not support the sm3 hash algorithm to sign files. ++ * Therefore, we do not add sm3. ++ */ + static const char *hash_algo_name[] = { + [RPM_HASH_MD5] = "md5", + [RPM_HASH_SHA1] = "sha1", +-- +2.33.0 + diff --git a/backport-Add-ECDSA-support-to-digest_openssl.patch b/backport-Add-ECDSA-support-to-digest_openssl.patch new file mode 100644 index 0000000..e817c68 --- /dev/null +++ b/backport-Add-ECDSA-support-to-digest_openssl.patch @@ -0,0 +1,263 @@ +From d2d35d1acb89d4113647a9aad2d049808112b935 Mon Sep 17 00:00:00 2001 +From: Michael Schroeder +Date: Wed, 17 Apr 2024 14:07:53 +0200 +Subject: [PATCH] Add ECDSA support to digest_openssl + +Conflict:modify digest_openssl.c in rpmio; adapt context +Reference:https://github.com/rpm-software-management/rpmpgp_legacy/commit/783a5ea3851b8509eb11a4998d6e4ea41cc7ba38 +--- + rpmio/digest_openssl.c | 208 ++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 207 insertions(+), 1 deletion(-) + +diff --git a/rpmio/digest_openssl.c b/rpmio/digest_openssl.c +index 4d930c9..c8eb15f 100644 +--- a/rpmio/digest_openssl.c ++++ b/rpmio/digest_openssl.c +@@ -6,6 +6,7 @@ + #endif + #include + #include ++#include + + #include + #include "rpmio/rpmpgp_internal.h" +@@ -801,6 +802,181 @@ done: + return rc; + } + ++/****************************** ECDSA ***************************************/ ++ ++struct pgpDigKeyECDSA_s { ++ EVP_PKEY *evp_pkey; /* Fully constructed key */ ++ unsigned char *q; /* compressed point */ ++ int qlen; ++}; ++ ++static int constructECDSASigningKey(struct pgpDigKeyECDSA_s *key, int curve) ++{ ++ if (key->evp_pkey) ++ return 1; /* We've already constructed it, so just reuse it */ ++ ++#if OPENSSL_VERSION_MAJOR >= 3 ++ if (curve == PGPCURVE_NIST_P_256) { ++ OSSL_PARAM params[] = { ++ OSSL_PARAM_utf8_string("group", "P-256", 5), ++ OSSL_PARAM_octet_string("pub", key->q, key->qlen), ++ OSSL_PARAM_END ++ }; ++ key->evp_pkey = construct_pkey_from_param(EVP_PKEY_EC, params); ++ } else if (curve == PGPCURVE_NIST_P_384) { ++ OSSL_PARAM params[] = { ++ OSSL_PARAM_utf8_string("group", "P-384", 5), ++ OSSL_PARAM_octet_string("pub", key->q, key->qlen), ++ OSSL_PARAM_END ++ }; ++ key->evp_pkey = construct_pkey_from_param(EVP_PKEY_EC, params); ++ } ++ return key->evp_pkey ? 1 : 0; ++#else ++ /* Create the EC key */ ++ EC_KEY *ec = NULL; ++ if (curve == PGPCURVE_NIST_P_256) ++ ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); ++ else if (curve == PGPCURVE_NIST_P_384) ++ ec = EC_KEY_new_by_curve_name(NID_secp384r1); ++ if (!ec) ++ return 0; ++ ++ if (!EC_KEY_oct2key(ec, key->q, key->qlen, NULL)) ++ goto exit; ++ ++ /* Create an EVP_PKEY container to abstract the key-type. */ ++ if (!(key->evp_pkey = EVP_PKEY_new())) ++ goto exit; ++ ++ /* Assign the EC key to the EVP_PKEY structure. ++ This will take over memory management of the RSA key */ ++ if (!EVP_PKEY_assign_EC_KEY(key->evp_pkey, ec)) { ++ EVP_PKEY_free(key->evp_pkey); ++ key->evp_pkey = NULL; ++ goto exit; ++ } ++ return 1; ++ ++exit: ++ EC_KEY_free(ec); ++ return 0; ++#endif ++} ++ ++static int pgpSetKeyMpiECDSA(pgpDigAlg pgpkey, int num, const uint8_t *p) ++{ ++ size_t mlen = pgpMpiLen(p) - 2; ++ struct pgpDigKeyECDSA_s *key = pgpkey->data; ++ int rc = 1; ++ ++ if (!key) ++ key = pgpkey->data = xcalloc(1, sizeof(*key)); ++ if (num == 0 && !key->q && mlen > 1 && p[2] == 0x04) { ++ key->qlen = mlen; ++ key->q = xmalloc(key->qlen); ++ memcpy(key->q, p + 2, key->qlen), ++ rc = 0; ++ } ++ return rc; ++} ++ ++static void pgpFreeKeyECDSA(pgpDigAlg pgpkey) ++{ ++ struct pgpDigKeyECDSA_s *key = pgpkey->data; ++ if (key) { ++ if (key->q) ++ free(key->q); ++ if (key->evp_pkey) ++ EVP_PKEY_free(key->evp_pkey); ++ free(key); ++ } ++} ++ ++struct pgpDigSigECDSA_s { ++ unsigned char *r; ++ int rlen; ++ unsigned char *s; ++ int slen; ++}; ++ ++static int pgpSetSigMpiECDSA(pgpDigAlg pgpsig, int num, const uint8_t *p) ++{ ++ int mlen = pgpMpiLen(p) - 2; ++ int rc = 1; ++ ++ struct pgpDigSigECDSA_s *sig = pgpsig->data; ++ if (!sig) { ++ sig = xcalloc(1, sizeof(*sig)); ++ pgpsig->data = sig; ++ } ++ ++ switch (num) { ++ case 0: ++ if (sig->r) ++ return 1; /* This should only ever happen once per signature */ ++ sig->rlen = mlen; ++ sig->r = memcpy(xmalloc(mlen), p + 2, mlen); ++ rc = 0; ++ break; ++ case 1: ++ if (sig->s) ++ return 1; /* This should only ever happen once per signature */ ++ sig->slen = mlen; ++ sig->s = memcpy(xmalloc(mlen), p + 2, mlen); ++ rc = 0; ++ break; ++ } ++ ++ return rc; ++} ++ ++static void pgpFreeSigECDSA(pgpDigAlg pgpsig) ++{ ++ struct pgpDigSigECDSA_s *sig = pgpsig->data; ++ if (sig) { ++ free(sig->r); ++ free(sig->s); ++ } ++ free(pgpsig->data); ++} ++ ++static int pgpVerifySigECDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, ++ uint8_t *hash, size_t hashlen, int hash_algo) ++{ ++ int rc = 1; /* assume failure */ ++ struct pgpDigSigECDSA_s *sig = pgpsig->data; ++ struct pgpDigKeyECDSA_s *key = pgpkey->data; ++ unsigned char *xsig = NULL; /* signature encoded for X509 */ ++ size_t xsig_len = 0; ++ EVP_PKEY_CTX *pkey_ctx = NULL; ++ ++ if (!constructECDSASigningKey(key, pgpkey->curve)) ++ goto done; ++ ++ xsig = constructDSASignature(sig->r, sig->rlen, sig->s, sig->slen, &xsig_len); ++ if (!xsig) ++ goto done; ++ ++ pkey_ctx = EVP_PKEY_CTX_new(key->evp_pkey, NULL); ++ if (!pkey_ctx) ++ goto done; ++ ++ if (EVP_PKEY_verify_init(pkey_ctx) != 1) ++ goto done; ++ ++ if (EVP_PKEY_verify(pkey_ctx, xsig, xsig_len, hash, hashlen) == 1) ++ { ++ /* Success */ ++ rc = 0; ++ } ++ ++done: ++ if (pkey_ctx) ++ EVP_PKEY_CTX_free(pkey_ctx); ++ free(xsig); ++ return rc; ++} + + /****************************** EDDSA ***************************************/ + +@@ -912,6 +1088,19 @@ static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig, + return 1; + } + ++static int pgpSupportedCurve(int algo, int curve) ++{ ++#ifdef EVP_PKEY_ED25519 ++ if (algo == PGPPUBKEYALGO_EDDSA && curve == PGPCURVE_ED25519) ++ return 1; ++#endif ++ if (algo == PGPPUBKEYALGO_ECDSA && curve == PGPCURVE_NIST_P_256) ++ return 1; ++ if (algo == PGPPUBKEYALGO_ECDSA && curve == PGPCURVE_NIST_P_384) ++ return 1; ++ return 0; ++} ++ + /****************************** PGP **************************************/ + pgpDigAlg pgpPubkeyNew(int algo, int curve) + { +@@ -928,9 +1117,20 @@ pgpDigAlg pgpPubkeyNew(int algo, int curve) + ka->free = pgpFreeKeyDSA; + ka->mpis = 4; + break; ++ case PGPPUBKEYALGO_ECDSA: ++ if (!pgpSupportedCurve(algo, curve)) { ++ ka->setmpi = pgpSetMpiNULL; ++ ka->mpis = -1; ++ break; ++ } ++ ka->setmpi = pgpSetKeyMpiECDSA; ++ ka->free = pgpFreeKeyECDSA; ++ ka->mpis = 1; ++ ka->curve = curve; ++ break; + #ifdef EVP_PKEY_ED25519 + case PGPPUBKEYALGO_EDDSA: +- if (curve != PGPCURVE_ED25519) { ++ if (!pgpSupportedCurve(algo, curve)) { + ka->setmpi = pgpSetMpiNULL; /* unsupported curve */ + ka->mpis = -1; + break; +@@ -969,6 +1169,12 @@ pgpDigAlg pgpSignatureNew(int algo) + sa->verify = pgpVerifySigDSA; + sa->mpis = 2; + break; ++ case PGPPUBKEYALGO_ECDSA: ++ sa->setmpi = pgpSetSigMpiECDSA; ++ sa->free = pgpFreeSigECDSA; ++ sa->verify = pgpVerifySigECDSA; ++ sa->mpis = 2; ++ break; + #ifdef EVP_PKEY_ED25519 + case PGPPUBKEYALGO_EDDSA: + sa->setmpi = pgpSetSigMpiEDDSA; +-- +2.23.0 + diff --git a/backport-Allow-signing-with-ECDSA-keys.patch b/backport-Allow-signing-with-ECDSA-keys.patch new file mode 100644 index 0000000..de4a8ce --- /dev/null +++ b/backport-Allow-signing-with-ECDSA-keys.patch @@ -0,0 +1,29 @@ +From ef0afa856a609bea765dbccaebb75ceeddd202f3 Mon Sep 17 00:00:00 2001 +From: Michael Schroeder +Date: Fri, 12 Apr 2024 14:40:29 +0200 +Subject: [PATCH] Allow signing with ECDSA keys + +Conflict:NA +Reference:https://github.com/rpm-software-management/rpm/commit/ef0afa856a609bea765dbccaebb75ceeddd202f3 + +Key import and verification already works, it's just that rpm +does not know where to put the signature. +--- + sign/rpmgensig.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c +index d7d08a2a3..4d2bbc31f 100644 +--- a/sign/rpmgensig.c ++++ b/sign/rpmgensig.c +@@ -158,6 +158,7 @@ static rpmtd makeSigTag(Header sigh, int ishdr, uint8_t *pkt, size_t pktlen) + pubkey_algo = pgpDigParamsAlgo(sigp, PGPVAL_PUBKEYALGO); + switch (pubkey_algo) { + case PGPPUBKEYALGO_DSA: ++ case PGPPUBKEYALGO_ECDSA: + case PGPPUBKEYALGO_EDDSA: + sigtag = ishdr ? RPMSIGTAG_DSA : RPMSIGTAG_GPG; + break; +-- +2.23.0 + diff --git a/backport-No-longer-use-the-low-level-API-in-openssl-3.patch b/backport-No-longer-use-the-low-level-API-in-openssl-3.patch new file mode 100644 index 0000000..3df0d51 --- /dev/null +++ b/backport-No-longer-use-the-low-level-API-in-openssl-3.patch @@ -0,0 +1,138 @@ +From 408f2053da61fa80c5a306b8f87cdd70a7c57a62 Mon Sep 17 00:00:00 2001 +From: Michael Schroeder +Date: Wed, 17 Apr 2024 13:05:28 +0200 +Subject: [PATCH] No longer use the low level API in openssl-3 + +Conflict:modify digest_openssl.c in rpmio; adapt context +Reference:https://github.com/rpm-software-management/rpmpgp_legacy/commit/de96811994b28d8fb43dfb101a9cbca263eb1ce5 + +Instead, construct the key with EVP_PKEY_fromdata() +--- + rpmio/digest_openssl.c | 73 +++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 72 insertions(+), 1 deletion(-) + +diff --git a/rpmio/digest_openssl.c b/rpmio/digest_openssl.c +index 41d77d0..4d930c9 100644 +--- a/rpmio/digest_openssl.c ++++ b/rpmio/digest_openssl.c +@@ -1,10 +1,13 @@ + #include "system.h" + + #include ++#if OPENSSL_VERSION_MAJOR >= 3 ++# include ++#endif + #include + #include +-#include + ++#include + #include "rpmio/rpmpgp_internal.h" + + +@@ -283,6 +286,46 @@ done: + } + + ++/*********************** pkey construction *******************************/ ++ ++#if OPENSSL_VERSION_MAJOR >= 3 ++ ++static EVP_PKEY * ++construct_pkey_from_param(int id, OSSL_PARAM *params) ++{ ++ EVP_PKEY *pkey = NULL; ++ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(id, NULL); ++ if (!ctx || EVP_PKEY_fromdata_init(ctx) <= 0 || EVP_PKEY_fromdata(ctx, &pkey, EVP_PKEY_PUBLIC_KEY, params) <= 0) ++ pkey = NULL; ++ if (ctx) ++ EVP_PKEY_CTX_free(ctx); ++ return pkey; ++} ++ ++static OSSL_PARAM ++create_bn_param(char *key, BIGNUM *bn) ++{ ++ int sz = bn ? BN_num_bytes(bn) : -1; ++ if (sz < 0 || BN_is_negative(bn)) { ++ OSSL_PARAM param = OSSL_PARAM_END; ++ return param; ++ } ++ if (sz == 0) ++ sz = 1; ++ unsigned char *buf = xmalloc(sz); ++ BN_bn2nativepad(bn, buf, sz); ++ OSSL_PARAM param = OSSL_PARAM_BN(key, buf, sz); ++ return param; ++} ++ ++static void ++free_bn_param(OSSL_PARAM *param) ++{ ++ free(param->data); ++} ++ ++#endif ++ + /****************************** RSA **************************************/ + + /* Key */ +@@ -300,6 +343,17 @@ static int constructRSASigningKey(struct pgpDigKeyRSA_s *key) + if (key->evp_pkey) + return 1; /* We've already constructed it, so just reuse it */ + ++#if OPENSSL_VERSION_MAJOR >= 3 ++ OSSL_PARAM params[] = { ++ create_bn_param("n", key->n), ++ create_bn_param("e", key->e), ++ OSSL_PARAM_END ++ }; ++ key->evp_pkey = construct_pkey_from_param(EVP_PKEY_RSA, params); ++ free_bn_param(params + 0); ++ free_bn_param(params + 1); ++ return key->evp_pkey ? 1 : 0; ++#else + /* Create the RSA key */ + RSA *rsa = RSA_new(); + if (!rsa) return 0; +@@ -324,6 +378,7 @@ static int constructRSASigningKey(struct pgpDigKeyRSA_s *key) + exit: + RSA_free(rsa); + return 0; ++#endif + } + + static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p) +@@ -506,6 +561,21 @@ static int constructDSASigningKey(struct pgpDigKeyDSA_s *key) + if (key->evp_pkey) + return 1; /* We've already constructed it, so just reuse it */ + ++#if OPENSSL_VERSION_MAJOR >= 3 ++ OSSL_PARAM params[] = { ++ create_bn_param("p", key->p), ++ create_bn_param("q", key->q), ++ create_bn_param("g", key->g), ++ create_bn_param("pub", key->y), ++ OSSL_PARAM_END ++ }; ++ key->evp_pkey = construct_pkey_from_param(EVP_PKEY_DSA, params); ++ free_bn_param(params + 0); ++ free_bn_param(params + 1); ++ free_bn_param(params + 2); ++ free_bn_param(params + 3); ++ return key->evp_pkey ? 1 : 0; ++#else + /* Create the DSA key */ + DSA *dsa = DSA_new(); + if (!dsa) return 0; +@@ -533,6 +603,7 @@ static int constructDSASigningKey(struct pgpDigKeyDSA_s *key) + exit: + DSA_free(dsa); + return 0; ++#endif + } + + +-- +2.23.0 + diff --git a/backport-Support-ECDSA-in-key-parsing.patch b/backport-Support-ECDSA-in-key-parsing.patch new file mode 100644 index 0000000..53be273 --- /dev/null +++ b/backport-Support-ECDSA-in-key-parsing.patch @@ -0,0 +1,78 @@ +From 8bc74f9ec48386beadf396ba5830aacf6672df4c Mon Sep 17 00:00:00 2001 +From: Michael Schroeder +Date: Thu, 11 Apr 2024 14:13:22 +0200 +Subject: [PATCH] Support ECDSA in key parsing + +Conflict:modify rpmpgp_internal.c in rpmio; adapt context because 296f2256b90 +and b5b9600834 is not mearged +Reference:https://github.com/rpm-software-management/rpmpgp_legacy/commit/ca6c204cfa95f016ba03a73d5e6e4451cf8d4d6d +--- + rpmio/rpmpgp_internal.c | 17 +++++++---------- + 1 file changed, 7 insertions(+), 10 deletions(-) + +diff --git a/rpmio/rpmpgp_internal.c b/rpmio/rpmpgp_internal.c +index 0fcd220..610a9b2 100644 +--- a/rpmio/rpmpgp_internal.c ++++ b/rpmio/rpmpgp_internal.c +@@ -576,11 +576,6 @@ static int pgpCurveByOid(const uint8_t *p, int l) + return 0; + } + +-static int isKey(pgpDigParams keyp) +-{ +- return keyp->tag == PGPTAG_PUBLIC_KEY || keyp->tag == PGPTAG_PUBLIC_SUBKEY; +-} +- + static int pgpPrtPubkeyParams(uint8_t pubkey_algo, + const uint8_t *p, const uint8_t *h, size_t hlen, + pgpDigParams keyp) +@@ -588,12 +583,12 @@ static int pgpPrtPubkeyParams(uint8_t pubkey_algo, + int rc = 1; /* assume failure */ + const uint8_t *pend = h + hlen; + int curve = 0; +- if (!isKey(keyp)) ++ if (keyp->tag != PGPTAG_PUBLIC_KEY && keyp->tag != PGPTAG_PUBLIC_SUBKEY) + return rc; + /* We can't handle more than one key at a time */ + if (keyp->alg) + return rc; +- if (pubkey_algo == PGPPUBKEYALGO_EDDSA) { ++ if (pubkey_algo == PGPPUBKEYALGO_EDDSA || pubkey_algo == PGPPUBKEYALGO_ECDSA) { + int len = (hlen > 1) ? p[0] : 0; + if (len == 0 || len == 0xff || len >= hlen) + return rc; +@@ -686,8 +681,9 @@ static int getPubkeyFingerprint(const uint8_t *h, size_t hlen, + return rc; + se = (uint8_t *)(v + 1); + switch (v->pubkey_algo) { ++ case PGPPUBKEYALGO_ECDSA: + case PGPPUBKEYALGO_EDDSA: +- /* EdDSA has a curve id before the MPIs */ ++ /* ECC has a curve id before the MPIs */ + if (se[0] == 0x00 || se[0] == 0xff || pend - se < 1 + se[0]) + return rc; + se += 1 + se[0]; +@@ -1206,8 +1202,11 @@ rpmRC pgpVerifySignature(pgpDigParams key, pgpDigParams sig, DIGEST_CTX hashctx) + if (sig == NULL || ctx == NULL) + goto exit; + ++ /* make sure the dig param types are correct */ + if (sig->tag != PGPTAG_SIGNATURE) + goto exit; ++ if (key && key->tag != PGPTAG_PUBLIC_KEY && key->tag != PGPTAG_PUBLIC_SUBKEY) ++ goto exit; + + if (sig->hash != NULL) + rpmDigestUpdate(ctx, sig->hash, sig->hashlen); +@@ -1235,8 +1234,6 @@ rpmRC pgpVerifySignature(pgpDigParams key, pgpDigParams sig, DIGEST_CTX hashctx) + * done all we can, return NOKEY to indicate "looks okay but dunno." + */ + if (key && key->alg) { +- if (!isKey(key)) +- goto exit; + pgpDigAlg sa = sig->alg; + pgpDigAlg ka = key->alg; + if (sa && sa->verify && sig->pubkey_algo == key->pubkey_algo) { +-- +2.23.0 + diff --git a/backport-Support-NIST-P-521.patch b/backport-Support-NIST-P-521.patch new file mode 100644 index 0000000..2c8da92 --- /dev/null +++ b/backport-Support-NIST-P-521.patch @@ -0,0 +1,52 @@ +From 6344fec232cdd0e9d821a0b17e480494f4dcfd4b Mon Sep 17 00:00:00 2001 +From: Michael Schroeder +Date: Mon, 22 Apr 2024 12:54:32 +0200 +Subject: [PATCH] Support NIST P-521 + +Conflict:don't modify digest_libgcrypt.c;modify digest_openssl.c in rpmio; +Reference:https://github.com/rpm-software-management/rpmpgp_legacy/commit/6344fec232cdd0e9d821a0b17e480494f4dcfd4b + +Because the standard says we SHOULD. +--- + rpmio/digest_openssl.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/rpmio/digest_openssl.c b/rpmio/digest_openssl.c +index 662b469..42eec66 100644 +--- a/rpmio/digest_openssl.c ++++ b/rpmio/digest_openssl.c +@@ -556,6 +556,13 @@ static int constructECDSASigningKey(struct pgpDigKeyECDSA_s *key, int curve) + OSSL_PARAM_END + }; + key->evp_pkey = construct_pkey_from_param(EVP_PKEY_EC, params); ++ } else if (curve == PGPCURVE_NIST_P_521) { ++ OSSL_PARAM params[] = { ++ OSSL_PARAM_utf8_string("group", "P-521", 5), ++ OSSL_PARAM_octet_string("pub", key->q, key->qlen), ++ OSSL_PARAM_END ++ }; ++ key->evp_pkey = construct_pkey_from_param(EVP_PKEY_EC, params); + } + return key->evp_pkey ? 1 : 0; + #else +@@ -565,6 +572,8 @@ static int constructECDSASigningKey(struct pgpDigKeyECDSA_s *key, int curve) + ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + else if (curve == PGPCURVE_NIST_P_384) + ec = EC_KEY_new_by_curve_name(NID_secp384r1); ++ else if (curve == PGPCURVE_NIST_P_521) ++ ec = EC_KEY_new_by_curve_name(NID_secp521r1); + if (!ec) + return 0; + +@@ -817,6 +826,8 @@ static int pgpSupportedCurve(int algo, int curve) + return 1; + if (algo == PGPPUBKEYALGO_ECDSA && curve == PGPCURVE_NIST_P_384) + return 1; ++ if (algo == PGPPUBKEYALGO_ECDSA && curve == PGPCURVE_NIST_P_521) ++ return 1; + return 0; + } + +-- +2.23.0 + diff --git a/backport-Use-EVP_PKEY_verify-to-verify-DSA-signatures.patch b/backport-Use-EVP_PKEY_verify-to-verify-DSA-signatures.patch new file mode 100644 index 0000000..dee1d97 --- /dev/null +++ b/backport-Use-EVP_PKEY_verify-to-verify-DSA-signatures.patch @@ -0,0 +1,316 @@ +From 8bf5c6b094e4f703d9fa1422a463654b512b25ae Mon Sep 17 00:00:00 2001 +From: Michael Schroeder +Date: Wed, 17 Apr 2024 11:05:17 +0200 +Subject: [PATCH] Use EVP_PKEY_verify to verify DSA signatures + +Conflict:modify digest_openssl.c in rpmio +Reference:https://github.com/rpm-software-management/rpmpgp_legacy/commit/8bf5c6b094e4f703d9fa1422a463654b512b25ae + +The low level API will be deprecated in openssl-3 +--- + rpmio/digest_openssl.c | 179 +++++++++++++++++++++++------------------------ + 1 file changed, 86 insertions(+), 93 deletions(-) + +diff --git a/rpmio/digest_openssl.c b/rpmio/digest_openssl.c +index 8dd7abe..2a39115 100644 +--- a/rpmio/digest_openssl.c ++++ b/rpmio/digest_openssl.c +@@ -43,17 +43,12 @@ struct pgpDigKeyRSA_s { + BIGNUM *n; /* Common Modulus */ + BIGNUM *e; /* Public Exponent */ + EVP_PKEY *evp_pkey; /* Fully constructed key */ +- unsigned char immutable; /* if set, this key cannot be mutated */ + }; + + static int constructRSASigningKey(struct pgpDigKeyRSA_s *key) + { +- if (key->evp_pkey) { +- /* We've already constructed it, so just reuse it */ +- return 1; +- } else if (key->immutable) +- return 0; +- key->immutable = 1; ++ if (key->evp_pkey) ++ return 1; /* We've already constructed it, so just reuse it */ + + /* Create the RSA key */ + RSA *rsa = RSA_new(); +@@ -88,7 +83,7 @@ static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p) + + if (!key) + key = pgpkey->data = xcalloc(1, sizeof(*key)); +- else if (key->immutable) ++ else if (key->evp_pkey) + return 1; + + switch (num) { +@@ -238,7 +233,8 @@ static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, + } + + done: +- EVP_PKEY_CTX_free(pkey_ctx); ++ if (pkey_ctx) ++ EVP_PKEY_CTX_free(pkey_ctx); + free(padded_sig); + return rc; + } +@@ -252,40 +248,41 @@ struct pgpDigKeyDSA_s { + BIGNUM *g; /* Base */ + BIGNUM *y; /* Public Key */ + +- DSA *dsa_key; /* Fully constructed key */ ++ EVP_PKEY *evp_pkey; /* Fully constructed key */ + }; + + static int constructDSASigningKey(struct pgpDigKeyDSA_s *key) + { +- int rc; +- +- if (key->dsa_key) { +- /* We've already constructed it, so just reuse it */ +- return 1; +- } ++ if (key->evp_pkey) ++ return 1; /* We've already constructed it, so just reuse it */ + + /* Create the DSA key */ + DSA *dsa = DSA_new(); + if (!dsa) return 0; + + if (!DSA_set0_pqg(dsa, key->p, key->q, key->g)) { +- rc = 0; +- goto done; ++ goto exit; + } +- + if (!DSA_set0_key(dsa, key->y, NULL)) { +- rc = 0; +- goto done; ++ goto exit; + } + +- key->dsa_key = dsa; ++ /* Create an EVP_PKEY container to abstract the key-type. */ ++ if (!(key->evp_pkey = EVP_PKEY_new())) ++ goto exit; + +- rc = 1; +-done: +- if (rc == 0) { +- DSA_free(dsa); ++ /* Assign the DSA key to the EVP_PKEY structure. ++ This will take over memory management of the RSA key */ ++ if (!EVP_PKEY_assign_DSA(key->evp_pkey, dsa)) { ++ EVP_PKEY_free(key->evp_pkey); ++ key->evp_pkey = NULL; ++ goto exit; + } +- return rc; ++ return 1; ++ ++exit: ++ DSA_free(dsa); ++ return 0; + } + + +@@ -349,10 +346,10 @@ static void pgpFreeKeyDSA(pgpDigAlg pgpkey) + { + struct pgpDigKeyDSA_s *key = pgpkey->data; + if (key) { +- if (key->dsa_key) { +- DSA_free(key->dsa_key); ++ if (key->evp_pkey) { ++ EVP_PKEY_free(key->evp_pkey); + } else { +- /* If sig->dsa_key was constructed, ++ /* If key->evp_pkey was constructed, + * the memory management of these BNs + * are freed with it. */ + BN_clear_free(key->p); +@@ -367,82 +364,72 @@ static void pgpFreeKeyDSA(pgpDigAlg pgpkey) + /* Signature */ + + struct pgpDigSigDSA_s { +- BIGNUM *r; +- BIGNUM *s; +- +- DSA_SIG *dsa_sig; ++ unsigned char *r; ++ int rlen; ++ unsigned char *s; ++ int slen; + }; + +-static int constructDSASignature(struct pgpDigSigDSA_s *sig) ++static void add_asn1_tag(unsigned char *p, int tag, int len) + { +- int rc; +- +- if (sig->dsa_sig) { +- /* We've already constructed it, so just reuse it */ +- return 1; +- } +- +- /* Create the DSA signature */ +- DSA_SIG *dsa_sig = DSA_SIG_new(); +- if (!dsa_sig) return 0; +- +- if (!DSA_SIG_set0(dsa_sig, sig->r, sig->s)) { +- rc = 0; +- goto done; ++ *p++ = tag; ++ if (len >= 256) { ++ *p++ = 130; ++ *p++ = len >> 8; ++ } else if (len > 128) { ++ *p++ = 129; + } ++ *p++ = len; ++} + +- sig->dsa_sig = dsa_sig; +- +- rc = 1; +-done: +- if (rc == 0) { +- DSA_SIG_free(sig->dsa_sig); +- } +- return rc; ++static unsigned char *constructDSASignature(unsigned char *r, int rlen, unsigned char *s, int slen, size_t *siglenp) ++{ ++ int len1 = rlen + (!rlen || (*r & 0x80) != 0 ? 1 : 0), hlen1 = len1 < 128 ? 2 : len1 < 256 ? 3 : 4; ++ int len2 = slen + (!slen || (*s & 0x80) != 0 ? 1 : 0), hlen2 = len2 < 128 ? 2 : len2 < 256 ? 3 : 4; ++ int len3 = hlen1 + len1 + hlen2 + len2, hlen3 = len3 < 128 ? 2 : len3 < 256 ? 3 : 4; ++ unsigned char *buf; ++ if (rlen < 0 || rlen >= 65534 || slen < 0 || slen >= 65534 || len3 > 65535) ++ return 0; /* should never happen as pgp's MPIs have a length < 8192 */ ++ buf = xmalloc(hlen3 + len3); ++ add_asn1_tag(buf, 0x30, len3); ++ add_asn1_tag(buf + hlen3, 0x02, len1); ++ buf[hlen3 + hlen1] = 0; /* zero first byte of the integer */ ++ memcpy(buf + hlen3 + hlen1 + len1 - rlen, r, rlen); ++ add_asn1_tag(buf + hlen3 + hlen1 + len1, 0x02, len2); ++ buf[hlen3 + len3 - len2] = 0; /* zero first byte of the integer */ ++ memcpy(buf + hlen3 + len3 - slen, s, slen); ++ *siglenp = hlen3 + len3; ++ return buf; + } + + static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num, const uint8_t *p) + { +- BIGNUM *bn = NULL; +- + int mlen = pgpMpiLen(p) - 2; + int rc = 1; + + struct pgpDigSigDSA_s *sig = pgpsig->data; + if (!sig) { + sig = xcalloc(1, sizeof(*sig)); ++ pgpsig->data = sig; + } + +- /* Create a BIGNUM from the signature pointer. +- Note: this assumes big-endian data as required +- by the PGP multiprecision integer format +- (RFC4880, Section 3.2) */ +- bn = BN_bin2bn(p+2, mlen, NULL); +- if (!bn) return 1; +- + switch (num) { + case 0: +- if (sig->r) { +- /* This should only ever happen once per signature */ +- BN_free(bn); +- return 1; +- } +- sig->r = bn; ++ if (sig->r) ++ return 1; /* This should only ever happen once per signature */ ++ sig->rlen = mlen; ++ sig->r = memcpy(xmalloc(mlen), p + 2, mlen); + rc = 0; + break; + case 1: +- if (sig->s) { +- /* This should only ever happen once per signature */ +- BN_free(bn); +- return 1; +- } +- sig->s = bn; ++ if (sig->s) ++ return 1; /* This should only ever happen once per signature */ ++ sig->slen = mlen; ++ sig->s = memcpy(xmalloc(mlen), p + 2, mlen); + rc = 0; + break; + } + +- pgpsig->data = sig; +- + return rc; + } + +@@ -450,17 +437,10 @@ static void pgpFreeSigDSA(pgpDigAlg pgpsig) + { + struct pgpDigSigDSA_s *sig = pgpsig->data; + if (sig) { +- if (sig->dsa_sig) { +- DSA_SIG_free(sig->dsa_sig); +- } else { +- /* If sig->dsa_sig was constructed, +- * the memory management of these BNs +- * are freed with it. */ +- BN_clear_free(sig->r); +- BN_clear_free(sig->s); +- } +- free(pgpsig->data); ++ free(sig->r); ++ free(sig->s); + } ++ free(pgpsig->data); + } + + static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, +@@ -468,22 +448,35 @@ static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, + { + int rc = 1; /* assume failure */ + struct pgpDigSigDSA_s *sig = pgpsig->data; +- + struct pgpDigKeyDSA_s *key = pgpkey->data; ++ unsigned char *xsig = NULL; /* signature encoded for X509 */ ++ size_t xsig_len = 0; ++ EVP_PKEY_CTX *pkey_ctx = NULL; + + if (!constructDSASigningKey(key)) + goto done; + +- if (!constructDSASignature(sig)) ++ xsig = constructDSASignature(sig->r, sig->rlen, sig->s, sig->slen, &xsig_len); ++ if (!xsig) ++ goto done; ++ ++ pkey_ctx = EVP_PKEY_CTX_new(key->evp_pkey, NULL); ++ if (!pkey_ctx) ++ goto done; ++ ++ if (EVP_PKEY_verify_init(pkey_ctx) != 1) + goto done; + +- if (DSA_do_verify(hash, hashlen, sig->dsa_sig, key->dsa_key) == 1) ++ if (EVP_PKEY_verify(pkey_ctx, xsig, xsig_len, hash, hashlen) == 1) + { + /* Success */ + rc = 0; + } + + done: ++ if (pkey_ctx) ++ EVP_PKEY_CTX_free(pkey_ctx); ++ free(xsig); + return rc; + } + +-- +2.23.0 + diff --git a/rpm.spec b/rpm.spec index f9860aa..09cc326 100644 --- a/rpm.spec +++ b/rpm.spec @@ -1,6 +1,6 @@ Name: rpm Version: 4.18.2 -Release: 19 +Release: 20 Summary: RPM Package Manager License: GPL-2.0-or-later URL: https://rpm.org/ @@ -48,9 +48,16 @@ Patch6025: backport-Fix-crash-on-Lua-file-trigger-exiting-with-return-ed.patch Patch6026: backport-Fix-V-option-usage-in-our-tests.patch Patch6027: backport-Remove-libtool-la-symlinks.patch Patch6028: backport-Specify-the-private-key-in-rpm-addsign.patch +Patch6029: backport-Use-EVP_PKEY_verify-to-verify-DSA-signatures.patch +Patch6030: backport-No-longer-use-the-low-level-API-in-openssl-3.patch +Patch6031: backport-Add-ECDSA-support-to-digest_openssl.patch +Patch6032: backport-Support-NIST-P-521.patch +Patch6033: backport-Allow-signing-with-ECDSA-keys.patch +Patch6034: backport-Support-ECDSA-in-key-parsing.patch Patch9000: Add-digest-list-plugin.patch Patch9001: Add-IMA-digest-list-support.patch +Patch9002: Support-sm2p256v1-of-ECDSA-and-sm3-of-hash.patch BuildRequires: gcc autoconf automake libtool make gawk popt-devel openssl-devel readline-devel BuildRequires: zlib-devel zstd-devel >= 1.3.8 xz-devel bzip2-devel libarchive-devel ima-evm-utils-devel @@ -336,6 +343,9 @@ make clean %exclude %{_mandir}/man8/rpmspec.8* %changelog +* Tue Oct 29 2024 xujing - 4.18.2-20 +- Support sm2p256v1 of ECDSA and sm3 of hash + * Sat Oct 26 2024 Funda Wang - 4.18.2-19 - fix RPM_LD_FLAGS not got exported