| From 3669fecaba2858aeca44d1bfc265760611ea8834 Mon Sep 17 00:00:00 2001 |
| From: Jes Sorensen <jsorensen@fb.com> |
| Date: Wed, 10 Jun 2020 12:30:54 -0400 |
| Subject: [PATCH 32/33] rpmsign: Add argument to specify algorithm for fsverity |
| signatures |
| |
| The argument --verity-algo can be used to specify the algorithm for |
| the fsverity signatures. If nothing is specified, this will default to |
| sha256. The available algorithms depend on libfsverity, currently |
| sha256 and sha512 are supported. |
| |
| Signed-off-by: Jes Sorensen <jsorensen@fb.com> |
| |
| doc/rpmsign.8 | 3 +++ |
| rpmsign.c | 7 +++++++ |
| sign/rpmgensig.c | 22 ++++++++++++++++++++-- |
| sign/rpmsignverity.c | 6 +++--- |
| sign/rpmsignverity.h | 2 +- |
| 5 files changed, 34 insertions(+), 6 deletions(-) |
| |
| diff --git a/doc/rpmsign.8 b/doc/rpmsign.8 |
| index a212746fe..5165e39f9 100644 |
| |
| |
| @@ -55,6 +55,9 @@ Used with \fB--signfiles\fR, use file signing key \fIKey\fR. |
| \fB--certpath \fICERT\fB\fR |
| Used with \fB--signverity\fR, use file signing certificate \fICert\fR. |
| .TP |
| +\fB--verityalgo \fIALG\fB\fR |
| +Used with \fB--signverity\fR, to specify the signing algorithm. sha256 and sha512 are supported, with sha256 being the default if this argument is not specified. This can also be specified with the macro %_verity_algorithm |
| +.TP |
| \fB--signfiles\fR |
| Sign package files. The macro \fB%_binary_filedigest_algorithm\fR must |
| be set to a supported algorithm before building the package. The |
| diff --git a/rpmsign.c b/rpmsign.c |
| index e43811e9f..12299379c 100644 |
| |
| |
| @@ -25,6 +25,7 @@ static char * fileSigningKey = NULL; |
| #endif |
| #ifdef WITH_FSVERITY |
| static char * fileSigningCert = NULL; |
| +static char * verityAlgorithm = NULL; |
| #endif |
| |
| static struct rpmSignArgs sargs = {NULL, 0, 0}; |
| @@ -52,6 +53,9 @@ static struct poptOption signOptsTable[] = { |
| { "signverity", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), |
| &sargs.signflags, RPMSIGN_FLAG_FSVERITY, |
| N_("generate fsverity signatures for package(s) files"), NULL}, |
| + { "verityalgo", '\0', POPT_ARG_STRING, &verityAlgorithm, 0, |
| + N_("algorithm to use for verity signatures, default sha256"), |
| + N_("<algorithm>") }, |
| { "certpath", '\0', POPT_ARG_STRING, &fileSigningCert, 0, |
| N_("use file signing cert <cert>"), |
| N_("<cert>") }, |
| @@ -138,6 +142,9 @@ static int doSign(poptContext optCon, struct rpmSignArgs *sargs) |
| if (fileSigningCert) { |
| rpmPushMacro(NULL, "_file_signing_cert", NULL, fileSigningCert, RMIL_GLOBAL); |
| } |
| + if (verityAlgorithm) { |
| + rpmPushMacro(NULL, "_verity_algorithm", NULL, verityAlgorithm, RMIL_GLOBAL); |
| + } |
| #endif |
| |
| if (flags_sign_files(sargs->signflags)) { |
| diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c |
| index 02cf0bc62..b3b02828a 100644 |
| |
| |
| @@ -8,6 +8,10 @@ |
| #include <sys/wait.h> |
| #include <popt.h> |
| #include <fcntl.h> |
| +#include <fcntl.h> |
| +#ifdef WITH_FSVERITY |
| +#include <libfsverity.h> |
| +#endif |
| |
| #include <rpm/rpmlib.h> /* RPMSIGTAG & related */ |
| #include <rpm/rpmmacro.h> |
| @@ -458,23 +462,37 @@ static rpmRC includeFileSignatures(Header *sigp, Header *hdrp) |
| static rpmRC includeVeritySignatures(FD_t fd, Header *sigp, Header *hdrp) |
| { |
| #ifdef WITH_FSVERITY |
| - rpmRC rc; |
| + rpmRC rc = RPMRC_OK; |
| char *key = rpmExpand("%{?_file_signing_key}", NULL); |
| char *keypass = rpmExpand("%{?_file_signing_key_password}", NULL); |
| char *cert = rpmExpand("%{?_file_signing_cert}", NULL); |
| + char *algorithm = rpmExpand("%{?_verity_algorithm}", NULL); |
| + uint16_t algo = 0; |
| |
| if (rstreq(keypass, "")) { |
| free(keypass); |
| keypass = NULL; |
| } |
| |
| + if (algorithm && strlen(algorithm) > 0) { |
| + algo = libfsverity_find_hash_alg_by_name(algorithm); |
| + rpmlog(RPMLOG_DEBUG, _("Searching for algorithm %s got %i\n"), |
| + algorithm, algo); |
| + if (!algo) { |
| + rpmlog(RPMLOG_ERR, _("Unsupported fsverity algorithm %s\n"), |
| + algorithm); |
| + rc = RPMRC_FAIL; |
| + goto out; |
| + } |
| + } |
| if (key && cert) { |
| - rc = rpmSignVerity(fd, *sigp, *hdrp, key, keypass, 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; |
| } |
| |
| + out: |
| free(keypass); |
| free(key); |
| free(cert); |
| diff --git a/sign/rpmsignverity.c b/sign/rpmsignverity.c |
| index 55096e732..e6c830cdc 100644 |
| |
| |
| @@ -95,7 +95,7 @@ static char *rpmVeritySignFile(rpmfi fi, size_t *sig_size, char *key, |
| } |
| |
| rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key, |
| - char *keypass, char *cert) |
| + char *keypass, char *cert, uint16_t algo) |
| { |
| int rc; |
| FD_t gzdi; |
| @@ -111,7 +111,6 @@ rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key, |
| char **signatures = NULL; |
| size_t sig_size; |
| int nr_files, idx; |
| - uint16_t algo; |
| uint32_t algo32; |
| |
| Fseek(fd, 0, SEEK_SET); |
| @@ -156,7 +155,8 @@ rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key, |
| nr_files = rpmfiFC(hfi); |
| signatures = xcalloc(nr_files, sizeof(char *)); |
| |
| - algo = FS_VERITY_HASH_ALG_SHA256; |
| + if (!algo) |
| + algo = FS_VERITY_HASH_ALG_SHA256; |
| |
| rpmlog(RPMLOG_DEBUG, _("file count - header: %i, payload %i\n"), |
| nr_files, rpmfiFC(fi)); |
| diff --git a/sign/rpmsignverity.h b/sign/rpmsignverity.h |
| index 69bbaf7f7..d869e8d8e 100644 |
| |
| |
| @@ -27,7 +27,7 @@ extern "C" { |
| */ |
| RPM_GNUC_INTERNAL |
| rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key, |
| - char *keypass, char *cert); |
| + char *keypass, char *cert, uint16_t algo); |
| |
| #ifdef _cplusplus |
| } |
| -- |
| 2.27.0 |
| |