From 9a114bb26e81f3b2764d84b8a6f5b9bd2e1528de Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Fri, 29 Mar 2013 18:00:55 +0800 Subject: [PATCH 1/3] Delete key from the pending request --- src/mokutil.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 108 insertions(+), 8 deletions(-) diff --git a/src/mokutil.c b/src/mokutil.c index 3f89db2..01a1b79 100644 --- a/src/mokutil.c +++ b/src/mokutil.c @@ -49,8 +49,9 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, #define SETTINGS_LEN (DEFAULT_SALT_SIZE*2) typedef struct { - uint32_t mok_size; - void *mok; + EFI_SIGNATURE_LIST *header; + uint32_t mok_size; + void *mok; } MokListNode; typedef struct { @@ -154,8 +155,9 @@ build_mok_list (void *data, unsigned long data_size, uint32_t *mok_num) return NULL; } + list[count].header = CertList; list[count].mok_size = CertList->SignatureSize - sizeof(efi_guid_t); - list[count].mok = (void *)Cert->SignatureData; + list[count].mok = (void *)Cert->SignatureData; count++; dbsize -= CertList->SignatureListSize; @@ -233,6 +235,74 @@ list_keys (efi_variable_t *var) } static int +delete_key_from_list (void *mok, uint32_t mok_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; + int i, del_ind, ret = 0; + + if (!var_name || !mok || mok_size == 0) + return 0; + + memset (&var, 0, sizeof(var)); + var.VariableName = var_name; + var.VendorGuid = guid; + + if (read_variable (&var) != EFI_SUCCESS) + return 0; + + total = var.DataSize; + + list = build_mok_list (var.Data, var.DataSize, &mok_num); + if (list == NULL) + goto done; + + for (i = 0; i < mok_num; i++) { + if (list[i].mok_size != mok_size) + 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; + break; + } + } + + /* the key is not in this list */ + if (data == 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; + if (remain > 0) + memmove (data, ptr, remain); + + var.DataSize = total; + 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 write %s\n", var_name); + goto done; + } + + ret = 1; +done: + free (var.Data); + + return ret; +} + +static int list_enrolled_keys () { efi_variable_t var; @@ -658,6 +728,34 @@ is_valid_request (void *mok, uint32_t mok_size, uint8_t import) } static int +in_pending_request (void *mok, uint32_t mok_size, uint8_t import) +{ + efi_variable_t authvar; + const char *var_name = import ? "MokDel" : "MokNew"; + + if (!mok || mok_size == 0) + return 0; + + memset (&authvar, 0, sizeof(authvar)); + authvar.VariableName = import ? "MokDelAuth" : "MokAuth"; + authvar.VendorGuid = SHIM_LOCK_GUID; + + if (read_variable (&authvar) != EFI_SUCCESS) { + return 0; + } + + free (authvar.Data); + /* Check if the password hash is in the old format */ + if (authvar.DataSize == SHA256_DIGEST_LENGTH) + return 0; + + if (delete_key_from_list (mok, mok_size, var_name, SHIM_LOCK_GUID)) + return 1; + + return 0; +} + +static int issue_mok_request (char **files, uint32_t total, uint8_t import, const char *hash_file, const int root_pw) { @@ -678,10 +776,7 @@ issue_mok_request (char **files, uint32_t total, uint8_t import, if (!files) return -1; - if (import) - req_name = "MokNew"; - else - req_name = "MokDel"; + req_name = import ? "MokNew" : "MokDel"; sizes = malloc (total * sizeof(uint32_t)); @@ -692,6 +787,7 @@ issue_mok_request (char **files, uint32_t total, uint8_t import, goto error; } + /* get the sizes of the key files */ for (i = 0; i < total; i++) { if (stat (files[i], &buf) != 0) { fprintf (stderr, "Failed to get file status, %s\n", @@ -752,6 +848,10 @@ issue_mok_request (char **files, uint32_t total, uint8_t import, if (is_valid_request (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)) { + printf ("Removed %s from %s\n", files[i], import ? "MokDel" : "MokNew"); + + ptr -= sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t); } else { printf ("Skip %s\n", files[i]); ptr -= sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t); @@ -760,7 +860,7 @@ issue_mok_request (char **files, uint32_t total, uint8_t import, close (fd); } - /* All keys are enrolled, nothing to do here... */ + /* All keys are in the list, nothing to do here... */ if (real_size == 0) { ret = 0; goto error; -- 1.8.1.4 From d00c50c0eb73c27b1c49d8d947b99e24a4da4a66 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Fri, 29 Mar 2013 14:21:00 +0800 Subject: [PATCH 2/3] Remove the unnecessary command flags --- src/mokutil.c | 47 ++++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/src/mokutil.c b/src/mokutil.c index 01a1b79..6c3a135 100644 --- a/src/mokutil.c +++ b/src/mokutil.c @@ -40,9 +40,7 @@ EFI_GUID (0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, #define SB_STATE 0x800 #define TEST_KEY 0x1000 #define RESET 0x2000 -#define HASH_FILE 0x4000 -#define GENERATE_PW_HASH 0x8000 -#define ROOT_PW 0x10000 +#define GENERATE_PW_HASH 0x4000 #define DEFAULT_CRYPT_METHOD SHA512_BASED #define DEFAULT_SALT_SIZE SHA512_SALT_MAX @@ -1247,6 +1245,7 @@ main (int argc, char *argv[]) const char *option; int c, i, f_ind, total = 0; unsigned int command = 0; + int use_root_pw = 0; int ret = -1; while (1) { @@ -1329,7 +1328,6 @@ main (int argc, char *argv[]) case 'f': hash_file = strdup (optarg); - command |= HASH_FILE; break; case 'g': if (optarg) @@ -1341,7 +1339,7 @@ main (int argc, char *argv[]) command |= PASSWORD; break; case 'P': - command |= ROOT_PW; + use_root_pw = 1; break; case 't': key_file = strdup (optarg); @@ -1360,6 +1358,9 @@ main (int argc, char *argv[]) } } + if (hash_file && use_root_pw) + command |= HELP; + switch (command) { case LIST_ENROLLED: ret = list_enrolled_keys (); @@ -1368,18 +1369,16 @@ main (int argc, char *argv[]) ret = list_new_keys (); break; case IMPORT: - case IMPORT | HASH_FILE: - ret = import_moks (files, total, hash_file, 0); - break; - case IMPORT | ROOT_PW: - ret = import_moks (files, total, NULL, 1); + if (use_root_pw) + ret = import_moks (files, total, NULL, 1); + else + ret = import_moks (files, total, hash_file, 0); break; case DELETE: - case DELETE | HASH_FILE: - ret = delete_moks (files, total, hash_file, 0); - break; - case DELETE | ROOT_PW: - ret = delete_moks (files, total, NULL, 1); + if (use_root_pw) + ret = delete_moks (files, total, NULL, 1); + else + ret = delete_moks (files, total, hash_file, 0); break; case REVOKE_IMPORT: ret = revoke_request (1); @@ -1391,11 +1390,10 @@ main (int argc, char *argv[]) ret = export_moks (); break; case PASSWORD: - case PASSWORD | HASH_FILE: - ret = set_password (hash_file, 0); - break; - case PASSWORD | ROOT_PW: - ret = set_password (NULL, 1); + if (use_root_pw) + ret = set_password (NULL, 1); + else + ret = set_password (hash_file, 0); break; case DISABLE_VALIDATION: ret = disable_validation (); @@ -1410,11 +1408,10 @@ main (int argc, char *argv[]) ret = test_key (key_file); break; case RESET: - case RESET | HASH_FILE: - ret = reset_moks (hash_file, 0); - break; - case RESET | ROOT_PW: - ret = reset_moks (NULL, 1); + if (use_root_pw) + ret = reset_moks (NULL, 1); + else + ret = reset_moks (hash_file, 0); break; case GENERATE_PW_HASH: ret = generate_pw_hash (input_pw); -- 1.8.1.4 From 3c3725784cd31d867443675cb5aa6698b952ac2b Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Tue, 2 Apr 2013 11:29:01 +0800 Subject: [PATCH 3/3] Show help if there is no key to be imported/deleted --- src/mokutil.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/mokutil.c b/src/mokutil.c index 6c3a135..58566f9 100644 --- a/src/mokutil.c +++ b/src/mokutil.c @@ -1317,6 +1317,11 @@ main (int argc, char *argv[]) total++; } + if (total == 0) { + command |= HELP; + break; + } + files = malloc (total * sizeof (char *)); for (i = 0; i < total; i++) { f_ind = i + optind - 1; -- 1.8.1.4