Accepting request 148524 from home:gary_lin:UEFI

mokutil is a program to manipulate the machine owner keys.
It sets up MOK requests, such as enroll and delete, and
shim/MokManager shows the information of the keys during
the next boot time.

OBS-URL: https://build.opensuse.org/request/show/148524
OBS-URL: https://build.opensuse.org/package/show/Base:System/mokutil?expand=0&rev=1
This commit is contained in:
Andreas Jaeger 2013-01-15 08:03:56 +00:00 committed by Git OBS Bridge
commit cb345da9fe
6 changed files with 500 additions and 0 deletions

23
.gitattributes vendored Normal file
View File

@ -0,0 +1,23 @@
## Default LFS
*.7z filter=lfs diff=lfs merge=lfs -text
*.bsp filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
*.gem filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.jar filter=lfs diff=lfs merge=lfs -text
*.lz filter=lfs diff=lfs merge=lfs -text
*.lzma filter=lfs diff=lfs merge=lfs -text
*.obscpio filter=lfs diff=lfs merge=lfs -text
*.oxt filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.rpm filter=lfs diff=lfs merge=lfs -text
*.tbz filter=lfs diff=lfs merge=lfs -text
*.tbz2 filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.ttf filter=lfs diff=lfs merge=lfs -text
*.txz filter=lfs diff=lfs merge=lfs -text
*.whl filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text

3
mokutil-0.1.0.tar.bz2 Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:739a241e18cc5b89c46eecc473568fb295952598ff518e7af90f81900afb62d4
size 94722

View File

@ -0,0 +1,283 @@
From 0e1ac853fb889b3d8d00e3a4751f388b0b8d8f26 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Wed, 5 Dec 2012 11:12:43 +0800
Subject: [PATCH 1/4] Correct MOK size and SignatureSize
The MOK size didn't include the SignatureOwner GUID.
The SignatureData header size was added twice accidentally.
---
src/mokutil.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index 1c32828..1b8465f 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -143,7 +143,7 @@ build_mok_list (void *data, unsigned long data_size, uint32_t *mok_num)
return NULL;
}
- list[count].mok_size = CertList->SignatureSize;
+ list[count].mok_size = CertList->SignatureSize - sizeof(efi_guid_t);
list[count].mok = (void *)Cert->SignatureData;
count++;
@@ -497,8 +497,7 @@ import_moks (char **files, uint32_t total)
CertList->SignatureListSize = sizes[i] +
sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1;
CertList->SignatureHeaderSize = 0;
- CertList->SignatureSize = sizes[i] +
- sizeof(EFI_SIGNATURE_DATA) + 16;
+ CertList->SignatureSize = sizes[i] + sizeof(efi_guid_t);
CertData->SignatureOwner = SHIM_LOCK_GUID;
fd = open (files[i], O_RDONLY);
--
1.7.10.4
From 69955da3819da3abaf198e5dae038c44814df5c0 Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Wed, 5 Dec 2012 11:24:58 +0800
Subject: [PATCH 2/4] Don't import duplicate keys
This commit compares keys in PK, KEK, db, MokListRT, and MokNew
before issuing a new request to avoid enrolling keys twice.
---
src/mokutil.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 124 insertions(+), 4 deletions(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index 1b8465f..cf38422 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -333,8 +333,8 @@ get_password (char **password, int *len, int min, int max)
}
static int
-generate_auth (void *new_list, int list_len, char *password, int pw_len,
- uint8_t *auth)
+generate_auth (void *new_list, unsigned long list_len, char *password,
+ int pw_len, uint8_t *auth)
{
efi_char16_t efichar_pass[PASSWORD_MAX+1];
unsigned long efichar_len;
@@ -444,12 +444,97 @@ is_valid_cert (void *cert, uint32_t cert_size)
}
static int
+is_duplicate (const void *cert, const uint32_t cert_size, const char *db_name,
+ efi_guid_t guid)
+{
+ efi_variable_t var;
+ uint32_t mok_num;
+ MokListNode *list;
+ int i, ret = 0;
+
+ if (!cert || cert_size == 0 || !db_name)
+ return 0;
+
+ memset (&var, 0, sizeof(var));
+ var.VariableName = db_name;
+ var.VendorGuid = guid;
+
+ if (read_variable (&var) != EFI_SUCCESS)
+ return 0;
+
+ list = build_mok_list (var.Data, var.DataSize, &mok_num);
+ if (list == NULL) {
+ goto done;
+ }
+
+ for (i = 0; i < mok_num; i++) {
+ if (list[i].mok_size != cert_size)
+ continue;
+
+ if (memcmp (list[i].mok, cert, cert_size) == 0) {
+ ret = 1;
+ break;
+ }
+ }
+
+done:
+ free (var.Data);
+
+ return ret;
+}
+
+static int
+verify_mok_new (void *mok_new, unsigned long mok_new_size)
+{
+ efi_variable_t mok_auth;
+ uint8_t auth[SHA256_DIGEST_LENGTH];
+ char *password;
+ int pw_len, fail = 0;
+ size_t n;
+ int ret = 0;
+
+ memset (&mok_auth, 0, sizeof(mok_auth));
+ mok_auth.VariableName = "MokAuth";
+ mok_auth.VendorGuid = SHIM_LOCK_GUID;
+ if (read_variable (&mok_auth) == EFI_SUCCESS)
+ return 0;
+
+ while (fail < 3) {
+ printf ("input old password: ");
+ pw_len = read_hidden_line (&password, &n);
+ printf ("\n");
+
+ if (pw_len > PASSWORD_MAX || pw_len < PASSWORD_MIN) {
+ free (password);
+ fprintf (stderr, "invalid password\n");
+ fail++;
+ continue;
+ }
+
+ generate_auth (mok_new, mok_new_size, password, pw_len, auth);
+ if (memcmp (auth, mok_auth.Data, SHA256_DIGEST_LENGTH) == 0) {
+ ret = 1;
+ break;
+ }
+
+ fail++;
+ }
+
+ if (mok_auth.Data)
+ free (mok_auth.Data);
+
+ return ret;
+}
+
+static int
import_moks (char **files, uint32_t total)
{
+ efi_variable_t mok_new;
void *new_list = NULL;
void *ptr;
struct stat buf;
unsigned long list_size = 0;
+ unsigned long real_size = 0;
uint32_t *sizes = NULL;
int fd = -1;
ssize_t read_size;
@@ -481,6 +566,12 @@ import_moks (char **files, uint32_t total)
list_size += sizeof(EFI_SIGNATURE_LIST) * total;
list_size += sizeof(efi_guid_t) * total;
+ memset (&mok_new, 0, sizeof(mok_new));
+ mok_new.VariableName = "MokNew";
+ mok_new.VendorGuid = SHIM_LOCK_GUID;
+ if (read_variable (&mok_new) == EFI_SUCCESS)
+ list_size += mok_new.DataSize;
+
new_list = malloc (list_size);
if (!new_list) {
fprintf (stderr, "Failed to allocate space for MokNew\n");
@@ -518,17 +609,46 @@ import_moks (char **files, uint32_t total)
fprintf (stderr, "Warning!!! %s is not a valid x509 certificate in DER format\n",
files[i]);
}
- ptr += sizes[i];
+
+ /* whether this key is already enrolled... */
+ if (!is_duplicate (ptr, sizes[i], "PK", EFI_GLOBAL_VARIABLE) &&
+ !is_duplicate (ptr, sizes[i], "KEK", EFI_GLOBAL_VARIABLE) &&
+ !is_duplicate (ptr, sizes[i], "db", EFI_GLOBAL_VARIABLE) &&
+ !is_duplicate (ptr, sizes[i], "MokListRT", SHIM_LOCK_GUID) &&
+ !is_duplicate (ptr, sizes[i], "MokNew", SHIM_LOCK_GUID)) {
+ ptr += sizes[i];
+ real_size += sizes[i] + sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t);
+ } else {
+ ptr -= sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t);
+ }
close (fd);
}
- if (update_request (new_list, list_size) < 0) {
+ /* All keys are enrolled, nothing to do here... */
+ if (real_size == 0) {
+ ret = 0;
+ goto error;
+ }
+
+ /* append the keys in MokNew */
+ if (mok_new.Data) {
+ /* request the previous password to verify the keys */
+ if (!verify_mok_new (mok_new.Data, mok_new.DataSize)) {
+ goto error;
+ }
+
+ memcpy (ptr, mok_new.Data, mok_new.DataSize);
+ }
+
+ if (update_request (new_list, real_size) < 0) {
goto error;
}
ret = 0;
error:
+ if (mok_new.Data)
+ free (mok_new.Data);
if (sizes)
free (sizes);
if (new_list)
--
1.7.10.4
From 10046350e223b6912bd9c3a7031f06779cb326bb Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Fri, 7 Dec 2012 15:57:50 +0800
Subject: [PATCH 3/4] Check MokAuth correctly
---
src/mokutil.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index cf38422..9d56a90 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -496,8 +496,10 @@ verify_mok_new (void *mok_new, unsigned long mok_new_size)
memset (&mok_auth, 0, sizeof(mok_auth));
mok_auth.VariableName = "MokAuth";
mok_auth.VendorGuid = SHIM_LOCK_GUID;
- if (read_variable (&mok_auth) == EFI_SUCCESS)
+ if (read_variable (&mok_auth) != EFI_SUCCESS) {
+ fprintf (stderr, "Failed to read MokAuth\n");
return 0;
+ }
while (fail < 3) {
printf ("input old password: ");
--
1.7.10.4
From 9674b3249fef0d2ba00364f9f120f1ef17b710fc Mon Sep 17 00:00:00 2001
From: Gary Ching-Pang Lin <glin@suse.com>
Date: Fri, 7 Dec 2012 15:58:30 +0800
Subject: [PATCH 4/4] Really append the old request to the new one...
---
src/mokutil.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/mokutil.c b/src/mokutil.c
index 9d56a90..aba1cfb 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -640,7 +640,8 @@ import_moks (char **files, uint32_t total)
goto error;
}
- memcpy (ptr, mok_new.Data, mok_new.DataSize);
+ memcpy (new_list + real_size, mok_new.Data, mok_new.DataSize);
+ real_size += mok_new.DataSize;
}
if (update_request (new_list, real_size) < 0) {
--
1.7.10.4

View File

@ -0,0 +1,111 @@
commit b2602eee326c15df8d23baa44f9e9e3e8b6bad93
Author: Gary Ching-Pang Lin <glin@suse.com>
Date: Mon Dec 3 17:45:41 2012 +0800
Probe the state of SecureBoot
diff --git a/src/mokutil.c b/src/mokutil.c
index 3707220..1c32828 100644
--- a/src/mokutil.c
+++ b/src/mokutil.c
@@ -40,6 +40,7 @@ enum Command {
COMMAND_PASSWORD,
COMMAND_DISABLE_VALIDATION,
COMMAND_ENABLE_VALIDATION,
+ COMMAND_SB_STATE,
};
static void
@@ -48,22 +49,33 @@ print_help ()
printf("Usage:\n");
printf("List the enrolled keys:\n");
printf(" mokutil --list-enrolled\n\n");
+
printf("List the keys to be enrolled:\n");
printf(" mokutil --list-new\n\n");
+
printf("Import keys:\n");
printf(" mokutil --import <der file>...\n\n");
+
printf("Request to delete all keys\n");
printf(" mokutil --delete-all\n\n");
+
printf("Revoke the request:\n");
printf(" mokutil --revoke\n\n");
+
printf("Export enrolled keys to files:\n");
printf(" mokutil --export\n\n");
+
printf("Set MOK password:\n");
printf(" mokutil --password\n\n");
+
printf("Disable signature validation:\n");
printf(" mokutil --disable-validation\n\n");
+
printf("Enable signature validation:\n");
printf(" mokutil --enable-validation\n\n");
+
+ printf("SecureBoot State:\n");
+ printf(" mokutil --sb-state\n\n");
}
static int
@@ -709,7 +721,36 @@ enable_validation()
{
return set_validation(1);
}
-
+
+static int
+sb_state ()
+{
+ efi_variable_t var;
+ char *state;
+
+ memset (&var, 0, sizeof(var));
+ var.VariableName = "SecureBoot";
+ var.VendorGuid = EFI_GLOBAL_VARIABLE;
+
+ if (read_variable (&var) != EFI_SUCCESS) {
+ fprintf (stderr, "Failed to read SecureBoot\n");
+ return -1;
+ }
+
+ state = (char *)var.Data;
+ if (*state == 1) {
+ printf ("SecureBoot enabled\n");
+ } else if (*state == 0) {
+ printf ("SecureBoot disabled\n");
+ } else {
+ printf ("SecureBoot unknown");
+ }
+
+ free (var.Data);
+
+ return 0;
+}
+
int
main (int argc, char *argv[])
{
@@ -786,6 +827,10 @@ main (int argc, char *argv[])
command = COMMAND_ENABLE_VALIDATION;
+ } else if (strcmp (argv[1], "--sb-state") == 0) {
+
+ command = COMMAND_SB_STATE;
+
} else {
fprintf (stderr, "Unknown argument: %s\n\n", argv[1]);
print_help ();
@@ -820,6 +865,9 @@ main (int argc, char *argv[])
case COMMAND_ENABLE_VALIDATION:
enable_validation ();
break;
+ case COMMAND_SB_STATE:
+ sb_state ();
+ break;
default:
fprintf (stderr, "Unknown command\n");
break;

13
mokutil.changes Normal file
View File

@ -0,0 +1,13 @@
-------------------------------------------------------------------
Tue Dec 11 08:07:32 UTC 2012 - glin@suse.com
- Add mokutil-probe-secure-boot-state.patch to probe the state of
secure boot
- Add mokutil-no-duplicate-keys-imported.patch to avoid importing
duplicate keys
-------------------------------------------------------------------
Wed Nov 7 08:10:45 UTC 2012 - glin@suse.com
- Add new package mokutil-0.1.0 (FATE#314510)

67
mokutil.spec Normal file
View File

@ -0,0 +1,67 @@
#
# spec file for package mokutil
#
# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via http://bugs.opensuse.org/
#
Name: mokutil
Version: 0.1.0
Release: 1
License: GPL-3.0
Summary: Tools for manipulating machine owner keys
Url: https://github.com/lcp/mokutil
Group: Productivity/Security
Source: %{name}-%{version}.tar.bz2
# PATCH-FIX-UPSTREAM mokutil-probe-secure-boot-state.patch glin@suse.com -- Probe the state of secure boot
Patch1: mokutil-probe-secure-boot-state.patch
# PATCH-FIX-UPSTREAM mokutil-no-duplicate-keys-imported.patch glin@suse.com -- Do not import duplicate keys
Patch2: mokutil-no-duplicate-keys-imported.patch
BuildRequires: pkg-config
BuildRequires: libopenssl-devel >= 0.9.8
BuildRoot: %{_tmppath}/%{name}-%{version}-build
ExclusiveArch: x86_64
%description
This program provides the means to enroll and erase the machine owner
keys (MOK) stored in the database of shim.
Authors:
--------
Gary Lin <glin@suse.com>
%prep
%setup -q
%patch1 -p1
%patch2 -p1
%build
%configure
make
%install
%makeinstall
%clean
%{?buildroot:%__rm -rf "%{buildroot}"}
%files
%defattr(-,root,root)
%{_bindir}/mokutil
%{_mandir}/man?/*
%changelog