File shim-mokmanager-ui-revamp.patch of Package shim

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

openSUSE Build Service is sponsored by