shim/shim-mokmanager-ui-revamp.patch
Gary Ching-Pang Lin 125b3129ee Accepting request 185349 from home:gary_lin:branches:devel:openSUSE:Factory
- 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
2013-08-01 02:49:52 +00:00

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