[Rpm-maint] [PATCH v9 12/13] Add support for passing the file signing key password
Fionnuala Gunter
fionnuala.gunter at gmail.com
Tue Jul 21 17:00:46 UTC 2015
From: Mimi Zohar <zohar at us.ibm.com>
The option to provide a password for signing an RPM package was
recently removed in favor of using the underlying mechanisms.
Requiring a user to enter a password for each file being signed,
however, is tedious. This patch adds support for prompting the
user for the password.
Dependency on ima-evm-utils version > "0.9"
Changelog:
- update get_fskpass() based on Dmitry's comments
---
lib/rpmsignfiles.c | 52 +++++++++++++++++++++++++++++++++++++++++++++-------
lib/rpmsignfiles.h | 5 ++++-
rpmsign.c | 22 +++++++++++++++++++++-
sign/rpmgensig.c | 7 ++++++-
4 files changed, 76 insertions(+), 10 deletions(-)
diff --git a/lib/rpmsignfiles.c b/lib/rpmsignfiles.c
index 414983b..4336f8c 100644
--- a/lib/rpmsignfiles.c
+++ b/lib/rpmsignfiles.c
@@ -7,6 +7,8 @@
#include "system.h"
#include "imaevm.h"
+#include <termios.h>
+
#include <rpm/rpmlog.h> /* rpmlog */
#include <rpm/rpmstring.h> /* rnibble */
#include <rpm/rpmpgp.h> /* rpmDigestLength */
@@ -30,7 +32,41 @@ static const char *hash_algo_name[] = {
[PGPHASHALGO_SHA224] = "sha224",
};
-static char *signFile(const char *algo, const char *fdigest, int diglen, const char *key)
+char *get_fskpass(void)
+{
+ struct termios flags, tmp_flags;
+ char *password, *pwd;
+ int passlen = 64;
+
+ password = malloc(passlen);
+ if (!password) {
+ perror("malloc");
+ return NULL;
+ }
+
+ tcgetattr(fileno(stdin), &flags);
+ tmp_flags = flags;
+ tmp_flags.c_lflag &= ~ECHO;
+ tmp_flags.c_lflag |= ECHONL;
+
+ if (tcsetattr(fileno(stdin), TCSANOW, &tmp_flags) != 0) {
+ perror("tcsetattr");
+ return NULL;
+ }
+
+ printf("PEM password: ");
+ pwd = fgets(password, passlen, stdin);
+ pwd[strlen(pwd) - 1] = '\0'; /* remove newline */
+
+ if (tcsetattr(fileno(stdin), TCSANOW, &flags) != 0) {
+ perror("tcsetattr");
+ return NULL;
+ }
+ return pwd;
+}
+
+static char *signFile(const char *algo, const char *fdigest, int diglen,
+const char *key, char *keypass)
{
char *fsignature;
unsigned char digest[diglen];
@@ -52,7 +88,7 @@ static char *signFile(const char *algo, const char *fdigest, int diglen, const c
signature[0] = '\x03';
/* calculate file signature */
- siglen = sign_hash(algo, digest, diglen, key, signature+1);
+ siglen = sign_hash(algo, digest, diglen, key, keypass, signature+1);
if (siglen < 0) {
rpmlog(RPMLOG_ERR, _("sign_hash failed\n"));
return NULL;
@@ -63,7 +99,8 @@ static char *signFile(const char *algo, const char *fdigest, int diglen, const c
return fsignature;
}
-static uint32_t signatureLength(const char *algo, int diglen, const char *key)
+static uint32_t signatureLength(const char *algo, int diglen, const char *key,
+char *keypass)
{
unsigned char digest[diglen];
unsigned char signature[MAX_SIGNATURE_LENGTH];
@@ -72,11 +109,12 @@ static uint32_t signatureLength(const char *algo, int diglen, const char *key)
memset(signature, 0, MAX_SIGNATURE_LENGTH);
signature[0] = '\x03';
- uint32_t siglen = sign_hash(algo, digest, diglen, key, signature+1);
+ uint32_t siglen = sign_hash(algo, digest, diglen, key, keypass,
+ signature+1);
return siglen + 1;
}
-rpmRC rpmSignFiles(Header h, const char *key)
+rpmRC rpmSignFiles(Header h, const char *key, char *keypass)
{
struct rpmtd_s digests;
int algo;
@@ -102,12 +140,12 @@ rpmRC rpmSignFiles(Header h, const char *key)
headerDel(h, RPMTAG_FILESIGNATURELENGTH);
headerDel(h, RPMTAG_FILESIGNATURES);
- siglen = signatureLength(algoname, diglen, key);
+ siglen = signatureLength(algoname, diglen, key, keypass);
headerPutUint32(h, RPMTAG_FILESIGNATURELENGTH, &siglen, 1);
headerGet(h, RPMTAG_FILEDIGESTS, &digests, HEADERGET_MINMEM);
while ((digest = rpmtdNextString(&digests))) {
- signature = signFile(algoname, digest, diglen, key);
+ signature = signFile(algoname, digest, diglen, key, keypass);
if (!signature) {
rpmlog(RPMLOG_ERR, _("signFile failed\n"));
rc = RPMRC_FAIL;
diff --git a/lib/rpmsignfiles.h b/lib/rpmsignfiles.h
index 70a5b9f..52e2482 100644
--- a/lib/rpmsignfiles.h
+++ b/lib/rpmsignfiles.h
@@ -9,9 +9,12 @@ extern "C" {
* Sign file digests in header and store the signatures in header
* @param h package header
* @param key signing key
+ * @param keypass signing key password
* @return RPMRC_OK on success
*/
-rpmRC rpmSignFiles(Header h, const char *key);
+rpmRC rpmSignFiles(Header h, const char *key, char *keypass);
+
+char *get_fskpass(void); /* get file signing key password */
#ifdef _cplusplus
}
diff --git a/rpmsign.c b/rpmsign.c
index ce4198a..7f48d98 100644
--- a/rpmsign.c
+++ b/rpmsign.c
@@ -6,6 +6,7 @@
#include <rpm/rpmcli.h>
#include <rpm/rpmsign.h>
#include "cliutils.h"
+#include "lib/rpmsignfiles.h"
#include "debug.h"
#if !defined(__GLIBC__) && !defined(__APPLE__)
@@ -20,8 +21,9 @@ enum modes {
static int mode = 0;
-static int signfiles = 0;
+static int signfiles = 0, fskpass = 0;
static char * fileSigningKey = NULL;
+static char * fileSigningKeyPassword = NULL;
static struct poptOption signOptsTable[] = {
{ "addsign", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_OR), &mode, MODE_ADDSIGN,
@@ -35,6 +37,8 @@ static struct poptOption signOptsTable[] = {
{ "fskpath", '\0', POPT_ARG_STRING, &fileSigningKey, 0,
N_("use file signing key <key>"),
N_("<key>") },
+ { "fskpass", '\0', POPT_ARG_NONE, &fskpass, 0,
+ N_("prompt for file signing key password"), NULL},
POPT_TABLEEND
};
@@ -72,6 +76,22 @@ static int doSign(poptContext optCon)
fprintf(stderr, _("You must set \"$$_file_signing_key\" in your macro file or on the command line with --fskpath\n"));
goto exit;
}
+
+ if (fskpass) {
+#ifndef WITH_IMAEVM
+ argerror(_("--fskpass may only be specified when signing files"));
+#else
+ fileSigningKeyPassword = get_fskpass();
+#endif
+ }
+
+ addMacro(NULL, "_file_signing_key_password", NULL,
+ fileSigningKeyPassword, RMIL_CMDLINE);
+ if (fileSigningKeyPassword) {
+ memset(fileSigningKeyPassword, 0, strlen(fileSigningKeyPassword));
+ free(fileSigningKeyPassword);
+ }
+
sig.signfiles = 1;
}
diff --git a/sign/rpmgensig.c b/sign/rpmgensig.c
index bc50ee4..c312e39 100644
--- a/sign/rpmgensig.c
+++ b/sign/rpmgensig.c
@@ -553,6 +553,7 @@ static rpmRC includeFileSignatures(FD_t fd, const char *rpm,
FD_t ofd = NULL;
char *trpm = NULL;
const char *key;
+ char *keypass;
char *SHA1 = NULL;
uint8_t *MD5 = NULL;
size_t sha1len;
@@ -571,7 +572,11 @@ static rpmRC includeFileSignatures(FD_t fd, const char *rpm,
key = rpmExpand("%{?_file_signing_key}", NULL);
- rc = rpmSignFiles(*hdrp, key);
+ keypass = rpmExpand("%{_file_signing_key_password}", NULL);
+ if (rstreq(keypass, ""))
+ keypass = NULL;
+
+ rc = rpmSignFiles(*hdrp, key, keypass);
if (rc != RPMRC_OK) {
goto exit;
}
--
2.4.3
More information about the Rpm-maint
mailing list