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