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 }