diff --git a/0034-rpmsign-Adopting-PKCS11-opaque-keys-support-in-libfsverity-for-fsverity-signatures.patch b/0034-rpmsign-Adopting-PKCS11-opaque-keys-support-in-libfsverity-for-fsverity-signatures.patch new file mode 100644 index 0000000..692ab33 --- /dev/null +++ b/0034-rpmsign-Adopting-PKCS11-opaque-keys-support-in-libfsverity-for-fsverity-signatures.patch @@ -0,0 +1,257 @@ +From aee5af8e4fe7908df90649eb699c3a1decf06b0c Mon Sep 17 00:00:00 2001 +From: Yu Wu +Date: Wed, 3 Nov 2021 23:13:15 -0700 +Subject: [PATCH 1/2] rpmsign: Adopting PKCS#11 opaque keys support in + libfsverity for fsverity signatures + +--- + rpmsign.c | 29 ++++++++++++++++++++---- + sign/rpmgensig.c | 53 +++++++++++++++++++++++++++++++++++++++----- + sign/rpmsignverity.c | 24 +++++++++++++------- + sign/rpmsignverity.h | 9 +++++--- + 4 files changed, 94 insertions(+), 21 deletions(-) + +diff --git a/rpmsign.c b/rpmsign.c +index 12299379ce..63b8616382 100644 +--- a/rpmsign.c ++++ b/rpmsign.c +@@ -24,6 +24,9 @@ static int fskpass = 0; + static char * fileSigningKey = NULL; + #endif + #ifdef WITH_FSVERITY ++static char * pkcs11Engine = NULL; ++static char * pkcs11Module = NULL; ++static char * pkcs11KeyId = NULL; + static char * fileSigningCert = NULL; + static char * verityAlgorithm = NULL; + #endif +@@ -59,6 +62,15 @@ static struct poptOption signOptsTable[] = { + { "certpath", '\0', POPT_ARG_STRING, &fileSigningCert, 0, + N_("use file signing cert "), + N_("") }, ++ { "pkcs11_engine", '\0', POPT_ARG_STRING, &pkcs11Engine, 0, ++ N_("use pkcs#11 token for fsverity signing key with openssl engine "), ++ N_("") }, ++ { "pkcs11_module", '\0', POPT_ARG_STRING, &pkcs11Module, 0, ++ N_("use pkcs#11 token for fsverity signing key with openssl module "), ++ N_("") }, ++ { "pkcs11_keyid", '\0', POPT_ARG_STRING, &pkcs11KeyId, 0, ++ N_("use pkcs#11 token for fsverity signing key with keyid "), ++ N_("") }, + #endif + #if defined(WITH_IMAEVM) || defined(WITH_FSVERITY) + { "fskpath", '\0', POPT_ARG_STRING, &fileSigningKey, 0, +@@ -139,6 +151,15 @@ static int doSign(poptContext optCon, struct rpmSignArgs *sargs) + } + + #ifdef WITH_FSVERITY ++ if (pkcs11Engine) { ++ rpmPushMacro(NULL, "_pkcs11_engine", NULL, pkcs11Engine, RMIL_GLOBAL); ++ } ++ if (pkcs11Module) { ++ rpmPushMacro(NULL, "_pkcs11_module", NULL, pkcs11Module, RMIL_GLOBAL); ++ } ++ if (pkcs11KeyId) { ++ rpmPushMacro(NULL, "_pkcs11_keyid", NULL, pkcs11KeyId, RMIL_GLOBAL); ++ } + if (fileSigningCert) { + rpmPushMacro(NULL, "_file_signing_cert", NULL, fileSigningCert, RMIL_GLOBAL); + } +@@ -149,9 +170,9 @@ static int doSign(poptContext optCon, struct rpmSignArgs *sargs) + + if (flags_sign_files(sargs->signflags)) { + char *fileSigningKeyPassword = NULL; +- char *key = rpmExpand("%{?_file_signing_key}", NULL); +- if (rstreq(key, "")) { +- fprintf(stderr, _("You must set \"%%_file_signing_key\" in your macro file or on the command line with --fskpath\n")); ++ char *cert = rpmExpand("%{?_file_signing_cert}", NULL); ++ if (rstreq(cert, "")) { ++ fprintf(stderr, _("You must set \"%%_file_signing_cert\" in your macro file or on the command line with --certpath\n")); + goto exit; + } + +@@ -166,7 +187,7 @@ static int doSign(poptContext optCon, struct rpmSignArgs *sargs) + free(fileSigningKeyPassword); + } + +- free(key); ++ free(cert); + } + #endif + +diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c +index d8c84e9377..cb264679b6 100644 +--- a/sign/rpmgensig.c ++++ b/sign/rpmgensig.c +@@ -461,15 +461,56 @@ static rpmRC includeVeritySignatures(FD_t fd, Header *sigp, Header *hdrp) + rpmRC rc = RPMRC_OK; + char *key = rpmExpand("%{?_file_signing_key}", NULL); + char *keypass = rpmExpand("%{?_file_signing_key_password}", NULL); ++ char *pkcs11_engine = rpmExpand("%{?_pkcs11_engine}", NULL); ++ char *pkcs11_module = rpmExpand("%{?_pkcs11_module}", NULL); ++ char *pkcs11_keyid = rpmExpand("%{?_pkcs11_keyid}", NULL); + char *cert = rpmExpand("%{?_file_signing_cert}", NULL); + char *algorithm = rpmExpand("%{?_verity_algorithm}", NULL); + uint16_t algo = 0; + ++ if (rstreq(key, "")) { ++ free(key); ++ key = NULL; ++ } ++ ++ if (rstreq(pkcs11_engine, "")) { ++ free(pkcs11_engine); ++ pkcs11_engine = NULL; ++ } ++ ++ if (rstreq(pkcs11_module, "")) { ++ free(pkcs11_module); ++ pkcs11_module = NULL; ++ } ++ ++ if (rstreq(pkcs11_keyid, "")) { ++ free(pkcs11_keyid); ++ pkcs11_keyid = NULL; ++ } ++ + if (rstreq(keypass, "")) { + free(keypass); + keypass = NULL; + } + ++ if (key) { ++ if (pkcs11_engine || pkcs11_module || pkcs11_keyid) { ++ rpmlog( ++ RPMLOG_ERR, ++ _("fsverity signatures require a key specified either by file or by PKCS#11 token, not both\n")); ++ rc = RPMRC_FAIL; ++ goto out; ++ } ++ } else { ++ if (!pkcs11_engine || !pkcs11_module) { ++ rpmlog( ++ RPMLOG_ERR, ++ _("fsverity signatures require both PKCS#11 engine and module to use PKCS#11 token\n")); ++ rc = RPMRC_FAIL; ++ goto out; ++ } ++ } ++ + if (algorithm && strlen(algorithm) > 0) { + algo = libfsverity_find_hash_alg_by_name(algorithm); + rpmlog(RPMLOG_DEBUG, _("Searching for algorithm %s got %i\n"), +@@ -481,16 +522,16 @@ static rpmRC includeVeritySignatures(FD_t fd, Header *sigp, Header *hdrp) + goto out; + } + } +- if (key && cert) { +- rc = rpmSignVerity(fd, *sigp, *hdrp, key, keypass, cert, algo); +- } else { +- rpmlog(RPMLOG_ERR, _("fsverity signatures requires a key and a cert\n")); +- rc = RPMRC_FAIL; +- } ++ ++ rc = rpmSignVerity(fd, *sigp, *hdrp, key, keypass, ++ pkcs11_engine, pkcs11_module, pkcs11_keyid, cert, algo); + + out: + free(keypass); + free(key); ++ free(pkcs11_engine); ++ free(pkcs11_module); ++ free(pkcs11_keyid); + free(cert); + return rc; + #else +diff --git a/sign/rpmsignverity.c b/sign/rpmsignverity.c +index e6c830cdcb..b7924e7ad1 100644 +--- a/sign/rpmsignverity.c ++++ b/sign/rpmsignverity.c +@@ -34,8 +34,9 @@ static int rpmVerityRead(void *opaque, void *buf, size_t size) + return retval; + } + +-static char *rpmVeritySignFile(rpmfi fi, size_t *sig_size, char *key, +- char *keypass, char *cert, uint16_t algo) ++static char *rpmVeritySignFile(rpmfi fi, size_t *sig_size, char *key, char *keypass, ++ char *pkcs11_engine, char *pkcs11_module, char *pkcs11_keyid, ++ char *cert, uint16_t algo) + { + struct libfsverity_merkle_tree_params params; + struct libfsverity_signature_params sig_params; +@@ -76,6 +77,9 @@ static char *rpmVeritySignFile(rpmfi fi, size_t *sig_size, char *key, + + memset(&sig_params, 0, sizeof(struct libfsverity_signature_params)); + sig_params.keyfile = key; ++ sig_params.pkcs11_engine = pkcs11_engine; ++ sig_params.pkcs11_module = pkcs11_module; ++ sig_params.pkcs11_keyid = pkcs11_keyid; + sig_params.certfile = cert; + if (libfsverity_sign_digest(digest, &sig_params, &sig, sig_size)) { + rpmlog(RPMLOG_DEBUG, _("failed to sign digest\n")); +@@ -94,8 +98,9 @@ static char *rpmVeritySignFile(rpmfi fi, size_t *sig_size, char *key, + return sig_base64; + } + +-rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key, +- char *keypass, char *cert, uint16_t algo) ++rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key, char *keypass, ++ char *pkcs11_engine, char *pkcs11_module, char *pkcs11_keyid, ++ char *cert, uint16_t algo) + { + int rc; + FD_t gzdi; +@@ -125,6 +130,9 @@ rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key, + } + + rpmlog(RPMLOG_DEBUG, _("key: %s\n"), key); ++ rpmlog(RPMLOG_DEBUG, _("pkcs11_engine: %s\n"), pkcs11_engine); ++ rpmlog(RPMLOG_DEBUG, _("pkcs11_module: %s\n"), pkcs11_module); ++ rpmlog(RPMLOG_DEBUG, _("pkcs11_keyid: %s\n"), pkcs11_keyid); + rpmlog(RPMLOG_DEBUG, _("cert: %s\n"), cert); + + compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR); +@@ -164,16 +172,16 @@ rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key, + while (rpmfiNext(fi) >= 0) { + idx = rpmfiFX(fi); + +- signatures[idx] = rpmVeritySignFile(fi, &sig_size, key, keypass, cert, +- algo); ++ signatures[idx] = rpmVeritySignFile(fi, &sig_size, key, keypass, pkcs11_engine, ++ pkcs11_module, pkcs11_keyid, cert, algo); + } + + while (rpmfiNext(hfi) >= 0) { + idx = rpmfiFX(hfi); + if (signatures[idx]) + continue; +- signatures[idx] = rpmVeritySignFile(hfi, &sig_size, key, keypass, cert, +- algo); ++ signatures[idx] = rpmVeritySignFile(fi, &sig_size, key, keypass, pkcs11_engine, ++ pkcs11_module, pkcs11_keyid, cert, algo); + } + + rpmtdReset(&td); +diff --git a/sign/rpmsignverity.h b/sign/rpmsignverity.h +index d869e8d8e8..32d2d6359a 100644 +--- a/sign/rpmsignverity.h ++++ b/sign/rpmsignverity.h +@@ -22,12 +22,15 @@ extern "C" { + * @param h package header + * @param key signing key + * @param keypass signing key password ++ * @param pkcs11_engine PKCS#11 engine to use PKCS#11 token support for signing key ++ * @param pkcs11_module PKCS#11 module to use PKCS#11 token support for signing key ++ * @param pkcs11_keyid PKCS#11 key identifier + * @param cert signing cert + * @return RPMRC_OK on success + */ +-RPM_GNUC_INTERNAL +-rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key, +- char *keypass, char *cert, uint16_t algo); ++rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key, char *keypass, ++ char *pkcs11_engine, char *pkcs11_module, char *pkcs11_keyid, ++ char *cert, uint16_t algo); + + #ifdef _cplusplus + } diff --git a/rpm.spec b/rpm.spec index 02387e7..0ba7783 100644 --- a/rpm.spec +++ b/rpm.spec @@ -131,6 +131,7 @@ Patch1979: 0030-Add-delfilesign-flag-to-delete-IMA-and-fsverity-file.patch Patch1980: 0031-Update-man-page-for-rpmsign.patch Patch1981: 0032-rpmsign-Add-argument-to-specify-algorithm-for-fsveri.patch Patch1982: 0033-Enable-fsverity-in-CI.patch +Patch1983: 0034-rpmsign-Adopting-PKCS11-opaque-keys-support-in-libfsverity-for-fsverity-signatures.patch %endif Patch9999: measure.patch @@ -197,7 +198,7 @@ BuildRequires: ima-evm-utils-devel >= 1.0 %endif %if %{with libfsverity} -BuildRequires: fsverity-utils-devel >= 1.1 +BuildRequires: fsverity-utils-devel >= 1.4 %endif %description