Blame SOURCES/0016-efikeygen-add-modsign.patch

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