mokutil/mokutil-mokx-support.patch
2014-01-22 06:52:14 +00:00

2969 lines
85 KiB
Diff

From 65c8d2eb32beda5e90af891de3e5bda41a8aa6f1 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Mon, 21 Oct 2013 17:49:33 +0800
Subject: [PATCH 01/20] Update TODO
---
TODO | 16 ++--------------
1 file changed, 2 insertions(+), 14 deletions(-)
diff --git a/TODO b/TODO
index 373e48d..465835a 100644
--- a/TODO
+++ b/TODO
@@ -1,17 +1,5 @@
-* Validate the DER file [DONE]
* Show the detail of the DER file when enrolling (?)
* Add an option to slience the output (?)
-* Show the current value of MokNew and MokListRT [DONE]
-* Request the user to input a password before enrolling [DONE]
-* Read the list from a volatile RT variable [DONE]
-* Export keys in MokListRT [DONE]
* List hashes in MokListRT
-* Add a new command to probe the state of SecureBoot
- - SecureBoot, EFI_GLOBAL_VARIABLE
-* Do not to enroll duplicate key
- - compare the keys in MokListRT before enrolling the new keys
- - compare the keys in MokNew
- - add a new command to check duplicate
-* Add a new command to append the new key request to the old one
- - use the old password to verify the old request
-* Delete a specific key
+* Support MokX
+* Import hash into MokNew, NokDel, MokXNew
--
1.8.4
From 012d82be0468e876a10691fbabab2ed11b7a4954 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 22 Oct 2013 14:24:13 +0800
Subject: [PATCH 02/20] Show the hashes in the database
---
src/efi.h | 2 +-
src/mokutil.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
src/signature.h | 14 ++++++--
3 files changed, 113 insertions(+), 13 deletions(-)
diff --git a/src/efi.h b/src/efi.h
index a622a2b..33579c5 100644
--- a/src/efi.h
+++ b/src/efi.h
@@ -102,7 +102,7 @@ EFI_GUID( 0x47c7b226, 0xc42a, 0x11d2, 0x8e, 0x57, 0x00, 0xa0, 0xc9, 0x69, 0x72,
EFI_GUID( 0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f)
static inline int
-efi_guidcmp(efi_guid_t left, efi_guid_t right)
+efi_guidcmp(const efi_guid_t left, const efi_guid_t right)
{
return memcmp(&left, &right, sizeof (efi_guid_t));
}
diff --git a/src/mokutil.c b/src/mokutil.c
index e4e247c..62690ef 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -157,14 +157,29 @@ test_and_delete_var (const char *var_name)
return 0;
}
+static uint32_t
+signature_size (efi_guid_t hash_type)
+{
+ if (efi_guidcmp (hash_type, EfiHashSha1Guid) == 0)
+ return (SHA_DIGEST_LENGTH + sizeof(efi_guid_t));
+ else if (efi_guidcmp (hash_type, EfiHashSha224Guid) == 0)
+ return (SHA224_DIGEST_LENGTH + sizeof(efi_guid_t));
+ else if (efi_guidcmp (hash_type, EfiHashSha256Guid) == 0)
+ return (SHA256_DIGEST_LENGTH + sizeof(efi_guid_t));
+ else if (efi_guidcmp (hash_type, EfiHashSha384Guid) == 0)
+ return (SHA384_DIGEST_LENGTH + sizeof(efi_guid_t));
+ else if (efi_guidcmp (hash_type, EfiHashSha512Guid) == 0)
+ return (SHA512_DIGEST_LENGTH + sizeof(efi_guid_t));
+
+ return 0;
+}
+
static MokListNode*
build_mok_list (void *data, unsigned long data_size, uint32_t *mok_num)
{
MokListNode *list;
EFI_SIGNATURE_LIST *CertList = data;
EFI_SIGNATURE_DATA *Cert;
- efi_guid_t CertType = EfiCertX509Guid;
- efi_guid_t HashType = EfiHashSha256Guid;
unsigned long dbsize = data_size;
unsigned long count = 0;
@@ -176,16 +191,20 @@ build_mok_list (void *data, unsigned long data_size, uint32_t *mok_num)
}
while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
- if ((efi_guidcmp (CertList->SignatureType, CertType) != 0) &&
- (efi_guidcmp (CertList->SignatureType, HashType) != 0)) {
+ if ((efi_guidcmp (CertList->SignatureType, EfiCertX509Guid) != 0) &&
+ (efi_guidcmp (CertList->SignatureType, EfiHashSha1Guid) != 0) &&
+ (efi_guidcmp (CertList->SignatureType, EfiHashSha224Guid) != 0) &&
+ (efi_guidcmp (CertList->SignatureType, EfiHashSha256Guid) != 0) &&
+ (efi_guidcmp (CertList->SignatureType, EfiHashSha384Guid) != 0) &&
+ (efi_guidcmp (CertList->SignatureType, EfiHashSha512Guid) != 0)) {
dbsize -= CertList->SignatureListSize;
CertList = (EFI_SIGNATURE_LIST *)((uint8_t *) CertList +
CertList->SignatureListSize);
continue;
}
- if ((efi_guidcmp (CertList->SignatureType, HashType) == 0) &&
- (CertList->SignatureSize != 48)) {
+ if ((efi_guidcmp (CertList->SignatureType, EfiCertX509Guid) != 0) &&
+ (CertList->SignatureSize != signature_size (CertList->SignatureType))) {
dbsize -= CertList->SignatureListSize;
CertList = (EFI_SIGNATURE_LIST *)((uint8_t *) CertList +
CertList->SignatureListSize);
@@ -203,8 +222,18 @@ build_mok_list (void *data, unsigned long data_size, uint32_t *mok_num)
}
list[count].header = CertList;
- list[count].mok_size = CertList->SignatureSize - sizeof(efi_guid_t);
- list[count].mok = (void *)Cert->SignatureData;
+ if (efi_guidcmp (CertList->SignatureType, EfiCertX509Guid) == 0) {
+ /* X509 certificate */
+ list[count].mok_size = CertList->SignatureSize -
+ sizeof(efi_guid_t);
+ list[count].mok = (void *)Cert->SignatureData;
+ } else {
+ /* hash array */
+ list[count].mok_size = CertList->SignatureListSize -
+ sizeof(EFI_SIGNATURE_LIST) -
+ CertList->SignatureHeaderSize;
+ list[count].mok = (void *)Cert;
+ }
count++;
dbsize -= CertList->SignatureListSize;
@@ -258,6 +287,64 @@ print_x509 (char *cert, int cert_size)
}
static int
+print_hash_array (efi_guid_t hash_type, void *hash_array, uint32_t array_size)
+{
+ uint32_t hash_size, remain;
+ uint32_t sig_size;
+ uint8_t *hash;
+ const char *name;
+ int i;
+
+ if (!hash_array || array_size == 0) {
+ fprintf (stderr, "invalid hash array\n");
+ return -1;
+ }
+
+ if (efi_guidcmp (hash_type, EfiHashSha1Guid) == 0) {
+ name = "SHA1";
+ hash_size = SHA_DIGEST_LENGTH;
+ } else if (efi_guidcmp (hash_type, EfiHashSha224Guid) == 0) {
+ name = "SHA224";
+ hash_size = SHA224_DIGEST_LENGTH;
+ } else if (efi_guidcmp (hash_type, EfiHashSha256Guid) == 0) {
+ name = "SHA256";
+ hash_size = SHA256_DIGEST_LENGTH;
+ } else if (efi_guidcmp (hash_type, EfiHashSha384Guid) == 0) {
+ name = "SHA384";
+ hash_size = SHA384_DIGEST_LENGTH;
+ } else if (efi_guidcmp (hash_type, EfiHashSha512Guid) == 0) {
+ name = "SHA512";
+ hash_size = SHA512_DIGEST_LENGTH;
+ } else {
+ fprintf (stderr, "unknown hash type\n");
+ return -1;
+ }
+ sig_size = hash_size + sizeof(efi_guid_t);
+
+ printf (" [%s]\n", name);
+
+ remain = array_size;
+ hash = (uint8_t *)hash_array;
+
+ while (remain > 0) {
+ if (remain < sig_size) {
+ fprintf (stderr, "invalid array size\n");
+ return -1;
+ }
+
+ printf (" ");
+ hash += sizeof(efi_guid_t);
+ for (i = 0; i<hash_size; i++)
+ printf ("%02x", *(hash + i));
+ printf ("\n");
+ hash += hash_size;
+ remain -= sig_size;
+ }
+
+ return 0;
+}
+
+static int
list_keys (efi_variable_t *var)
{
uint32_t mok_num;
@@ -271,7 +358,12 @@ list_keys (efi_variable_t *var)
for (i = 0; i < mok_num; i++) {
printf ("[key %d]\n", i+1);
- print_x509 ((char *)list[i].mok, list[i].mok_size);
+ if (efi_guidcmp (list[i].header->SignatureType, EfiCertX509Guid) == 0) {
+ print_x509 ((char *)list[i].mok, list[i].mok_size);
+ } else {
+ print_hash_array (list[i].header->SignatureType,
+ list[i].mok, list[i].mok_size);
+ }
if (i < mok_num - 1)
printf ("\n");
}
diff --git a/src/signature.h b/src/signature.h
index df88e98..02f0211 100644
--- a/src/signature.h
+++ b/src/signature.h
@@ -28,11 +28,17 @@
* version. If you delete this exception statement from all source
* files in the program, then also delete it here.
*/
-#define SHA256_DIGEST_SIZE 32
+#ifndef SIGNATURE_H
+#define SIGNATURE_H
-#define EfiHashSha1Guid EFI_GUID (0x826ca512, 0xcf10, 0x4ac9, 0xb1, 0x87, 0xbe, 0x1, 0x49, 0x66, 0x31, 0xbd)
+#include "efi.h"
+
+#define EfiHashSha1Guid EFI_GUID (0x826ca512, 0xcf10, 0x4ac9, 0xb1, 0x87, 0xbe, 0x1, 0x49, 0x66, 0x31, 0xbd)
+#define EfiHashSha224Guid EFI_GUID (0xb6e5233, 0xa65c, 0x44c9, 0x94, 0x7, 0xd9, 0xab, 0x83, 0xbf, 0xc8, 0xbd)
#define EfiHashSha256Guid EFI_GUID (0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28)
-#define EfiCertX509Guid EFI_GUID (0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72)
+#define EfiHashSha384Guid EFI_GUID (0xff3e5307, 0x9fd0, 0x48c9, 0x85, 0xf1, 0x8a, 0xd5, 0x6c, 0x70, 0x1e, 0x1)
+#define EfiHashSha512Guid EFI_GUID (0x93e0fae, 0xa6c4, 0x4f50, 0x9f, 0x1b, 0xd4, 0x1e, 0x2b, 0x89, 0xc1, 0x9a)
+#define EfiCertX509Guid EFI_GUID (0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72)
typedef struct {
///
@@ -71,3 +77,5 @@ typedef struct {
/// EFI_SIGNATURE_DATA Signatures[][SignatureSize];
///
} __attribute__ ((packed)) EFI_SIGNATURE_LIST;
+
+#endif /* SIGNATURE_H */
--
1.8.4
From 77a215f86139b21fd55dca4d032b7269f62b51c1 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 22 Oct 2013 14:34:21 +0800
Subject: [PATCH 03/20] Don't allocate the MOK list until there is a node
---
src/mokutil.c | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index 62690ef..ec476dd 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -177,19 +177,12 @@ signature_size (efi_guid_t hash_type)
static MokListNode*
build_mok_list (void *data, unsigned long data_size, uint32_t *mok_num)
{
- MokListNode *list;
+ MokListNode *list = NULL;
EFI_SIGNATURE_LIST *CertList = data;
EFI_SIGNATURE_DATA *Cert;
unsigned long dbsize = data_size;
unsigned long count = 0;
- list = malloc(sizeof(MokListNode));
-
- if (!list) {
- fprintf(stderr, "Unable to allocate MOK list\n");
- return NULL;
- }
-
while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
if ((efi_guidcmp (CertList->SignatureType, EfiCertX509Guid) != 0) &&
(efi_guidcmp (CertList->SignatureType, EfiHashSha1Guid) != 0) &&
--
1.8.4
From befae0e92ea24e35208b07786857d195ce8aa086 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 22 Oct 2013 14:40:58 +0800
Subject: [PATCH 04/20] Skip hashes while exporting MokListRT
---
src/mokutil.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/mokutil.c b/src/mokutil.c
index ec476dd..04f7655 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -1119,6 +1119,10 @@ export_moks ()
/* mode 644 */
mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
for (i = 0; i < mok_num; i++) {
+ if (efi_guidcmp (list[i].header->SignatureType, EfiCertX509Guid) != 0)
+ continue;
+
+ /* Dump X509 certificate to files */
snprintf (filename, PATH_MAX, "MOK-%04d.der", i+1);
fd = open (filename, O_CREAT | O_WRONLY, mode);
if (fd == -1) {
--
1.8.4
From 9cfc5f93e15e05dabf46a86e4f8e899e32443176 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 22 Oct 2013 16:05:33 +0800
Subject: [PATCH 05/20] Match the hashes in the database
---
src/mokutil.c | 162 +++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 109 insertions(+), 53 deletions(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index 04f7655..fa5d668 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -157,19 +157,50 @@ test_and_delete_var (const char *var_name)
return 0;
}
+static const char*
+efi_hash_to_string (efi_guid_t hash_type)
+{
+ if (efi_guidcmp (hash_type, EfiHashSha1Guid) == 0) {
+ return "SHA1";
+ } else if (efi_guidcmp (hash_type, EfiHashSha224Guid) == 0) {
+ return "SHA224";
+ } else if (efi_guidcmp (hash_type, EfiHashSha256Guid) == 0) {
+ return "SHA256";
+ } else if (efi_guidcmp (hash_type, EfiHashSha384Guid) == 0) {
+ return "SHA384";
+ } else if (efi_guidcmp (hash_type, EfiHashSha512Guid) == 0) {
+ return "SHA512";
+ }
+
+ return NULL;
+}
+
+static uint32_t
+efi_hash_size (efi_guid_t hash_type)
+{
+ if (efi_guidcmp (hash_type, EfiHashSha1Guid) == 0) {
+ return SHA_DIGEST_LENGTH;
+ } else if (efi_guidcmp (hash_type, EfiHashSha224Guid) == 0) {
+ return SHA224_DIGEST_LENGTH;
+ } else if (efi_guidcmp (hash_type, EfiHashSha256Guid) == 0) {
+ return SHA256_DIGEST_LENGTH;
+ } else if (efi_guidcmp (hash_type, EfiHashSha384Guid) == 0) {
+ return SHA384_DIGEST_LENGTH;
+ } else if (efi_guidcmp (hash_type, EfiHashSha512Guid) == 0) {
+ return SHA512_DIGEST_LENGTH;
+ }
+
+ return 0;
+}
+
static uint32_t
signature_size (efi_guid_t hash_type)
{
- if (efi_guidcmp (hash_type, EfiHashSha1Guid) == 0)
- return (SHA_DIGEST_LENGTH + sizeof(efi_guid_t));
- else if (efi_guidcmp (hash_type, EfiHashSha224Guid) == 0)
- return (SHA224_DIGEST_LENGTH + sizeof(efi_guid_t));
- else if (efi_guidcmp (hash_type, EfiHashSha256Guid) == 0)
- return (SHA256_DIGEST_LENGTH + sizeof(efi_guid_t));
- else if (efi_guidcmp (hash_type, EfiHashSha384Guid) == 0)
- return (SHA384_DIGEST_LENGTH + sizeof(efi_guid_t));
- else if (efi_guidcmp (hash_type, EfiHashSha512Guid) == 0)
- return (SHA512_DIGEST_LENGTH + sizeof(efi_guid_t));
+ uint32_t hash_size;
+
+ hash_size = efi_hash_size (hash_type);
+ if (hash_size)
+ return (hash_size + sizeof(efi_guid_t));
return 0;
}
@@ -293,29 +324,16 @@ print_hash_array (efi_guid_t hash_type, void *hash_array, uint32_t array_size)
return -1;
}
- if (efi_guidcmp (hash_type, EfiHashSha1Guid) == 0) {
- name = "SHA1";
- hash_size = SHA_DIGEST_LENGTH;
- } else if (efi_guidcmp (hash_type, EfiHashSha224Guid) == 0) {
- name = "SHA224";
- hash_size = SHA224_DIGEST_LENGTH;
- } else if (efi_guidcmp (hash_type, EfiHashSha256Guid) == 0) {
- name = "SHA256";
- hash_size = SHA256_DIGEST_LENGTH;
- } else if (efi_guidcmp (hash_type, EfiHashSha384Guid) == 0) {
- name = "SHA384";
- hash_size = SHA384_DIGEST_LENGTH;
- } else if (efi_guidcmp (hash_type, EfiHashSha512Guid) == 0) {
- name = "SHA512";
- hash_size = SHA512_DIGEST_LENGTH;
- } else {
+ name = efi_hash_to_string (hash_type);
+ hash_size = efi_hash_size (hash_type);
+ sig_size = hash_size + sizeof(efi_guid_t);
+
+ if (!name) {
fprintf (stderr, "unknown hash type\n");
return -1;
}
- sig_size = hash_size + sizeof(efi_guid_t);
printf (" [%s]\n", name);
-
remain = array_size;
hash = (uint8_t *)hash_array;
@@ -829,36 +847,78 @@ is_valid_cert (void *cert, uint32_t cert_size)
}
static int
-is_duplicate (const void *cert, const uint32_t cert_size, const char *db_name,
- efi_guid_t guid)
+match_hash_array (efi_guid_t hash_type, const void *hash,
+ const void *hash_array, const uint32_t array_size)
+{
+ uint32_t hash_size, hash_count;
+ uint32_t sig_size;
+ int i;
+ void *ptr;
+
+ hash_size = efi_hash_size (hash_type);
+ if (!hash_size)
+ return 0;
+
+ sig_size = hash_size + sizeof(efi_guid_t);
+ if ((array_size % sig_size) != 0) {
+ fprintf (stderr, "invalid hash array size\n");
+ return 0;
+ }
+
+ ptr = (void *)hash_array;
+ hash_count = array_size / sig_size;
+ for (i = 0; i < hash_count; i++) {
+ ptr += sizeof(efi_guid_t);
+ if (memcmp (ptr, hash, hash_size) == 0)
+ return 1;
+ ptr += hash_size;
+ }
+
+ return 0;
+}
+
+static int
+is_duplicate (efi_guid_t type, const void *data, const uint32_t data_size,
+ efi_guid_t vendor, const char *db_name)
{
efi_variable_t var;
- uint32_t mok_num;
+ uint32_t node_num;
MokListNode *list;
int i, ret = 0;
- if (!cert || cert_size == 0 || !db_name)
+ if (!data || data_size == 0 || !db_name)
return 0;
memset (&var, 0, sizeof(var));
var.VariableName = db_name;
- var.VendorGuid = guid;
+ var.VendorGuid = vendor;
if (read_variable (&var) != EFI_SUCCESS)
return 0;
- list = build_mok_list (var.Data, var.DataSize, &mok_num);
+ list = build_mok_list (var.Data, var.DataSize, &node_num);
if (list == NULL) {
goto done;
}
- for (i = 0; i < mok_num; i++) {
- if (list[i].mok_size != cert_size)
+ for (i = 0; i < node_num; i++) {
+ if (efi_guidcmp (list[i].header->SignatureType, type) != 0)
continue;
- if (memcmp (list[i].mok, cert, cert_size) == 0) {
- ret = 1;
- break;
+ if (efi_guidcmp (type, EfiCertX509Guid) == 0) {
+ if (list[i].mok_size != data_size)
+ continue;
+
+ if (memcmp (list[i].mok, data, data_size) == 0) {
+ ret = 1;
+ break;
+ }
+ } else {
+ if (match_hash_array (type, data, list[i].mok,
+ list[i].mok_size)) {
+ ret = 1;
+ break;
+ }
}
}
@@ -870,19 +930,19 @@ done:
}
static int
-is_valid_request (void *mok, uint32_t mok_size, uint8_t import)
+is_valid_request (efi_guid_t type, void *mok, uint32_t mok_size, uint8_t import)
{
if (import) {
- if (is_duplicate (mok, mok_size, "PK", EFI_GLOBAL_VARIABLE) ||
- is_duplicate (mok, mok_size, "KEK", EFI_GLOBAL_VARIABLE) ||
- is_duplicate (mok, mok_size, "db", EFI_IMAGE_SECURITY_DATABASE_GUID) ||
- is_duplicate (mok, mok_size, "MokListRT", SHIM_LOCK_GUID) ||
- is_duplicate (mok, mok_size, "MokNew", SHIM_LOCK_GUID)) {
+ if (is_duplicate (type, mok, mok_size, EFI_GLOBAL_VARIABLE, "PK") ||
+ is_duplicate (type, mok, mok_size, EFI_GLOBAL_VARIABLE, "KEK") ||
+ is_duplicate (type, mok, mok_size, EFI_IMAGE_SECURITY_DATABASE_GUID, "db") ||
+ is_duplicate (type, mok, mok_size, SHIM_LOCK_GUID, "MokListRT") ||
+ is_duplicate (type, mok, mok_size, SHIM_LOCK_GUID, "MokNew")) {
return 0;
}
} else {
- if (!is_duplicate (mok, mok_size, "MokListRT", SHIM_LOCK_GUID) ||
- is_duplicate (mok, mok_size, "MokDel", SHIM_LOCK_GUID)) {
+ if (!is_duplicate (type, mok, mok_size, SHIM_LOCK_GUID, "MokListRT") ||
+ is_duplicate (type, mok, mok_size, SHIM_LOCK_GUID, "MokDel")) {
return 0;
}
}
@@ -1008,7 +1068,7 @@ issue_mok_request (char **files, uint32_t total, uint8_t import,
files[i]);
}
- if (is_valid_request (ptr, sizes[i], import)) {
+ if (is_valid_request (EfiCertX509Guid, ptr, sizes[i], import)) {
ptr += sizes[i];
real_size += sizes[i] + sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t);
} else if (in_pending_request (ptr, sizes[i], import)) {
@@ -1359,11 +1419,7 @@ test_key (const char *key_file)
goto error;
}
- if (!is_duplicate (key, read_size, "PK", EFI_GLOBAL_VARIABLE) &&
- !is_duplicate (key, read_size, "KEK", EFI_GLOBAL_VARIABLE) &&
- !is_duplicate (key, read_size, "db", EFI_GLOBAL_VARIABLE) &&
- !is_duplicate (key, read_size, "MokListRT", SHIM_LOCK_GUID) &&
- !is_duplicate (key, read_size, "MokNew", SHIM_LOCK_GUID)) {
+ if (!is_valid_request (EfiCertX509Guid, key, read_size, 1)) {
printf ("%s is not enrolled\n", key_file);
ret = 0;
} else {
--
1.8.4
From 9ec6f6836a386d527cf62d6583c3ea5e394f62a5 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 22 Oct 2013 18:01:11 +0800
Subject: [PATCH 06/20] Support MOK blacklist
---
src/mokutil.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 195 insertions(+), 28 deletions(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index fa5d668..f10e6e8 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -79,6 +79,7 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b,
#define SIMPLE_HASH (1 << 17)
#define IGNORE_DB (1 << 18)
#define USE_DB (1 << 19)
+#define MOKX (1 << 20)
#define DEFAULT_CRYPT_METHOD SHA512_BASED
#define DEFAULT_SALT_SIZE SHA512_SALT_MAX
@@ -86,6 +87,13 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b,
static int use_simple_hash;
+typedef enum {
+ DELETE_MOK = 0,
+ ENROLL_MOK,
+ DELETE_BLACKLIST,
+ ENROLL_BLACKLIST
+} MokRequest;
+
typedef struct {
EFI_SIGNATURE_LIST *header;
uint32_t mok_size;
@@ -135,6 +143,10 @@ print_help ()
printf (" --simple-hash\t\t\t\tUse the old password hash method\n");
printf (" \t\t\t\t(For --import, --delete, --password,\n");
printf (" \t\t\t\t --clear-password and --reset)\n");
+ printf (" --mokx\t\t\t\tManipulate the MOK blacklist\n");
+ printf (" \t\t\t\t(For --list-enrolled, --list-new,\n");
+ printf (" \t\t\t\t --list-delete, --import, --delete,\n");
+ printf (" \t\t\t\t --revoke-import, and --revoke-delete)\n");
}
static int
@@ -724,7 +736,7 @@ get_password_from_shadow (pw_crypt_t *pw_crypt)
}
static int
-update_request (void *new_list, int list_len, uint8_t import,
+update_request (void *new_list, int list_len, MokRequest req,
const char *hash_file, const int root_pw)
{
efi_variable_t var;
@@ -739,12 +751,25 @@ update_request (void *new_list, int list_len, uint8_t import,
bzero (&pw_crypt, sizeof(pw_crypt_t));
pw_crypt.method = DEFAULT_CRYPT_METHOD;
- if (import) {
+ switch (req) {
+ case ENROLL_MOK:
req_name = "MokNew";
auth_name = "MokAuth";
- } else {
+ break;
+ case DELETE_MOK:
req_name = "MokDel";
auth_name = "MokDelAuth";
+ break;
+ case ENROLL_BLACKLIST:
+ req_name = "MokXNew";
+ auth_name = "MokXAuth";
+ break;
+ case DELETE_BLACKLIST:
+ req_name = "MokXDel";
+ auth_name = "MokXDelAuth";
+ break;
+ default:
+ return -1;
}
if (hash_file) {
@@ -776,7 +801,7 @@ update_request (void *new_list, int list_len, uint8_t import,
}
if (new_list) {
- /* Write MokNew*/
+ /* Write MokNew, MokDel, MokXNew, or MokXDel*/
var.Data = new_list;
var.DataSize = list_len;
var.VariableName = req_name;
@@ -787,15 +812,27 @@ update_request (void *new_list, int list_len, uint8_t import,
| EFI_VARIABLE_RUNTIME_ACCESS;
if (edit_variable (&var) != EFI_SUCCESS) {
- fprintf (stderr, "Failed to %s keys\n",
- import ? "enroll new" : "delete");
+ switch (req) {
+ case ENROLL_MOK:
+ fprintf (stderr, "Failed to enroll new keys\n");
+ break;
+ case ENROLL_BLACKLIST:
+ fprintf (stderr, "Failed to enroll blacklist\n");
+ break;
+ case DELETE_MOK:
+ fprintf (stderr, "Failed to delete keys\n");
+ break;
+ case DELETE_BLACKLIST:
+ fprintf (stderr, "Failed to delete blacklist\n");
+ break;
+ }
goto error;
}
} else {
test_and_delete_var (req_name);
}
- /* Write MokAuth or MokDelAuth */
+ /* Write MokAuth, MokDelAuth, MokXAuth, or MokXDelAuth */
if (!use_simple_hash) {
var.Data = (void *)&pw_crypt;
var.DataSize = PASSWORD_CRYPT_SIZE;
@@ -930,9 +967,10 @@ done:
}
static int
-is_valid_request (efi_guid_t type, void *mok, uint32_t mok_size, uint8_t import)
+is_valid_request (efi_guid_t type, void *mok, uint32_t mok_size, MokRequest req)
{
- if (import) {
+ switch (req) {
+ case ENROLL_MOK:
if (is_duplicate (type, mok, mok_size, EFI_GLOBAL_VARIABLE, "PK") ||
is_duplicate (type, mok, mok_size, EFI_GLOBAL_VARIABLE, "KEK") ||
is_duplicate (type, mok, mok_size, EFI_IMAGE_SECURITY_DATABASE_GUID, "db") ||
@@ -940,29 +978,63 @@ is_valid_request (efi_guid_t type, void *mok, uint32_t mok_size, uint8_t import)
is_duplicate (type, mok, mok_size, SHIM_LOCK_GUID, "MokNew")) {
return 0;
}
- } else {
+ break;
+ case DELETE_MOK:
if (!is_duplicate (type, mok, mok_size, SHIM_LOCK_GUID, "MokListRT") ||
is_duplicate (type, mok, mok_size, SHIM_LOCK_GUID, "MokDel")) {
return 0;
}
+ break;
+ case ENROLL_BLACKLIST:
+ if (is_duplicate (type, mok, mok_size, SHIM_LOCK_GUID, "MokListXRT") ||
+ is_duplicate (type, mok, mok_size, SHIM_LOCK_GUID, "MokXNew")) {
+ return 0;
+ }
+ break;
+ case DELETE_BLACKLIST:
+ if (!is_duplicate (type, mok, mok_size, SHIM_LOCK_GUID, "MokListXRT") ||
+ is_duplicate (type, mok, mok_size, SHIM_LOCK_GUID, "MokXDel")) {
+ return 0;
+ }
+ break;
}
return 1;
}
static int
-in_pending_request (void *mok, uint32_t mok_size, uint8_t import)
+in_pending_request (void *mok, uint32_t mok_size, MokRequest req)
{
efi_variable_t authvar;
- const char *var_name = import ? "MokDel" : "MokNew";
+ const char *var_name;
if (!mok || mok_size == 0)
return 0;
memset (&authvar, 0, sizeof(authvar));
- authvar.VariableName = import ? "MokDelAuth" : "MokAuth";
authvar.VendorGuid = SHIM_LOCK_GUID;
+ switch (req) {
+ case ENROLL_MOK:
+ var_name = "MokDel";
+ authvar.VariableName = "MokDelAuth";
+ break;
+ case DELETE_MOK:
+ var_name = "MokNew";
+ authvar.VariableName = "MokAuth";
+ break;
+ case ENROLL_BLACKLIST:
+ var_name = "MokXDel";
+ authvar.VariableName = "MokXDelAuth";
+ break;
+ case DELETE_BLACKLIST:
+ var_name = "MokXNew";
+ authvar.VariableName = "MokXAuth";
+ break;
+ default:
+ return 0;
+ }
+
if (read_variable (&authvar) != EFI_SUCCESS) {
return 0;
}
@@ -979,7 +1051,7 @@ in_pending_request (void *mok, uint32_t mok_size, uint8_t import)
}
static int
-issue_mok_request (char **files, uint32_t total, uint8_t import,
+issue_mok_request (char **files, uint32_t total, MokRequest req,
const char *hash_file, const int root_pw)
{
efi_variable_t old_req;
@@ -999,7 +1071,22 @@ issue_mok_request (char **files, uint32_t total, uint8_t import,
if (!files)
return -1;
- req_name = import ? "MokNew" : "MokDel";
+ switch (req) {
+ case ENROLL_MOK:
+ req_name = "MokNew";
+ break;
+ case DELETE_MOK:
+ req_name = "MokDel";
+ break;
+ case ENROLL_BLACKLIST:
+ req_name = "MokXNew";
+ break;
+ case DELETE_BLACKLIST:
+ req_name = "MokXDel";
+ break;
+ default:
+ return -1;
+ }
sizes = malloc (total * sizeof(uint32_t));
@@ -1068,11 +1155,29 @@ issue_mok_request (char **files, uint32_t total, uint8_t import,
files[i]);
}
- if (is_valid_request (EfiCertX509Guid, ptr, sizes[i], import)) {
+ if (is_valid_request (EfiCertX509Guid, ptr, sizes[i], req)) {
ptr += sizes[i];
real_size += sizes[i] + sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t);
- } else if (in_pending_request (ptr, sizes[i], import)) {
- printf ("Removed %s from %s\n", files[i], import ? "MokDel" : "MokNew");
+ } else if (in_pending_request (ptr, sizes[i], req)) {
+ const char *pending;
+ switch (req) {
+ case ENROLL_MOK:
+ pending = "MokDel";
+ break;
+ case DELETE_MOK:
+ pending = "MokNew";
+ break;
+ case ENROLL_BLACKLIST:
+ pending = "MokXDel";
+ break;
+ case DELETE_BLACKLIST:
+ pending = "MokXNew";
+ break;
+ default:
+ pending = "";
+ break;
+ }
+ printf ("Removed %s from %s\n", files[i], pending);
ptr -= sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t);
} else {
@@ -1095,7 +1200,7 @@ issue_mok_request (char **files, uint32_t total, uint8_t import,
real_size += old_req.DataSize;
}
- if (update_request (new_list, real_size, import, hash_file, root_pw) < 0) {
+ if (update_request (new_list, real_size, req, hash_file, root_pw) < 0) {
goto error;
}
@@ -1115,29 +1220,58 @@ static int
import_moks (char **files, uint32_t total, const char *hash_file,
const int root_pw)
{
- return issue_mok_request (files, total, 1, hash_file, root_pw);
+ return issue_mok_request (files, total, ENROLL_MOK, hash_file, root_pw);
}
static int
delete_moks (char **files, uint32_t total, const char *hash_file,
const int root_pw)
{
- return issue_mok_request (files, total, 0, hash_file, root_pw);
+ return issue_mok_request (files, total, DELETE_MOK, hash_file, root_pw);
}
static int
-revoke_request (uint8_t import)
+import_blacklist (char **files, uint32_t total, const char *hash_file,
+ const int root_pw)
{
- if (import == 1) {
+ return issue_mok_request (files, total, ENROLL_BLACKLIST, hash_file, root_pw);
+}
+
+static int
+delete_blacklist (char **files, uint32_t total, const char *hash_file,
+ const int root_pw)
+{
+ return issue_mok_request (files, total, DELETE_BLACKLIST, hash_file, root_pw);
+}
+
+static int
+revoke_request (MokRequest req)
+{
+ switch (req) {
+ case ENROLL_MOK:
if (test_and_delete_var ("MokNew") < 0)
return -1;
if (test_and_delete_var ("MokAuth") < 0)
return -1;
- } else {
+ break;
+ case DELETE_MOK:
if (test_and_delete_var ("MokDel") < 0)
return -1;
if (test_and_delete_var ("MokDelAuth") < 0)
return -1;
+ break;
+ case ENROLL_BLACKLIST:
+ if (test_and_delete_var ("MokXNew") < 0)
+ return -1;
+ if (test_and_delete_var ("MokXAuth") < 0)
+ return -1;
+ break;
+ case DELETE_BLACKLIST:
+ if (test_and_delete_var ("MokXDel") < 0)
+ return -1;
+ if (test_and_delete_var ("MokXDelAuth") < 0)
+ return -1;
+ break;
}
return 0;
@@ -1419,7 +1553,7 @@ test_key (const char *key_file)
goto error;
}
- if (!is_valid_request (EfiCertX509Guid, key, read_size, 1)) {
+ if (!is_valid_request (EfiCertX509Guid, key, read_size, ENROLL_MOK)) {
printf ("%s is not enrolled\n", key_file);
ret = 0;
} else {
@@ -1440,7 +1574,7 @@ error:
static int
reset_moks (const char *hash_file, const int root_pw)
{
- if (update_request (NULL, 0, 1, hash_file, root_pw)) {
+ if (update_request (NULL, 0, ENROLL_MOK, hash_file, root_pw)) {
fprintf (stderr, "Failed to issue a reset request\n");
return -1;
}
@@ -1539,6 +1673,7 @@ main (int argc, char *argv[])
{"simple-hash", no_argument, 0, 's'},
{"ignore-db", no_argument, 0, 0 },
{"use-db", no_argument, 0, 0 },
+ {"mokx", no_argument, 0, 0 },
{0, 0, 0, 0}
};
@@ -1574,6 +1709,8 @@ main (int argc, char *argv[])
command |= IGNORE_DB;
} else if (strcmp (option, "use-db") == 0) {
command |= USE_DB;
+ } else if (strcmp (option, "mokx") == 0) {
+ command |= MOKX;
}
break;
case 'd':
@@ -1683,10 +1820,10 @@ main (int argc, char *argv[])
ret = delete_moks (files, total, hash_file, 0);
break;
case REVOKE_IMPORT:
- ret = revoke_request (1);
+ ret = revoke_request (ENROLL_MOK);
break;
case REVOKE_DELETE:
- ret = revoke_request (0);
+ ret = revoke_request (DELETE_MOK);
break;
case EXPORT:
ret = export_moks ();
@@ -1730,6 +1867,36 @@ main (int argc, char *argv[])
case USE_DB:
ret = enable_db ();
break;
+ case LIST_ENROLLED | MOKX:
+ ret = list_keys_in_var ("MokListXRT");
+ break;
+ case LIST_NEW | MOKX:
+ ret = list_keys_in_var ("MokXNew");
+ break;
+ case LIST_DELETE | MOKX:
+ ret = list_keys_in_var ("MokXDel");
+ break;
+ case IMPORT | MOKX:
+ case IMPORT | SIMPLE_HASH | MOKX:
+ if (use_root_pw)
+ ret = import_blacklist (files, total, NULL, 1);
+ else
+ ret = import_blacklist (files, total, hash_file, 0);
+ break;
+ case DELETE | MOKX:
+ case DELETE | SIMPLE_HASH | MOKX:
+ if (use_root_pw)
+ ret = delete_blacklist (files, total, NULL, 1);
+ else
+ ret = delete_blacklist (files, total, hash_file, 0);
+ break;
+ case REVOKE_IMPORT | MOKX:
+ ret = revoke_request (ENROLL_BLACKLIST);
+ break;
+ case REVOKE_DELETE | MOKX:
+ ret = revoke_request (DELETE_BLACKLIST);
+ break;
+
default:
print_help ();
break;
--
1.8.4
From 73c2a558b6fa9fb42526d4d2ac5c7db40d402c8f Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Wed, 23 Oct 2013 10:41:58 +0800
Subject: [PATCH 07/20] Fix the memory leakage
---
src/mokutil.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/mokutil.c b/src/mokutil.c
index f10e6e8..bcc12ca 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -1746,10 +1746,18 @@ main (int argc, char *argv[])
break;
case 'f':
+ if (hash_file) {
+ command |= HELP;
+ break;
+ }
hash_file = strdup (optarg);
break;
case 'g':
+ if (input_pw) {
+ command |= HELP;
+ break;
+ }
if (optarg)
input_pw = strdup (optarg);
@@ -1765,6 +1773,10 @@ main (int argc, char *argv[])
use_root_pw = 1;
break;
case 't':
+ if (key_file) {
+ command |= HELP;
+ break;
+ }
key_file = strdup (optarg);
if (key_file == NULL) {
fprintf (stderr, "Could not allocate space: %m\n");
--
1.8.4
From 62162fc5a5c33c987e4b8106a9e98c3abf8288ae Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Wed, 23 Oct 2013 17:29:53 +0800
Subject: [PATCH 08/20] Support import and delete a hash
---
src/mokutil.c | 424 ++++++++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 322 insertions(+), 102 deletions(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index bcc12ca..b8edf74 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -80,6 +80,8 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b,
#define IGNORE_DB (1 << 18)
#define USE_DB (1 << 19)
#define MOKX (1 << 20)
+#define IMPORT_HASH (1 << 21)
+#define DELETE_HASH (1 << 22)
#define DEFAULT_CRYPT_METHOD SHA512_BASED
#define DEFAULT_SALT_SIZE SHA512_SALT_MAX
@@ -132,21 +134,27 @@ print_help ()
printf (" --generate-hash[=password]\t\tGenerate the password hash\n");
printf (" --ignore-db\t\t\t\tIgnore DB for validation\n");
printf (" --use-db\t\t\t\tUse DB for validation\n");
+ printf (" --import-hash <hash>\t\t\tImport a hash\n");
+ printf (" --delete-hash <hash>\t\t\tDelete a specific hash\n");
printf ("\n");
printf ("Supplimentary Options:\n");
printf (" --hash-file <hash file>\t\tUse the specific password hash\n");
printf (" \t\t(For --import, --delete, --password,\n");
- printf (" \t\t and --reset)\n");
+ printf (" \t\t --reset, --import-hash,\n");
+ printf (" \t\t and --delete-hash)\n");
printf (" --root-pw\t\t\t\tUse the root password\n");
printf (" \t\t\t\t(For --import, --delete, --password,\n");
- printf (" \t\t\t\t and --reset)\n");
+ printf (" \t\t\t\t --reset, --import-hash,\n");
+ printf (" \t\t\t\t and --delete-hash)\n");
printf (" --simple-hash\t\t\t\tUse the old password hash method\n");
printf (" \t\t\t\t(For --import, --delete, --password,\n");
- printf (" \t\t\t\t --clear-password and --reset)\n");
+ printf (" \t\t\t\t --clear-password, --reset,\n");
+ printf (" \t\t\t\t --import-hash, and --delete-hash)\n");
printf (" --mokx\t\t\t\tManipulate the MOK blacklist\n");
printf (" \t\t\t\t(For --list-enrolled, --list-new,\n");
printf (" \t\t\t\t --list-delete, --import, --delete,\n");
- printf (" \t\t\t\t --revoke-import, and --revoke-delete)\n");
+ printf (" \t\t\t\t --revoke-import, --revoke-delete,\n");
+ printf (" \t\t\t\t --import-hash, and --delete-hash)\n");
}
static int
@@ -396,17 +404,50 @@ list_keys (efi_variable_t *var)
return 0;
}
+/* match the hash in the hash array and return the index if matched */
static int
-delete_key_from_list (void *mok, uint32_t mok_size,
- const char *var_name, efi_guid_t guid)
+match_hash_array (efi_guid_t hash_type, const void *hash,
+ const void *hash_array, const uint32_t array_size)
+{
+ uint32_t hash_size, hash_count;
+ uint32_t sig_size;
+ int i;
+ void *ptr;
+
+ hash_size = efi_hash_size (hash_type);
+ if (!hash_size)
+ return -1;
+
+ sig_size = hash_size + sizeof(efi_guid_t);
+ if ((array_size % sig_size) != 0) {
+ fprintf (stderr, "invalid hash array size\n");
+ return -1;
+ }
+
+ ptr = (void *)hash_array;
+ hash_count = array_size / sig_size;
+ for (i = 0; i < hash_count; i++) {
+ ptr += sizeof(efi_guid_t);
+ if (memcmp (ptr, hash, hash_size) == 0)
+ return i;
+ ptr += hash_size;
+ }
+
+ return -1;
+}
+
+static int
+delete_data_from_list (efi_guid_t type, void *data, uint32_t data_size,
+ const char *var_name, efi_guid_t guid)
{
efi_variable_t var;
MokListNode *list;
uint32_t mok_num, total, remain;
- void *ptr, *data = NULL;
+ void *end, *start = NULL;
int i, del_ind, ret = 0;
+ uint32_t sig_list_size, sig_size;
- if (!var_name || !mok || mok_size == 0)
+ if (!var_name || !data || data_size == 0)
return 0;
memset (&var, 0, sizeof(var));
@@ -422,30 +463,56 @@ delete_key_from_list (void *mok, uint32_t mok_size,
if (list == NULL)
goto done;
+ remain = total;
for (i = 0; i < mok_num; i++) {
- if (list[i].mok_size != mok_size)
+ remain -= list[i].header->SignatureListSize;
+ if (efi_guidcmp (list[i].header->SignatureType, type) != 0)
continue;
- if (memcmp (list[i].mok, mok, mok_size) == 0) {
- /* Remove this key */
- del_ind = i;
- data = (void *)list[i].header;
- ptr = data + list[i].header->SignatureListSize;
- total -= list[i].header->SignatureListSize;
+ sig_list_size = list[i].header->SignatureListSize;
+
+ if (efi_guidcmp (type, EfiCertX509Guid) == 0) {
+ if (list[i].mok_size != data_size)
+ continue;
+
+ if (memcmp (list[i].mok, data, data_size) == 0) {
+ /* Remove this key */
+ start = (void *)list[i].header;
+ end = start + sig_list_size;
+ total -= sig_list_size;
+ break;
+ }
+ } else {
+ del_ind = match_hash_array (type, data, list[i].mok,
+ list[i].mok_size);
+ if (del_ind < 0)
+ continue;
+
+ start = (void *)list[i].header;
+ sig_size = signature_size (type);
+ if (sig_list_size == (sizeof(EFI_SIGNATURE_LIST) + sig_size)) {
+ /* Only one hash in the list */
+ end = start + sig_list_size;
+ total -= sig_list_size;
+ } else {
+ /* More than one hash in the list */
+ start += sizeof(EFI_SIGNATURE_LIST) + sig_size * del_ind;
+ end = start + sig_size;
+ total -= sig_size;
+ remain += sig_list_size - sizeof(EFI_SIGNATURE_LIST) -
+ (del_ind + 1) * sig_size;
+ }
break;
}
}
- /* the key is not in this list */
- if (data == NULL)
+ /* the key or hash is not in this list */
+ if (start == NULL)
return 0;
- /* Move the rest of the keys */
- remain = 0;
- for (i = del_ind + 1; i < mok_num; i++)
- remain += list[i].header->SignatureListSize;
+ /* remove the key or hash */
if (remain > 0)
- memmove (data, ptr, remain);
+ memmove (start, end, remain);
var.DataSize = total;
var.Attributes = EFI_VARIABLE_NON_VOLATILE
@@ -459,7 +526,8 @@ delete_key_from_list (void *mok, uint32_t mok_size,
ret = 1;
done:
- free (list);
+ if (list)
+ free (list);
free (var.Data);
return ret;
@@ -884,37 +952,6 @@ is_valid_cert (void *cert, uint32_t cert_size)
}
static int
-match_hash_array (efi_guid_t hash_type, const void *hash,
- const void *hash_array, const uint32_t array_size)
-{
- uint32_t hash_size, hash_count;
- uint32_t sig_size;
- int i;
- void *ptr;
-
- hash_size = efi_hash_size (hash_type);
- if (!hash_size)
- return 0;
-
- sig_size = hash_size + sizeof(efi_guid_t);
- if ((array_size % sig_size) != 0) {
- fprintf (stderr, "invalid hash array size\n");
- return 0;
- }
-
- ptr = (void *)hash_array;
- hash_count = array_size / sig_size;
- for (i = 0; i < hash_count; i++) {
- ptr += sizeof(efi_guid_t);
- if (memcmp (ptr, hash, hash_size) == 0)
- return 1;
- ptr += hash_size;
- }
-
- return 0;
-}
-
-static int
is_duplicate (efi_guid_t type, const void *data, const uint32_t data_size,
efi_guid_t vendor, const char *db_name)
{
@@ -952,7 +989,7 @@ is_duplicate (efi_guid_t type, const void *data, const uint32_t data_size,
}
} else {
if (match_hash_array (type, data, list[i].mok,
- list[i].mok_size)) {
+ list[i].mok_size) >= 0) {
ret = 1;
break;
}
@@ -960,7 +997,8 @@ is_duplicate (efi_guid_t type, const void *data, const uint32_t data_size,
}
done:
- free (list);
+ if (list)
+ free (list);
free (var.Data);
return ret;
@@ -1003,12 +1041,13 @@ is_valid_request (efi_guid_t type, void *mok, uint32_t mok_size, MokRequest req)
}
static int
-in_pending_request (void *mok, uint32_t mok_size, MokRequest req)
+in_pending_request (efi_guid_t type, void *data, uint32_t data_size,
+ MokRequest req)
{
efi_variable_t authvar;
const char *var_name;
- if (!mok || mok_size == 0)
+ if (!data || data_size == 0)
return 0;
memset (&authvar, 0, sizeof(authvar));
@@ -1044,8 +1083,9 @@ in_pending_request (void *mok, uint32_t mok_size, MokRequest req)
if (authvar.DataSize == SHA256_DIGEST_LENGTH)
return 0;
- if (delete_key_from_list (mok, mok_size, var_name, SHIM_LOCK_GUID))
- return 1;
+ if (delete_data_from_list (type, data, data_size, var_name,
+ SHIM_LOCK_GUID))
+ return 1;
return 0;
}
@@ -1158,7 +1198,7 @@ issue_mok_request (char **files, uint32_t total, MokRequest req,
if (is_valid_request (EfiCertX509Guid, ptr, sizes[i], req)) {
ptr += sizes[i];
real_size += sizes[i] + sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t);
- } else if (in_pending_request (ptr, sizes[i], req)) {
+ } else if (in_pending_request (EfiCertX509Guid, ptr, sizes[i], req)) {
const char *pending;
switch (req) {
case ENROLL_MOK:
@@ -1217,31 +1257,186 @@ error:
}
static int
-import_moks (char **files, uint32_t total, const char *hash_file,
- const int root_pw)
+identify_hash_type (const char *hash_str, efi_guid_t *type)
{
- return issue_mok_request (files, total, ENROLL_MOK, hash_file, root_pw);
-}
+ int len = strlen (hash_str);
+ int hash_size;
+ int i;
-static int
-delete_moks (char **files, uint32_t total, const char *hash_file,
- const int root_pw)
-{
- return issue_mok_request (files, total, DELETE_MOK, hash_file, root_pw);
+ for (i = 0; i < len; i++) {
+ if ((hash_str[i] > '9' || hash_str[i] < '0') &&
+ (hash_str[i] > 'f' || hash_str[i] < 'a') &&
+ (hash_str[i] > 'F' || hash_str[i] < 'A'))
+ return -1;
+ }
+
+ switch (len) {
+ case SHA_DIGEST_LENGTH*2:
+ *type = EfiHashSha1Guid;
+ hash_size = SHA_DIGEST_LENGTH;
+ break;
+ case SHA224_DIGEST_LENGTH*2:
+ *type = EfiHashSha224Guid;
+ hash_size = SHA224_DIGEST_LENGTH;
+ break;
+ case SHA256_DIGEST_LENGTH*2:
+ *type = EfiHashSha256Guid;
+ hash_size = SHA256_DIGEST_LENGTH;
+ break;
+ case SHA384_DIGEST_LENGTH*2:
+ *type = EfiHashSha384Guid;
+ hash_size = SHA384_DIGEST_LENGTH;
+ break;
+ case SHA512_DIGEST_LENGTH*2:
+ *type = EfiHashSha512Guid;
+ hash_size = SHA512_DIGEST_LENGTH;
+ break;
+ default:
+ return -1;
+ }
+
+ return hash_size;
}
static int
-import_blacklist (char **files, uint32_t total, const char *hash_file,
- const int root_pw)
+hex_str_to_binary (const char *hex_str, uint8_t *array, int len)
{
- return issue_mok_request (files, total, ENROLL_BLACKLIST, hash_file, root_pw);
+ char *pos;
+ int i;
+
+ if (!hex_str || !array)
+ return -1;
+
+ pos = (char *)hex_str;
+ for (i = 0; i < len; i++) {
+ sscanf (pos, "%2hhx", &array[i]);
+ pos += 2;
+ }
+
+ return 0;
}
static int
-delete_blacklist (char **files, uint32_t total, const char *hash_file,
- const int root_pw)
+issue_hash_request (const char *hash_str, MokRequest req,
+ const char *hash_file, const int root_pw)
{
- return issue_mok_request (files, total, DELETE_BLACKLIST, hash_file, root_pw);
+ efi_variable_t old_req;
+ const char *req_name;
+ void *new_list = NULL;
+ void *ptr;
+ unsigned long list_size = 0;
+ uint32_t sig_list_size;
+ int ret = -1;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_DATA *CertData;
+ efi_guid_t hash_type;
+ uint8_t db_hash[SHA512_DIGEST_LENGTH];
+ int hash_size;
+ uint8_t valid = 0;
+
+ if (!hash_str)
+ return -1;
+
+ hash_size = identify_hash_type (hash_str, &hash_type);
+ if (hash_size < 0)
+ return -1;
+
+ if (hex_str_to_binary (hash_str, db_hash, hash_size) < 0)
+ return -1;
+
+ switch (req) {
+ case ENROLL_MOK:
+ req_name = "MokNew";
+ break;
+ case DELETE_MOK:
+ req_name = "MokDel";
+ break;
+ case ENROLL_BLACKLIST:
+ req_name = "MokXNew";
+ break;
+ case DELETE_BLACKLIST:
+ req_name = "MokXDel";
+ break;
+ default:
+ return -1;
+ }
+
+ sig_list_size = sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t) + hash_size;
+ list_size += sig_list_size;
+
+ memset (&old_req, 0, sizeof(old_req));
+
+ old_req.VariableName = req_name;
+ old_req.VendorGuid = SHIM_LOCK_GUID;
+ if (read_variable (&old_req) == EFI_SUCCESS)
+ list_size += old_req.DataSize;
+
+ new_list = malloc (list_size);
+ if (!new_list) {
+ fprintf (stderr, "Failed to allocate space for %s\n", req_name);
+ goto error;
+ }
+ ptr = new_list;
+
+ CertList = ptr;
+ CertList->SignatureType = hash_type;
+ CertList->SignatureListSize = sig_list_size;
+ CertList->SignatureHeaderSize = 0;
+ CertList->SignatureSize = hash_size + sizeof(efi_guid_t);
+
+ CertData = (EFI_SIGNATURE_DATA *)(((uint8_t *)ptr) +
+ sizeof(EFI_SIGNATURE_LIST));
+ CertData->SignatureOwner = SHIM_LOCK_GUID;
+ memcpy (CertData->SignatureData, db_hash, hash_size);
+
+ if (is_valid_request (hash_type, db_hash, hash_size, req)) {
+ valid = 1;
+ } else if (in_pending_request (hash_type, db_hash, hash_size, req)) {
+ const char *pending;
+ switch (req) {
+ case ENROLL_MOK:
+ pending = "MokDel";
+ break;
+ case DELETE_MOK:
+ pending = "MokNew";
+ break;
+ case ENROLL_BLACKLIST:
+ pending = "MokXDel";
+ break;
+ case DELETE_BLACKLIST:
+ pending = "MokXNew";
+ break;
+ default:
+ pending = "";
+ break;
+ }
+ printf ("Removed hash from %s\n", pending);
+ } else {
+ printf ("Skip hash\n");
+ }
+
+ if (!valid) {
+ ret = 0;
+ goto error;
+ }
+
+ /* append the keys to the previous request */
+ if (old_req.Data) {
+ memcpy (new_list + sig_list_size, old_req.Data, old_req.DataSize);
+ }
+
+ if (update_request (new_list, list_size, req, hash_file, root_pw) < 0) {
+ goto error;
+ }
+
+ ret = 0;
+error:
+ if (old_req.Data)
+ free (old_req.Data);
+ if (new_list)
+ free (new_list);
+
+ return ret;
}
static int
@@ -1641,6 +1836,7 @@ main (int argc, char *argv[])
char *key_file = NULL;
char *hash_file = NULL;
char *input_pw = NULL;
+ char *hash_str = NULL;
const char *option;
int c, i, f_ind, total = 0;
unsigned int command = 0;
@@ -1674,6 +1870,8 @@ main (int argc, char *argv[])
{"ignore-db", no_argument, 0, 0 },
{"use-db", no_argument, 0, 0 },
{"mokx", no_argument, 0, 0 },
+ {"import-hash", required_argument, 0, 0 },
+ {"delete-hash", required_argument, 0, 0 },
{0, 0, 0, 0}
};
@@ -1711,6 +1909,20 @@ main (int argc, char *argv[])
command |= USE_DB;
} else if (strcmp (option, "mokx") == 0) {
command |= MOKX;
+ } else if (strcmp (option, "import-hash") == 0) {
+ command |= IMPORT_HASH;
+ if (hash_str) {
+ command |= HELP;
+ break;
+ }
+ hash_str = strdup (optarg);
+ } else if (strcmp (option, "delete-hash") == 0) {
+ command |= DELETE_HASH;
+ if (hash_str) {
+ command |= HELP;
+ break;
+ }
+ hash_str = strdup (optarg);
}
break;
case 'd':
@@ -1802,7 +2014,7 @@ main (int argc, char *argv[])
}
if (use_root_pw == 1 && use_simple_hash == 1)
- use_simple_hash = 0;;
+ use_simple_hash = 0;
if (hash_file && use_root_pw)
command |= HELP;
@@ -1819,17 +2031,23 @@ main (int argc, char *argv[])
break;
case IMPORT:
case IMPORT | SIMPLE_HASH:
- if (use_root_pw)
- ret = import_moks (files, total, NULL, 1);
- else
- ret = import_moks (files, total, hash_file, 0);
+ ret = issue_mok_request (files, total, ENROLL_MOK,
+ hash_file, use_root_pw);
break;
case DELETE:
case DELETE | SIMPLE_HASH:
- if (use_root_pw)
- ret = delete_moks (files, total, NULL, 1);
- else
- ret = delete_moks (files, total, hash_file, 0);
+ ret = issue_mok_request (files, total, DELETE_MOK,
+ hash_file, use_root_pw);
+ break;
+ case IMPORT_HASH:
+ case IMPORT_HASH | SIMPLE_HASH:
+ ret = issue_hash_request (hash_str, ENROLL_MOK,
+ hash_file, use_root_pw);
+ break;
+ case DELETE_HASH:
+ case DELETE_HASH | SIMPLE_HASH:
+ ret = issue_hash_request (hash_str, DELETE_MOK,
+ hash_file, use_root_pw);
break;
case REVOKE_IMPORT:
ret = revoke_request (ENROLL_MOK);
@@ -1842,10 +2060,7 @@ main (int argc, char *argv[])
break;
case PASSWORD:
case PASSWORD | SIMPLE_HASH:
- if (use_root_pw)
- ret = set_password (NULL, 1, 0);
- else
- ret = set_password (hash_file, 0, 0);
+ ret = set_password (hash_file, use_root_pw, 0);
break;
case CLEAR_PASSWORD:
case CLEAR_PASSWORD | SIMPLE_HASH:
@@ -1865,10 +2080,7 @@ main (int argc, char *argv[])
break;
case RESET:
case RESET | SIMPLE_HASH:
- if (use_root_pw)
- ret = reset_moks (NULL, 1);
- else
- ret = reset_moks (hash_file, 0);
+ ret = reset_moks (hash_file, use_root_pw);
break;
case GENERATE_PW_HASH:
ret = generate_pw_hash (input_pw);
@@ -1890,17 +2102,23 @@ main (int argc, char *argv[])
break;
case IMPORT | MOKX:
case IMPORT | SIMPLE_HASH | MOKX:
- if (use_root_pw)
- ret = import_blacklist (files, total, NULL, 1);
- else
- ret = import_blacklist (files, total, hash_file, 0);
+ ret = issue_mok_request (files, total, ENROLL_BLACKLIST,
+ hash_file, use_root_pw);
break;
case DELETE | MOKX:
case DELETE | SIMPLE_HASH | MOKX:
- if (use_root_pw)
- ret = delete_blacklist (files, total, NULL, 1);
- else
- ret = delete_blacklist (files, total, hash_file, 0);
+ ret = issue_mok_request (files, total, DELETE_BLACKLIST,
+ hash_file, use_root_pw);
+ break;
+ case IMPORT_HASH | MOKX:
+ case IMPORT_HASH | SIMPLE_HASH | MOKX:
+ ret = issue_hash_request (hash_str, ENROLL_BLACKLIST,
+ hash_file, use_root_pw);
+ break;
+ case DELETE_HASH | MOKX:
+ case DELETE_HASH | SIMPLE_HASH | MOKX:
+ ret = issue_hash_request (hash_str, DELETE_BLACKLIST,
+ hash_file, use_root_pw);
break;
case REVOKE_IMPORT | MOKX:
ret = revoke_request (ENROLL_BLACKLIST);
@@ -1908,7 +2126,6 @@ main (int argc, char *argv[])
case REVOKE_DELETE | MOKX:
ret = revoke_request (DELETE_BLACKLIST);
break;
-
default:
print_help ();
break;
@@ -1929,5 +2146,8 @@ main (int argc, char *argv[])
if (input_pw)
free (input_pw);
+ if (hash_str)
+ free (hash_str);
+
return ret;
}
--
1.8.4
From e852519aad00c669716c76db8908b89c6b5583e1 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Wed, 23 Oct 2013 17:42:05 +0800
Subject: [PATCH 09/20] Reorganize issue_*_request
---
src/mokutil.c | 75 +++++++++++++++++++----------------------------------------
1 file changed, 24 insertions(+), 51 deletions(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index b8edf74..862cfbf 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -1096,6 +1096,7 @@ issue_mok_request (char **files, uint32_t total, MokRequest req,
{
efi_variable_t old_req;
const char *req_name;
+ const char *reverse_req;
void *new_list = NULL;
void *ptr;
struct stat buf;
@@ -1114,15 +1115,19 @@ issue_mok_request (char **files, uint32_t total, MokRequest req,
switch (req) {
case ENROLL_MOK:
req_name = "MokNew";
+ reverse_req = "MokDel";
break;
case DELETE_MOK:
req_name = "MokDel";
+ reverse_req = "MokNew";
break;
case ENROLL_BLACKLIST:
req_name = "MokXNew";
+ reverse_req = "MokXDel";
break;
case DELETE_BLACKLIST:
req_name = "MokXDel";
+ reverse_req = "MokXNew";
break;
default:
return -1;
@@ -1199,26 +1204,7 @@ issue_mok_request (char **files, uint32_t total, MokRequest req,
ptr += sizes[i];
real_size += sizes[i] + sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t);
} else if (in_pending_request (EfiCertX509Guid, ptr, sizes[i], req)) {
- const char *pending;
- switch (req) {
- case ENROLL_MOK:
- pending = "MokDel";
- break;
- case DELETE_MOK:
- pending = "MokNew";
- break;
- case ENROLL_BLACKLIST:
- pending = "MokXDel";
- break;
- case DELETE_BLACKLIST:
- pending = "MokXNew";
- break;
- default:
- pending = "";
- break;
- }
- printf ("Removed %s from %s\n", files[i], pending);
-
+ printf ("Removed %s from %s\n", files[i], reverse_req);
ptr -= sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t);
} else {
printf ("Skip %s\n", files[i]);
@@ -1322,6 +1308,7 @@ issue_hash_request (const char *hash_str, MokRequest req,
{
efi_variable_t old_req;
const char *req_name;
+ const char *reverse_req;
void *new_list = NULL;
void *ptr;
unsigned long list_size = 0;
@@ -1347,20 +1334,37 @@ issue_hash_request (const char *hash_str, MokRequest req,
switch (req) {
case ENROLL_MOK:
req_name = "MokNew";
+ reverse_req = "MokDel";
break;
case DELETE_MOK:
req_name = "MokDel";
+ reverse_req = "MokNew";
break;
case ENROLL_BLACKLIST:
req_name = "MokXNew";
+ reverse_req = "MokXDel";
break;
case DELETE_BLACKLIST:
req_name = "MokXDel";
+ reverse_req = "MokXNew";
break;
default:
return -1;
}
+ if (is_valid_request (hash_type, db_hash, hash_size, req)) {
+ valid = 1;
+ } else if (in_pending_request (hash_type, db_hash, hash_size, req)) {
+ printf ("Removed hash from %s\n", reverse_req);
+ } else {
+ printf ("Skip hash\n");
+ }
+
+ if (!valid) {
+ ret = 0;
+ goto error;
+ }
+
sig_list_size = sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t) + hash_size;
list_size += sig_list_size;
@@ -1389,37 +1393,6 @@ issue_hash_request (const char *hash_str, MokRequest req,
CertData->SignatureOwner = SHIM_LOCK_GUID;
memcpy (CertData->SignatureData, db_hash, hash_size);
- if (is_valid_request (hash_type, db_hash, hash_size, req)) {
- valid = 1;
- } else if (in_pending_request (hash_type, db_hash, hash_size, req)) {
- const char *pending;
- switch (req) {
- case ENROLL_MOK:
- pending = "MokDel";
- break;
- case DELETE_MOK:
- pending = "MokNew";
- break;
- case ENROLL_BLACKLIST:
- pending = "MokXDel";
- break;
- case DELETE_BLACKLIST:
- pending = "MokXNew";
- break;
- default:
- pending = "";
- break;
- }
- printf ("Removed hash from %s\n", pending);
- } else {
- printf ("Skip hash\n");
- }
-
- if (!valid) {
- ret = 0;
- goto error;
- }
-
/* append the keys to the previous request */
if (old_req.Data) {
memcpy (new_list + sig_list_size, old_req.Data, old_req.DataSize);
--
1.8.4
From 8603b648095d847fbed56b956b0b5aeaa62f091a Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Wed, 23 Oct 2013 18:29:09 +0800
Subject: [PATCH 10/20] Merge the hash into an existed signature list
---
src/mokutil.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 70 insertions(+), 17 deletions(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index 862cfbf..f87ae7a 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -1312,14 +1312,17 @@ issue_hash_request (const char *hash_str, MokRequest req,
void *new_list = NULL;
void *ptr;
unsigned long list_size = 0;
- uint32_t sig_list_size;
+ uint32_t sig_size, sig_list_size;
int ret = -1;
EFI_SIGNATURE_LIST *CertList;
EFI_SIGNATURE_DATA *CertData;
efi_guid_t hash_type;
uint8_t db_hash[SHA512_DIGEST_LENGTH];
int hash_size;
+ int merge_ind = -1;
uint8_t valid = 0;
+ MokListNode *mok_list = NULL;
+ uint32_t mok_num;
if (!hash_str)
return -1;
@@ -1365,16 +1368,31 @@ issue_hash_request (const char *hash_str, MokRequest req,
goto error;
}
- sig_list_size = sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t) + hash_size;
- list_size += sig_list_size;
-
memset (&old_req, 0, sizeof(old_req));
old_req.VariableName = req_name;
old_req.VendorGuid = SHIM_LOCK_GUID;
- if (read_variable (&old_req) == EFI_SUCCESS)
+ if (read_variable (&old_req) == EFI_SUCCESS) {
+ int i;
list_size += old_req.DataSize;
+ mok_list = build_mok_list (old_req.Data, old_req.DataSize,
+ &mok_num);
+ if (mok_list == NULL)
+ goto error;
+
+ /* Check if there is a signature list with the same type */
+ for (i = 0; i < mok_num; i++) {
+ if (efi_guidcmp (mok_list[i].header->SignatureType,
+ hash_type) == 0) {
+ merge_ind = i;
+ break;
+ }
+ }
+ }
+
+ list_size += sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t) + hash_size;
+
new_list = malloc (list_size);
if (!new_list) {
fprintf (stderr, "Failed to allocate space for %s\n", req_name);
@@ -1382,20 +1400,53 @@ issue_hash_request (const char *hash_str, MokRequest req,
}
ptr = new_list;
- CertList = ptr;
- CertList->SignatureType = hash_type;
- CertList->SignatureListSize = sig_list_size;
- CertList->SignatureHeaderSize = 0;
- CertList->SignatureSize = hash_size + sizeof(efi_guid_t);
+ if (merge_ind < 0) {
+ /* Create a new signature list for the hash */
+ sig_list_size = sizeof(EFI_SIGNATURE_LIST) +
+ sizeof(efi_guid_t) + hash_size;
+ CertList = ptr;
+ CertList->SignatureType = hash_type;
+ CertList->SignatureListSize = sig_list_size;
+ CertList->SignatureHeaderSize = 0;
+ CertList->SignatureSize = hash_size + sizeof(efi_guid_t);
- CertData = (EFI_SIGNATURE_DATA *)(((uint8_t *)ptr) +
- sizeof(EFI_SIGNATURE_LIST));
- CertData->SignatureOwner = SHIM_LOCK_GUID;
- memcpy (CertData->SignatureData, db_hash, hash_size);
+ CertData = (EFI_SIGNATURE_DATA *)(((uint8_t *)ptr) +
+ sizeof(EFI_SIGNATURE_LIST));
+ CertData->SignatureOwner = SHIM_LOCK_GUID;
+ memcpy (CertData->SignatureData, db_hash, hash_size);
- /* append the keys to the previous request */
- if (old_req.Data) {
- memcpy (new_list + sig_list_size, old_req.Data, old_req.DataSize);
+ /* prepend the hash to the previous request */
+ ptr += sig_list_size;
+ if (old_req.Data) {
+ memcpy (ptr, old_req.Data, old_req.DataSize);
+ }
+ } else {
+ /* Merge the hash into an existed signature list */
+ int i;
+
+ for (i = 0; i < merge_ind; i++) {
+ sig_list_size = mok_list[i].header->SignatureListSize;
+ memcpy (ptr, (void *)mok_list[i].header, sig_list_size);
+ ptr += sig_list_size;
+ }
+
+ /* Append the hash to the list */
+ i = merge_ind;
+ sig_list_size = mok_list[i].header->SignatureListSize;
+ sig_size = hash_size + sizeof(efi_guid_t);
+ mok_list[i].header->SignatureListSize += sig_size;
+ memcpy (ptr, (void *)mok_list[i].header, sig_list_size);
+ ptr += sig_list_size;
+ memcpy (ptr, (void *)&hash_type, sizeof(efi_guid_t));
+ ptr += sizeof(efi_guid_t);
+ memcpy (ptr, db_hash, hash_size);
+ ptr += hash_size;
+
+ for (i = merge_ind + 1; i < mok_num; i++) {
+ sig_list_size = mok_list[i].header->SignatureListSize;
+ memcpy (ptr, (void *)mok_list[i].header, sig_list_size);
+ ptr += sig_list_size;
+ }
}
if (update_request (new_list, list_size, req, hash_file, root_pw) < 0) {
@@ -1406,6 +1457,8 @@ issue_hash_request (const char *hash_str, MokRequest req,
error:
if (old_req.Data)
free (old_req.Data);
+ if (mok_list)
+ free (mok_list);
if (new_list)
free (new_list);
--
1.8.4
From d933eba21ebad708d85ff23a715a14a7d67f51a9 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Thu, 24 Oct 2013 17:54:18 +0800
Subject: [PATCH 11/20] Initialize the request variable to avoid the potential
crash
---
src/mokutil.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index f87ae7a..880c38f 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -1334,6 +1334,8 @@ issue_hash_request (const char *hash_str, MokRequest req,
if (hex_str_to_binary (hash_str, db_hash, hash_size) < 0)
return -1;
+ memset (&old_req, 0, sizeof(old_req));
+
switch (req) {
case ENROLL_MOK:
req_name = "MokNew";
@@ -1368,8 +1370,6 @@ issue_hash_request (const char *hash_str, MokRequest req,
goto error;
}
- memset (&old_req, 0, sizeof(old_req));
-
old_req.VariableName = req_name;
old_req.VendorGuid = SHIM_LOCK_GUID;
if (read_variable (&old_req) == EFI_SUCCESS) {
--
1.8.4
From 6c9d5519172ca5f87a08d1a46105c2a68b9f4db7 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Fri, 25 Oct 2013 18:29:07 +0800
Subject: [PATCH 12/20] Make test-key and reset support MOK blacklist
---
src/mokutil.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index 880c38f..8ff4b41 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -154,7 +154,8 @@ print_help ()
printf (" \t\t\t\t(For --list-enrolled, --list-new,\n");
printf (" \t\t\t\t --list-delete, --import, --delete,\n");
printf (" \t\t\t\t --revoke-import, --revoke-delete,\n");
- printf (" \t\t\t\t --import-hash, and --delete-hash)\n");
+ printf (" \t\t\t\t --import-hash, --delete-hash,\n");
+ printf (" \t\t\t\t --reset, and --test-key)\n");
}
static int
@@ -1756,7 +1757,7 @@ read_file(int fd, void **bufp, size_t *lenptr) {
}
static int
-test_key (const char *key_file)
+test_key (MokRequest req, const char *key_file)
{
void *key = NULL;
size_t read_size;
@@ -1774,7 +1775,7 @@ test_key (const char *key_file)
goto error;
}
- if (!is_valid_request (EfiCertX509Guid, key, read_size, ENROLL_MOK)) {
+ if (!is_valid_request (EfiCertX509Guid, key, read_size, req)) {
printf ("%s is not enrolled\n", key_file);
ret = 0;
} else {
@@ -1793,9 +1794,9 @@ error:
}
static int
-reset_moks (const char *hash_file, const int root_pw)
+reset_moks (MokRequest req, const char *hash_file, const int root_pw)
{
- if (update_request (NULL, 0, ENROLL_MOK, hash_file, root_pw)) {
+ if (update_request (NULL, 0, req, hash_file, root_pw)) {
fprintf (stderr, "Failed to issue a reset request\n");
return -1;
}
@@ -2102,11 +2103,11 @@ main (int argc, char *argv[])
ret = sb_state ();
break;
case TEST_KEY:
- ret = test_key (key_file);
+ ret = test_key (ENROLL_MOK, key_file);
break;
case RESET:
case RESET | SIMPLE_HASH:
- ret = reset_moks (hash_file, use_root_pw);
+ ret = reset_moks (ENROLL_MOK, hash_file, use_root_pw);
break;
case GENERATE_PW_HASH:
ret = generate_pw_hash (input_pw);
@@ -2152,6 +2153,13 @@ main (int argc, char *argv[])
case REVOKE_DELETE | MOKX:
ret = revoke_request (DELETE_BLACKLIST);
break;
+ case RESET | MOKX:
+ case RESET | SIMPLE_HASH | MOKX:
+ ret = reset_moks (ENROLL_BLACKLIST, hash_file, use_root_pw);
+ break;
+ case TEST_KEY | MOKX:
+ ret = test_key (ENROLL_BLACKLIST, key_file);
+ break;
default:
print_help ();
break;
--
1.8.4
From 0fdc023cf98addb23ae511b91c963619ec1e8e2d Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Wed, 30 Oct 2013 10:29:25 +0800
Subject: [PATCH 13/20] Set the verbosity for shim and MokManager
---
src/mokutil.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/src/mokutil.c b/src/mokutil.c
index 8ff4b41..cd3b622 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -82,6 +82,7 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b,
#define MOKX (1 << 20)
#define IMPORT_HASH (1 << 21)
#define DELETE_HASH (1 << 22)
+#define VERBOSITY (1 << 23)
#define DEFAULT_CRYPT_METHOD SHA512_BASED
#define DEFAULT_SALT_SIZE SHA512_SALT_MAX
@@ -136,6 +137,7 @@ print_help ()
printf (" --use-db\t\t\t\tUse DB for validation\n");
printf (" --import-hash <hash>\t\t\tImport a hash\n");
printf (" --delete-hash <hash>\t\t\tDelete a specific hash\n");
+ printf (" --set-verbosity <true/false>\t\tSet the verbosity bit for shim\n");
printf ("\n");
printf ("Supplimentary Options:\n");
printf (" --hash-file <hash file>\t\tUse the specific password hash\n");
@@ -1856,6 +1858,31 @@ generate_pw_hash (const char *input_pw)
return 0;
}
+static int
+set_verbosity (uint8_t verbosity)
+{
+ efi_variable_t var;
+
+ if (verbosity) {
+ var.VariableName = "SHIM_VERBOSE";
+ var.VendorGuid = SHIM_LOCK_GUID;
+ var.Data = (void *)&verbosity;
+ var.DataSize = sizeof(uint8_t);
+ var.Attributes = EFI_VARIABLE_NON_VOLATILE
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS
+ | EFI_VARIABLE_RUNTIME_ACCESS;
+
+ if (edit_protected_variable (&var) != EFI_SUCCESS) {
+ fprintf (stderr, "Failed to set SHIM_VERBOSE\n");
+ return -1;
+ }
+ } else {
+ return test_and_delete_var ("SHIM_VERBOSE");
+ }
+
+ return 0;
+}
+
int
main (int argc, char *argv[])
{
@@ -1868,6 +1895,7 @@ main (int argc, char *argv[])
int c, i, f_ind, total = 0;
unsigned int command = 0;
int use_root_pw = 0;
+ uint8_t verbosity = 0;
int ret = -1;
use_simple_hash = 0;
@@ -1899,6 +1927,7 @@ main (int argc, char *argv[])
{"mokx", no_argument, 0, 0 },
{"import-hash", required_argument, 0, 0 },
{"delete-hash", required_argument, 0, 0 },
+ {"set-verbosity", required_argument, 0, 0 },
{0, 0, 0, 0}
};
@@ -1950,6 +1979,14 @@ main (int argc, char *argv[])
break;
}
hash_str = strdup (optarg);
+ } else if (strcmp (option, "set-verbosity") == 0) {
+ command |= VERBOSITY;
+ if (strcmp (optarg, "true") == 0)
+ verbosity = 1;
+ else if (strcmp (optarg, "false") == 0)
+ verbosity = 0;
+ else
+ command |= HELP;
}
break;
case 'd':
@@ -2160,6 +2197,9 @@ main (int argc, char *argv[])
case TEST_KEY | MOKX:
ret = test_key (ENROLL_BLACKLIST, key_file);
break;
+ case VERBOSITY:
+ ret = set_verbosity (verbosity);
+ break;
default:
print_help ();
break;
--
1.8.4
From 96dfa331c2067c3a44d6086ec86e6abb87f3c30f Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 26 Nov 2013 12:36:12 +0800
Subject: [PATCH 14/20] Update the help and manpage
---
man/mokutil.1 | 30 +++++++++++++++++++++++++++---
src/mokutil.c | 4 ++--
2 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/man/mokutil.1 b/man/mokutil.1
index abfdebb..fa990e5 100644
--- a/man/mokutil.1
+++ b/man/mokutil.1
@@ -5,22 +5,27 @@ mokutil \- utility to manipulate machine owner keys
.SH SYNOPSIS
\fBmokutil\fR [--list-enrolled]
+ ([--mokx])
.br
\fBmokutil\fR [--list-new]
+ ([--mokx])
.br
\fBmokutil\fR [--list-delete]
+ ([--mokx])
.br
\fBmokutil\fR [--import \fIkeylist\fR| -i \fIkeylist\fR]
([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] |
- [--simple-hash | -s])
+ [--simple-hash | -s] | [--mokx])
.br
\fBmokutil\fR [--delete \fIkeylist\fR | -d \fIkeylist\fR]
([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] |
- [--simple-hash | -s])
+ [--simple-hash | -s] | [--mokx])
.br
\fBmokutil\fR [--revoke-import]
+ ([--mokx])
.br
\fBmokutil\fR [--revoke-delete]
+ ([--mokx])
.br
\fBmokutil\fR [--export | -x]
.br
@@ -41,10 +46,16 @@ mokutil \- utility to manipulate machine owner keys
.br
\fBmokutil\fR [--reset]
([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] |
- [--simple-hash | -s])
+ [--simple-hash | -s] | [--mok])
.br
\fBmokutil\fR [--generate-hash=\fIpassword\fR | -g\fIpassword\fR]
.br
+\fBmokutil\fR [--ignore-db]
+.br
+\fBmokutil\fR [--use-db]
+.br
+\fBmokutil\fR [--set-verbosity (\fItrue\fR | \fIfalse\fR)]
+.br
.SH DESCRIPTION
\fBmokutil\fR is a tool to import or delete the machines owner keys
@@ -108,3 +119,16 @@ Use the root password hash from /etc/shadow
Use the old SHA256 password hash method to hash the password
.br
Note: --root-pw invalidates --simple-hash
+.TP
+\fB--ignore-db\fR
+Tell shim to not use the keys in db to verify EFI images
+.TP
+\fB--use-db\fR
+Tell shim to use the keys in db to verify EFI images (default)
+.TP
+\fB--mokx\fR
+Manipulate the MOK blacklist (MOKX) instead of the MOK list
+.TP
+\fB--set-verbosity\fR
+Set the SHIM_VERBOSE to make shim more or less verbose
+.TP
diff --git a/src/mokutil.c b/src/mokutil.c
index cd3b622..a1f1213 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -135,8 +135,8 @@ print_help ()
printf (" --generate-hash[=password]\t\tGenerate the password hash\n");
printf (" --ignore-db\t\t\t\tIgnore DB for validation\n");
printf (" --use-db\t\t\t\tUse DB for validation\n");
- printf (" --import-hash <hash>\t\t\tImport a hash\n");
- printf (" --delete-hash <hash>\t\t\tDelete a specific hash\n");
+ printf (" --import-hash <hash>\t\t\tImport a hash into MOK or MOKX\n");
+ printf (" --delete-hash <hash>\t\t\tDelete a hash in MOK or MOKX\n");
printf (" --set-verbosity <true/false>\t\tSet the verbosity bit for shim\n");
printf ("\n");
printf ("Supplimentary Options:\n");
--
1.8.4
From e2ea0acb875247d70626545d5f3837f2a422af2f Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 26 Nov 2013 12:40:57 +0800
Subject: [PATCH 15/20] Make the help less verbose
It's all in the manpage anyway.
---
src/mokutil.c | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index a1f1213..628df7d 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -141,23 +141,9 @@ print_help ()
printf ("\n");
printf ("Supplimentary Options:\n");
printf (" --hash-file <hash file>\t\tUse the specific password hash\n");
- printf (" \t\t(For --import, --delete, --password,\n");
- printf (" \t\t --reset, --import-hash,\n");
- printf (" \t\t and --delete-hash)\n");
printf (" --root-pw\t\t\t\tUse the root password\n");
- printf (" \t\t\t\t(For --import, --delete, --password,\n");
- printf (" \t\t\t\t --reset, --import-hash,\n");
- printf (" \t\t\t\t and --delete-hash)\n");
printf (" --simple-hash\t\t\t\tUse the old password hash method\n");
- printf (" \t\t\t\t(For --import, --delete, --password,\n");
- printf (" \t\t\t\t --clear-password, --reset,\n");
- printf (" \t\t\t\t --import-hash, and --delete-hash)\n");
printf (" --mokx\t\t\t\tManipulate the MOK blacklist\n");
- printf (" \t\t\t\t(For --list-enrolled, --list-new,\n");
- printf (" \t\t\t\t --list-delete, --import, --delete,\n");
- printf (" \t\t\t\t --revoke-import, --revoke-delete,\n");
- printf (" \t\t\t\t --import-hash, --delete-hash,\n");
- printf (" \t\t\t\t --reset, and --test-key)\n");
}
static int
--
1.8.4
From 72dd17981660747bc84b7ce643451110529ece38 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 26 Nov 2013 16:26:16 +0800
Subject: [PATCH 16/20] New options to list the firmware keys
---
man/mokutil.1 | 20 +++++++++++++
src/mokutil.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 102 insertions(+), 11 deletions(-)
diff --git a/man/mokutil.1 b/man/mokutil.1
index fa990e5..86846b4 100644
--- a/man/mokutil.1
+++ b/man/mokutil.1
@@ -56,6 +56,14 @@ mokutil \- utility to manipulate machine owner keys
.br
\fBmokutil\fR [--set-verbosity (\fItrue\fR | \fIfalse\fR)]
.br
+\fBmokutil\fR [--pk]
+.br
+\fBmokutil\fR [--kek]
+.br
+\fBmokutil\fR [--db]
+.br
+\fBmokutil\fR [--dbx]
+.br
.SH DESCRIPTION
\fBmokutil\fR is a tool to import or delete the machines owner keys
@@ -132,3 +140,15 @@ Manipulate the MOK blacklist (MOKX) instead of the MOK list
\fB--set-verbosity\fR
Set the SHIM_VERBOSE to make shim more or less verbose
.TP
+\fB--pk\fR
+List the keys in the public Platform Key (PK)
+.TP
+\fB--kek\fR
+List the keys in the Key Exchange Key Signature database (KEK)
+.TP
+\fB--db\fR
+List the keys in the secure boot signature store (db)
+.TP
+\fB--dbx\fR
+List the keys in the secure boot blacklist signature store (dbx)
+.TP
diff --git a/src/mokutil.c b/src/mokutil.c
index 628df7d..6f5aec4 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -97,6 +97,15 @@ typedef enum {
ENROLL_BLACKLIST
} MokRequest;
+typedef enum {
+ MOK_LIST_RT = 0,
+ MOK_LIST_X_RT,
+ PK,
+ KEK,
+ DB,
+ DBX,
+} DBName;
+
typedef struct {
EFI_SIGNATURE_LIST *header;
uint32_t mok_size;
@@ -138,6 +147,10 @@ print_help ()
printf (" --import-hash <hash>\t\t\tImport a hash into MOK or MOKX\n");
printf (" --delete-hash <hash>\t\t\tDelete a hash in MOK or MOKX\n");
printf (" --set-verbosity <true/false>\t\tSet the verbosity bit for shim\n");
+ printf (" --pk\t\t\t\t\tList the keys in PK\n");
+ printf (" --kek\t\t\t\t\tList the keys in KEK\n");
+ printf (" --db\t\t\t\t\tList the keys in db\n");
+ printf (" --dbx\t\t\t\t\tList the keys in dbx\n");
printf ("\n");
printf ("Supplimentary Options:\n");
printf (" --hash-file <hash file>\t\tUse the specific password hash\n");
@@ -523,7 +536,7 @@ done:
}
static int
-list_keys_in_var (const char *var_name)
+list_keys_in_var (const char *var_name, const efi_guid_t guid)
{
efi_variable_t var;
efi_status_t status;
@@ -531,7 +544,7 @@ list_keys_in_var (const char *var_name)
memset (&var, 0, sizeof(var));
var.VariableName = var_name;
- var.VendorGuid = SHIM_LOCK_GUID;
+ var.VendorGuid = guid;
status = read_variable (&var);
if (status != EFI_SUCCESS) {
@@ -1869,6 +1882,27 @@ set_verbosity (uint8_t verbosity)
return 0;
}
+static inline int
+list_db (DBName db_name)
+{
+ switch (db_name) {
+ case MOK_LIST_RT:
+ return list_keys_in_var ("MokListRT", SHIM_LOCK_GUID);
+ case MOK_LIST_X_RT:
+ return list_keys_in_var ("MokListXRT", SHIM_LOCK_GUID);
+ case PK:
+ return list_keys_in_var ("PK", EFI_GLOBAL_VARIABLE);
+ case KEK:
+ return list_keys_in_var ("KEK", EFI_GLOBAL_VARIABLE);
+ case DB:
+ return list_keys_in_var ("db", EFI_IMAGE_SECURITY_DATABASE_GUID);
+ case DBX:
+ return list_keys_in_var ("dbx", EFI_IMAGE_SECURITY_DATABASE_GUID);
+ }
+
+ return -1;
+}
+
int
main (int argc, char *argv[])
{
@@ -1882,6 +1916,7 @@ main (int argc, char *argv[])
unsigned int command = 0;
int use_root_pw = 0;
uint8_t verbosity = 0;
+ DBName db_name = MOK_LIST_RT;
int ret = -1;
use_simple_hash = 0;
@@ -1914,6 +1949,10 @@ main (int argc, char *argv[])
{"import-hash", required_argument, 0, 0 },
{"delete-hash", required_argument, 0, 0 },
{"set-verbosity", required_argument, 0, 0 },
+ {"pk", no_argument, 0, 0 },
+ {"kek", no_argument, 0, 0 },
+ {"db", no_argument, 0, 0 },
+ {"dbx", no_argument, 0, 0 },
{0, 0, 0, 0}
};
@@ -1950,7 +1989,12 @@ main (int argc, char *argv[])
} else if (strcmp (option, "use-db") == 0) {
command |= USE_DB;
} else if (strcmp (option, "mokx") == 0) {
- command |= MOKX;
+ if (db_name != MOK_LIST_RT) {
+ command |= HELP;
+ } else {
+ command |= MOKX;
+ db_name = MOK_LIST_X_RT;
+ }
} else if (strcmp (option, "import-hash") == 0) {
command |= IMPORT_HASH;
if (hash_str) {
@@ -1973,7 +2017,36 @@ main (int argc, char *argv[])
verbosity = 0;
else
command |= HELP;
+ } else if (strcmp (option, "pk") == 0) {
+ if (db_name != MOK_LIST_RT) {
+ command |= HELP;
+ } else {
+ command |= LIST_ENROLLED;
+ db_name = PK;
+ }
+ } else if (strcmp (option, "kek") == 0) {
+ if (db_name != MOK_LIST_RT) {
+ command |= HELP;
+ } else {
+ command |= LIST_ENROLLED;
+ db_name = KEK;
+ }
+ } else if (strcmp (option, "db") == 0) {
+ if (db_name != MOK_LIST_RT) {
+ command |= HELP;
+ } else {
+ command |= LIST_ENROLLED;
+ db_name = DB;
+ }
+ } else if (strcmp (option, "dbx") == 0) {
+ if (db_name != MOK_LIST_RT) {
+ command |= HELP;
+ } else {
+ command |= LIST_ENROLLED;
+ db_name = DBX;
+ }
}
+
break;
case 'd':
case 'i':
@@ -2071,13 +2144,14 @@ main (int argc, char *argv[])
switch (command) {
case LIST_ENROLLED:
- ret = list_keys_in_var ("MokListRT");
+ case LIST_ENROLLED | MOKX:
+ ret = list_db (db_name);
break;
case LIST_NEW:
- ret = list_keys_in_var ("MokNew");
+ ret = list_keys_in_var ("MokNew", SHIM_LOCK_GUID);
break;
case LIST_DELETE:
- ret = list_keys_in_var ("MokDel");
+ ret = list_keys_in_var ("MokDel", SHIM_LOCK_GUID);
break;
case IMPORT:
case IMPORT | SIMPLE_HASH:
@@ -2141,14 +2215,11 @@ main (int argc, char *argv[])
case USE_DB:
ret = enable_db ();
break;
- case LIST_ENROLLED | MOKX:
- ret = list_keys_in_var ("MokListXRT");
- break;
case LIST_NEW | MOKX:
- ret = list_keys_in_var ("MokXNew");
+ ret = list_keys_in_var ("MokXNew", SHIM_LOCK_GUID);
break;
case LIST_DELETE | MOKX:
- ret = list_keys_in_var ("MokXDel");
+ ret = list_keys_in_var ("MokXDel", SHIM_LOCK_GUID);
break;
case IMPORT | MOKX:
case IMPORT | SIMPLE_HASH | MOKX:
--
1.8.4
From 9820c083e2a9b605a59aae7bdf56992f63abf7b8 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 26 Nov 2013 16:49:14 +0800
Subject: [PATCH 17/20] Add more short options
---
man/mokutil.1 | 54 +++++++++++++++++++++++++++++-------------------------
src/mokutil.c | 42 +++++++++++++++++++++++-------------------
2 files changed, 52 insertions(+), 44 deletions(-)
diff --git a/man/mokutil.1 b/man/mokutil.1
index 86846b4..02b346f 100644
--- a/man/mokutil.1
+++ b/man/mokutil.1
@@ -4,28 +4,28 @@
mokutil \- utility to manipulate machine owner keys
.SH SYNOPSIS
-\fBmokutil\fR [--list-enrolled]
- ([--mokx])
+\fBmokutil\fR [--list-enrolled | -l]
+ ([--mokx | -X])
.br
-\fBmokutil\fR [--list-new]
- ([--mokx])
+\fBmokutil\fR [--list-new | -N]
+ ([--mokx | -X])
.br
-\fBmokutil\fR [--list-delete]
- ([--mokx])
+\fBmokutil\fR [--list-delete | -D]
+ ([--mokx | -X])
.br
\fBmokutil\fR [--import \fIkeylist\fR| -i \fIkeylist\fR]
([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] |
- [--simple-hash | -s] | [--mokx])
+ [--simple-hash | -s] | [--mokx | -X])
.br
\fBmokutil\fR [--delete \fIkeylist\fR | -d \fIkeylist\fR]
([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] |
- [--simple-hash | -s] | [--mokx])
+ [--simple-hash | -s] | [--mokx |- X])
.br
\fBmokutil\fR [--revoke-import]
- ([--mokx])
+ ([--mokx | -X])
.br
\fBmokutil\fR [--revoke-delete]
- ([--mokx])
+ ([--mokx | -X])
.br
\fBmokutil\fR [--export | -x]
.br
@@ -42,11 +42,11 @@ mokutil \- utility to manipulate machine owner keys
.br
\fBmokutil\fR [--sb-state]
.br
-\fBmokutil\fR [--test-key | -t] ...
+\fBmokutil\fR [--test-key \fIkeyfile\fR | -t \fIkeyfile\fR]
.br
\fBmokutil\fR [--reset]
([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] |
- [--simple-hash | -s] | [--mok])
+ [--simple-hash | -s] | [--mok | -X])
.br
\fBmokutil\fR [--generate-hash=\fIpassword\fR | -g\fIpassword\fR]
.br
@@ -71,18 +71,22 @@ mokutil \- utility to manipulate machine owner keys
.SH OPTIONS
.TP
-\fB--list-enrolled\fR
+\fB-l, --list-enrolled\fR
List the keys the already stored in the database
.TP
-\fB--list-new\fR
+\fB-N, --list-new\fR
List the keys to be enrolled
.TP
-\fB--list-delete\fR
+\fB-D, --list-delete\fR
List the keys to be deleted
.TP
-\fB--import\fR
-Collect the followed files and form a request to shim. The files must be in DER
-format.
+\fB-i, --import\fR
+Collect the followed files and form a enrolling request to shim. The files must
+be in DER format.
+.TP
+\fB-d, --delete\fR
+Collect the followed files and form a deleting request to shim. The files must be
+in DER format.
.TP
\fB--revoke-import\fR
Revoke the current import request (MokNew)
@@ -90,13 +94,13 @@ Revoke the current import request (MokNew)
\fB--revoke-delete\fR
Revoke the current delete request (MokDel)
.TP
-\fB--export\fR
+\fB-x, --export\fR
Export the keys stored in MokListRT
.TP
-\fB--password\fR
+\fB-p, --password\fR
Setup the password for MokManager (MokPW)
.TP
-\fB--clear-password\fR
+\fB-c, --clear-password\fR
Clear the password for MokManager (MokPW)
.TP
\fB--disable-validation\fR
@@ -108,7 +112,7 @@ Enable the validation process in shim
\fB--sb-state\fR
Show SecureBoot State
.TP
-\fB--test-key\fR
+\fB-t, --test-key\fR
Test if the key is enrolled or not
.TP
\fB--reset\fR
@@ -120,10 +124,10 @@ Generate the password hash
\fB--hash-file\fR
Use the password hash from a specific file
.TP
-\fB--root-pw\fR
+\fB-P, --root-pw\fR
Use the root password hash from /etc/shadow
.TP
-\fB--simple-hash\fR
+\fB-s, --simple-hash\fR
Use the old SHA256 password hash method to hash the password
.br
Note: --root-pw invalidates --simple-hash
@@ -134,7 +138,7 @@ Tell shim to not use the keys in db to verify EFI images
\fB--use-db\fR
Tell shim to use the keys in db to verify EFI images (default)
.TP
-\fB--mokx\fR
+\fB-X, --mokx\fR
Manipulate the MOK blacklist (MOKX) instead of the MOK list
.TP
\fB--set-verbosity\fR
diff --git a/src/mokutil.c b/src/mokutil.c
index 6f5aec4..6fe8ae2 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -1924,9 +1924,9 @@ main (int argc, char *argv[])
while (1) {
static struct option long_options[] = {
{"help", no_argument, 0, 'h'},
- {"list-enrolled", no_argument, 0, 0 },
- {"list-new", no_argument, 0, 0 },
- {"list-delete", no_argument, 0, 0 },
+ {"list-enrolled", no_argument, 0, 'l'},
+ {"list-new", no_argument, 0, 'N'},
+ {"list-delete", no_argument, 0, 'D'},
{"import", required_argument, 0, 'i'},
{"delete", required_argument, 0, 'd'},
{"revoke-import", no_argument, 0, 0 },
@@ -1945,7 +1945,7 @@ main (int argc, char *argv[])
{"simple-hash", no_argument, 0, 's'},
{"ignore-db", no_argument, 0, 0 },
{"use-db", no_argument, 0, 0 },
- {"mokx", no_argument, 0, 0 },
+ {"mokx", no_argument, 0, 'X'},
{"import-hash", required_argument, 0, 0 },
{"delete-hash", required_argument, 0, 0 },
{"set-verbosity", required_argument, 0, 0 },
@@ -1957,7 +1957,7 @@ main (int argc, char *argv[])
};
int option_index = 0;
- c = getopt_long (argc, argv, "cd:f:g::hi:pst:xP",
+ c = getopt_long (argc, argv, "cd:f:g::hi:lpst:xDNPX",
long_options, &option_index);
if (c == -1)
@@ -1966,13 +1966,7 @@ main (int argc, char *argv[])
switch (c) {
case 0:
option = long_options[option_index].name;
- if (strcmp (option, "list-enrolled") == 0) {
- command |= LIST_ENROLLED;
- } else if (strcmp (option, "list-new") == 0) {
- command |= LIST_NEW;
- } else if (strcmp (option, "list-delete") == 0) {
- command |= LIST_DELETE;
- } else if (strcmp (option, "revoke-import") == 0) {
+ if (strcmp (option, "revoke-import") == 0) {
command |= REVOKE_IMPORT;
} else if (strcmp (option, "revoke-delete") == 0) {
command |= REVOKE_DELETE;
@@ -1988,13 +1982,6 @@ main (int argc, char *argv[])
command |= IGNORE_DB;
} else if (strcmp (option, "use-db") == 0) {
command |= USE_DB;
- } else if (strcmp (option, "mokx") == 0) {
- if (db_name != MOK_LIST_RT) {
- command |= HELP;
- } else {
- command |= MOKX;
- db_name = MOK_LIST_X_RT;
- }
} else if (strcmp (option, "import-hash") == 0) {
command |= IMPORT_HASH;
if (hash_str) {
@@ -2048,6 +2035,15 @@ main (int argc, char *argv[])
}
break;
+ case 'l':
+ command |= LIST_ENROLLED;
+ break;
+ case 'N':
+ command |= LIST_NEW;
+ break;
+ case 'D':
+ command |= LIST_DELETE;
+ break;
case 'd':
case 'i':
if (c == 'd')
@@ -2127,6 +2123,14 @@ main (int argc, char *argv[])
command |= SIMPLE_HASH;
use_simple_hash = 1;
break;
+ case 'X':
+ if (db_name != MOK_LIST_RT) {
+ command |= HELP;
+ } else {
+ command |= MOKX;
+ db_name = MOK_LIST_X_RT;
+ }
+ break;
case 'h':
case '?':
command |= HELP;
--
1.8.4
From 0ff8112146c355c1bc4eec57cdeb0aed4cc4065c Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Tue, 26 Nov 2013 18:13:20 +0800
Subject: [PATCH 18/20] Catch the error from strdup()
---
src/mokutil.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index 6fe8ae2..27b9585 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -1989,6 +1989,10 @@ main (int argc, char *argv[])
break;
}
hash_str = strdup (optarg);
+ if (hash_str == NULL) {
+ fprintf (stderr, "Could not allocate space: %m\n");
+ exit(1);
+ }
} else if (strcmp (option, "delete-hash") == 0) {
command |= DELETE_HASH;
if (hash_str) {
@@ -1996,6 +2000,10 @@ main (int argc, char *argv[])
break;
}
hash_str = strdup (optarg);
+ if (hash_str == NULL) {
+ fprintf (stderr, "Could not allocate space: %m\n");
+ exit(1);
+ }
} else if (strcmp (option, "set-verbosity") == 0) {
command |= VERBOSITY;
if (strcmp (optarg, "true") == 0)
@@ -2069,6 +2077,10 @@ main (int argc, char *argv[])
}
files = malloc (total * sizeof (char *));
+ if (files == NULL) {
+ fprintf (stderr, "Could not allocate space: %m\n");
+ exit(1);
+ }
for (i = 0; i < total; i++) {
f_ind = i + optind - 1;
files[i] = malloc (strlen(argv[f_ind]) + 1);
@@ -2082,6 +2094,10 @@ main (int argc, char *argv[])
break;
}
hash_file = strdup (optarg);
+ if (hash_file == NULL) {
+ fprintf (stderr, "Could not allocate space: %m\n");
+ exit(1);
+ }
break;
case 'g':
@@ -2089,8 +2105,13 @@ main (int argc, char *argv[])
command |= HELP;
break;
}
- if (optarg)
+ if (optarg) {
input_pw = strdup (optarg);
+ if (input_pw == NULL) {
+ fprintf (stderr, "Could not allocate space: %m\n");
+ exit(1);
+ }
+ }
command |= GENERATE_PW_HASH;
break;
--
1.8.4
From f77d5e52b0318dbf8f92b2bd89aab0a3d5d77078 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Wed, 22 Jan 2014 13:46:24 +0800
Subject: [PATCH 19/20] Fix the test-key request check
---
src/mokutil.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index 27b9585..dbec25b 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -1776,7 +1776,7 @@ test_key (MokRequest req, const char *key_file)
goto error;
}
- if (!is_valid_request (EfiCertX509Guid, key, read_size, req)) {
+ if (is_valid_request (EfiCertX509Guid, key, read_size, req)) {
printf ("%s is not enrolled\n", key_file);
ret = 0;
} else {
--
1.8.4
From d921883b2f8ce4e9e9304af5d9b44aac1e701e51 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Wed, 22 Jan 2014 13:51:36 +0800
Subject: [PATCH 20/20] Update manpage for --test-key
---
man/mokutil.1 | 1 +
1 file changed, 1 insertion(+)
diff --git a/man/mokutil.1 b/man/mokutil.1
index 02b346f..ca9380d 100644
--- a/man/mokutil.1
+++ b/man/mokutil.1
@@ -43,6 +43,7 @@ mokutil \- utility to manipulate machine owner keys
\fBmokutil\fR [--sb-state]
.br
\fBmokutil\fR [--test-key \fIkeyfile\fR | -t \fIkeyfile\fR]
+ ([--mokx | -X])
.br
\fBmokutil\fR [--reset]
([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] |
--
1.8.4