@@ -81,6 +81,7 @@ static struct option long_options[] = {
{"no-downgrading", required_argument, NULL, 'N'},
#ifdef CONFIG_SIGNED_IMAGES
{"key", required_argument, NULL, 'k'},
+ {"cert-purpose", required_argument, NULL, '1'},
#endif
#ifdef CONFIG_ENCRYPTED_IMAGES
{"key-aes", required_argument, NULL, 'K'},
@@ -126,6 +127,8 @@ static void usage(char *programname)
" -L, --syslog : enable syslog logger\n"
#ifdef CONFIG_SIGNED_IMAGES
" -k, --key <public key file> : file with public key to verify images\n"
+ " --cert-purpose <purpose> : set expected certificate purpose\n"
+ " [emailProtection|codeSigning] (default: emailProtection)\n"
#endif
#ifdef CONFIG_ENCRYPTED_IMAGES
" -K, --key-aes <key file> : the file contains the symmetric key to be used\n"
@@ -446,6 +449,7 @@ static void swupdate_init(struct swupdate_cfg *sw)
LIST_INIT(&sw->bootscripts);
LIST_INIT(&sw->bootloader);
LIST_INIT(&sw->extprocs);
+ sw->globals.cert_purpose = X509_PURPOSE_SMIME_SIGN;
/* Create directories for scripts */
@@ -462,8 +466,24 @@ static void swupdate_init(struct swupdate_cfg *sw)
#endif
}
+static int parse_cert_purpose(const char *text)
+{
+ static const char CODE_SIGN[] = "codeSigning";
+ static const char EMAIL_PROT[] = "emailProtection";
+
+ if (strncmp(CODE_SIGN, text, sizeof(CODE_SIGN)) == 0)
+ return X509_PURPOSE_CODE_SIGN;
+
+ if (strncmp(EMAIL_PROT, text, sizeof(EMAIL_PROT)) == 0)
+ return X509_PURPOSE_SMIME_SIGN;
+
+ ERROR("unknown certificate purpose '%s'\n", text);
+ exit(EXIT_FAILURE);
+}
+
static int read_globals_settings(void *elem, void *data)
{
+ char tmp[SWUPDATE_GENERAL_STRING_SIZE];
struct swupdate_cfg *sw = (struct swupdate_cfg *)data;
GET_FIELD_STRING(LIBCFG_PARSER, elem,
@@ -481,6 +501,9 @@ static int read_globals_settings(void *elem, void *data)
"no-downgrading", sw->globals.current_version);
if (strlen(sw->globals.current_version))
sw->globals.no_downgrading = 1;
+ GET_FIELD_STRING(LIBCFG_PARSER, elem,
+ "cert-purpose", tmp);
+ sw->globals.cert_purpose = parse_cert_purpose(tmp);
return 0;
}
@@ -694,6 +717,9 @@ int main(int argc, char **argv)
optarg,
sizeof(swcfg.globals.publickeyfname));
break;
+ case '1':
+ swcfg.globals.cert_purpose = parse_cert_purpose(optarg);
+ break;
#ifdef CONFIG_ENCRYPTED_IMAGES
case 'K':
strncpy(swcfg.globals.aeskeyfname,
@@ -195,6 +195,13 @@ out:
}
#elif defined(CONFIG_SIGALG_CMS)
+static int check_purpose_code_sign(const X509_PURPOSE *xp, const X509 *x,
+ int ca)
+{
+ (void)xp;
+ (void)ca;
+ return (x->ex_flags & EXFLAG_XKUSAGE) && (x->ex_xkusage & XKU_CODE_SIGN);
+}
static int cms_verify_callback(int ok, X509_STORE_CTX *ctx) {
int cert_error = X509_STORE_CTX_get_error(ctx);
@@ -439,6 +446,24 @@ int swupdate_dgst_init(struct swupdate_cfg *sw, const char *keyfile)
ret = -EINVAL;
goto dgst_init_error;
}
+
+ {
+ static char code_sign_name[] = "Code signing";
+ static char code_sign_sname[] = "codesign";
+ if (!X509_PURPOSE_add(X509_PURPOSE_CODE_SIGN, X509_TRUST_EMAIL,
+ 0, check_purpose_code_sign, code_sign_name,
+ code_sign_sname, NULL)) {
+ ERROR("failed to add code sign purpose");
+ ret = -EINVAL;
+ goto dgst_init_error;
+ }
+ }
+
+ if (!X509_STORE_set_purpose(dgst->certs, sw->globals.cert_purpose)) {
+ ERROR("failed to set purpose");
+ ret = -EINVAL;
+ goto dgst_init_error;
+ }
#else
TRACE("public key / cert %s ignored, you need to set SIGALG", keyfile);
#endif
@@ -36,6 +36,8 @@
#include <openssl/opensslv.h>
+#define X509_PURPOSE_CODE_SIGN (X509_PURPOSE_MAX + 1)
+
struct swupdate_digest {
EVP_PKEY *pkey; /* this is used for RSA key */
X509_STORE *certs; /* this is used if CMS is set */
@@ -112,6 +112,7 @@ struct swupdate_global_cfg {
char aeskeyfname[SWUPDATE_GENERAL_STRING_SIZE];
char postupdatecmd[SWUPDATE_GENERAL_STRING_SIZE];
char current_version[SWUPDATE_GENERAL_STRING_SIZE];
+ int cert_purpose;
};
struct swupdate_cfg {
OpenSSL CMS checks only for emailProtection key usage, but codeSigning makes more sense here. This patch adds command line parameter and configuration variable to set expected certificate purpose. Signed-off-by: Denis Osterland <Denis.Osterland@diehl.com> --- v1 -> v2: set expected purpose before call to verify, add configuration options for the expected purpose core/swupdate.c | 26 ++++++++++++++++++++++++++ corelib/verify_signature.c | 25 +++++++++++++++++++++++++ include/sslapi.h | 2 ++ include/swupdate.h | 1 + 4 files changed, 54 insertions(+)