Support sm2p256v1 of ECDSA and sm3 of hash
This commit is contained in:
parent
0396a74350
commit
24cbd83f22
251
Support-sm2p256v1-of-ECDSA-and-sm3-of-hash.patch
Normal file
251
Support-sm2p256v1-of-ECDSA-and-sm3-of-hash.patch
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
From 32ab7eb58556d41df302af8166a77f2f2bf38754 Mon Sep 17 00:00:00 2001
|
||||||
|
From: xujing <xujing125@huawei.com>
|
||||||
|
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 <openssl/ec.h>
|
||||||
|
|
||||||
|
#include <rpm/rpmcrypto.h>
|
||||||
|
+#include <rpm/rpmmacro.h>
|
||||||
|
#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
|
||||||
|
|
||||||
263
backport-Add-ECDSA-support-to-digest_openssl.patch
Normal file
263
backport-Add-ECDSA-support-to-digest_openssl.patch
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
From d2d35d1acb89d4113647a9aad2d049808112b935 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
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 <openssl/rsa.h>
|
||||||
|
#include <openssl/dsa.h>
|
||||||
|
+#include <openssl/ec.h>
|
||||||
|
|
||||||
|
#include <rpm/rpmcrypto.h>
|
||||||
|
#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
|
||||||
|
|
||||||
29
backport-Allow-signing-with-ECDSA-keys.patch
Normal file
29
backport-Allow-signing-with-ECDSA-keys.patch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
From ef0afa856a609bea765dbccaebb75ceeddd202f3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
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
|
||||||
|
|
||||||
138
backport-No-longer-use-the-low-level-API-in-openssl-3.patch
Normal file
138
backport-No-longer-use-the-low-level-API-in-openssl-3.patch
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
From 408f2053da61fa80c5a306b8f87cdd70a7c57a62 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
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 <openssl/evp.h>
|
||||||
|
+#if OPENSSL_VERSION_MAJOR >= 3
|
||||||
|
+# include <openssl/params.h>
|
||||||
|
+#endif
|
||||||
|
#include <openssl/rsa.h>
|
||||||
|
#include <openssl/dsa.h>
|
||||||
|
-#include <rpm/rpmcrypto.h>
|
||||||
|
|
||||||
|
+#include <rpm/rpmcrypto.h>
|
||||||
|
#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
|
||||||
|
|
||||||
78
backport-Support-ECDSA-in-key-parsing.patch
Normal file
78
backport-Support-ECDSA-in-key-parsing.patch
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
From 8bc74f9ec48386beadf396ba5830aacf6672df4c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
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
|
||||||
|
|
||||||
52
backport-Support-NIST-P-521.patch
Normal file
52
backport-Support-NIST-P-521.patch
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
From 6344fec232cdd0e9d821a0b17e480494f4dcfd4b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
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
|
||||||
|
|
||||||
316
backport-Use-EVP_PKEY_verify-to-verify-DSA-signatures.patch
Normal file
316
backport-Use-EVP_PKEY_verify-to-verify-DSA-signatures.patch
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
From 8bf5c6b094e4f703d9fa1422a463654b512b25ae Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Schroeder <mls@suse.de>
|
||||||
|
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
|
||||||
|
|
||||||
12
rpm.spec
12
rpm.spec
@ -1,6 +1,6 @@
|
|||||||
Name: rpm
|
Name: rpm
|
||||||
Version: 4.18.2
|
Version: 4.18.2
|
||||||
Release: 19
|
Release: 20
|
||||||
Summary: RPM Package Manager
|
Summary: RPM Package Manager
|
||||||
License: GPL-2.0-or-later
|
License: GPL-2.0-or-later
|
||||||
URL: https://rpm.org/
|
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
|
Patch6026: backport-Fix-V-option-usage-in-our-tests.patch
|
||||||
Patch6027: backport-Remove-libtool-la-symlinks.patch
|
Patch6027: backport-Remove-libtool-la-symlinks.patch
|
||||||
Patch6028: backport-Specify-the-private-key-in-rpm-addsign.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
|
Patch9000: Add-digest-list-plugin.patch
|
||||||
Patch9001: Add-IMA-digest-list-support.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: 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
|
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*
|
%exclude %{_mandir}/man8/rpmspec.8*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Oct 29 2024 xujing<xujing125@huawei.com> - 4.18.2-20
|
||||||
|
- Support sm2p256v1 of ECDSA and sm3 of hash
|
||||||
|
|
||||||
* Sat Oct 26 2024 Funda Wang <fundawang@yeah.net> - 4.18.2-19
|
* Sat Oct 26 2024 Funda Wang <fundawang@yeah.net> - 4.18.2-19
|
||||||
- fix RPM_LD_FLAGS not got exported
|
- fix RPM_LD_FLAGS not got exported
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user