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:
commit
cb345da9fe
23
.gitattributes
vendored
Normal file
23
.gitattributes
vendored
Normal 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
3
mokutil-0.1.0.tar.bz2
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:739a241e18cc5b89c46eecc473568fb295952598ff518e7af90f81900afb62d4
|
||||
size 94722
|
283
mokutil-no-duplicate-keys-imported.patch
Normal file
283
mokutil-no-duplicate-keys-imported.patch
Normal 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
|
||||
|
111
mokutil-probe-secure-boot-state.patch
Normal file
111
mokutil-probe-secure-boot-state.patch
Normal 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
13
mokutil.changes
Normal 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
67
mokutil.spec
Normal 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
|
Loading…
Reference in New Issue
Block a user