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>
This commit is contained in:
Jes Sorensen 2020-06-10 12:30:54 -04:00 committed by Panu Matilainen
parent 32e94048a3
commit ae4b1b1fe8
5 changed files with 33 additions and 6 deletions

View File

@ -55,6 +55,9 @@ Used with \fB--signfiles\fR, use file signing key \fIKey\fR.
\fB--certpath \fICERT\fB\fR \fB--certpath \fICERT\fB\fR
Used with \fB--signverity\fR, use file signing certificate \fICert\fR. Used with \fB--signverity\fR, use file signing certificate \fICert\fR.
.TP .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 \fB--signfiles\fR
Sign package files. The macro \fB%_binary_filedigest_algorithm\fR must Sign package files. The macro \fB%_binary_filedigest_algorithm\fR must
be set to a supported algorithm before building the package. The be set to a supported algorithm before building the package. The

View File

@ -25,6 +25,7 @@ static char * fileSigningKey = NULL;
#endif #endif
#ifdef WITH_FSVERITY #ifdef WITH_FSVERITY
static char * fileSigningCert = NULL; static char * fileSigningCert = NULL;
static char * verityAlgorithm = NULL;
#endif #endif
static struct rpmSignArgs sargs = {NULL, 0, 0}; static struct rpmSignArgs sargs = {NULL, 0, 0};
@ -52,6 +53,9 @@ static struct poptOption signOptsTable[] = {
{ "signverity", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), { "signverity", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR),
&sargs.signflags, RPMSIGN_FLAG_FSVERITY, &sargs.signflags, RPMSIGN_FLAG_FSVERITY,
N_("generate fsverity signatures for package(s) files"), NULL}, 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, { "certpath", '\0', POPT_ARG_STRING, &fileSigningCert, 0,
N_("use file signing cert <cert>"), N_("use file signing cert <cert>"),
N_("<cert>") }, N_("<cert>") },
@ -138,6 +142,9 @@ static int doSign(poptContext optCon, struct rpmSignArgs *sargs)
if (fileSigningCert) { if (fileSigningCert) {
rpmPushMacro(NULL, "_file_signing_cert", NULL, fileSigningCert, RMIL_GLOBAL); rpmPushMacro(NULL, "_file_signing_cert", NULL, fileSigningCert, RMIL_GLOBAL);
} }
if (verityAlgorithm) {
rpmPushMacro(NULL, "_verity_algorithm", NULL, verityAlgorithm, RMIL_GLOBAL);
}
#endif #endif
if (flags_sign_files(sargs->signflags)) { if (flags_sign_files(sargs->signflags)) {

View File

@ -9,6 +9,9 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <popt.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/rpmlib.h> /* RPMSIGTAG & related */
#include <rpm/rpmmacro.h> #include <rpm/rpmmacro.h>
@ -454,23 +457,37 @@ static rpmRC includeFileSignatures(Header *sigp, Header *hdrp)
static rpmRC includeVeritySignatures(FD_t fd, Header *sigp, Header *hdrp) static rpmRC includeVeritySignatures(FD_t fd, Header *sigp, Header *hdrp)
{ {
#ifdef WITH_FSVERITY #ifdef WITH_FSVERITY
rpmRC rc; rpmRC rc = RPMRC_OK;
char *key = rpmExpand("%{?_file_signing_key}", NULL); char *key = rpmExpand("%{?_file_signing_key}", NULL);
char *keypass = rpmExpand("%{?_file_signing_key_password}", NULL); char *keypass = rpmExpand("%{?_file_signing_key_password}", NULL);
char *cert = rpmExpand("%{?_file_signing_cert}", NULL); char *cert = rpmExpand("%{?_file_signing_cert}", NULL);
char *algorithm = rpmExpand("%{?_verity_algorithm}", NULL);
uint16_t algo = 0;
if (rstreq(keypass, "")) { if (rstreq(keypass, "")) {
free(keypass); free(keypass);
keypass = NULL; 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) { if (key && cert) {
rc = rpmSignVerity(fd, *sigp, *hdrp, key, keypass, cert); rc = rpmSignVerity(fd, *sigp, *hdrp, key, keypass, cert, algo);
} else { } else {
rpmlog(RPMLOG_ERR, _("fsverity signatures requires a key and a cert\n")); rpmlog(RPMLOG_ERR, _("fsverity signatures requires a key and a cert\n"));
rc = RPMRC_FAIL; rc = RPMRC_FAIL;
} }
out:
free(keypass); free(keypass);
free(key); free(key);
free(cert); free(cert);

View File

@ -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, rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key,
char *keypass, char *cert) char *keypass, char *cert, uint16_t algo)
{ {
int rc; int rc;
FD_t gzdi; FD_t gzdi;
@ -111,7 +111,6 @@ rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key,
char **signatures = NULL; char **signatures = NULL;
size_t sig_size; size_t sig_size;
int nr_files, idx; int nr_files, idx;
uint16_t algo;
uint32_t algo32; uint32_t algo32;
Fseek(fd, 0, SEEK_SET); Fseek(fd, 0, SEEK_SET);
@ -156,7 +155,8 @@ rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key,
nr_files = rpmfiFC(hfi); nr_files = rpmfiFC(hfi);
signatures = xcalloc(nr_files, sizeof(char *)); 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"), rpmlog(RPMLOG_DEBUG, _("file count - header: %i, payload %i\n"),
nr_files, rpmfiFC(fi)); nr_files, rpmfiFC(fi));

View File

@ -27,7 +27,7 @@ extern "C" {
*/ */
RPM_GNUC_INTERNAL RPM_GNUC_INTERNAL
rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key, rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key,
char *keypass, char *cert); char *keypass, char *cert, uint16_t algo);
#ifdef _cplusplus #ifdef _cplusplus
} }