125b3129ee
- Update shim-mokmanager-ui-revamp.patch to include fixes for MokManager + reboot the system after clearing MOK password + fetch more info from X509 name + check the suffix of the key file OBS-URL: https://build.opensuse.org/request/show/185349 OBS-URL: https://build.opensuse.org/package/show/devel:openSUSE:Factory/shim?expand=0&rev=30
2083 lines
56 KiB
Diff
2083 lines
56 KiB
Diff
From a6436443a82b23de4c5dfe83f3c8389f8b554ad3 Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Thu, 30 May 2013 14:22:43 +0800
|
|
Subject: [PATCH 01/11] MokManager: Remove the unnecessary string duplication
|
|
|
|
---
|
|
MokManager.c | 19 ++++++++-----------
|
|
1 file changed, 8 insertions(+), 11 deletions(-)
|
|
|
|
diff --git a/MokManager.c b/MokManager.c
|
|
index b05a52f..918d96b 100644
|
|
--- a/MokManager.c
|
|
+++ b/MokManager.c
|
|
@@ -1433,45 +1433,45 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
- menu_strings[i] = StrDuplicate(L"Continue boot");
|
|
+ menu_strings[i] = L"Continue boot";
|
|
menu_item[i] = MOK_CONTINUE_BOOT;
|
|
|
|
i++;
|
|
|
|
if (MokNew || MokAuth) {
|
|
if (!MokNew) {
|
|
- menu_strings[i] = StrDuplicate(L"Reset MOK");
|
|
+ menu_strings[i] = L"Reset MOK";
|
|
menu_item[i] = MOK_RESET_MOK;
|
|
} else {
|
|
- menu_strings[i] = StrDuplicate(L"Enroll MOK");
|
|
+ menu_strings[i] = L"Enroll MOK";
|
|
menu_item[i] = MOK_ENROLL_MOK;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
if (MokDel || MokDelAuth) {
|
|
- menu_strings[i] = StrDuplicate(L"Delete MOK");
|
|
+ menu_strings[i] = L"Delete MOK";
|
|
menu_item[i] = MOK_DELETE_MOK;
|
|
i++;
|
|
}
|
|
|
|
if (MokSB) {
|
|
- menu_strings[i] = StrDuplicate(L"Change Secure Boot state");
|
|
+ menu_strings[i] = L"Change Secure Boot state";
|
|
menu_item[i] = MOK_CHANGE_SB;
|
|
i++;
|
|
}
|
|
|
|
if (MokPW) {
|
|
- menu_strings[i] = StrDuplicate(L"Set MOK password");
|
|
+ menu_strings[i] = L"Set MOK password";
|
|
menu_item[i] = MOK_SET_PW;
|
|
i++;
|
|
}
|
|
|
|
- menu_strings[i] = StrDuplicate(L"Enroll key from disk");
|
|
+ menu_strings[i] = L"Enroll key from disk";
|
|
menu_item[i] = MOK_KEY_ENROLL;
|
|
i++;
|
|
|
|
- menu_strings[i] = StrDuplicate(L"Enroll hash from disk");
|
|
+ menu_strings[i] = L"Enroll hash from disk";
|
|
menu_item[i] = MOK_HASH_ENROLL;
|
|
i++;
|
|
|
|
@@ -1514,9 +1514,6 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
|
out:
|
|
console_reset();
|
|
|
|
- for (i=0; menu_strings[i] != NULL; i++)
|
|
- FreePool(menu_strings[i]);
|
|
-
|
|
FreePool(menu_strings);
|
|
|
|
if (menu_item)
|
|
--
|
|
1.8.1.4
|
|
|
|
|
|
From ef8fdc597fd532cc4c91c3d2ee638ef339002618 Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Thu, 18 Apr 2013 17:13:12 +0800
|
|
Subject: [PATCH 02/11] MokManager: draw the countdown screen
|
|
|
|
---
|
|
MokManager.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 60 insertions(+)
|
|
|
|
diff --git a/MokManager.c b/MokManager.c
|
|
index 918d96b..6b8c79b 100644
|
|
--- a/MokManager.c
|
|
+++ b/MokManager.c
|
|
@@ -1360,6 +1360,63 @@ static BOOLEAN verify_pw(void)
|
|
return TRUE;
|
|
}
|
|
|
|
+static int draw_countdown()
|
|
+{
|
|
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
|
|
+ EFI_INPUT_KEY key;
|
|
+ EFI_STATUS status;
|
|
+ UINTN cols, rows;
|
|
+ CHAR16 *title[2];
|
|
+ CHAR16 *message = L"Press any key to perform MOK management";
|
|
+ int timeout = 10, wait = 10000000;
|
|
+
|
|
+ CopyMem(&SavedMode, ST->ConOut->Mode, sizeof(SavedMode));
|
|
+ uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE);
|
|
+ uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
|
|
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
|
|
+
|
|
+ title[0] = PoolPrint (L"%s UEFI key management", SHIM_VENDOR);
|
|
+ title[1] = NULL;
|
|
+
|
|
+ console_print_box_at(title, -1, 0, 0, -1, -1, 1, 1);
|
|
+
|
|
+ uefi_call_wrapper(ST->ConOut->QueryMode, 4, ST->ConOut,
|
|
+ ST->ConOut->Mode->Mode, &cols, &rows);
|
|
+
|
|
+ PrintAt((cols - StrLen(message))/2, rows/2, message);
|
|
+ while (1) {
|
|
+ if (timeout > 1)
|
|
+ PrintAt(2, rows - 3, L"Booting in %d seconds ", timeout);
|
|
+ else if (timeout)
|
|
+ PrintAt(2, rows - 3, L"Booting in %d second ", timeout);
|
|
+
|
|
+ status = WaitForSingleEvent(ST->ConIn->WaitForKey, wait);
|
|
+
|
|
+ if (status != EFI_TIMEOUT) {
|
|
+ /* Clear the key in the queue */
|
|
+ uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2,
|
|
+ ST->ConIn, &key);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ timeout--;
|
|
+ if (!timeout)
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ FreePool(title[0]);
|
|
+
|
|
+ /* Restore everything */
|
|
+ uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut,
|
|
+ SavedMode.CursorVisible);
|
|
+ uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut,
|
|
+ SavedMode.CursorColumn, SavedMode.CursorRow);
|
|
+ uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
|
|
+ SavedMode.Attribute);
|
|
+
|
|
+ return timeout;
|
|
+}
|
|
+
|
|
typedef enum {
|
|
MOK_CONTINUE_BOOT,
|
|
MOK_RESET_MOK,
|
|
@@ -1477,6 +1534,9 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
|
|
|
menu_strings[i] = NULL;
|
|
|
|
+ if (draw_countdown() == 0)
|
|
+ goto out;
|
|
+
|
|
while (choice >= 0) {
|
|
choice = console_select((CHAR16 *[]){ L"Perform MOK management", NULL },
|
|
menu_strings, 0);
|
|
--
|
|
1.8.1.4
|
|
|
|
|
|
From 9ff682d251b3d30fae63c026aa0105c49db7db16 Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Wed, 26 Jun 2013 12:23:26 +0800
|
|
Subject: [PATCH 03/11] MokManager: remove the duplicate get_keystroke()
|
|
|
|
---
|
|
MokManager.c | 14 +-------------
|
|
1 file changed, 1 insertion(+), 13 deletions(-)
|
|
|
|
diff --git a/MokManager.c b/MokManager.c
|
|
index 6b8c79b..6555a06 100644
|
|
--- a/MokManager.c
|
|
+++ b/MokManager.c
|
|
@@ -58,18 +58,6 @@ static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes,
|
|
return efi_status;
|
|
}
|
|
|
|
-static EFI_INPUT_KEY get_keystroke (void)
|
|
-{
|
|
- EFI_INPUT_KEY key;
|
|
- UINTN EventIndex;
|
|
-
|
|
- uefi_call_wrapper(BS->WaitForEvent, 3, 1, &ST->ConIn->WaitForKey,
|
|
- &EventIndex);
|
|
- uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn, &key);
|
|
-
|
|
- return key;
|
|
-}
|
|
-
|
|
static EFI_STATUS get_sha1sum (void *Data, int DataSize, UINT8 *hash)
|
|
{
|
|
EFI_STATUS status;
|
|
@@ -538,7 +526,7 @@ static UINT8 get_line (UINT32 *length, CHAR16 *line, UINT32 line_max, UINT8 show
|
|
int count = 0;
|
|
|
|
do {
|
|
- key = get_keystroke();
|
|
+ key = console_get_keystroke();
|
|
|
|
if ((count >= line_max &&
|
|
key.UnicodeChar != CHAR_BACKSPACE) ||
|
|
--
|
|
1.8.1.4
|
|
|
|
|
|
From 4c9f6b0b2100f5e878d8578db3ee232c20440735 Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Wed, 26 Jun 2013 15:21:35 +0800
|
|
Subject: [PATCH 04/11] MokManager: enhance the password prompt
|
|
|
|
---
|
|
MokManager.c | 106 +++++++++++++++++++++++++++++++++++++++++++++--------------
|
|
1 file changed, 81 insertions(+), 25 deletions(-)
|
|
|
|
diff --git a/MokManager.c b/MokManager.c
|
|
index 6555a06..4393aec 100644
|
|
--- a/MokManager.c
|
|
+++ b/MokManager.c
|
|
@@ -606,6 +606,61 @@ done:
|
|
return status;
|
|
}
|
|
|
|
+static void console_save_and_set_mode (SIMPLE_TEXT_OUTPUT_MODE *SavedMode)
|
|
+{
|
|
+ if (!SavedMode) {
|
|
+ Print(L"Invalid parameter: SavedMode\n");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ CopyMem(SavedMode, ST->ConOut->Mode, sizeof(SIMPLE_TEXT_OUTPUT_MODE));
|
|
+ uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE);
|
|
+ uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
|
|
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
|
|
+}
|
|
+
|
|
+static void console_restore_mode (SIMPLE_TEXT_OUTPUT_MODE *SavedMode)
|
|
+{
|
|
+ uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut,
|
|
+ SavedMode->CursorVisible);
|
|
+ uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut,
|
|
+ SavedMode->CursorColumn, SavedMode->CursorRow);
|
|
+ uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
|
|
+ SavedMode->Attribute);
|
|
+}
|
|
+
|
|
+static UINT32 get_password (CHAR16 *prompt, CHAR16 *password, UINT32 max)
|
|
+{
|
|
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
|
|
+ CHAR16 *str;
|
|
+ CHAR16 *message[2];
|
|
+ UINTN length;
|
|
+ UINT32 pw_length;
|
|
+
|
|
+ if (!prompt)
|
|
+ prompt = L"Password:";
|
|
+
|
|
+ console_save_and_set_mode(&SavedMode);
|
|
+
|
|
+ str = PoolPrint(L"%s ", prompt);
|
|
+ if (!str) {
|
|
+ console_errorbox(L"Failed to allocate prompt");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ message[0] = str;
|
|
+ message[1] = NULL;
|
|
+ length = StrLen(message[0]);
|
|
+ console_print_box_at(message, -1, -length-4, -5, length+4, 3, 0, 1);
|
|
+ get_line(&pw_length, password, max, 0);
|
|
+
|
|
+ console_restore_mode(&SavedMode);
|
|
+
|
|
+ FreePool(str);
|
|
+
|
|
+ return pw_length;
|
|
+}
|
|
+
|
|
static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
|
|
void *Data, UINTN DataSize,
|
|
UINT8 *auth, CHAR16 *prompt)
|
|
@@ -632,15 +687,10 @@ static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
|
|
}
|
|
|
|
while (fail_count < 3) {
|
|
- if (prompt) {
|
|
- Print(L"%s", prompt);
|
|
- } else {
|
|
- Print(L"Password: ");
|
|
- }
|
|
- get_line(&pw_length, password, PASSWORD_MAX, 0);
|
|
+ pw_length = get_password(prompt, password, PASSWORD_MAX);
|
|
|
|
if (pw_length < PASSWORD_MIN || pw_length > PASSWORD_MAX) {
|
|
- Print(L"Invalid password length\n");
|
|
+ console_errorbox(L"Invalid password length");
|
|
fail_count++;
|
|
continue;
|
|
}
|
|
@@ -663,13 +713,13 @@ static EFI_STATUS match_password (PASSWORD_CRYPT *pw_crypt,
|
|
pw_length * sizeof(CHAR16), hash);
|
|
}
|
|
if (status != EFI_SUCCESS) {
|
|
- Print(L"Unable to generate password hash\n");
|
|
+ console_errorbox(L"Unable to generate password hash");
|
|
fail_count++;
|
|
continue;
|
|
}
|
|
|
|
if (CompareMem(auth_hash, hash, auth_size) != 0) {
|
|
- Print(L"Password doesn't match\n");
|
|
+ console_errorbox(L"Password doesn't match");
|
|
fail_count++;
|
|
continue;
|
|
}
|
|
@@ -1307,13 +1357,17 @@ static void mok_key_enroll(void)
|
|
FreePool(data);
|
|
}
|
|
|
|
-static BOOLEAN verify_pw(void)
|
|
+static BOOLEAN verify_pw(BOOLEAN *protected)
|
|
{
|
|
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
|
EFI_STATUS efi_status;
|
|
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
|
|
UINT8 pwhash[PASSWORD_CRYPT_SIZE];
|
|
UINTN size = PASSWORD_CRYPT_SIZE;
|
|
UINT32 attributes;
|
|
+ CHAR16 *message[2];
|
|
+
|
|
+ *protected = FALSE;
|
|
|
|
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokPWStore",
|
|
&shim_lock_guid, &attributes, &size,
|
|
@@ -1333,18 +1387,28 @@ static BOOLEAN verify_pw(void)
|
|
|
|
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
|
|
|
+ /* Draw the background */
|
|
+ console_save_and_set_mode(&SavedMode);
|
|
+ message[0] = PoolPrint (L"%s UEFI key management", SHIM_VENDOR);
|
|
+ message[1] = NULL;
|
|
+ console_print_box_at(message, -1, 0, 0, -1, -1, 1, 1);
|
|
+ FreePool(message[0]);
|
|
+ console_restore_mode(&SavedMode);
|
|
+
|
|
if (size == PASSWORD_CRYPT_SIZE) {
|
|
efi_status = match_password((PASSWORD_CRYPT *)pwhash, NULL, 0,
|
|
- NULL, L"Enter MOK password: ");
|
|
+ NULL, L"Enter MOK password:");
|
|
} else {
|
|
efi_status = match_password(NULL, NULL, 0, pwhash,
|
|
- L"Enter MOK password: ");
|
|
+ L"Enter MOK password:");
|
|
}
|
|
if (efi_status != EFI_SUCCESS) {
|
|
console_notify(L"Password limit reached");
|
|
return FALSE;
|
|
}
|
|
|
|
+ *protected = TRUE;
|
|
+
|
|
return TRUE;
|
|
}
|
|
|
|
@@ -1358,10 +1422,7 @@ static int draw_countdown()
|
|
CHAR16 *message = L"Press any key to perform MOK management";
|
|
int timeout = 10, wait = 10000000;
|
|
|
|
- CopyMem(&SavedMode, ST->ConOut->Mode, sizeof(SavedMode));
|
|
- uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut, FALSE);
|
|
- uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
|
|
- EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
|
|
+ console_save_and_set_mode (&SavedMode);
|
|
|
|
title[0] = PoolPrint (L"%s UEFI key management", SHIM_VENDOR);
|
|
title[1] = NULL;
|
|
@@ -1394,13 +1455,7 @@ static int draw_countdown()
|
|
|
|
FreePool(title[0]);
|
|
|
|
- /* Restore everything */
|
|
- uefi_call_wrapper(ST->ConOut->EnableCursor, 2, ST->ConOut,
|
|
- SavedMode.CursorVisible);
|
|
- uefi_call_wrapper(ST->ConOut->SetCursorPosition, 3, ST->ConOut,
|
|
- SavedMode.CursorColumn, SavedMode.CursorRow);
|
|
- uefi_call_wrapper(ST->ConOut->SetAttribute, 2, ST->ConOut,
|
|
- SavedMode.Attribute);
|
|
+ console_restore_mode(&SavedMode);
|
|
|
|
return timeout;
|
|
}
|
|
@@ -1433,9 +1488,10 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
|
UINT8 auth[PASSWORD_CRYPT_SIZE];
|
|
UINTN auth_size = PASSWORD_CRYPT_SIZE;
|
|
UINT32 attributes;
|
|
+ BOOLEAN protected;
|
|
EFI_STATUS ret = EFI_SUCCESS;
|
|
|
|
- if (verify_pw() == FALSE)
|
|
+ if (verify_pw(&protected) == FALSE)
|
|
return EFI_ACCESS_DENIED;
|
|
|
|
efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokAuth",
|
|
@@ -1522,7 +1578,7 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle,
|
|
|
|
menu_strings[i] = NULL;
|
|
|
|
- if (draw_countdown() == 0)
|
|
+ if (protected == FALSE && draw_countdown() == 0)
|
|
goto out;
|
|
|
|
while (choice >= 0) {
|
|
--
|
|
1.8.1.4
|
|
|
|
|
|
From 6e71cb7900b99482c7b51a6076f8392022ba15a6 Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Thu, 27 Jun 2013 11:59:09 +0800
|
|
Subject: [PATCH 05/11] Enable openssl bio_printf()
|
|
|
|
bio_printf() was replaced with a dummy function and this made
|
|
several openssl functions useless. This commit adds the print
|
|
functions back, so that we don't have to implement our own
|
|
ASN1 time print function.
|
|
---
|
|
Cryptlib/OpenSSL/Makefile | 1 +
|
|
Cryptlib/OpenSSL/crypto/bio/b_print.c | 842 ++++++++++++++++++++++++++++++++++
|
|
Cryptlib/SysCall/CrtWrapper.c | 10 -
|
|
3 files changed, 843 insertions(+), 10 deletions(-)
|
|
create mode 100644 Cryptlib/OpenSSL/crypto/bio/b_print.c
|
|
|
|
diff --git a/Cryptlib/OpenSSL/Makefile b/Cryptlib/OpenSSL/Makefile
|
|
index f8ab841..c93d5af 100644
|
|
--- a/Cryptlib/OpenSSL/Makefile
|
|
+++ b/Cryptlib/OpenSSL/Makefile
|
|
@@ -215,6 +215,7 @@ OBJS = crypto/cryptlib.o \
|
|
crypto/bio/bf_null.o \
|
|
crypto/bio/bf_buff.o \
|
|
crypto/bio/b_dump.o \
|
|
+ crypto/bio/b_print.o \
|
|
crypto/bio/bf_nbio.o \
|
|
crypto/bio/bss_log.o \
|
|
crypto/bio/bss_bio.o \
|
|
diff --git a/Cryptlib/OpenSSL/crypto/bio/b_print.c b/Cryptlib/OpenSSL/crypto/bio/b_print.c
|
|
new file mode 100644
|
|
index 0000000..3a87b0e
|
|
--- /dev/null
|
|
+++ b/Cryptlib/OpenSSL/crypto/bio/b_print.c
|
|
@@ -0,0 +1,842 @@
|
|
+/* crypto/bio/b_print.c */
|
|
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * This package is an SSL implementation written
|
|
+ * by Eric Young (eay@cryptsoft.com).
|
|
+ * The implementation was written so as to conform with Netscapes SSL.
|
|
+ *
|
|
+ * This library is free for commercial and non-commercial use as long as
|
|
+ * the following conditions are aheared to. The following conditions
|
|
+ * apply to all code found in this distribution, be it the RC4, RSA,
|
|
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
|
+ * included with this distribution is covered by the same copyright terms
|
|
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
|
+ *
|
|
+ * Copyright remains Eric Young's, and as such any Copyright notices in
|
|
+ * the code are not to be removed.
|
|
+ * If this package is used in a product, Eric Young should be given attribution
|
|
+ * as the author of the parts of the library used.
|
|
+ * This can be in the form of a textual message at program startup or
|
|
+ * in documentation (online or textual) provided with the package.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ * 3. All advertising materials mentioning features or use of this software
|
|
+ * must display the following acknowledgement:
|
|
+ * "This product includes cryptographic software written by
|
|
+ * Eric Young (eay@cryptsoft.com)"
|
|
+ * The word 'cryptographic' can be left out if the rouines from the library
|
|
+ * being used are not cryptographic related :-).
|
|
+ * 4. If you include any Windows specific code (or a derivative thereof) from
|
|
+ * the apps directory (application code) you must include an acknowledgement:
|
|
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ *
|
|
+ * The licence and distribution terms for any publically available version or
|
|
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
|
|
+ * copied and put under another distribution licence
|
|
+ * [including the GNU Public Licence.]
|
|
+ */
|
|
+
|
|
+/* disable assert() unless BIO_DEBUG has been defined */
|
|
+#ifndef BIO_DEBUG
|
|
+# ifndef NDEBUG
|
|
+# define NDEBUG
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+/*
|
|
+ * Stolen from tjh's ssl/ssl_trc.c stuff.
|
|
+ */
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <string.h>
|
|
+#include <ctype.h>
|
|
+#include <assert.h>
|
|
+#include <limits.h>
|
|
+#include "cryptlib.h"
|
|
+#ifndef NO_SYS_TYPES_H
|
|
+#include <sys/types.h>
|
|
+#endif
|
|
+#include <openssl/bn.h> /* To get BN_LLONG properly defined */
|
|
+#include <openssl/bio.h>
|
|
+
|
|
+#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT)
|
|
+# ifndef HAVE_LONG_LONG
|
|
+# define HAVE_LONG_LONG 1
|
|
+# endif
|
|
+#endif
|
|
+
|
|
+/***************************************************************************/
|
|
+
|
|
+/*
|
|
+ * Copyright Patrick Powell 1995
|
|
+ * This code is based on code written by Patrick Powell <papowell@astart.com>
|
|
+ * It may be used for any purpose as long as this notice remains intact
|
|
+ * on all source code distributions.
|
|
+ */
|
|
+
|
|
+/*
|
|
+ * This code contains numerious changes and enhancements which were
|
|
+ * made by lots of contributors over the last years to Patrick Powell's
|
|
+ * original code:
|
|
+ *
|
|
+ * o Patrick Powell <papowell@astart.com> (1995)
|
|
+ * o Brandon Long <blong@fiction.net> (1996, for Mutt)
|
|
+ * o Thomas Roessler <roessler@guug.de> (1998, for Mutt)
|
|
+ * o Michael Elkins <me@cs.hmc.edu> (1998, for Mutt)
|
|
+ * o Andrew Tridgell <tridge@samba.org> (1998, for Samba)
|
|
+ * o Luke Mewburn <lukem@netbsd.org> (1999, for LukemFTP)
|
|
+ * o Ralf S. Engelschall <rse@engelschall.com> (1999, for Pth)
|
|
+ * o ... (for OpenSSL)
|
|
+ */
|
|
+
|
|
+#ifdef HAVE_LONG_DOUBLE
|
|
+#define LDOUBLE long double
|
|
+#else
|
|
+#define LDOUBLE double
|
|
+#endif
|
|
+
|
|
+#if HAVE_LONG_LONG
|
|
+# if defined(OPENSSL_SYS_WIN32) && !defined(__GNUC__)
|
|
+# define LLONG __int64
|
|
+# else
|
|
+# define LLONG long long
|
|
+# endif
|
|
+#else
|
|
+#define LLONG long
|
|
+#endif
|
|
+
|
|
+static void fmtstr (char **, char **, size_t *, size_t *,
|
|
+ const char *, int, int, int);
|
|
+static void fmtint (char **, char **, size_t *, size_t *,
|
|
+ LLONG, int, int, int, int);
|
|
+static void fmtfp (char **, char **, size_t *, size_t *,
|
|
+ LDOUBLE, int, int, int);
|
|
+static void doapr_outch (char **, char **, size_t *, size_t *, int);
|
|
+static void _dopr(char **sbuffer, char **buffer,
|
|
+ size_t *maxlen, size_t *retlen, int *truncated,
|
|
+ const char *format, va_list args);
|
|
+
|
|
+/* format read states */
|
|
+#define DP_S_DEFAULT 0
|
|
+#define DP_S_FLAGS 1
|
|
+#define DP_S_MIN 2
|
|
+#define DP_S_DOT 3
|
|
+#define DP_S_MAX 4
|
|
+#define DP_S_MOD 5
|
|
+#define DP_S_CONV 6
|
|
+#define DP_S_DONE 7
|
|
+
|
|
+/* format flags - Bits */
|
|
+#define DP_F_MINUS (1 << 0)
|
|
+#define DP_F_PLUS (1 << 1)
|
|
+#define DP_F_SPACE (1 << 2)
|
|
+#define DP_F_NUM (1 << 3)
|
|
+#define DP_F_ZERO (1 << 4)
|
|
+#define DP_F_UP (1 << 5)
|
|
+#define DP_F_UNSIGNED (1 << 6)
|
|
+
|
|
+/* conversion flags */
|
|
+#define DP_C_SHORT 1
|
|
+#define DP_C_LONG 2
|
|
+#define DP_C_LDOUBLE 3
|
|
+#define DP_C_LLONG 4
|
|
+
|
|
+/* some handy macros */
|
|
+#define char_to_int(p) (p - '0')
|
|
+#define OSSL_MAX(p,q) ((p >= q) ? p : q)
|
|
+
|
|
+static void
|
|
+_dopr(
|
|
+ char **sbuffer,
|
|
+ char **buffer,
|
|
+ size_t *maxlen,
|
|
+ size_t *retlen,
|
|
+ int *truncated,
|
|
+ const char *format,
|
|
+ va_list args)
|
|
+{
|
|
+ char ch;
|
|
+ LLONG value;
|
|
+ LDOUBLE fvalue;
|
|
+ char *strvalue;
|
|
+ int min;
|
|
+ int max;
|
|
+ int state;
|
|
+ int flags;
|
|
+ int cflags;
|
|
+ size_t currlen;
|
|
+
|
|
+ state = DP_S_DEFAULT;
|
|
+ flags = currlen = cflags = min = 0;
|
|
+ max = -1;
|
|
+ ch = *format++;
|
|
+
|
|
+ while (state != DP_S_DONE) {
|
|
+ if (ch == '\0' || (buffer == NULL && currlen >= *maxlen))
|
|
+ state = DP_S_DONE;
|
|
+
|
|
+ switch (state) {
|
|
+ case DP_S_DEFAULT:
|
|
+ if (ch == '%')
|
|
+ state = DP_S_FLAGS;
|
|
+ else
|
|
+ doapr_outch(sbuffer,buffer, &currlen, maxlen, ch);
|
|
+ ch = *format++;
|
|
+ break;
|
|
+ case DP_S_FLAGS:
|
|
+ switch (ch) {
|
|
+ case '-':
|
|
+ flags |= DP_F_MINUS;
|
|
+ ch = *format++;
|
|
+ break;
|
|
+ case '+':
|
|
+ flags |= DP_F_PLUS;
|
|
+ ch = *format++;
|
|
+ break;
|
|
+ case ' ':
|
|
+ flags |= DP_F_SPACE;
|
|
+ ch = *format++;
|
|
+ break;
|
|
+ case '#':
|
|
+ flags |= DP_F_NUM;
|
|
+ ch = *format++;
|
|
+ break;
|
|
+ case '0':
|
|
+ flags |= DP_F_ZERO;
|
|
+ ch = *format++;
|
|
+ break;
|
|
+ default:
|
|
+ state = DP_S_MIN;
|
|
+ break;
|
|
+ }
|
|
+ break;
|
|
+ case DP_S_MIN:
|
|
+ if (isdigit((unsigned char)ch)) {
|
|
+ min = 10 * min + char_to_int(ch);
|
|
+ ch = *format++;
|
|
+ } else if (ch == '*') {
|
|
+ min = va_arg(args, int);
|
|
+ ch = *format++;
|
|
+ state = DP_S_DOT;
|
|
+ } else
|
|
+ state = DP_S_DOT;
|
|
+ break;
|
|
+ case DP_S_DOT:
|
|
+ if (ch == '.') {
|
|
+ state = DP_S_MAX;
|
|
+ ch = *format++;
|
|
+ } else
|
|
+ state = DP_S_MOD;
|
|
+ break;
|
|
+ case DP_S_MAX:
|
|
+ if (isdigit((unsigned char)ch)) {
|
|
+ if (max < 0)
|
|
+ max = 0;
|
|
+ max = 10 * max + char_to_int(ch);
|
|
+ ch = *format++;
|
|
+ } else if (ch == '*') {
|
|
+ max = va_arg(args, int);
|
|
+ ch = *format++;
|
|
+ state = DP_S_MOD;
|
|
+ } else
|
|
+ state = DP_S_MOD;
|
|
+ break;
|
|
+ case DP_S_MOD:
|
|
+ switch (ch) {
|
|
+ case 'h':
|
|
+ cflags = DP_C_SHORT;
|
|
+ ch = *format++;
|
|
+ break;
|
|
+ case 'l':
|
|
+ if (*format == 'l') {
|
|
+ cflags = DP_C_LLONG;
|
|
+ format++;
|
|
+ } else
|
|
+ cflags = DP_C_LONG;
|
|
+ ch = *format++;
|
|
+ break;
|
|
+ case 'q':
|
|
+ cflags = DP_C_LLONG;
|
|
+ ch = *format++;
|
|
+ break;
|
|
+ case 'L':
|
|
+ cflags = DP_C_LDOUBLE;
|
|
+ ch = *format++;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ state = DP_S_CONV;
|
|
+ break;
|
|
+ case DP_S_CONV:
|
|
+ switch (ch) {
|
|
+ case 'd':
|
|
+ case 'i':
|
|
+ switch (cflags) {
|
|
+ case DP_C_SHORT:
|
|
+ value = (short int)va_arg(args, int);
|
|
+ break;
|
|
+ case DP_C_LONG:
|
|
+ value = va_arg(args, long int);
|
|
+ break;
|
|
+ case DP_C_LLONG:
|
|
+ value = va_arg(args, LLONG);
|
|
+ break;
|
|
+ default:
|
|
+ value = va_arg(args, int);
|
|
+ break;
|
|
+ }
|
|
+ fmtint(sbuffer, buffer, &currlen, maxlen,
|
|
+ value, 10, min, max, flags);
|
|
+ break;
|
|
+ case 'X':
|
|
+ flags |= DP_F_UP;
|
|
+ /* FALLTHROUGH */
|
|
+ case 'x':
|
|
+ case 'o':
|
|
+ case 'u':
|
|
+ flags |= DP_F_UNSIGNED;
|
|
+ switch (cflags) {
|
|
+ case DP_C_SHORT:
|
|
+ value = (unsigned short int)va_arg(args, unsigned int);
|
|
+ break;
|
|
+ case DP_C_LONG:
|
|
+ value = (LLONG) va_arg(args,
|
|
+ unsigned long int);
|
|
+ break;
|
|
+ case DP_C_LLONG:
|
|
+ value = va_arg(args, unsigned LLONG);
|
|
+ break;
|
|
+ default:
|
|
+ value = (LLONG) va_arg(args,
|
|
+ unsigned int);
|
|
+ break;
|
|
+ }
|
|
+ fmtint(sbuffer, buffer, &currlen, maxlen, value,
|
|
+ ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
|
|
+ min, max, flags);
|
|
+ break;
|
|
+ case 'f':
|
|
+ if (cflags == DP_C_LDOUBLE)
|
|
+ fvalue = va_arg(args, LDOUBLE);
|
|
+ else
|
|
+ fvalue = va_arg(args, double);
|
|
+ fmtfp(sbuffer, buffer, &currlen, maxlen,
|
|
+ fvalue, min, max, flags);
|
|
+ break;
|
|
+ case 'E':
|
|
+ flags |= DP_F_UP;
|
|
+ case 'e':
|
|
+ if (cflags == DP_C_LDOUBLE)
|
|
+ fvalue = va_arg(args, LDOUBLE);
|
|
+ else
|
|
+ fvalue = va_arg(args, double);
|
|
+ break;
|
|
+ case 'G':
|
|
+ flags |= DP_F_UP;
|
|
+ case 'g':
|
|
+ if (cflags == DP_C_LDOUBLE)
|
|
+ fvalue = va_arg(args, LDOUBLE);
|
|
+ else
|
|
+ fvalue = va_arg(args, double);
|
|
+ break;
|
|
+ case 'c':
|
|
+ doapr_outch(sbuffer, buffer, &currlen, maxlen,
|
|
+ va_arg(args, int));
|
|
+ break;
|
|
+ case 's':
|
|
+ strvalue = va_arg(args, char *);
|
|
+ if (max < 0) {
|
|
+ if (buffer)
|
|
+ max = INT_MAX;
|
|
+ else
|
|
+ max = *maxlen;
|
|
+ }
|
|
+ fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue,
|
|
+ flags, min, max);
|
|
+ break;
|
|
+ case 'p':
|
|
+ value = (long)va_arg(args, void *);
|
|
+ fmtint(sbuffer, buffer, &currlen, maxlen,
|
|
+ value, 16, min, max, flags|DP_F_NUM);
|
|
+ break;
|
|
+ case 'n': /* XXX */
|
|
+ if (cflags == DP_C_SHORT) {
|
|
+ short int *num;
|
|
+ num = va_arg(args, short int *);
|
|
+ *num = currlen;
|
|
+ } else if (cflags == DP_C_LONG) { /* XXX */
|
|
+ long int *num;
|
|
+ num = va_arg(args, long int *);
|
|
+ *num = (long int) currlen;
|
|
+ } else if (cflags == DP_C_LLONG) { /* XXX */
|
|
+ LLONG *num;
|
|
+ num = va_arg(args, LLONG *);
|
|
+ *num = (LLONG) currlen;
|
|
+ } else {
|
|
+ int *num;
|
|
+ num = va_arg(args, int *);
|
|
+ *num = currlen;
|
|
+ }
|
|
+ break;
|
|
+ case '%':
|
|
+ doapr_outch(sbuffer, buffer, &currlen, maxlen, ch);
|
|
+ break;
|
|
+ case 'w':
|
|
+ /* not supported yet, treat as next char */
|
|
+ ch = *format++;
|
|
+ break;
|
|
+ default:
|
|
+ /* unknown, skip */
|
|
+ break;
|
|
+ }
|
|
+ ch = *format++;
|
|
+ state = DP_S_DEFAULT;
|
|
+ flags = cflags = min = 0;
|
|
+ max = -1;
|
|
+ break;
|
|
+ case DP_S_DONE:
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ *truncated = (currlen > *maxlen - 1);
|
|
+ if (*truncated)
|
|
+ currlen = *maxlen - 1;
|
|
+ doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0');
|
|
+ *retlen = currlen - 1;
|
|
+ return;
|
|
+}
|
|
+
|
|
+static void
|
|
+fmtstr(
|
|
+ char **sbuffer,
|
|
+ char **buffer,
|
|
+ size_t *currlen,
|
|
+ size_t *maxlen,
|
|
+ const char *value,
|
|
+ int flags,
|
|
+ int min,
|
|
+ int max)
|
|
+{
|
|
+ int padlen, strln;
|
|
+ int cnt = 0;
|
|
+
|
|
+ if (value == 0)
|
|
+ value = "<NULL>";
|
|
+ for (strln = 0; value[strln]; ++strln)
|
|
+ ;
|
|
+ padlen = min - strln;
|
|
+ if (padlen < 0)
|
|
+ padlen = 0;
|
|
+ if (flags & DP_F_MINUS)
|
|
+ padlen = -padlen;
|
|
+
|
|
+ while ((padlen > 0) && (cnt < max)) {
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
|
+ --padlen;
|
|
+ ++cnt;
|
|
+ }
|
|
+ while (*value && (cnt < max)) {
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, *value++);
|
|
+ ++cnt;
|
|
+ }
|
|
+ while ((padlen < 0) && (cnt < max)) {
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
|
+ ++padlen;
|
|
+ ++cnt;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+fmtint(
|
|
+ char **sbuffer,
|
|
+ char **buffer,
|
|
+ size_t *currlen,
|
|
+ size_t *maxlen,
|
|
+ LLONG value,
|
|
+ int base,
|
|
+ int min,
|
|
+ int max,
|
|
+ int flags)
|
|
+{
|
|
+ int signvalue = 0;
|
|
+ const char *prefix = "";
|
|
+ unsigned LLONG uvalue;
|
|
+ char convert[DECIMAL_SIZE(value)+3];
|
|
+ int place = 0;
|
|
+ int spadlen = 0;
|
|
+ int zpadlen = 0;
|
|
+ int caps = 0;
|
|
+
|
|
+ if (max < 0)
|
|
+ max = 0;
|
|
+ uvalue = value;
|
|
+ if (!(flags & DP_F_UNSIGNED)) {
|
|
+ if (value < 0) {
|
|
+ signvalue = '-';
|
|
+ uvalue = -value;
|
|
+ } else if (flags & DP_F_PLUS)
|
|
+ signvalue = '+';
|
|
+ else if (flags & DP_F_SPACE)
|
|
+ signvalue = ' ';
|
|
+ }
|
|
+ if (flags & DP_F_NUM) {
|
|
+ if (base == 8) prefix = "0";
|
|
+ if (base == 16) prefix = "0x";
|
|
+ }
|
|
+ if (flags & DP_F_UP)
|
|
+ caps = 1;
|
|
+ do {
|
|
+ convert[place++] =
|
|
+ (caps ? "0123456789ABCDEF" : "0123456789abcdef")
|
|
+ [uvalue % (unsigned) base];
|
|
+ uvalue = (uvalue / (unsigned) base);
|
|
+ } while (uvalue && (place < (int)sizeof(convert)));
|
|
+ if (place == sizeof(convert))
|
|
+ place--;
|
|
+ convert[place] = 0;
|
|
+
|
|
+ zpadlen = max - place;
|
|
+ spadlen = min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix);
|
|
+ if (zpadlen < 0)
|
|
+ zpadlen = 0;
|
|
+ if (spadlen < 0)
|
|
+ spadlen = 0;
|
|
+ if (flags & DP_F_ZERO) {
|
|
+ zpadlen = OSSL_MAX(zpadlen, spadlen);
|
|
+ spadlen = 0;
|
|
+ }
|
|
+ if (flags & DP_F_MINUS)
|
|
+ spadlen = -spadlen;
|
|
+
|
|
+ /* spaces */
|
|
+ while (spadlen > 0) {
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
|
+ --spadlen;
|
|
+ }
|
|
+
|
|
+ /* sign */
|
|
+ if (signvalue)
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
|
|
+
|
|
+ /* prefix */
|
|
+ while (*prefix) {
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix);
|
|
+ prefix++;
|
|
+ }
|
|
+
|
|
+ /* zeros */
|
|
+ if (zpadlen > 0) {
|
|
+ while (zpadlen > 0) {
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
|
|
+ --zpadlen;
|
|
+ }
|
|
+ }
|
|
+ /* digits */
|
|
+ while (place > 0)
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]);
|
|
+
|
|
+ /* left justified spaces */
|
|
+ while (spadlen < 0) {
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
|
+ ++spadlen;
|
|
+ }
|
|
+ return;
|
|
+}
|
|
+
|
|
+static LDOUBLE
|
|
+abs_val(LDOUBLE value)
|
|
+{
|
|
+ LDOUBLE result = value;
|
|
+ if (value < 0)
|
|
+ result = -value;
|
|
+ return result;
|
|
+}
|
|
+
|
|
+static LDOUBLE
|
|
+pow_10(int in_exp)
|
|
+{
|
|
+ LDOUBLE result = 1;
|
|
+ while (in_exp) {
|
|
+ result *= 10;
|
|
+ in_exp--;
|
|
+ }
|
|
+ return result;
|
|
+}
|
|
+
|
|
+static long
|
|
+roundv(LDOUBLE value)
|
|
+{
|
|
+ long intpart;
|
|
+ intpart = (long) value;
|
|
+ value = value - intpart;
|
|
+ if (value >= 0.5)
|
|
+ intpart++;
|
|
+ return intpart;
|
|
+}
|
|
+
|
|
+static void
|
|
+fmtfp(
|
|
+ char **sbuffer,
|
|
+ char **buffer,
|
|
+ size_t *currlen,
|
|
+ size_t *maxlen,
|
|
+ LDOUBLE fvalue,
|
|
+ int min,
|
|
+ int max,
|
|
+ int flags)
|
|
+{
|
|
+ int signvalue = 0;
|
|
+ LDOUBLE ufvalue;
|
|
+ char iconvert[20];
|
|
+ char fconvert[20];
|
|
+ int iplace = 0;
|
|
+ int fplace = 0;
|
|
+ int padlen = 0;
|
|
+ int zpadlen = 0;
|
|
+ int caps = 0;
|
|
+ long intpart;
|
|
+ long fracpart;
|
|
+ long max10;
|
|
+
|
|
+ if (max < 0)
|
|
+ max = 6;
|
|
+ ufvalue = abs_val(fvalue);
|
|
+ if (fvalue < 0)
|
|
+ signvalue = '-';
|
|
+ else if (flags & DP_F_PLUS)
|
|
+ signvalue = '+';
|
|
+ else if (flags & DP_F_SPACE)
|
|
+ signvalue = ' ';
|
|
+
|
|
+ intpart = (long)ufvalue;
|
|
+
|
|
+ /* sorry, we only support 9 digits past the decimal because of our
|
|
+ conversion method */
|
|
+ if (max > 9)
|
|
+ max = 9;
|
|
+
|
|
+ /* we "cheat" by converting the fractional part to integer by
|
|
+ multiplying by a factor of 10 */
|
|
+ max10 = roundv(pow_10(max));
|
|
+ fracpart = roundv(pow_10(max) * (ufvalue - intpart));
|
|
+
|
|
+ if (fracpart >= max10) {
|
|
+ intpart++;
|
|
+ fracpart -= max10;
|
|
+ }
|
|
+
|
|
+ /* convert integer part */
|
|
+ do {
|
|
+ iconvert[iplace++] =
|
|
+ (caps ? "0123456789ABCDEF"
|
|
+ : "0123456789abcdef")[intpart % 10];
|
|
+ intpart = (intpart / 10);
|
|
+ } while (intpart && (iplace < (int)sizeof(iconvert)));
|
|
+ if (iplace == sizeof iconvert)
|
|
+ iplace--;
|
|
+ iconvert[iplace] = 0;
|
|
+
|
|
+ /* convert fractional part */
|
|
+ do {
|
|
+ fconvert[fplace++] =
|
|
+ (caps ? "0123456789ABCDEF"
|
|
+ : "0123456789abcdef")[fracpart % 10];
|
|
+ fracpart = (fracpart / 10);
|
|
+ } while (fplace < max);
|
|
+ if (fplace == sizeof fconvert)
|
|
+ fplace--;
|
|
+ fconvert[fplace] = 0;
|
|
+
|
|
+ /* -1 for decimal point, another -1 if we are printing a sign */
|
|
+ padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
|
|
+ zpadlen = max - fplace;
|
|
+ if (zpadlen < 0)
|
|
+ zpadlen = 0;
|
|
+ if (padlen < 0)
|
|
+ padlen = 0;
|
|
+ if (flags & DP_F_MINUS)
|
|
+ padlen = -padlen;
|
|
+
|
|
+ if ((flags & DP_F_ZERO) && (padlen > 0)) {
|
|
+ if (signvalue) {
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
|
|
+ --padlen;
|
|
+ signvalue = 0;
|
|
+ }
|
|
+ while (padlen > 0) {
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
|
|
+ --padlen;
|
|
+ }
|
|
+ }
|
|
+ while (padlen > 0) {
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
|
+ --padlen;
|
|
+ }
|
|
+ if (signvalue)
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue);
|
|
+
|
|
+ while (iplace > 0)
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]);
|
|
+
|
|
+ /*
|
|
+ * Decimal point. This should probably use locale to find the correct
|
|
+ * char to print out.
|
|
+ */
|
|
+ if (max > 0 || (flags & DP_F_NUM)) {
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, '.');
|
|
+
|
|
+ while (fplace > 0)
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]);
|
|
+ }
|
|
+ while (zpadlen > 0) {
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, '0');
|
|
+ --zpadlen;
|
|
+ }
|
|
+
|
|
+ while (padlen < 0) {
|
|
+ doapr_outch(sbuffer, buffer, currlen, maxlen, ' ');
|
|
+ ++padlen;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+doapr_outch(
|
|
+ char **sbuffer,
|
|
+ char **buffer,
|
|
+ size_t *currlen,
|
|
+ size_t *maxlen,
|
|
+ int c)
|
|
+{
|
|
+ /* If we haven't at least one buffer, someone has doe a big booboo */
|
|
+ assert(*sbuffer != NULL || buffer != NULL);
|
|
+
|
|
+ if (buffer) {
|
|
+ while (*currlen >= *maxlen) {
|
|
+ if (*buffer == NULL) {
|
|
+ if (*maxlen == 0)
|
|
+ *maxlen = 1024;
|
|
+ *buffer = OPENSSL_malloc(*maxlen);
|
|
+ if (*currlen > 0) {
|
|
+ assert(*sbuffer != NULL);
|
|
+ memcpy(*buffer, *sbuffer, *currlen);
|
|
+ }
|
|
+ *sbuffer = NULL;
|
|
+ } else {
|
|
+ *maxlen += 1024;
|
|
+ *buffer = OPENSSL_realloc(*buffer, *maxlen);
|
|
+ }
|
|
+ }
|
|
+ /* What to do if *buffer is NULL? */
|
|
+ assert(*sbuffer != NULL || *buffer != NULL);
|
|
+ }
|
|
+
|
|
+ if (*currlen < *maxlen) {
|
|
+ if (*sbuffer)
|
|
+ (*sbuffer)[(*currlen)++] = (char)c;
|
|
+ else
|
|
+ (*buffer)[(*currlen)++] = (char)c;
|
|
+ }
|
|
+
|
|
+ return;
|
|
+}
|
|
+
|
|
+/***************************************************************************/
|
|
+
|
|
+int BIO_printf (BIO *bio, const char *format, ...)
|
|
+ {
|
|
+ va_list args;
|
|
+ int ret;
|
|
+
|
|
+ va_start(args, format);
|
|
+
|
|
+ ret = BIO_vprintf(bio, format, args);
|
|
+
|
|
+ va_end(args);
|
|
+ return(ret);
|
|
+ }
|
|
+
|
|
+int BIO_vprintf (BIO *bio, const char *format, va_list args)
|
|
+ {
|
|
+ int ret;
|
|
+ size_t retlen;
|
|
+ char hugebuf[1024*2]; /* Was previously 10k, which is unreasonable
|
|
+ in small-stack environments, like threads
|
|
+ or DOS programs. */
|
|
+ char *hugebufp = hugebuf;
|
|
+ size_t hugebufsize = sizeof(hugebuf);
|
|
+ char *dynbuf = NULL;
|
|
+ int ignored;
|
|
+
|
|
+ dynbuf = NULL;
|
|
+ CRYPTO_push_info("doapr()");
|
|
+ _dopr(&hugebufp, &dynbuf, &hugebufsize,
|
|
+ &retlen, &ignored, format, args);
|
|
+ if (dynbuf)
|
|
+ {
|
|
+ ret=BIO_write(bio, dynbuf, (int)retlen);
|
|
+ OPENSSL_free(dynbuf);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ ret=BIO_write(bio, hugebuf, (int)retlen);
|
|
+ }
|
|
+ CRYPTO_pop_info();
|
|
+ return(ret);
|
|
+ }
|
|
+
|
|
+/* As snprintf is not available everywhere, we provide our own implementation.
|
|
+ * This function has nothing to do with BIOs, but it's closely related
|
|
+ * to BIO_printf, and we need *some* name prefix ...
|
|
+ * (XXX the function should be renamed, but to what?) */
|
|
+int BIO_snprintf(char *buf, size_t n, const char *format, ...)
|
|
+ {
|
|
+ va_list args;
|
|
+ int ret;
|
|
+
|
|
+ va_start(args, format);
|
|
+
|
|
+ ret = BIO_vsnprintf(buf, n, format, args);
|
|
+
|
|
+ va_end(args);
|
|
+ return(ret);
|
|
+ }
|
|
+
|
|
+int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args)
|
|
+ {
|
|
+ size_t retlen;
|
|
+ int truncated;
|
|
+
|
|
+ _dopr(&buf, NULL, &n, &retlen, &truncated, format, args);
|
|
+
|
|
+ if (truncated)
|
|
+ /* In case of truncation, return -1 like traditional snprintf.
|
|
+ * (Current drafts for ISO/IEC 9899 say snprintf should return
|
|
+ * the number of characters that would have been written,
|
|
+ * had the buffer been large enough.) */
|
|
+ return -1;
|
|
+ else
|
|
+ return (retlen <= INT_MAX) ? (int)retlen : -1;
|
|
+ }
|
|
diff --git a/Cryptlib/SysCall/CrtWrapper.c b/Cryptlib/SysCall/CrtWrapper.c
|
|
index fb446b6..5a8322d 100644
|
|
--- a/Cryptlib/SysCall/CrtWrapper.c
|
|
+++ b/Cryptlib/SysCall/CrtWrapper.c
|
|
@@ -293,16 +293,6 @@ size_t fwrite (const void *buffer, size_t size, size_t count, FILE *stream)
|
|
// -- Dummy OpenSSL Support Routines --
|
|
//
|
|
|
|
-int BIO_printf (void *bio, const char *format, ...)
|
|
-{
|
|
- return 0;
|
|
-}
|
|
-
|
|
-int BIO_snprintf(char *buf, size_t n, const char *format, ...)
|
|
-{
|
|
- return 0;
|
|
-}
|
|
-
|
|
void *UI_OpenSSL(void)
|
|
{
|
|
return NULL;
|
|
--
|
|
1.8.1.4
|
|
|
|
|
|
From 0b5a0362d6bd3fd1a0721e05353046e387ef2a22 Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Thu, 27 Jun 2013 12:03:14 +0800
|
|
Subject: [PATCH 06/11] Disable floating points in b_print
|
|
|
|
The long double declaration will enable SSE and cause a compilation
|
|
error. Disabling everything related to floating points avoids the
|
|
error.
|
|
---
|
|
Cryptlib/OpenSSL/crypto/bio/b_print.c | 8 ++++++++
|
|
1 file changed, 8 insertions(+)
|
|
|
|
diff --git a/Cryptlib/OpenSSL/crypto/bio/b_print.c b/Cryptlib/OpenSSL/crypto/bio/b_print.c
|
|
index 3a87b0e..b8b630c 100644
|
|
--- a/Cryptlib/OpenSSL/crypto/bio/b_print.c
|
|
+++ b/Cryptlib/OpenSSL/crypto/bio/b_print.c
|
|
@@ -129,8 +129,10 @@ static void fmtstr (char **, char **, size_t *, size_t *,
|
|
const char *, int, int, int);
|
|
static void fmtint (char **, char **, size_t *, size_t *,
|
|
LLONG, int, int, int, int);
|
|
+#ifndef OPENSSL_SYS_UEFI
|
|
static void fmtfp (char **, char **, size_t *, size_t *,
|
|
LDOUBLE, int, int, int);
|
|
+#endif
|
|
static void doapr_outch (char **, char **, size_t *, size_t *, int);
|
|
static void _dopr(char **sbuffer, char **buffer,
|
|
size_t *maxlen, size_t *retlen, int *truncated,
|
|
@@ -177,7 +179,9 @@ _dopr(
|
|
{
|
|
char ch;
|
|
LLONG value;
|
|
+#ifndef OPENSSL_SYS_UEFI
|
|
LDOUBLE fvalue;
|
|
+#endif
|
|
char *strvalue;
|
|
int min;
|
|
int max;
|
|
@@ -336,6 +340,7 @@ _dopr(
|
|
ch == 'o' ? 8 : (ch == 'u' ? 10 : 16),
|
|
min, max, flags);
|
|
break;
|
|
+#ifndef OPENSSL_SYS_UEFI
|
|
case 'f':
|
|
if (cflags == DP_C_LDOUBLE)
|
|
fvalue = va_arg(args, LDOUBLE);
|
|
@@ -360,6 +365,7 @@ _dopr(
|
|
else
|
|
fvalue = va_arg(args, double);
|
|
break;
|
|
+#endif
|
|
case 'c':
|
|
doapr_outch(sbuffer, buffer, &currlen, maxlen,
|
|
va_arg(args, int));
|
|
@@ -566,6 +572,7 @@ fmtint(
|
|
return;
|
|
}
|
|
|
|
+#ifndef OPENSSL_SYS_UEFI
|
|
static LDOUBLE
|
|
abs_val(LDOUBLE value)
|
|
{
|
|
@@ -721,6 +728,7 @@ fmtfp(
|
|
++padlen;
|
|
}
|
|
}
|
|
+#endif
|
|
|
|
static void
|
|
doapr_outch(
|
|
--
|
|
1.8.1.4
|
|
|
|
|
|
From bb29385b30d6958fa99e43bfcf64815ca4bc4a53 Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Thu, 27 Jun 2013 12:28:08 +0800
|
|
Subject: [PATCH 07/11] MokManager: rearrange the output of MOK info
|
|
|
|
---
|
|
MokManager.c | 239 ++++++++++++++++++++---------------------------------------
|
|
1 file changed, 81 insertions(+), 158 deletions(-)
|
|
|
|
diff --git a/MokManager.c b/MokManager.c
|
|
index 4393aec..8b770ff 100644
|
|
--- a/MokManager.c
|
|
+++ b/MokManager.c
|
|
@@ -180,136 +180,30 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
|
|
return list;
|
|
}
|
|
|
|
-static CHAR16* get_x509_name (X509_NAME *X509Name, CHAR16 *name)
|
|
+static CHAR16* get_x509_common_name (X509_NAME *X509Name)
|
|
{
|
|
- char *str;
|
|
- CHAR16 *ret = NULL;
|
|
+ char str[80];
|
|
|
|
- str = X509_NAME_oneline(X509Name, NULL, 0);
|
|
- if (str) {
|
|
- ret = PoolPrint(L"%s: %a", name, str);
|
|
- OPENSSL_free(str);
|
|
- }
|
|
- return ret;
|
|
-}
|
|
-
|
|
-static const char *mon[12]= {
|
|
-"Jan","Feb","Mar","Apr","May","Jun",
|
|
-"Jul","Aug","Sep","Oct","Nov","Dec"
|
|
-};
|
|
-
|
|
-static void print_x509_GENERALIZEDTIME_time (ASN1_TIME *time, CHAR16 *time_string)
|
|
-{
|
|
- char *v;
|
|
- int gmt = 0;
|
|
- int i;
|
|
- int y = 0,M = 0,d = 0,h = 0,m = 0,s = 0;
|
|
- char *f = NULL;
|
|
- int f_len = 0;
|
|
-
|
|
- i=time->length;
|
|
- v=(char *)time->data;
|
|
-
|
|
- if (i < 12)
|
|
- goto error;
|
|
-
|
|
- if (v[i-1] == 'Z')
|
|
- gmt=1;
|
|
-
|
|
- for (i=0; i<12; i++) {
|
|
- if ((v[i] > '9') || (v[i] < '0'))
|
|
- goto error;
|
|
- }
|
|
-
|
|
- y = (v[0]-'0')*1000+(v[1]-'0')*100 + (v[2]-'0')*10+(v[3]-'0');
|
|
- M = (v[4]-'0')*10+(v[5]-'0');
|
|
-
|
|
- if ((M > 12) || (M < 1))
|
|
- goto error;
|
|
-
|
|
- d = (v[6]-'0')*10+(v[7]-'0');
|
|
- h = (v[8]-'0')*10+(v[9]-'0');
|
|
- m = (v[10]-'0')*10+(v[11]-'0');
|
|
-
|
|
- if (time->length >= 14 &&
|
|
- (v[12] >= '0') && (v[12] <= '9') &&
|
|
- (v[13] >= '0') && (v[13] <= '9')) {
|
|
- s = (v[12]-'0')*10+(v[13]-'0');
|
|
- /* Check for fractions of seconds. */
|
|
- if (time->length >= 15 && v[14] == '.') {
|
|
- int l = time->length;
|
|
- f = &v[14]; /* The decimal point. */
|
|
- f_len = 1;
|
|
- while (14 + f_len < l && f[f_len] >= '0' &&
|
|
- f[f_len] <= '9')
|
|
- ++f_len;
|
|
- }
|
|
- }
|
|
-
|
|
- SPrint(time_string, 0, L"%a %2d %02d:%02d:%02d%.*a %d%a",
|
|
- mon[M-1], d, h, m, s, f_len, f, y, (gmt)?" GMT":"");
|
|
-error:
|
|
- return;
|
|
-}
|
|
-
|
|
-static void print_x509_UTCTIME_time (ASN1_TIME *time, CHAR16 *time_string)
|
|
-{
|
|
- char *v;
|
|
- int gmt=0;
|
|
- int i;
|
|
- int y = 0,M = 0,d = 0,h = 0,m = 0,s = 0;
|
|
-
|
|
- i=time->length;
|
|
- v=(char *)time->data;
|
|
+ ZeroMem(str, 80);
|
|
+ X509_NAME_get_text_by_NID (X509Name, NID_commonName, str, 80);
|
|
|
|
- if (i < 10)
|
|
- goto error;
|
|
-
|
|
- if (v[i-1] == 'Z')
|
|
- gmt=1;
|
|
-
|
|
- for (i=0; i<10; i++)
|
|
- if ((v[i] > '9') || (v[i] < '0'))
|
|
- goto error;
|
|
-
|
|
- y = (v[0]-'0')*10+(v[1]-'0');
|
|
-
|
|
- if (y < 50)
|
|
- y+=100;
|
|
-
|
|
- M = (v[2]-'0')*10+(v[3]-'0');
|
|
-
|
|
- if ((M > 12) || (M < 1))
|
|
- goto error;
|
|
-
|
|
- d = (v[4]-'0')*10+(v[5]-'0');
|
|
- h = (v[6]-'0')*10+(v[7]-'0');
|
|
- m = (v[8]-'0')*10+(v[9]-'0');
|
|
-
|
|
- if (time->length >=12 &&
|
|
- (v[10] >= '0') && (v[10] <= '9') &&
|
|
- (v[11] >= '0') && (v[11] <= '9'))
|
|
- s = (v[10]-'0')*10+(v[11]-'0');
|
|
-
|
|
- SPrint(time_string, 0, L"%a %2d %02d:%02d:%02d %d%a",
|
|
- mon[M-1], d, h, m, s, y+1900, (gmt)?" GMT":"");
|
|
-error:
|
|
- return;
|
|
+ return PoolPrint(L"%a", str);
|
|
}
|
|
|
|
-static CHAR16* get_x509_time (ASN1_TIME *time, CHAR16 *name)
|
|
+static CHAR16* get_x509_time (ASN1_TIME *time)
|
|
{
|
|
- CHAR16 time_string[30];
|
|
-
|
|
- if (time->type == V_ASN1_UTCTIME) {
|
|
- print_x509_UTCTIME_time(time, time_string);
|
|
- } else if (time->type == V_ASN1_GENERALIZEDTIME) {
|
|
- print_x509_GENERALIZEDTIME_time(time, time_string);
|
|
- } else {
|
|
- time_string[0] = '\0';
|
|
- }
|
|
-
|
|
- return PoolPrint(L"%s: %s", name, time_string);
|
|
+ BIO *bio = BIO_new (BIO_s_mem());
|
|
+ char str[30];
|
|
+ int len;
|
|
+
|
|
+ ASN1_TIME_print (bio, time);
|
|
+ len = BIO_read(bio, str, 29);
|
|
+ if (len < 0)
|
|
+ len = 0;
|
|
+ str[len] = '\0';
|
|
+ BIO_free (bio);
|
|
+
|
|
+ return PoolPrint(L"%a", str);
|
|
}
|
|
|
|
static void show_x509_info (X509 *X509Cert, UINT8 *hash)
|
|
@@ -339,7 +233,6 @@ static void show_x509_info (X509 *X509Cert, UINT8 *hash)
|
|
int i, n;
|
|
bnser = ASN1_INTEGER_to_BN(serial, NULL);
|
|
n = BN_bn2bin(bnser, hexbuf);
|
|
- CatPrint(&serial_string, L"Serial Number:");
|
|
for (i = 0; i < n; i++) {
|
|
CatPrint(&serial_string, L"%02x:", hexbuf[i]);
|
|
}
|
|
@@ -350,34 +243,32 @@ static void show_x509_info (X509 *X509Cert, UINT8 *hash)
|
|
|
|
X509Name = X509_get_issuer_name(X509Cert);
|
|
if (X509Name) {
|
|
- issuer = get_x509_name(X509Name, L"Issuer");
|
|
+ issuer = get_x509_common_name(X509Name);
|
|
if (issuer)
|
|
fields++;
|
|
}
|
|
|
|
X509Name = X509_get_subject_name(X509Cert);
|
|
if (X509Name) {
|
|
- subject = get_x509_name(X509Name, L"Subject");
|
|
+ subject = get_x509_common_name(X509Name);
|
|
if (subject)
|
|
fields++;
|
|
}
|
|
|
|
time = X509_get_notBefore(X509Cert);
|
|
if (time) {
|
|
- from = get_x509_time(time, L"Validity from");
|
|
- if (time)
|
|
+ from = get_x509_time(time);
|
|
+ if (from)
|
|
fields++;
|
|
}
|
|
|
|
time = X509_get_notAfter(X509Cert);
|
|
if (time) {
|
|
- until = get_x509_time(time, L"Validity till");
|
|
+ until = get_x509_time(time);
|
|
if (until)
|
|
fields++;
|
|
}
|
|
|
|
-#if 0
|
|
- CatPrint(&hash_string1, L"SHA1 Fingerprint: ");
|
|
for (i=0; i<10; i++)
|
|
CatPrint(&hash_string1, L"%02x ", hash[i]);
|
|
for (i=10; i<20; i++)
|
|
@@ -388,42 +279,48 @@ static void show_x509_info (X509 *X509Cert, UINT8 *hash)
|
|
|
|
if (hash_string2.str)
|
|
fields++;
|
|
-#endif
|
|
+
|
|
if (!fields)
|
|
return;
|
|
|
|
- text = AllocateZeroPool(sizeof(CHAR16 *) * (fields + 1));
|
|
+ i = 0;
|
|
+ text = AllocateZeroPool(sizeof(CHAR16 *) * (fields*3 + 1));
|
|
if (serial_string.str) {
|
|
- text[i] = serial_string.str;
|
|
- i++;
|
|
+ text[i++] = StrDuplicate(L"[Serial Number]");
|
|
+ text[i++] = serial_string.str;
|
|
+ text[i++] = StrDuplicate(L"");
|
|
}
|
|
if (issuer) {
|
|
- text[i] = issuer;
|
|
- i++;
|
|
+ text[i++] = StrDuplicate(L"[Issuer]");
|
|
+ text[i++] = issuer;
|
|
+ text[i++] = StrDuplicate(L"");
|
|
}
|
|
if (subject) {
|
|
- text[i] = subject;
|
|
- i++;
|
|
+ text[i++] = StrDuplicate(L"[Subject]");
|
|
+ text[i++] = subject;
|
|
+ text[i++] = StrDuplicate(L"");
|
|
}
|
|
if (from) {
|
|
- text[i] = from;
|
|
- i++;
|
|
+ text[i++] = StrDuplicate(L"[Valid Not Before]");
|
|
+ text[i++] = from;
|
|
+ text[i++] = StrDuplicate(L"");
|
|
}
|
|
if (until) {
|
|
- text[i] = until;
|
|
- i++;
|
|
+ text[i++] = StrDuplicate(L"[Valid Not After]");
|
|
+ text[i++] = until;
|
|
+ text[i++] = StrDuplicate(L"");
|
|
}
|
|
if (hash_string1.str) {
|
|
- text[i] = hash_string1.str;
|
|
- i++;
|
|
+ text[i++] = StrDuplicate(L"[Fingerprint]");
|
|
+ text[i++] = hash_string1.str;
|
|
}
|
|
if (hash_string2.str) {
|
|
- text[i] = hash_string2.str;
|
|
- i++;
|
|
+ text[i++] = hash_string2.str;
|
|
+ text[i++] = StrDuplicate(L"");
|
|
}
|
|
text[i] = NULL;
|
|
|
|
- console_alertbox(text);
|
|
+ console_print_box(text, -1);
|
|
|
|
for (i=0; text[i] != NULL; i++)
|
|
FreePool(text[i]);
|
|
@@ -431,11 +328,41 @@ static void show_x509_info (X509 *X509Cert, UINT8 *hash)
|
|
FreePool(text);
|
|
}
|
|
|
|
+static void show_efi_hash (UINT8 *hash)
|
|
+{
|
|
+ CHAR16 *text[5];
|
|
+ POOL_PRINT hash_string1;
|
|
+ POOL_PRINT hash_string2;
|
|
+ int i;
|
|
+
|
|
+ ZeroMem(&hash_string1, sizeof(hash_string1));
|
|
+ ZeroMem(&hash_string2, sizeof(hash_string2));
|
|
+
|
|
+ text[0] = L"SHA256 hash";
|
|
+ text[1] = L"";
|
|
+
|
|
+ for (i=0; i<16; i++)
|
|
+ CatPrint(&hash_string1, L"%02x ", hash[i]);
|
|
+ for (i=16; i<32; i++)
|
|
+ CatPrint(&hash_string2, L"%02x ", hash[i]);
|
|
+
|
|
+ text[2] = hash_string1.str;
|
|
+ text[3] = hash_string2.str;
|
|
+ text[4] = NULL;
|
|
+
|
|
+ console_print_box(text, -1);
|
|
+
|
|
+ if (hash_string1.str)
|
|
+ FreePool(hash_string1.str);
|
|
+
|
|
+ if (hash_string2.str)
|
|
+ FreePool(hash_string2.str);
|
|
+}
|
|
+
|
|
static void show_mok_info (void *Mok, UINTN MokSize)
|
|
{
|
|
EFI_STATUS efi_status;
|
|
UINT8 hash[SHA1_DIGEST_SIZE];
|
|
- unsigned int i;
|
|
X509 *X509Cert;
|
|
|
|
if (!Mok || MokSize == 0)
|
|
@@ -458,13 +385,7 @@ static void show_mok_info (void *Mok, UINTN MokSize)
|
|
return;
|
|
}
|
|
} else {
|
|
- Print(L"SHA256 hash:\n ");
|
|
- for (i = 0; i < SHA256_DIGEST_SIZE; i++) {
|
|
- Print(L" %02x", ((UINT8 *)Mok)[i]);
|
|
- if (i % 10 == 9)
|
|
- Print(L"\n ");
|
|
- }
|
|
- Print(L"\n");
|
|
+ show_efi_hash(Mok);
|
|
}
|
|
}
|
|
|
|
@@ -506,7 +427,9 @@ static EFI_STATUS list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title)
|
|
key_num = console_select((CHAR16 *[]){ title, NULL },
|
|
menu_strings, 0);
|
|
|
|
- if (key_num < MokNum)
|
|
+ if (key_num < 0)
|
|
+ break;
|
|
+ else if (key_num < MokNum)
|
|
show_mok_info(keys[key_num].Mok, keys[key_num].MokSize);
|
|
}
|
|
|
|
--
|
|
1.8.1.4
|
|
|
|
|
|
From 139e31d514772f7aa74cf130ac1e4f2d548734ca Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Thu, 27 Jun 2013 15:04:07 +0800
|
|
Subject: [PATCH 08/11] MokManager: enhance the password prompt for SB state
|
|
|
|
---
|
|
MokManager.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
|
|
1 file changed, 55 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/MokManager.c b/MokManager.c
|
|
index 8b770ff..b832e40 100644
|
|
--- a/MokManager.c
|
|
+++ b/MokManager.c
|
|
@@ -942,13 +942,39 @@ static INTN mok_deletion_prompt (void *MokDel, UINTN MokDelSize)
|
|
return -1;
|
|
}
|
|
|
|
+static CHAR16 get_password_charater (CHAR16 *prompt)
|
|
+{
|
|
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
|
|
+ CHAR16 *message[2];
|
|
+ CHAR16 character;
|
|
+ UINTN length;
|
|
+ UINT32 pw_length;
|
|
+
|
|
+ if (!prompt)
|
|
+ prompt = L"Password charater: ";
|
|
+
|
|
+ console_save_and_set_mode(&SavedMode);
|
|
+
|
|
+ message[0] = prompt;
|
|
+ message[1] = NULL;
|
|
+ length = StrLen(message[0]);
|
|
+ console_print_box_at(message, -1, -length-4, -5, length+4, 3, 0, 1);
|
|
+ get_line(&pw_length, &character, 1, 0);
|
|
+
|
|
+ console_restore_mode(&SavedMode);
|
|
+
|
|
+ return character;
|
|
+}
|
|
+
|
|
static INTN mok_sb_prompt (void *MokSB, UINTN MokSBSize) {
|
|
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
|
EFI_STATUS efi_status;
|
|
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
|
|
MokSBvar *var = MokSB;
|
|
+ CHAR16 *message[4];
|
|
CHAR16 pass1, pass2, pass3;
|
|
+ CHAR16 *str;
|
|
UINT8 fail_count = 0;
|
|
- UINT32 length;
|
|
UINT8 sbval = 1;
|
|
UINT8 pos1, pos2, pos3;
|
|
int ret;
|
|
@@ -960,6 +986,13 @@ static INTN mok_sb_prompt (void *MokSB, UINTN MokSBSize) {
|
|
|
|
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
|
|
|
|
+ message[0] = L"Change Secure Boot state";
|
|
+ message[1] = NULL;
|
|
+
|
|
+ console_save_and_set_mode(&SavedMode);
|
|
+ console_print_box_at(message, -1, 0, 0, -1, -1, 1, 1);
|
|
+ console_restore_mode(&SavedMode);
|
|
+
|
|
while (fail_count < 3) {
|
|
RandomBytes (&pos1, sizeof(pos1));
|
|
pos1 = (pos1 % var->PWLen);
|
|
@@ -974,14 +1007,29 @@ static INTN mok_sb_prompt (void *MokSB, UINTN MokSBSize) {
|
|
pos3 = (pos3 % var->PWLen) ;
|
|
} while (pos3 == pos2 || pos3 == pos1);
|
|
|
|
- Print(L"Enter password character %d: ", pos1 + 1);
|
|
- get_line(&length, &pass1, 1, 0);
|
|
+ str = PoolPrint(L"Enter password character %d: ", pos1 + 1);
|
|
+ if (!str) {
|
|
+ console_errorbox(L"Failed to allocate buffer");
|
|
+ return -1;
|
|
+ }
|
|
+ pass1 = get_password_charater(str);
|
|
+ FreePool(str);
|
|
|
|
- Print(L"Enter password character %d: ", pos2 + 1);
|
|
- get_line(&length, &pass2, 1, 0);
|
|
+ str = PoolPrint(L"Enter password character %d: ", pos2 + 1);
|
|
+ if (!str) {
|
|
+ console_errorbox(L"Failed to allocate buffer");
|
|
+ return -1;
|
|
+ }
|
|
+ pass2 = get_password_charater(str);
|
|
+ FreePool(str);
|
|
|
|
- Print(L"Enter password character %d: ", pos3 + 1);
|
|
- get_line(&length, &pass3, 1, 0);
|
|
+ str = PoolPrint(L"Enter password character %d: ", pos3 + 1);
|
|
+ if (!str) {
|
|
+ console_errorbox(L"Failed to allocate buffer");
|
|
+ return -1;
|
|
+ }
|
|
+ pass3 = get_password_charater(str);
|
|
+ FreePool(str);
|
|
|
|
if (pass1 != var->Password[pos1] ||
|
|
pass2 != var->Password[pos2] ||
|
|
--
|
|
1.8.1.4
|
|
|
|
|
|
From f6102590b773cef0825eb707a793e70b54b882e9 Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Wed, 24 Jul 2013 14:39:39 +0800
|
|
Subject: [PATCH 09/11] MokManager: reboot the system after clearing MOK
|
|
password
|
|
|
|
---
|
|
MokManager.c | 6 +++++-
|
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/MokManager.c b/MokManager.c
|
|
index b832e40..bef4d8c 100644
|
|
--- a/MokManager.c
|
|
+++ b/MokManager.c
|
|
@@ -1107,7 +1107,11 @@ static INTN mok_pw_prompt (void *MokPW, UINTN MokPWSize) {
|
|
|
|
LibDeleteVariable(L"MokPWStore", &shim_lock_guid);
|
|
LibDeleteVariable(L"MokPW", &shim_lock_guid);
|
|
- return 0;
|
|
+ console_notify(L"The system must now be rebooted");
|
|
+ uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, EFI_SUCCESS, 0,
|
|
+ NULL);
|
|
+ console_notify(L"Failed to reboot");
|
|
+ return -1;
|
|
}
|
|
|
|
if (MokPWSize == PASSWORD_CRYPT_SIZE) {
|
|
--
|
|
1.8.1.4
|
|
|
|
|
|
From 05eeef80e4ae2bac8f0f27a8c1bc6c3869e030ce Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Fri, 26 Jul 2013 12:44:42 +0800
|
|
Subject: [PATCH 10/11] MokManager: fetch more info from X509 name
|
|
|
|
---
|
|
MokManager.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++-------
|
|
1 file changed, 56 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/MokManager.c b/MokManager.c
|
|
index bef4d8c..911c510 100644
|
|
--- a/MokManager.c
|
|
+++ b/MokManager.c
|
|
@@ -14,6 +14,8 @@
|
|
#define PASSWORD_MIN 1
|
|
#define SB_PASSWORD_LEN 16
|
|
|
|
+#define NAME_LINE_MAX 70
|
|
+
|
|
#ifndef SHIM_VENDOR
|
|
#define SHIM_VENDOR L"Shim"
|
|
#endif
|
|
@@ -180,14 +182,61 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) {
|
|
return list;
|
|
}
|
|
|
|
-static CHAR16* get_x509_common_name (X509_NAME *X509Name)
|
|
+typedef struct {
|
|
+ int nid;
|
|
+ CHAR16 *name;
|
|
+} NidName;
|
|
+
|
|
+static NidName nidname[] = {
|
|
+ {NID_commonName, L"CN"},
|
|
+ {NID_organizationName, L"O"},
|
|
+ {NID_countryName, L"C"},
|
|
+ {NID_stateOrProvinceName, L"ST"},
|
|
+ {NID_localityName, L"L"},
|
|
+ {-1, NULL}
|
|
+};
|
|
+
|
|
+static CHAR16* get_x509_name (X509_NAME *X509Name)
|
|
{
|
|
- char str[80];
|
|
+ CHAR16 name[NAME_LINE_MAX+1];
|
|
+ CHAR16 part[NAME_LINE_MAX+1];
|
|
+ char str[NAME_LINE_MAX];
|
|
+ int i, len, rest, first;
|
|
+
|
|
+ name[0] = '\0';
|
|
+ rest = NAME_LINE_MAX;
|
|
+ first = 1;
|
|
+ for (i = 0; nidname[i].name != NULL; i++) {
|
|
+ int add;
|
|
+ len = X509_NAME_get_text_by_NID (X509Name, nidname[i].nid,
|
|
+ str, NAME_LINE_MAX);
|
|
+ if (len <= 0)
|
|
+ continue;
|
|
|
|
- ZeroMem(str, 80);
|
|
- X509_NAME_get_text_by_NID (X509Name, NID_commonName, str, 80);
|
|
+ if (first)
|
|
+ add = len + (int)StrLen(nidname[i].name) + 1;
|
|
+ else
|
|
+ add = len + (int)StrLen(nidname[i].name) + 3;
|
|
|
|
- return PoolPrint(L"%a", str);
|
|
+ if (add > rest)
|
|
+ continue;
|
|
+
|
|
+ if (first) {
|
|
+ SPrint(part, NAME_LINE_MAX * sizeof(CHAR16), L"%s=%a",
|
|
+ nidname[i].name, str);
|
|
+ } else {
|
|
+ SPrint(part, NAME_LINE_MAX * sizeof(CHAR16), L", %s=%a",
|
|
+ nidname[i].name, str);
|
|
+ }
|
|
+ StrCat(name, part);
|
|
+ rest -= add;
|
|
+ first = 0;
|
|
+ }
|
|
+
|
|
+ if (rest >= 0 && rest < NAME_LINE_MAX)
|
|
+ return PoolPrint(L"%s", name);
|
|
+
|
|
+ return NULL;
|
|
}
|
|
|
|
static CHAR16* get_x509_time (ASN1_TIME *time)
|
|
@@ -243,14 +292,14 @@ static void show_x509_info (X509 *X509Cert, UINT8 *hash)
|
|
|
|
X509Name = X509_get_issuer_name(X509Cert);
|
|
if (X509Name) {
|
|
- issuer = get_x509_common_name(X509Name);
|
|
+ issuer = get_x509_name(X509Name);
|
|
if (issuer)
|
|
fields++;
|
|
}
|
|
|
|
X509Name = X509_get_subject_name(X509Cert);
|
|
if (X509Name) {
|
|
- subject = get_x509_common_name(X509Name);
|
|
+ subject = get_x509_name(X509Name);
|
|
if (subject)
|
|
fields++;
|
|
}
|
|
--
|
|
1.8.1.4
|
|
|
|
|
|
From 6d6df739005169333734ee04fc379a28d213ab8c Mon Sep 17 00:00:00 2001
|
|
From: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Fri, 26 Jul 2013 15:44:49 +0800
|
|
Subject: [PATCH 11/11] MokManager: check the suffix of the key file
|
|
|
|
---
|
|
MokManager.c | 39 ++++++++++++++++++++++++++++++++++++++-
|
|
1 file changed, 38 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/MokManager.c b/MokManager.c
|
|
index 911c510..604129f 100644
|
|
--- a/MokManager.c
|
|
+++ b/MokManager.c
|
|
@@ -1199,7 +1199,7 @@ static INTN mok_pw_prompt (void *MokPW, UINTN MokPWSize) {
|
|
return -1;
|
|
}
|
|
|
|
-static UINTN verify_certificate(void *cert, UINTN size)
|
|
+static BOOLEAN verify_certificate(void *cert, UINTN size)
|
|
{
|
|
X509 *X509Cert;
|
|
if (!cert || size == 0)
|
|
@@ -1341,6 +1341,34 @@ static void mok_hash_enroll(void)
|
|
FreePool(data);
|
|
}
|
|
|
|
+static CHAR16 *der_suffix[] = {
|
|
+ L".cer",
|
|
+ L".der",
|
|
+ L".crt",
|
|
+ NULL
|
|
+};
|
|
+
|
|
+static BOOLEAN check_der_suffix (CHAR16 *file_name)
|
|
+{
|
|
+ CHAR16 suffix[5];
|
|
+ int i;
|
|
+
|
|
+ if (!file_name || StrLen(file_name) <= 4)
|
|
+ return FALSE;
|
|
+
|
|
+ suffix[0] = '\0';
|
|
+ StrCat(suffix, file_name + StrLen(file_name) - 4);
|
|
+
|
|
+ StrLwr (suffix);
|
|
+ for (i = 0; der_suffix[i] != NULL; i++) {
|
|
+ if (StrCmp(suffix, der_suffix[i]) == 0) {
|
|
+ return TRUE;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
static void mok_key_enroll(void)
|
|
{
|
|
EFI_STATUS efi_status;
|
|
@@ -1362,6 +1390,15 @@ static void mok_key_enroll(void)
|
|
if (!file_name)
|
|
return;
|
|
|
|
+ if (!check_der_suffix(file_name)) {
|
|
+ console_alertbox((CHAR16 *[]){
|
|
+ L"Unsupported Format",
|
|
+ L"",
|
|
+ L"Only DER encoded certificate (*.cer/der/crt) is supported",
|
|
+ NULL});
|
|
+ return;
|
|
+ }
|
|
+
|
|
efi_status = simple_file_open(im, file_name, &file, EFI_FILE_MODE_READ);
|
|
|
|
if (efi_status != EFI_SUCCESS) {
|
|
--
|
|
1.8.1.4
|
|
|