2918 lines
83 KiB
Diff
2918 lines
83 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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.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/18] 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.1.4
|
||
|
|