summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Ching-Pang Lin <glin@suse.com>2012-09-19 17:12:30 +0800
committerGary Ching-Pang Lin <glin@suse.com>2012-09-19 17:12:30 +0800
commitc326e2dff41a6b3a67d37350bce32db3e532d458 (patch)
tree94b188b971e1dfbcc8d3a2e9dee27a26917b9112
parent1041805a18fcff094ab59328b576a301d5d727a3 (diff)
downloadefi-boot-shim-c326e2dff41a6b3a67d37350bce32db3e532d458.tar.gz
efi-boot-shim-c326e2dff41a6b3a67d37350bce32db3e532d458.zip
Simplify the key management
Move the key list building and management to mokutil to keep MokManager as simple as possible.
-rw-r--r--MokManager.c336
1 files changed, 44 insertions, 292 deletions
diff --git a/MokManager.c b/MokManager.c
index b42be707..28213249 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -97,7 +97,8 @@ done:
static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
MokListNode *list;
- int i, remain = DataSize;
+ INT64 remain = DataSize;
+ int i;
void *ptr;
list = AllocatePool(sizeof(MokListNode) * num);
@@ -109,24 +110,23 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
ptr = Data;
for (i = 0; i < num; i++) {
+ CopyMem(&list[i].MokSize, ptr, sizeof(UINT32));
+ remain -= sizeof(UINT32) + list[i].MokSize;
+
if (remain < 0) {
- Print(L"MOK list was corrupted\n");
+ Print(L"the list was corrupted\n");
FreePool(list);
return NULL;
}
- CopyMem(&list[i].MokSize, ptr, sizeof(UINT32));
ptr += sizeof(UINT32);
list[i].Mok = ptr;
ptr += list[i].MokSize;
-
- remain -= sizeof(UINT32) + list[i].MokSize;
}
return list;
}
-/* XXX MOK functions */
static void print_x509_name (X509_NAME *X509Name, char *name)
{
char *str;
@@ -285,6 +285,8 @@ static void show_mok_info (void *Mok, UINTN MokSize)
if (!Mok || MokSize == 0)
return;
+Print(L"size: %d\n", MokSize);
+
efi_status = get_sha256sum(Mok, MokSize, hash);
if (efi_status != EFI_SUCCESS) {
@@ -306,220 +308,51 @@ static void show_mok_info (void *Mok, UINTN MokSize)
}
}
-static UINT8 delete_mok(MokListNode *list, UINT32 MokNum, UINT32 delete)
-{
- if (!list || !MokNum || MokNum <= delete)
- return 0;
-
- list[delete].Mok = NULL;
- list[delete].MokSize = 0;
-
- return 1;
-}
-
-static UINT8 mok_deletion_prompt(MokListNode *list, UINT32 MokNum)
-{
- EFI_INPUT_KEY key;
- CHAR16 line[10];
- unsigned int word_count = 0;
- UINTN delete;
-
- Print(L"delete key: ");
- do {
- key = get_keystroke();
- if ((key.UnicodeChar < '0' ||
- key.UnicodeChar > '9' ||
- word_count >= 10) &&
- key.UnicodeChar != CHAR_BACKSPACE)
- continue;
-
- if (word_count == 0 && key.UnicodeChar == CHAR_BACKSPACE)
- continue;
-
- Print(L"%c", key.UnicodeChar);
-
- if (key.UnicodeChar == CHAR_BACKSPACE) {
- word_count--;
- line[word_count] = '\0';
- continue;
- }
-
- line[word_count] = key.UnicodeChar;
- word_count++;
- } while (key.UnicodeChar != CHAR_CARRIAGE_RETURN);
- Print(L"\n");
-
- if (word_count == 0)
- return 0;
-
- line[word_count] = '\0';
- delete = Atoi(line)-1;
-
- if (delete >= MokNum) {
- Print(L"No such key\n");
- return 0;
- }
-
- if (!list[delete].Mok) {
- Print(L"Already deleted\n");
- return 0;
- }
-
- Print(L"Delete this key?\n");
- show_mok_info(list[delete].Mok, list[delete].MokSize);
- Print(L"(y/N) ");
- key = get_keystroke();
- if (key.UnicodeChar != 'y' && key.UnicodeChar != 'Y') {
- Print(L"N\nAbort\n");
- return 0;
- }
- Print(L"y\nDelete key %d\n", delete+1);
-
- return delete_mok(list, MokNum, delete);
-}
-
-static void write_mok_list(void *MokListData, UINTN MokListDataSize,
- MokListNode *list, UINT32 MokNum)
-{
- EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
- EFI_STATUS efi_status;
- UINT32 new_num = 0;
- unsigned int i;
- UINTN DataSize = 0;
- void *Data, *ptr;
-
- if (!MokListData || !list)
- return;
-
- for (i = 0; i < MokNum; i++) {
- if (list[i].Mok && list[i].MokSize > 0) {
- DataSize += list[i].MokSize + sizeof(UINT32);
- if (new_num < i) {
- list[new_num].Mok = list[i].Mok;
- list[new_num].MokSize = list[i].MokSize;
- }
- new_num++;
- }
- }
-
- if (new_num == 0) {
- Data = NULL;
- goto done;
- }
-
- DataSize += sizeof(UINT32);
-
- Data = AllocatePool(DataSize * sizeof(UINT8));
- ptr = Data;
-
- CopyMem(Data, &new_num, sizeof(new_num));
- ptr += sizeof(new_num);
-
- for (i = 0; i < new_num; i++) {
- CopyMem(ptr, &list[i].MokSize, sizeof(list[i].MokSize));
- ptr += sizeof(list[i].MokSize);
- CopyMem(ptr, list[i].Mok, list[i].MokSize);
- ptr += list[i].MokSize;
- }
-
-done:
- efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList",
- &shim_lock_guid,
- EFI_VARIABLE_NON_VOLATILE
- | EFI_VARIABLE_BOOTSERVICE_ACCESS,
- DataSize, Data);
- if (efi_status != EFI_SUCCESS) {
- Print(L"Failed to set variable %d\n", efi_status);
- }
-
- if (Data)
- FreePool(Data);
-}
-
-static void mok_mgmt_shell (void)
+static UINT8 list_keys (void *MokNew, UINTN MokNewSize)
{
- EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
- EFI_STATUS efi_status;
- unsigned int i, changed = 0;
- void *MokListData = NULL;
- UINTN MokListDataSize = 0;
UINT32 MokNum;
- UINT32 attributes;
- MokListNode *list = NULL;
- EFI_INPUT_KEY key;
-
- efi_status = get_variable(L"MokList", shim_lock_guid, &attributes,
- &MokListDataSize, &MokListData);
+ MokListNode *keys = NULL;
+ int i, ret = 0;
- if (efi_status != EFI_SUCCESS) {
- Print(L"Failed to get MokList\n");
- goto error;
- }
-
- if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
- Print(L"MokList is compromised!\nErase all keys in MokList!\n");
- if (delete_variable(L"MokList", shim_lock_guid) != EFI_SUCCESS) {
- Print(L"Failed to erase MokList\n");
- }
- goto error;
- }
-
- CopyMem(&MokNum, MokListData, sizeof(UINT32));
+ CopyMem(&MokNum, MokNew, sizeof(UINT32));
if (MokNum == 0) {
- Print(L"No key enrolled\n");
+ Print(L"No key exists\n");
goto error;
}
- list = build_mok_list(MokNum,
- (void *)MokListData + sizeof(UINT32),
- MokListDataSize - sizeof(UINT32));
- if (!list) {
- Print(L"Failed to construct MOK list\n");
+ keys = build_mok_list(MokNum,
+ (void *)MokNew + sizeof(UINT32),
+ MokNewSize - sizeof(UINT32));
+
+ if (!keys) {
+ Print(L"Failed to construct key list in MokNew\n");
goto error;
}
- do {
- Print(L"shim) ");
- key = get_keystroke();
- Print(L"%c\n", key.UnicodeChar);
-
- switch (key.UnicodeChar) {
- case 'l':
- case 'L':
- for (i = 0; i < MokNum; i++) {
- if (list[i].Mok) {
- Print(L"Key %d\n", i+1);
- show_mok_info(list[i].Mok, list[i].MokSize);
- Print(L"\n");
- }
- }
- break;
- case 'd':
- case 'D':
- if (mok_deletion_prompt(list, MokNum) && changed == 0)
- changed = 1;
- break;
- }
- } while (key.UnicodeChar != 'c' && key.UnicodeChar != 'C');
-
- if (changed) {
- write_mok_list(MokListData, MokListDataSize, list, MokNum);
+ Print(L"New machine owner key(s):\n\n");
+ for (i = 0; i < MokNum; i++) {
+ Print(L"Key %d:\n", i);
+ show_mok_info(keys[i].Mok, keys[i].MokSize);
+ Print(L"\n");
}
+ ret = 1;
error:
- if (MokListData)
- FreePool(MokListData);
- if (list)
- FreePool(list);
+ if (keys)
+ FreePool(keys);
+
+ return ret;
}
-static UINT8 mok_enrollment_prompt (void *Mok, UINTN MokSize)
+static UINT8 mok_enrollment_prompt (void *MokNew, UINTN MokNewSize)
{
EFI_INPUT_KEY key;
- Print(L"New machine owner key:\n\n");
- show_mok_info(Mok, MokSize);
- Print(L"\nEnroll the key? (y/N): ");
+ if (!list_keys(MokNew, MokNewSize)) {
+ return 0;
+ }
+
+ Print(L"\nEnroll the key(s)? (y/N): ");
key = get_keystroke();
Print(L"%c\n", key.UnicodeChar);
@@ -533,59 +366,23 @@ static UINT8 mok_enrollment_prompt (void *Mok, UINTN MokSize)
return 0;
}
-static EFI_STATUS enroll_mok (void *Mok, UINT32 MokSize, void *OldData,
- UINT32 OldDataSize, UINT32 MokNum)
+static EFI_STATUS enroll_mok (void *MokNew, UINT32 MokNewSize)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
- void *Data, *ptr;
- UINT32 DataSize = 0;
-
- if (OldData)
- DataSize += OldDataSize;
- else
- DataSize += sizeof(UINT32);
- DataSize += sizeof(UINT32);
- DataSize += MokSize;
- MokNum += 1;
-
- Data = AllocatePool(DataSize);
-
- if (!Data) {
- Print(L"Failed to allocate buffer for MOK list\n");
- return EFI_OUT_OF_RESOURCES;
- }
-
- ptr = Data;
-
- if (OldData) {
- CopyMem(ptr, OldData, OldDataSize);
- CopyMem(ptr, &MokNum, sizeof(MokNum));
- ptr += OldDataSize;
- } else {
- CopyMem(ptr, &MokNum, sizeof(MokNum));
- ptr += sizeof(MokNum);
- }
/* Write new MOK */
- CopyMem(ptr, &MokSize, sizeof(MokSize));
- ptr += sizeof(MokSize);
- CopyMem(ptr, Mok, MokSize);
-
efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList",
&shim_lock_guid,
EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS,
- DataSize, Data);
+ MokNewSize, MokNew);
if (efi_status != EFI_SUCCESS) {
Print(L"Failed to set variable %d\n", efi_status);
goto error;
}
error:
- if (Data)
- FreePool(Data);
-
return efi_status;
}
@@ -593,83 +390,38 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle)
{
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
EFI_STATUS efi_status;
- UINTN MokSize = 0, MokListDataSize = 0;
- void *Mok = NULL, *MokListData = NULL;
- UINT32 MokNum = 0;
+ UINTN MokNewSize = 0;
+ void *MokNew = NULL;
UINT32 attributes;
- MokListNode *list = NULL;
UINT8 confirmed;
efi_status = get_variable(L"MokNew", shim_lock_guid, &attributes,
- &MokSize, &Mok);
+ &MokNewSize, &MokNew);
if (efi_status != EFI_SUCCESS) {
goto error;
}
- efi_status = get_variable(L"MokList", shim_lock_guid, &attributes,
- &MokListDataSize, &MokListData);
-
- if (efi_status == EFI_SUCCESS && MokListData) {
- int i;
-
- if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) {
- Print(L"MokList is compromised!\nErase all keys in MokList!\n");
- if (delete_variable(L"MokList", shim_lock_guid) != EFI_SUCCESS) {
- Print(L"Failed to erase MokList\n");
- }
- goto error;
- }
-
- CopyMem(&MokNum, MokListData, sizeof(UINT32));
- list = build_mok_list(MokNum,
- (void *)MokListData + sizeof(UINT32),
- MokListDataSize - sizeof(UINT32));
-
- if (!list) {
- Print(L"Failed to construct MOK list\n");
- goto error;
- }
-
- /* check if the key is already enrolled */
- for (i = 0; i < MokNum; i++) {
- if (list[i].MokSize == MokSize &&
- CompareMem(list[i].Mok, Mok, MokSize) == 0) {
- Print(L"MOK was already enrolled\n");
- goto error;
- }
- }
- }
-
- confirmed = mok_enrollment_prompt(Mok, MokSize);
+ confirmed = mok_enrollment_prompt(MokNew, MokNewSize);
if (!confirmed)
goto error;
- efi_status = enroll_mok(Mok, MokSize, MokListData,
- MokListDataSize, MokNum);
+ efi_status = enroll_mok(MokNew, MokNewSize);
if (efi_status != EFI_SUCCESS) {
Print(L"Failed to enroll MOK\n");
goto error;
}
- mok_mgmt_shell();
-
error:
- if (Mok) {
+ if (MokNew) {
if (delete_variable(L"MokNew", shim_lock_guid) != EFI_SUCCESS) {
Print(L"Failed to delete MokNew\n");
}
- FreePool (Mok);
+ FreePool (MokNew);
}
- if (list)
- FreePool (list);
-
- if (MokListData)
- FreePool (MokListData);
-
return EFI_SUCCESS;
}