From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 22 Aug 2016 13:43:56 -0400 Subject: [PATCH] efikeygen: add --modsign --- src/cms_common.c | 29 +++++++++++++++++++++++++++ src/efikeygen.c | 61 ++++++++++++++++++++++++++++++++++++++++++++------------ src/cms_common.h | 1 + 3 files changed, 78 insertions(+), 13 deletions(-) diff --git a/src/cms_common.c b/src/cms_common.c index 6a4e6a7..2df2cfe 100644 --- a/src/cms_common.c +++ b/src/cms_common.c @@ -715,6 +715,35 @@ make_context_specific(cms_context *cms, int ctxt, SECItem *encoded, return 0; } +static SEC_ASN1Template EKUOidSequence[] = { + { + .kind = SEC_ASN1_OBJECT_ID, + .offset = 0, + .sub = &SEC_AnyTemplate, + .size = sizeof (SECItem), + }, + { 0 } +}; + +int +make_eku_oid(cms_context *cms, SECItem *encoded, SECOidTag oid_tag) +{ + void *rv; + SECOidData *oid_data; + + oid_data = SECOID_FindOIDByTag(oid_tag); + if (!oid_data) + cmsreterr(-1, cms, "could not encode eku oid data"); + + rv = SEC_ASN1EncodeItem(cms->arena, encoded, &oid_data->oid, + EKUOidSequence); + if (rv == NULL) + cmsreterr(-1, cms, "could not encode eku oid data"); + + encoded->type = siBuffer; + return 0; +} + int generate_octet_string(cms_context *cms, SECItem *encoded, SECItem *original) { diff --git a/src/efikeygen.c b/src/efikeygen.c index 8a515a5..9390578 100644 --- a/src/efikeygen.c +++ b/src/efikeygen.c @@ -49,6 +49,7 @@ #include #include "cms_common.h" +#include "oid.h" #include "util.h" typedef struct { @@ -249,20 +250,34 @@ add_basic_constraints(cms_context *cms, void *extHandle) } static int -add_extended_key_usage(cms_context *cms, void *extHandle) +add_extended_key_usage(cms_context *cms, int modsign_only, void *extHandle) { - SECItem value = { - .data = (unsigned char *)"\x30\x0a\x06\x08\x2b\x06\x01" - "\x05\x05\x07\x03\x03", - .len = 12, - .type = siBuffer - }; - - + SECItem values[2]; + SECItem wrapped = { 0 }; SECStatus status; + SECOidTag tag; + int rc; + + if (modsign_only < 1 || modsign_only > 2) + cmsreterr(-1, cms, "could not encode extended key usage"); + + rc = make_eku_oid(cms, &values[0], SEC_OID_EXT_KEY_USAGE_CODE_SIGN); + if (rc < 0) + cmsreterr(-1, cms, "could not encode extended key usage"); + + tag = find_ms_oid_tag(SHIM_EKU_MODULE_SIGNING_ONLY); + printf("tag: %d\n", tag); + rc = make_eku_oid(cms, &values[1], tag); + if (rc < 0) + cmsreterr(-1, cms, "could not encode extended key usage"); + + rc = wrap_in_seq(cms, &wrapped, values, modsign_only); + if (rc < 0) + cmsreterr(-1, cms, "could not encode extended key usage"); + status = CERT_AddExtension(extHandle, SEC_OID_X509_EXT_KEY_USAGE, - &value, PR_FALSE, PR_TRUE); + &wrapped, PR_FALSE, PR_TRUE); if (status != SECSuccess) cmsreterr(-1, cms, "could not encode extended key usage"); @@ -294,7 +309,7 @@ static int add_extensions_to_crq(cms_context *cms, CERTCertificateRequest *crq, int is_ca, int is_self_signed, SECKEYPublicKey *pubkey, SECKEYPublicKey *spubkey, - char *url) + char *url, int modsign_only) { void *mark = PORT_ArenaMark(cms->arena); @@ -319,7 +334,7 @@ add_extensions_to_crq(cms_context *cms, CERTCertificateRequest *crq, if (rc < 0) cmsreterr(-1, cms, "could not generate certificate extensions"); - rc = add_extended_key_usage(cms, extHandle); + rc = add_extended_key_usage(cms, modsign_only, extHandle); if (rc < 0) cmsreterr(-1, cms, "could not generate certificate extensions"); @@ -469,6 +484,7 @@ int main(int argc, char *argv[]) { int is_ca = 0; int is_self_signed = -1; + int modsign_only = 0; char *tokenname = "NSS Certificate DB"; char *signer = NULL; char *nickname = NULL; @@ -522,6 +538,18 @@ int main(int argc, char *argv[]) .descrip = "Generate a self-signed certificate" }, /* stuff about the generated key */ + {.longName = "kernel", + .shortName = 'k', + .argInfo = POPT_ARG_VAL|POPT_ARGFLAG_OR, + .arg = &modsign_only, + .val = 1, + .descrip = "Generate a kernel-signing certificate" }, + {.longName = "module", + .shortName = 'm', + .argInfo = POPT_ARG_VAL|POPT_ARGFLAG_OR, + .arg = &modsign_only, + .val = 2, + .descrip = "Generate a module-signing certificate" }, {.longName = "nickname", .shortName = 'n', .argInfo = POPT_ARG_STRING, @@ -628,6 +656,9 @@ int main(int argc, char *argv[]) liberr(1, "could not allocate cms context"); } + if (modsign_only < 1 || modsign_only > 2) + errx(1, "either --kernel or --module must be used"); + SECStatus status = NSS_InitReadWrite(dbdir); if (status != SECSuccess) nsserr(1, "could not initialize NSS"); @@ -639,6 +670,10 @@ int main(int argc, char *argv[]) SECKEYPublicKey *pubkey = NULL; SECKEYPrivateKey *privkey = NULL; + status = register_oids(cms); + if (status != SECSuccess) + nsserr(1, "Could not register OIDs"); + PK11SlotInfo *slot = NULL; if (pubfile) { rc = get_pubkey_from_file(pubfile, &pubkey); @@ -713,7 +748,7 @@ int main(int argc, char *argv[]) crq = CERT_CreateCertificateRequest(name, spki, &attributes); rc = add_extensions_to_crq(cms, crq, is_ca, is_self_signed, pubkey, - spubkey, url); + spubkey, url, modsign_only); if (rc < 0) exit(1); diff --git a/src/cms_common.h b/src/cms_common.h index c7d7268..7a31273 100644 --- a/src/cms_common.h +++ b/src/cms_common.h @@ -123,6 +123,7 @@ extern int wrap_in_seq(cms_context *cms, SECItem *der, SECItem *items, int num_items); extern int make_context_specific(cms_context *cms, int ctxt, SECItem *encoded, SECItem *original); +extern int make_eku_oid(cms_context *cms, SECItem *encoded, SECOidTag oid_tag); extern int generate_validity(cms_context *cms, SECItem *der, time_t start, time_t end); extern int generate_common_name(cms_context *cms, SECItem *der, char *cn);