1160 lines
35 KiB
Diff
1160 lines
35 KiB
Diff
|
From edbb90e7b9dddcb6561af244a65d10d6a22e6bae Mon Sep 17 00:00:00 2001
|
||
|
From: Gary Lin <glin@suse.com>
|
||
|
Date: Thu, 27 Aug 2020 11:31:08 +0800
|
||
|
Subject: [PATCH 01/13] efi_x509: add the function to check immediate CA
|
||
|
|
||
|
Add a new function, is_immediate_ca(), to check whether the given CA
|
||
|
cert is the immediate CA of the cert.
|
||
|
|
||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||
|
(cherry picked from commit 643bb8dacb221979354dab814fc2d41e94a02d67)
|
||
|
---
|
||
|
src/mokutil.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
1 file changed, 73 insertions(+)
|
||
|
|
||
|
diff --git a/src/mokutil.c b/src/mokutil.c
|
||
|
index e2d567d..3735167 100644
|
||
|
--- a/src/mokutil.c
|
||
|
+++ b/src/mokutil.c
|
||
|
@@ -1032,6 +1032,79 @@ is_valid_cert (void *cert, uint32_t cert_size)
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
+/**
|
||
|
+ * Check whether the given CA cert is the immediate CA of the given cert
|
||
|
+ **/
|
||
|
+static int
|
||
|
+is_immediate_ca (const uint8_t *cert, const uint32_t cert_size,
|
||
|
+ const uint8_t *ca_cert, const uint32_t ca_cert_size)
|
||
|
+{
|
||
|
+ X509 *X509cert = NULL;
|
||
|
+ X509 *X509ca = NULL;
|
||
|
+ X509_STORE *cert_store = NULL;
|
||
|
+ X509_STORE_CTX *cert_ctx = NULL;
|
||
|
+ int ret = 0;
|
||
|
+
|
||
|
+ if (cert == NULL || ca_cert == NULL)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ if (EVP_add_digest (EVP_md5 ()) == 0)
|
||
|
+ return 0;
|
||
|
+ if (EVP_add_digest (EVP_sha1 ()) == 0)
|
||
|
+ return 0;
|
||
|
+ if (EVP_add_digest (EVP_sha256 ()) == 0)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ X509cert = d2i_X509 (NULL, &cert, cert_size);
|
||
|
+ if (X509cert == NULL)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ X509ca = d2i_X509 (NULL, &ca_cert, ca_cert_size);
|
||
|
+ if (X509ca == NULL)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ cert_store = X509_STORE_new ();
|
||
|
+ if (cert_store == NULL)
|
||
|
+ goto err;
|
||
|
+
|
||
|
+ if (X509_STORE_add_cert (cert_store, X509ca) == 0)
|
||
|
+ goto err;
|
||
|
+
|
||
|
+ /* Follow edk2 CryptoPkg to allow partial certificate chains and
|
||
|
+ * disable time checks */
|
||
|
+ X509_STORE_set_flags (cert_store,
|
||
|
+ X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME);
|
||
|
+
|
||
|
+ cert_ctx = X509_STORE_CTX_new ();
|
||
|
+ if (cert_ctx == NULL)
|
||
|
+ goto err;
|
||
|
+
|
||
|
+ if (X509_STORE_CTX_init (cert_ctx, cert_store, X509cert, NULL) == 0)
|
||
|
+ goto err;
|
||
|
+
|
||
|
+ /* Verify the cert */
|
||
|
+ ret = X509_verify_cert (cert_ctx);
|
||
|
+ /* Treat the exceptional error as FALSE */
|
||
|
+ if (ret < 0)
|
||
|
+ ret = 0;
|
||
|
+ X509_STORE_CTX_cleanup (cert_ctx);
|
||
|
+
|
||
|
+err:
|
||
|
+ if (X509cert)
|
||
|
+ X509_free (X509cert);
|
||
|
+
|
||
|
+ if (X509ca)
|
||
|
+ X509_free (X509ca);
|
||
|
+
|
||
|
+ if (cert_store)
|
||
|
+ X509_STORE_free (cert_store);
|
||
|
+
|
||
|
+ if (cert_store)
|
||
|
+ X509_STORE_CTX_free (cert_ctx);
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
static int
|
||
|
is_duplicate (const efi_guid_t *type, const void *data, const uint32_t data_size,
|
||
|
const efi_guid_t *vendor, const char *db_name)
|
||
|
--
|
||
|
2.28.0
|
||
|
|
||
|
|
||
|
From db7216b3a758ba62f02154b79a77c878fd0fd85e Mon Sep 17 00:00:00 2001
|
||
|
From: Gary Lin <glin@suse.com>
|
||
|
Date: Thu, 27 Aug 2020 14:11:56 +0800
|
||
|
Subject: [PATCH 02/13] mokutil: do the CA check
|
||
|
|
||
|
Check whether th CA cert is already enrolled in the key database before
|
||
|
enrolling the key.
|
||
|
|
||
|
The check can be disabled with "--ignore-ca-check".
|
||
|
|
||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||
|
(cherry picked from commit ff20a53a111fe3e027da7250175b7ef09ce3b1da)
|
||
|
---
|
||
|
src/mokutil.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
1 file changed, 88 insertions(+)
|
||
|
|
||
|
diff --git a/src/mokutil.c b/src/mokutil.c
|
||
|
index 3735167..4ac6619 100644
|
||
|
--- a/src/mokutil.c
|
||
|
+++ b/src/mokutil.c
|
||
|
@@ -95,6 +95,7 @@ typedef uint8_t efi_bool_t;
|
||
|
typedef wchar_t efi_char16_t; /* UNICODE character */
|
||
|
|
||
|
static int use_simple_hash;
|
||
|
+static int force_ca_check;
|
||
|
|
||
|
typedef enum {
|
||
|
DELETE_MOK = 0,
|
||
|
@@ -182,6 +183,7 @@ print_help ()
|
||
|
printf (" --root-pw\t\t\t\tUse the root password\n");
|
||
|
printf (" --simple-hash\t\t\t\tUse the old password hash method\n");
|
||
|
printf (" --mokx\t\t\t\tManipulate the MOK blacklist\n");
|
||
|
+ printf (" --ignore-ca-check\t\t\tDon't check CA of the given certificate\n");
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
@@ -1237,6 +1239,70 @@ in_pending_request (const efi_guid_t *type, void *data, uint32_t data_size,
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
+static int
|
||
|
+is_ca_in_db (const void *cert, const uint32_t cert_size,
|
||
|
+ const efi_guid_t *vendor, const char *db_name)
|
||
|
+{
|
||
|
+ uint8_t *var_data;
|
||
|
+ size_t var_data_size;
|
||
|
+ uint32_t attributes;
|
||
|
+ uint32_t node_num;
|
||
|
+ MokListNode *list;
|
||
|
+ int ret = 0;
|
||
|
+
|
||
|
+ if (!cert || cert_size == 0 || !vendor || !db_name)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ ret = efi_get_variable (*vendor, db_name, &var_data, &var_data_size,
|
||
|
+ &attributes);
|
||
|
+ if (ret < 0)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ list = build_mok_list (var_data, var_data_size, &node_num);
|
||
|
+ if (list == NULL) {
|
||
|
+ goto done;
|
||
|
+ }
|
||
|
+
|
||
|
+ for (unsigned int i = 0; i < node_num; i++) {
|
||
|
+ efi_guid_t sigtype = list[i].header->SignatureType;
|
||
|
+ if (efi_guid_cmp (&sigtype, &efi_guid_x509_cert) != 0)
|
||
|
+ continue;
|
||
|
+
|
||
|
+ if (is_immediate_ca (cert, cert_size, list[i].mok,
|
||
|
+ list[i].mok_size)) {
|
||
|
+ ret = 1;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+done:
|
||
|
+ if (list)
|
||
|
+ free (list);
|
||
|
+ free (var_data);
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
+/* Check whether the CA cert is already enrolled */
|
||
|
+static int
|
||
|
+is_ca_enrolled (void *mok, uint32_t mok_size, MokRequest req)
|
||
|
+{
|
||
|
+ switch (req) {
|
||
|
+ case ENROLL_MOK:
|
||
|
+ if (is_ca_in_db (mok, mok_size, &efi_guid_shim, "MokListRT"))
|
||
|
+ return 1;
|
||
|
+ break;
|
||
|
+ case ENROLL_BLACKLIST:
|
||
|
+ if (is_ca_in_db (mok, mok_size, &efi_guid_shim, "MokListXRT"))
|
||
|
+ return 1;
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
static void
|
||
|
print_skip_message (const char *filename, void *mok, uint32_t mok_size,
|
||
|
MokRequest req)
|
||
|
@@ -1394,6 +1460,13 @@ issue_mok_request (char **files, uint32_t total, MokRequest req,
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
+ /* Check whether CA is already enrolled */
|
||
|
+ if (force_ca_check && is_ca_enrolled (ptr, sizes[i], req)) {
|
||
|
+ fprintf (stderr, "CA of %s is already enrolled\n",
|
||
|
+ files[i]);
|
||
|
+ goto error;
|
||
|
+ }
|
||
|
+
|
||
|
if (is_valid_request (&efi_guid_x509_cert, ptr, sizes[i], req)) {
|
||
|
ptr += sizes[i];
|
||
|
real_size += sizes[i] + sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t);
|
||
|
@@ -2041,6 +2114,17 @@ test_key (MokRequest req, const char *key_file)
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
+ if (!is_valid_cert (key, read_size)) {
|
||
|
+ fprintf (stderr, "Not a valid x509 certificate\n");
|
||
|
+ goto error;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (force_ca_check && is_ca_enrolled (key, read_size, req)) {
|
||
|
+ fprintf (stderr, "CA of %s is already enrolled\n",
|
||
|
+ key_file);
|
||
|
+ goto error;
|
||
|
+ }
|
||
|
+
|
||
|
if (is_valid_request (&efi_guid_x509_cert, key, read_size, req)) {
|
||
|
printf ("%s is not enrolled\n", key_file);
|
||
|
ret = 0;
|
||
|
@@ -2215,6 +2299,7 @@ main (int argc, char *argv[])
|
||
|
int ret = -1;
|
||
|
|
||
|
use_simple_hash = 0;
|
||
|
+ force_ca_check = 1;
|
||
|
|
||
|
if (!efi_variables_supported ()) {
|
||
|
fprintf (stderr, "EFI variables are not supported on this system\n");
|
||
|
@@ -2255,6 +2340,7 @@ main (int argc, char *argv[])
|
||
|
{"db", no_argument, 0, 0 },
|
||
|
{"dbx", no_argument, 0, 0 },
|
||
|
{"timeout", required_argument, 0, 0 },
|
||
|
+ {"ignore-ca-check", no_argument, 0, 0 },
|
||
|
{0, 0, 0, 0}
|
||
|
};
|
||
|
|
||
|
@@ -2341,6 +2427,8 @@ main (int argc, char *argv[])
|
||
|
} else if (strcmp (option, "timeout") == 0) {
|
||
|
command |= TIMEOUT;
|
||
|
timeout = strdup (optarg);
|
||
|
+ } else if (strcmp (option, "ignore-ca-check") == 0) {
|
||
|
+ force_ca_check = 0;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
--
|
||
|
2.28.0
|
||
|
|
||
|
|
||
|
From 3bfcf1db9ab1ff2bd4a2ddd2649c03337f823a2d Mon Sep 17 00:00:00 2001
|
||
|
From: Gary Lin <glin@suse.com>
|
||
|
Date: Thu, 27 Aug 2020 14:18:29 +0800
|
||
|
Subject: [PATCH 03/13] mokutil: close file in the error path
|
||
|
|
||
|
We should close the file descriptor when encountering an error in
|
||
|
issue_mok_request();
|
||
|
|
||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||
|
(cherry picked from commit 0a0813d6f7dfa73f7947566e7fad2d42e016f30a)
|
||
|
---
|
||
|
src/mokutil.c | 3 +++
|
||
|
1 file changed, 3 insertions(+)
|
||
|
|
||
|
diff --git a/src/mokutil.c b/src/mokutil.c
|
||
|
index 4ac6619..760b54a 100644
|
||
|
--- a/src/mokutil.c
|
||
|
+++ b/src/mokutil.c
|
||
|
@@ -1452,11 +1452,13 @@ issue_mok_request (char **files, uint32_t total, MokRequest req,
|
||
|
read_size = read (fd, ptr, sizes[i]);
|
||
|
if (read_size < 0 || read_size != (int64_t)sizes[i]) {
|
||
|
fprintf (stderr, "Failed to read %s\n", files[i]);
|
||
|
+ close (fd);
|
||
|
goto error;
|
||
|
}
|
||
|
if (!is_valid_cert (ptr, read_size)) {
|
||
|
fprintf (stderr, "Abort!!! %s is not a valid x509 certificate in DER format\n",
|
||
|
files[i]);
|
||
|
+ close (fd);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
@@ -1464,6 +1466,7 @@ issue_mok_request (char **files, uint32_t total, MokRequest req,
|
||
|
if (force_ca_check && is_ca_enrolled (ptr, sizes[i], req)) {
|
||
|
fprintf (stderr, "CA of %s is already enrolled\n",
|
||
|
files[i]);
|
||
|
+ close (fd);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
--
|
||
|
2.28.0
|
||
|
|
||
|
|
||
|
From 77be7a26815233e798f6ab61cbbd8a1cd4a89817 Mon Sep 17 00:00:00 2001
|
||
|
From: Gary Lin <glin@suse.com>
|
||
|
Date: Thu, 27 Aug 2020 14:22:52 +0800
|
||
|
Subject: [PATCH 04/13] make CA check non-fatal
|
||
|
|
||
|
(cherry picked from commit 50098834780ee6d5dd0cfd3073d504030cc25037)
|
||
|
---
|
||
|
src/mokutil.c | 5 ++---
|
||
|
1 file changed, 2 insertions(+), 3 deletions(-)
|
||
|
|
||
|
diff --git a/src/mokutil.c b/src/mokutil.c
|
||
|
index 760b54a..f4f21f8 100644
|
||
|
--- a/src/mokutil.c
|
||
|
+++ b/src/mokutil.c
|
||
|
@@ -1464,10 +1464,9 @@ issue_mok_request (char **files, uint32_t total, MokRequest req,
|
||
|
|
||
|
/* Check whether CA is already enrolled */
|
||
|
if (force_ca_check && is_ca_enrolled (ptr, sizes[i], req)) {
|
||
|
- fprintf (stderr, "CA of %s is already enrolled\n",
|
||
|
- files[i]);
|
||
|
+ printf ("CA enrolled. Skip %s\n", files[i]);
|
||
|
close (fd);
|
||
|
- goto error;
|
||
|
+ continue;
|
||
|
}
|
||
|
|
||
|
if (is_valid_request (&efi_guid_x509_cert, ptr, sizes[i], req)) {
|
||
|
--
|
||
|
2.28.0
|
||
|
|
||
|
|
||
|
From e4a28a587f39912c65e3f74f0ff9766158ef9dff Mon Sep 17 00:00:00 2001
|
||
|
From: Sandy <39258624+sandy-lcq@users.noreply.github.com>
|
||
|
Date: Fri, 13 Dec 2019 10:38:28 +0800
|
||
|
Subject: [PATCH 05/13] mokutil.c: fix typo enrollement -> enrollment
|
||
|
|
||
|
Signed-off-by: Changqing Li <changqing.li@windriver.com>
|
||
|
(cherry picked from commit e37eeef4866f5f3bbeaef3fe1d1360ebac76bdc5)
|
||
|
---
|
||
|
src/mokutil.c | 2 +-
|
||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/src/mokutil.c b/src/mokutil.c
|
||
|
index f4f21f8..ee95e20 100644
|
||
|
--- a/src/mokutil.c
|
||
|
+++ b/src/mokutil.c
|
||
|
@@ -1323,7 +1323,7 @@ print_skip_message (const char *filename, void *mok, uint32_t mok_size,
|
||
|
printf ("SKIP: %s is already enrolled\n", filename);
|
||
|
else if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_shim, "MokNew"))
|
||
|
- printf ("SKIP: %s is already in the enrollement request\n", filename);
|
||
|
+ printf ("SKIP: %s is already in the enrollment request\n", filename);
|
||
|
break;
|
||
|
case DELETE_MOK:
|
||
|
if (!is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
--
|
||
|
2.28.0
|
||
|
|
||
|
|
||
|
From f18969c91a44fee03a1ab8da336973f36ef7e5e9 Mon Sep 17 00:00:00 2001
|
||
|
From: Gary Lin <glin@suse.com>
|
||
|
Date: Fri, 28 Aug 2020 11:53:24 +0800
|
||
|
Subject: [PATCH 06/13] mokutil: check the blocklists before enrolling a key
|
||
|
|
||
|
Check "dbx" and "MokListXRT" when enrolling a key.
|
||
|
|
||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||
|
(cherry picked from commit 8de04a4dd566376316432bd60c3b0ab2686797a4)
|
||
|
---
|
||
|
src/mokutil.c | 40 ++++++++++++++++++++++++++++++++++++++++
|
||
|
1 file changed, 40 insertions(+)
|
||
|
|
||
|
diff --git a/src/mokutil.c b/src/mokutil.c
|
||
|
index ee95e20..834228a 100644
|
||
|
--- a/src/mokutil.c
|
||
|
+++ b/src/mokutil.c
|
||
|
@@ -1173,6 +1173,10 @@ is_valid_request (const efi_guid_t *type, void *mok, uint32_t mok_size,
|
||
|
is_duplicate (type, mok, mok_size, &efi_guid_shim, "MokNew")) {
|
||
|
return 0;
|
||
|
}
|
||
|
+ /* Also check the blocklists */
|
||
|
+ if (is_duplicate (type, mok, mok_size, &efi_guid_security, "dbx") ||
|
||
|
+ is_duplicate (type, mok, mok_size, &efi_guid_shim, "MokListXRT"))
|
||
|
+ return 0;
|
||
|
break;
|
||
|
case DELETE_MOK:
|
||
|
if (!is_duplicate (type, mok, mok_size, &efi_guid_shim, "MokListRT") ||
|
||
|
@@ -1303,6 +1307,23 @@ is_ca_enrolled (void *mok, uint32_t mok_size, MokRequest req)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+/* Check whether the CA cert is blocked */
|
||
|
+static int
|
||
|
+is_ca_blocked (void *mok, uint32_t mok_size, MokRequest req)
|
||
|
+{
|
||
|
+ switch (req) {
|
||
|
+ case ENROLL_MOK:
|
||
|
+ if (is_ca_in_db (mok, mok_size, &efi_guid_security, "dbx") ||
|
||
|
+ is_ca_in_db (mok, mok_size, &efi_guid_shim, "MokListXRT"))
|
||
|
+ return 1;
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
static void
|
||
|
print_skip_message (const char *filename, void *mok, uint32_t mok_size,
|
||
|
MokRequest req)
|
||
|
@@ -1324,6 +1345,12 @@ print_skip_message (const char *filename, void *mok, uint32_t mok_size,
|
||
|
else if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_shim, "MokNew"))
|
||
|
printf ("SKIP: %s is already in the enrollment request\n", filename);
|
||
|
+ else if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
+ &efi_guid_security, "dbx"))
|
||
|
+ printf ("SKIP: %s is blocked in dbx\n", filename);
|
||
|
+ else if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
+ &efi_guid_shim, "MokListXRT"))
|
||
|
+ printf ("SKIP: %s is blocked in MokListXRT\n", filename);
|
||
|
break;
|
||
|
case DELETE_MOK:
|
||
|
if (!is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
@@ -1469,6 +1496,13 @@ issue_mok_request (char **files, uint32_t total, MokRequest req,
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
+ /* Check whether CA is blocked */
|
||
|
+ if (force_ca_check && is_ca_blocked (ptr, sizes[i], req)) {
|
||
|
+ printf ("CA blocked. Skip %s\n", files[i]);
|
||
|
+ close (fd);
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+
|
||
|
if (is_valid_request (&efi_guid_x509_cert, ptr, sizes[i], req)) {
|
||
|
ptr += sizes[i];
|
||
|
real_size += sizes[i] + sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t);
|
||
|
@@ -2127,6 +2161,12 @@ test_key (MokRequest req, const char *key_file)
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
+ if (force_ca_check && is_ca_blocked (key, read_size, req)) {
|
||
|
+ fprintf (stderr, "CA of %s is blocked\n",
|
||
|
+ key_file);
|
||
|
+ goto error;
|
||
|
+ }
|
||
|
+
|
||
|
if (is_valid_request (&efi_guid_x509_cert, key, read_size, req)) {
|
||
|
printf ("%s is not enrolled\n", key_file);
|
||
|
ret = 0;
|
||
|
--
|
||
|
2.28.0
|
||
|
|
||
|
|
||
|
From 057f96e6842af030b1f68a609019043f0f853708 Mon Sep 17 00:00:00 2001
|
||
|
From: Gary Lin <glin@suse.com>
|
||
|
Date: Fri, 28 Aug 2020 11:58:12 +0800
|
||
|
Subject: [PATCH 07/13] mokutil: improve the message from "--test-key"
|
||
|
|
||
|
Print the details of the test result.
|
||
|
|
||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||
|
(cherry picked from commit 5ede0bd0d68d27afc6d3d06556d0077e2840502b)
|
||
|
---
|
||
|
src/mokutil.c | 29 +++++++++++++++--------------
|
||
|
1 file changed, 15 insertions(+), 14 deletions(-)
|
||
|
|
||
|
diff --git a/src/mokutil.c b/src/mokutil.c
|
||
|
index 834228a..e8b48fe 100644
|
||
|
--- a/src/mokutil.c
|
||
|
+++ b/src/mokutil.c
|
||
|
@@ -1332,49 +1332,49 @@ print_skip_message (const char *filename, void *mok, uint32_t mok_size,
|
||
|
case ENROLL_MOK:
|
||
|
if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_global, "PK"))
|
||
|
- printf ("SKIP: %s is already in PK\n", filename);
|
||
|
+ printf ("%s is already in PK\n", filename);
|
||
|
else if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_global, "KEK"))
|
||
|
- printf ("SKIP: %s is already in KEK\n", filename);
|
||
|
+ printf ("%s is already in KEK\n", filename);
|
||
|
else if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_security, "db"))
|
||
|
- printf ("SKIP: %s is already in db\n", filename);
|
||
|
+ printf ("%s is already in db\n", filename);
|
||
|
else if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_shim, "MokListRT"))
|
||
|
- printf ("SKIP: %s is already enrolled\n", filename);
|
||
|
+ printf ("%s is already enrolled\n", filename);
|
||
|
else if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_shim, "MokNew"))
|
||
|
- printf ("SKIP: %s is already in the enrollment request\n", filename);
|
||
|
+ printf ("%s is already in the enrollment request\n", filename);
|
||
|
else if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_security, "dbx"))
|
||
|
- printf ("SKIP: %s is blocked in dbx\n", filename);
|
||
|
+ printf ("%s is blocked in dbx\n", filename);
|
||
|
else if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_shim, "MokListXRT"))
|
||
|
- printf ("SKIP: %s is blocked in MokListXRT\n", filename);
|
||
|
+ printf ("%s is blocked in MokListXRT\n", filename);
|
||
|
break;
|
||
|
case DELETE_MOK:
|
||
|
if (!is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_shim, "MokListRT"))
|
||
|
- printf ("SKIP: %s is not in MokList\n", filename);
|
||
|
+ printf ("%s is not in MokList\n", filename);
|
||
|
else if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_shim, "MokDel"))
|
||
|
- printf ("SKIP: %s is already in the deletion request\n", filename);
|
||
|
+ printf ("%s is already in the deletion request\n", filename);
|
||
|
break;
|
||
|
case ENROLL_BLACKLIST:
|
||
|
if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_shim, "MokListXRT"))
|
||
|
- printf ("SKIP: %s is already in MokListX\n", filename);
|
||
|
+ printf ("%s is already in MokListX\n", filename);
|
||
|
else if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_shim, "MokXNew"))
|
||
|
- printf ("SKIP: %s is already in the MokX enrollment request\n", filename);
|
||
|
+ printf ("%s is already in the MokX enrollment request\n", filename);
|
||
|
break;
|
||
|
case DELETE_BLACKLIST:
|
||
|
if (!is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_shim, "MokListXRT"))
|
||
|
- printf ("SKIP: %s is not in MokListX\n", filename);
|
||
|
+ printf ("%s is not in MokListX\n", filename);
|
||
|
else if (is_duplicate (&efi_guid_x509_cert, mok, mok_size,
|
||
|
&efi_guid_shim, "MokXDel"))
|
||
|
- printf ("SKIP: %s is already in the MokX deletion request\n", filename);
|
||
|
+ printf ("%s is already in the MokX deletion request\n", filename);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
@@ -1511,6 +1511,7 @@ issue_mok_request (char **files, uint32_t total, MokRequest req,
|
||
|
reverse_req_names[req]);
|
||
|
ptr -= sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t);
|
||
|
} else {
|
||
|
+ printf ("SKIP: ");
|
||
|
print_skip_message (files[i], ptr, sizes[i], req);
|
||
|
ptr -= sizeof(EFI_SIGNATURE_LIST) + sizeof(efi_guid_t);
|
||
|
}
|
||
|
@@ -2171,7 +2172,7 @@ test_key (MokRequest req, const char *key_file)
|
||
|
printf ("%s is not enrolled\n", key_file);
|
||
|
ret = 0;
|
||
|
} else {
|
||
|
- printf ("%s is already enrolled\n", key_file);
|
||
|
+ print_skip_message (key_file, key, read_size, req);
|
||
|
ret = 1;
|
||
|
}
|
||
|
|
||
|
--
|
||
|
2.28.0
|
||
|
|
||
|
|
||
|
From 7e5d2cb51a8360ad461e1031b9b3280e72d6338c Mon Sep 17 00:00:00 2001
|
||
|
From: Gary Lin <glin@suse.com>
|
||
|
Date: Wed, 2 Sep 2020 16:09:04 +0800
|
||
|
Subject: [PATCH 08/13] mokutil: disable CA check by default
|
||
|
|
||
|
The SUSE PTF certificate is also issued by SUSE CA, so enabling CA check
|
||
|
by default would ignore the enrollment of the PTF certificates and the
|
||
|
PTF would be unloadable.
|
||
|
|
||
|
Flip "--ignore-ca-check" to "--ca-check" and set force_ca_check to 0 by
|
||
|
default.
|
||
|
|
||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||
|
(cherry picked from commit 235e92a1d3e0f32f7be44aa0f37d7f3041306ccc)
|
||
|
---
|
||
|
src/mokutil.c | 10 +++++-----
|
||
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||
|
|
||
|
diff --git a/src/mokutil.c b/src/mokutil.c
|
||
|
index e8b48fe..b04deb3 100644
|
||
|
--- a/src/mokutil.c
|
||
|
+++ b/src/mokutil.c
|
||
|
@@ -183,7 +183,7 @@ print_help ()
|
||
|
printf (" --root-pw\t\t\t\tUse the root password\n");
|
||
|
printf (" --simple-hash\t\t\t\tUse the old password hash method\n");
|
||
|
printf (" --mokx\t\t\t\tManipulate the MOK blacklist\n");
|
||
|
- printf (" --ignore-ca-check\t\t\tDon't check CA of the given certificate\n");
|
||
|
+ printf (" --ca-check\t\t\t\tCheck if CA of the key is enrolled/blocked\n");
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
@@ -2342,7 +2342,7 @@ main (int argc, char *argv[])
|
||
|
int ret = -1;
|
||
|
|
||
|
use_simple_hash = 0;
|
||
|
- force_ca_check = 1;
|
||
|
+ force_ca_check = 0;
|
||
|
|
||
|
if (!efi_variables_supported ()) {
|
||
|
fprintf (stderr, "EFI variables are not supported on this system\n");
|
||
|
@@ -2383,7 +2383,7 @@ main (int argc, char *argv[])
|
||
|
{"db", no_argument, 0, 0 },
|
||
|
{"dbx", no_argument, 0, 0 },
|
||
|
{"timeout", required_argument, 0, 0 },
|
||
|
- {"ignore-ca-check", no_argument, 0, 0 },
|
||
|
+ {"ca-check", no_argument, 0, 0 },
|
||
|
{0, 0, 0, 0}
|
||
|
};
|
||
|
|
||
|
@@ -2470,8 +2470,8 @@ main (int argc, char *argv[])
|
||
|
} else if (strcmp (option, "timeout") == 0) {
|
||
|
command |= TIMEOUT;
|
||
|
timeout = strdup (optarg);
|
||
|
- } else if (strcmp (option, "ignore-ca-check") == 0) {
|
||
|
- force_ca_check = 0;
|
||
|
+ } else if (strcmp (option, "ca-check") == 0) {
|
||
|
+ force_ca_check = 1;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
--
|
||
|
2.28.0
|
||
|
|
||
|
|
||
|
From 8fee022cb2df7357bbc92c2c337af7b0057f1f23 Mon Sep 17 00:00:00 2001
|
||
|
From: Gary Lin <glin@suse.com>
|
||
|
Date: Wed, 2 Sep 2020 16:19:44 +0800
|
||
|
Subject: [PATCH 09/13] man: add "--ca-check" to the man page
|
||
|
|
||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||
|
(cherry picked from commit ae0aaf1a62faaba16183ed01a7ac9406535d96a1)
|
||
|
---
|
||
|
man/mokutil.1 | 8 ++++++--
|
||
|
1 file changed, 6 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/man/mokutil.1 b/man/mokutil.1
|
||
|
index 25fe8b4..cb37484 100644
|
||
|
--- a/man/mokutil.1
|
||
|
+++ b/man/mokutil.1
|
||
|
@@ -15,7 +15,7 @@ mokutil \- utility to manipulate machine owner keys
|
||
|
.br
|
||
|
\fBmokutil\fR [--import \fIkeylist\fR| -i \fIkeylist\fR]
|
||
|
([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] |
|
||
|
- [--simple-hash | -s] | [--mokx | -X])
|
||
|
+ [--simple-hash | -s] | [--mokx | -X] | [--ca-check])
|
||
|
.br
|
||
|
\fBmokutil\fR [--delete \fIkeylist\fR | -d \fIkeylist\fR]
|
||
|
([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] |
|
||
|
@@ -43,7 +43,7 @@ mokutil \- utility to manipulate machine owner keys
|
||
|
\fBmokutil\fR [--sb-state]
|
||
|
.br
|
||
|
\fBmokutil\fR [--test-key \fIkeyfile\fR | -t \fIkeyfile\fR]
|
||
|
- ([--mokx | -X])
|
||
|
+ ([--mokx | -X] | [--ca-check])
|
||
|
.br
|
||
|
\fBmokutil\fR [--reset]
|
||
|
([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] |
|
||
|
@@ -173,3 +173,7 @@ List the keys in the secure boot signature store (db)
|
||
|
\fB--dbx\fR
|
||
|
List the keys in the secure boot blacklist signature store (dbx)
|
||
|
.TP
|
||
|
+\fB--ca-check\fR
|
||
|
+Check if the CA of the given key is already enrolled or blocked in the key
|
||
|
+databases.
|
||
|
+.TP
|
||
|
--
|
||
|
2.28.0
|
||
|
|
||
|
|
||
|
From cbada2d9ac9bfc36528a51dc9fcf136eb8290473 Mon Sep 17 00:00:00 2001
|
||
|
From: Gary Lin <glin@suse.com>
|
||
|
Date: Wed, 16 Sep 2020 11:59:02 +0800
|
||
|
Subject: [PATCH 10/13] keyring: add the function to check kernel keyring
|
||
|
|
||
|
Add match_skid_in_trusted_keyring() to check if the given SKID is in the
|
||
|
kernel trusted keys keyring.
|
||
|
|
||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||
|
(cherry picked from commit 9e5c6fd4fbdce386ecd2482a27f8a29e5d0c7eff)
|
||
|
---
|
||
|
configure.ac | 1 +
|
||
|
src/Makefile.am | 4 ++
|
||
|
src/keyring.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
src/keyring.h | 37 ++++++++++++++++
|
||
|
4 files changed, 153 insertions(+)
|
||
|
create mode 100644 src/keyring.c
|
||
|
create mode 100644 src/keyring.h
|
||
|
|
||
|
diff --git a/configure.ac b/configure.ac
|
||
|
index d74fd21..b0b0376 100644
|
||
|
--- a/configure.ac
|
||
|
+++ b/configure.ac
|
||
|
@@ -85,6 +85,7 @@ AC_CHECK_FUNCS([memset])
|
||
|
|
||
|
PKG_CHECK_MODULES(OPENSSL, [openssl >= 0.9.8])
|
||
|
PKG_CHECK_MODULES(EFIVAR, [efivar >= 0.12])
|
||
|
+PKG_CHECK_MODULES(LIBKEYUTILS, [libkeyutils >= 1.5])
|
||
|
|
||
|
AC_ARG_WITH([bash-completion-dir],
|
||
|
AS_HELP_STRING([--with-bash-completion-dir[=PATH]],
|
||
|
diff --git a/src/Makefile.am b/src/Makefile.am
|
||
|
index 87b1515..f616b90 100644
|
||
|
--- a/src/Makefile.am
|
||
|
+++ b/src/Makefile.am
|
||
|
@@ -2,13 +2,17 @@ bin_PROGRAMS = mokutil
|
||
|
|
||
|
mokutil_CFLAGS = $(OPENSSL_CFLAGS) \
|
||
|
$(EFIVAR_CFLAGS) \
|
||
|
+ $(LIBKEYUTILS_CFLAGS) \
|
||
|
$(WARNINGFLAGS_C)
|
||
|
|
||
|
mokutil_LDADD = $(OPENSSL_LIBS) \
|
||
|
$(EFIVAR_LIBS) \
|
||
|
+ $(LIBKEYUTILS_LIBS) \
|
||
|
-lcrypt
|
||
|
|
||
|
mokutil_SOURCES = signature.h \
|
||
|
+ keyring.h \
|
||
|
+ keyring.c \
|
||
|
password-crypt.h \
|
||
|
password-crypt.c \
|
||
|
mokutil.c
|
||
|
diff --git a/src/keyring.c b/src/keyring.c
|
||
|
new file mode 100644
|
||
|
index 0000000..9709efd
|
||
|
--- /dev/null
|
||
|
+++ b/src/keyring.c
|
||
|
@@ -0,0 +1,111 @@
|
||
|
+/**
|
||
|
+ * Copyright (C) 2020 Gary Lin <glin@suse.com>
|
||
|
+ *
|
||
|
+ * This program is free software: you can redistribute it and/or modify
|
||
|
+ * it under the terms of the GNU General Public License as published by
|
||
|
+ * the Free Software Foundation, either version 3 of the License, or
|
||
|
+ * (at your option) any later version.
|
||
|
+ *
|
||
|
+ * This program is distributed in the hope that it will be useful,
|
||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
+ * GNU General Public License for more details.
|
||
|
+ *
|
||
|
+ * You should have received a copy of the GNU General Public License
|
||
|
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
+ *
|
||
|
+ * In addition, as a special exception, the copyright holders give
|
||
|
+ * permission to link the code of portions of this program with the
|
||
|
+ * OpenSSL library under certain conditions as described in each
|
||
|
+ * individual source file, and distribute linked combinations
|
||
|
+ * including the two.
|
||
|
+ *
|
||
|
+ * You must obey the GNU General Public License in all respects
|
||
|
+ * for all of the code used other than OpenSSL. If you modify
|
||
|
+ * file(s) with this exception, you may extend this exception to your
|
||
|
+ * version of the file(s), but you are not obligated to do so. If you
|
||
|
+ * do not wish to do so, delete this exception statement from your
|
||
|
+ * version. If you delete this exception statement from all source
|
||
|
+ * files in the program, then also delete it here.
|
||
|
+ */
|
||
|
+
|
||
|
+#include <stdio.h>
|
||
|
+#include <stdlib.h>
|
||
|
+#include <errno.h>
|
||
|
+#include <string.h>
|
||
|
+
|
||
|
+#include <keyutils.h>
|
||
|
+
|
||
|
+#include "keyring.h"
|
||
|
+
|
||
|
+/**
|
||
|
+ * Match the x509v3 Subject Key ID in the descriptions of the kernel built-in
|
||
|
+ * trusted keys keyring
|
||
|
+ *
|
||
|
+ * return value
|
||
|
+ * - 0 : not matched
|
||
|
+ * - 1 : matched
|
||
|
+ * - -1 : error
|
||
|
+ */
|
||
|
+int
|
||
|
+match_skid_in_trusted_keyring (const char *skid)
|
||
|
+{
|
||
|
+ key_serial_t ring_id, key_id, *key_ptr;
|
||
|
+ void *keylist = NULL;
|
||
|
+ int count;
|
||
|
+ char buffer[1024];
|
||
|
+ char *ptr;
|
||
|
+ long buf_size;
|
||
|
+ int ret = -1;
|
||
|
+
|
||
|
+ if (skid == NULL)
|
||
|
+ return -1;
|
||
|
+
|
||
|
+ /* Find the keyring ID of the kernel trusted keys */
|
||
|
+ ring_id = find_key_by_type_and_desc("keyring", ".builtin_trusted_keys", 0);
|
||
|
+ if (ring_id < 0) {
|
||
|
+ fprintf(stderr, "Failed to accesss kernel trusted keyring: %m\n");
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ count = keyctl_read_alloc(ring_id, &keylist);
|
||
|
+ if (count < 0) {
|
||
|
+ fprintf(stderr, "Failed to read kernel trusted keyring\n");
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ count /= sizeof(key_serial_t);
|
||
|
+ if (count == 0) {
|
||
|
+ /* The keyring is empty */
|
||
|
+ ret = 0;
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Iterate the keylist and match SKID */
|
||
|
+ key_ptr = keylist;
|
||
|
+ do {
|
||
|
+ key_id = *key_ptr++;
|
||
|
+
|
||
|
+ buf_size = keyctl_describe(key_id, buffer, sizeof(buffer));
|
||
|
+ if (buf_size < 0) {
|
||
|
+ fprintf(stderr, "key %X inaccessible %m\n", key_id);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Check if SKID is in the description */
|
||
|
+ ptr = strstr(buffer, skid);
|
||
|
+ if (ptr && *(ptr + strlen(skid)) == '\0') {
|
||
|
+ /* Matched */
|
||
|
+ ret = 1;
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+ } while (--count);
|
||
|
+
|
||
|
+ ret = 0;
|
||
|
+out:
|
||
|
+ if (keylist)
|
||
|
+ free(keylist);
|
||
|
+
|
||
|
+ return ret;
|
||
|
+
|
||
|
+}
|
||
|
diff --git a/src/keyring.h b/src/keyring.h
|
||
|
new file mode 100644
|
||
|
index 0000000..44127cf
|
||
|
--- /dev/null
|
||
|
+++ b/src/keyring.h
|
||
|
@@ -0,0 +1,37 @@
|
||
|
+/**
|
||
|
+ * Copyright (C) 2020 Gary Lin <glin@suse.com>
|
||
|
+ *
|
||
|
+ * This program is free software: you can redistribute it and/or modify
|
||
|
+ * it under the terms of the GNU General Public License as published by
|
||
|
+ * the Free Software Foundation, either version 3 of the License, or
|
||
|
+ * (at your option) any later version.
|
||
|
+ *
|
||
|
+ * This program is distributed in the hope that it will be useful,
|
||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
+ * GNU General Public License for more details.
|
||
|
+ *
|
||
|
+ * You should have received a copy of the GNU General Public License
|
||
|
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
+ *
|
||
|
+ * In addition, as a special exception, the copyright holders give
|
||
|
+ * permission to link the code of portions of this program with the
|
||
|
+ * OpenSSL library under certain conditions as described in each
|
||
|
+ * individual source file, and distribute linked combinations
|
||
|
+ * including the two.
|
||
|
+ *
|
||
|
+ * You must obey the GNU General Public License in all respects
|
||
|
+ * for all of the code used other than OpenSSL. If you modify
|
||
|
+ * file(s) with this exception, you may extend this exception to your
|
||
|
+ * version of the file(s), but you are not obligated to do so. If you
|
||
|
+ * do not wish to do so, delete this exception statement from your
|
||
|
+ * version. If you delete this exception statement from all source
|
||
|
+ * files in the program, then also delete it here.
|
||
|
+ */
|
||
|
+
|
||
|
+#ifndef __KEYRING_H__
|
||
|
+#define __KEYRING_H__
|
||
|
+
|
||
|
+int match_skid_in_trusted_keyring (const char *skid);
|
||
|
+
|
||
|
+#endif /* __KEYRING_H__ */
|
||
|
--
|
||
|
2.28.0
|
||
|
|
||
|
|
||
|
From 8fc0f7bb5b9826fd3af99836a7e39fed607d3646 Mon Sep 17 00:00:00 2001
|
||
|
From: Gary Lin <glin@suse.com>
|
||
|
Date: Wed, 16 Sep 2020 12:00:18 +0800
|
||
|
Subject: [PATCH 11/13] efi_x509: add the function to fetch SKID
|
||
|
|
||
|
Add get_cert_skid() to fetch SKID of a given certiticate.
|
||
|
|
||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||
|
(cherry picked from commit 7a7a85ba5f057c0c155787d695561a051b6b5eb4)
|
||
|
---
|
||
|
src/mokutil.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
1 file changed, 57 insertions(+)
|
||
|
|
||
|
diff --git a/src/mokutil.c b/src/mokutil.c
|
||
|
index b04deb3..e4e405e 100644
|
||
|
--- a/src/mokutil.c
|
||
|
+++ b/src/mokutil.c
|
||
|
@@ -47,6 +47,7 @@
|
||
|
|
||
|
#include <openssl/sha.h>
|
||
|
#include <openssl/x509.h>
|
||
|
+#include <openssl/x509v3.h>
|
||
|
|
||
|
#include <crypt.h>
|
||
|
#include <efivar.h>
|
||
|
@@ -1034,6 +1035,62 @@ is_valid_cert (void *cert, uint32_t cert_size)
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
+/**
|
||
|
+ * Get the Subject Key Identifier of the given certificate
|
||
|
+ *
|
||
|
+ * This function allocates the SKID string and the caller is responsible to
|
||
|
+ * free the string.
|
||
|
+ *
|
||
|
+ * Return value:
|
||
|
+ * - 0 : Success
|
||
|
+ * - -1 : Error
|
||
|
+ */
|
||
|
+static int
|
||
|
+get_cert_skid(const uint8_t *cert, const uint32_t cert_size, char **skid)
|
||
|
+{
|
||
|
+ X509 *X509cert;
|
||
|
+ const ASN1_OCTET_STRING *asn1_id;
|
||
|
+ const uint8_t *data;
|
||
|
+ int data_len, i;
|
||
|
+ char *id_str, *ptr;
|
||
|
+ int ret = -1;
|
||
|
+
|
||
|
+ X509cert = d2i_X509 (NULL, &cert, cert_size);
|
||
|
+ if (X509cert == NULL) {
|
||
|
+ fprintf (stderr, "invalid x509 certificate\n");
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ asn1_id = X509_get0_subject_key_id (X509cert);
|
||
|
+ if (asn1_id == NULL) {
|
||
|
+ fprintf (stderr, "Failed to get Subject Key ID\n");
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ data = ASN1_STRING_get0_data (asn1_id);
|
||
|
+ data_len = ASN1_STRING_length (asn1_id);
|
||
|
+
|
||
|
+ id_str = malloc (data_len*2 + 1);
|
||
|
+ if (id_str == NULL) {
|
||
|
+ fprintf (stderr, "Failed to allocated id string\n");
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
+ ptr = id_str;
|
||
|
+ for (i = 0; i < data_len; i++) {
|
||
|
+ snprintf (ptr, 3, "%02x", data[i]);
|
||
|
+ ptr += 2;
|
||
|
+ }
|
||
|
+
|
||
|
+ *skid = id_str;
|
||
|
+ ret = 0;
|
||
|
+out:
|
||
|
+ if (X509cert)
|
||
|
+ X509_free (X509cert);
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
/**
|
||
|
* Check whether the given CA cert is the immediate CA of the given cert
|
||
|
**/
|
||
|
--
|
||
|
2.28.0
|
||
|
|
||
|
|
||
|
From 8f8ee97cd068eaeabe6897314f63bc4a5606b97c Mon Sep 17 00:00:00 2001
|
||
|
From: Gary Lin <glin@suse.com>
|
||
|
Date: Wed, 16 Sep 2020 12:03:33 +0800
|
||
|
Subject: [PATCH 12/13] mokutil: check the kernel trusted keyring by default
|
||
|
|
||
|
When enrolling a new key, mokutil now checks whether the key is one of
|
||
|
the kernel built-in trusted keys.
|
||
|
|
||
|
The kernel keyring check can be disabled by "--ignore-keyring".
|
||
|
|
||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||
|
(cherry picked from commit 8bac3f53e2c4600f0843234e1b525a816f255955)
|
||
|
---
|
||
|
src/mokutil.c | 41 +++++++++++++++++++++++++++++++++++++++++
|
||
|
1 file changed, 41 insertions(+)
|
||
|
|
||
|
diff --git a/src/mokutil.c b/src/mokutil.c
|
||
|
index e4e405e..02ed21f 100644
|
||
|
--- a/src/mokutil.c
|
||
|
+++ b/src/mokutil.c
|
||
|
@@ -53,6 +53,7 @@
|
||
|
#include <efivar.h>
|
||
|
|
||
|
#include "signature.h"
|
||
|
+#include "keyring.h"
|
||
|
#include "password-crypt.h"
|
||
|
|
||
|
#define PASSWORD_MAX 256
|
||
|
@@ -97,6 +98,7 @@ typedef wchar_t efi_char16_t; /* UNICODE character */
|
||
|
|
||
|
static int use_simple_hash;
|
||
|
static int force_ca_check;
|
||
|
+static int check_keyring;
|
||
|
|
||
|
typedef enum {
|
||
|
DELETE_MOK = 0,
|
||
|
@@ -185,6 +187,7 @@ print_help ()
|
||
|
printf (" --simple-hash\t\t\t\tUse the old password hash method\n");
|
||
|
printf (" --mokx\t\t\t\tManipulate the MOK blacklist\n");
|
||
|
printf (" --ca-check\t\t\t\tCheck if CA of the key is enrolled/blocked\n");
|
||
|
+ printf (" --ignore-keyring\t\t\tDon't check if the key is the kernel keyring\n");
|
||
|
}
|
||
|
|
||
|
static int
|
||
|
@@ -1381,6 +1384,25 @@ is_ca_blocked (void *mok, uint32_t mok_size, MokRequest req)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+/* Check whether the key is already in the kernel trusted keyring */
|
||
|
+static int
|
||
|
+is_in_trusted_keyring (const void *cert, const uint32_t cert_size)
|
||
|
+{
|
||
|
+ char *skid = NULL;
|
||
|
+ int ret;
|
||
|
+
|
||
|
+ if (get_cert_skid (cert, cert_size, &skid) < 0)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ ret = match_skid_in_trusted_keyring (skid);
|
||
|
+ if (ret < 0)
|
||
|
+ ret = 0;
|
||
|
+
|
||
|
+ free (skid);
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
static void
|
||
|
print_skip_message (const char *filename, void *mok, uint32_t mok_size,
|
||
|
MokRequest req)
|
||
|
@@ -1546,6 +1568,15 @@ issue_mok_request (char **files, uint32_t total, MokRequest req,
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
+ /* Check whether the key is already in the trusted keyring */
|
||
|
+ if (req == ENROLL_MOK && check_keyring &&
|
||
|
+ is_in_trusted_keyring (ptr, sizes[i])) {
|
||
|
+ printf ("Already in kernel trusted keyring. Skip %s\n",
|
||
|
+ files[i]);
|
||
|
+ close (fd);
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+
|
||
|
/* Check whether CA is already enrolled */
|
||
|
if (force_ca_check && is_ca_enrolled (ptr, sizes[i], req)) {
|
||
|
printf ("CA enrolled. Skip %s\n", files[i]);
|
||
|
@@ -2213,6 +2244,12 @@ test_key (MokRequest req, const char *key_file)
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
+ if (check_keyring && is_in_trusted_keyring (key, read_size)) {
|
||
|
+ fprintf (stderr, "%s is already in the built-in trusted keyring\n",
|
||
|
+ key_file);
|
||
|
+ goto error;
|
||
|
+ }
|
||
|
+
|
||
|
if (force_ca_check && is_ca_enrolled (key, read_size, req)) {
|
||
|
fprintf (stderr, "CA of %s is already enrolled\n",
|
||
|
key_file);
|
||
|
@@ -2400,6 +2437,7 @@ main (int argc, char *argv[])
|
||
|
|
||
|
use_simple_hash = 0;
|
||
|
force_ca_check = 0;
|
||
|
+ check_keyring = 1;
|
||
|
|
||
|
if (!efi_variables_supported ()) {
|
||
|
fprintf (stderr, "EFI variables are not supported on this system\n");
|
||
|
@@ -2441,6 +2479,7 @@ main (int argc, char *argv[])
|
||
|
{"dbx", no_argument, 0, 0 },
|
||
|
{"timeout", required_argument, 0, 0 },
|
||
|
{"ca-check", no_argument, 0, 0 },
|
||
|
+ {"ignore-keyring", no_argument, 0, 0 },
|
||
|
{0, 0, 0, 0}
|
||
|
};
|
||
|
|
||
|
@@ -2529,6 +2568,8 @@ main (int argc, char *argv[])
|
||
|
timeout = strdup (optarg);
|
||
|
} else if (strcmp (option, "ca-check") == 0) {
|
||
|
force_ca_check = 1;
|
||
|
+ } else if (strcmp (option, "ignore-keyring") == 0) {
|
||
|
+ check_keyring = 0;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
--
|
||
|
2.28.0
|
||
|
|
||
|
|
||
|
From 4a1e8c43ada0896ed169826ae9cfc7c83d4d7f27 Mon Sep 17 00:00:00 2001
|
||
|
From: Gary Lin <glin@suse.com>
|
||
|
Date: Wed, 16 Sep 2020 16:10:29 +0800
|
||
|
Subject: [PATCH 13/13] man: add "--ignore-keyring"
|
||
|
|
||
|
Signed-off-by: Gary Lin <glin@suse.com>
|
||
|
(cherry picked from commit c24deaa37d72f8aa06cf22d35c91b218d1a3d99e)
|
||
|
---
|
||
|
man/mokutil.1 | 7 +++++--
|
||
|
1 file changed, 5 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/man/mokutil.1 b/man/mokutil.1
|
||
|
index cb37484..cbea367 100644
|
||
|
--- a/man/mokutil.1
|
||
|
+++ b/man/mokutil.1
|
||
|
@@ -15,7 +15,7 @@ mokutil \- utility to manipulate machine owner keys
|
||
|
.br
|
||
|
\fBmokutil\fR [--import \fIkeylist\fR| -i \fIkeylist\fR]
|
||
|
([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] |
|
||
|
- [--simple-hash | -s] | [--mokx | -X] | [--ca-check])
|
||
|
+ [--simple-hash | -s] | [--mokx | -X] | [--ca-check] | [--ignore-keyring])
|
||
|
.br
|
||
|
\fBmokutil\fR [--delete \fIkeylist\fR | -d \fIkeylist\fR]
|
||
|
([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] |
|
||
|
@@ -43,7 +43,7 @@ mokutil \- utility to manipulate machine owner keys
|
||
|
\fBmokutil\fR [--sb-state]
|
||
|
.br
|
||
|
\fBmokutil\fR [--test-key \fIkeyfile\fR | -t \fIkeyfile\fR]
|
||
|
- ([--mokx | -X] | [--ca-check])
|
||
|
+ ([--mokx | -X] | [--ca-check] | [--ignore-keyring])
|
||
|
.br
|
||
|
\fBmokutil\fR [--reset]
|
||
|
([--hash-file \fIhashfile\fR | -f \fIhashfile\fR] | [--root-pw | -P] |
|
||
|
@@ -177,3 +177,6 @@ List the keys in the secure boot blacklist signature store (dbx)
|
||
|
Check if the CA of the given key is already enrolled or blocked in the key
|
||
|
databases.
|
||
|
.TP
|
||
|
+\fB--ignore-keyring\fR
|
||
|
+Ignore the kernel builtin trusted keys keyring check when enrolling a key into MokList
|
||
|
+.TP
|
||
|
--
|
||
|
2.28.0
|
||
|
|