You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
5.7 KiB
196 lines
5.7 KiB
2 years ago
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Peter Jones <pjones@redhat.com>
|
||
|
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 <libdpe/libdpe.h>
|
||
|
|
||
|
#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);
|