[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v1 16/21] appendedsig: The creation of trusted and distrusted lis
From: |
Sudhakar Kuppusamy |
Subject: |
[PATCH v1 16/21] appendedsig: The creation of trusted and distrusted lists |
Date: |
Wed, 18 Dec 2024 20:26:42 +0530 |
The trusted certificates and binary hashes, distrusted certificates and
binary/certificate hashes will be extracted from the platform keystore buffer
if Secure Boot is enabled with PKS.
In order to verify the integerity of the kernel, the extracted data
would be stored in the buffer db and dbx.
The trusted certificates will be extracted from the grub ELFNOTE if Secure Boot
is
enabled with static key. In order to verify the integerity of the kernel,
the extracted data would be stored in the buffer db.
Note:-
if the trusted certificate nor binary hash exists in the distrusted list (DBX),
rejected it while extracting it from the platform keystore buffer.
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
---
grub-core/commands/appendedsig/appendedsig.c | 636 +++++++++++++++++--
1 file changed, 592 insertions(+), 44 deletions(-)
diff --git a/grub-core/commands/appendedsig/appendedsig.c
b/grub-core/commands/appendedsig/appendedsig.c
index 5c82b96a4..31649e800 100644
--- a/grub-core/commands/appendedsig/appendedsig.c
+++ b/grub-core/commands/appendedsig/appendedsig.c
@@ -34,7 +34,7 @@
#include <libtasn1.h>
#include <grub/env.h>
#include <grub/lockdown.h>
-
+#include <grub/platform_keystore.h>
#include "appendedsig.h"
GRUB_MOD_LICENSE ("GPLv3+");
@@ -64,9 +64,23 @@ struct grub_appended_signature
struct pkcs7_signedData pkcs7; /* Parsed PKCS#7 data */
};
-/* Trusted certificates for verifying appended signatures */
-struct x509_certificate *grub_trusted_key;
+/* This represents a trusted/distrusted list*/
+struct grub_database
+{
+ struct x509_certificate *keys; /* Certificates */
+ grub_size_t key_entries; /* Number of certificates */
+ grub_uint8_t **signatures; /* Certificate/binary hashes */
+ grub_size_t *signature_size; /* Size of certificate/binary hashes */
+ grub_size_t signature_entries; /* Number of certificate/binary hashes */
+};
+
+/* Trusted list */
+struct grub_database grub_db = {.keys = NULL, .key_entries = 0, .signatures =
NULL,
+ .signature_size = NULL, .signature_entries =
0};
+/* Distrusted list */
+struct grub_database grub_dbx = {.signatures = NULL, .signature_size = NULL,
+ .signature_entries = 0};
/*
* Force gcry_rsa to be a module dependency.
*
@@ -87,6 +101,13 @@ struct x509_certificate *grub_trusted_key;
* also resolves our concerns about loading from the filesystem.
*/
extern gcry_pk_spec_t _gcry_pubkey_spec_rsa;
+extern gcry_md_spec_t _gcry_digest_spec_sha224;
+extern gcry_md_spec_t _gcry_digest_spec_sha384;
+
+/* releasing trusted list memory */
+static void grub_release_trusted_list (void);
+/* releasing distrusted list memory */
+static void grub_release_distrusted_list (void);
static enum
{
@@ -95,6 +116,248 @@ static enum
check_sigs_forced = 2
} check_sigs = check_sigs_no;
+/*
+ * GUID can be used to determine the hashing function and
+ * generate the hash using determined hashing function.
+ */
+static grub_err_t
+grub_get_hash (const grub_uuid_t *guid, const grub_uint8_t *data, const
grub_size_t data_size,
+ grub_uint8_t *hash, grub_size_t *hash_size)
+{
+ gcry_md_spec_t *hash_func = NULL;
+
+ if (guid == NULL)
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "GUID is null");
+
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_UUID_SIZE) == 0 ||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA256_GUID, GRUB_UUID_SIZE)
== 0)
+ hash_func = &_gcry_digest_spec_sha256;
+ else if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA384_GUID, GRUB_UUID_SIZE) == 0
||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA384_GUID, GRUB_UUID_SIZE)
== 0)
+ hash_func = &_gcry_digest_spec_sha384;
+ else if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA512_GUID, GRUB_UUID_SIZE) == 0
||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA512_GUID, GRUB_UUID_SIZE)
== 0)
+ hash_func = &_gcry_digest_spec_sha512;
+ else
+ return GRUB_ERR_UNKNOWN_COMMAND;
+
+ grub_memset (hash, 0x00, GRUB_MAX_HASH_SIZE);
+ grub_crypto_hash (hash_func, hash, data, data_size);
+ *hash_size = hash_func->mdlen;
+
+ return GRUB_ERR_NONE;
+}
+
+/* adding the certificate/binary hash into the trusted/distrusted list */
+static grub_err_t
+grub_add_hash (const grub_uint8_t **data, const grub_size_t data_size,
+ grub_uint8_t ***signature_list, grub_size_t
**signature_size_list,
+ grub_size_t *signature_list_entries)
+{
+ grub_uint8_t **signatures = *signature_list;
+ grub_size_t *signature_size = *signature_size_list;
+ grub_size_t signature_entries = *signature_list_entries;
+
+ if (*data == NULL || data_size == 0)
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "certificate/binary hash
data/size is null");
+
+ if (signatures == NULL && signature_size == NULL)
+ {
+ signatures = grub_zalloc (sizeof (grub_uint8_t *));
+ signature_size = grub_zalloc (sizeof (grub_size_t));
+ }
+ else
+ {
+ signatures = grub_realloc (signatures, sizeof (grub_uint8_t *) *
(signature_entries + 1));
+ signature_size = grub_realloc (signature_size,
+ sizeof (grub_size_t) * (signature_entries
+ 1));
+ }
+
+ if (signatures == NULL || signature_size == NULL)
+ {
+ /*
+ * allocated memory will be freed by
+ * grub_release_trusted_list/grub_release_distrusted_list
+ */
+ if (signatures != NULL)
+ {
+ *signature_list = signatures;
+ *signature_list_entries = signature_entries + 1;
+ }
+
+ if (signature_size != NULL)
+ *signature_size_list = signature_size;
+
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
+ }
+
+ signatures[signature_entries] = (grub_uint8_t *) *data;
+ signature_size[signature_entries] = data_size;
+ signature_entries++;
+ *data = NULL;
+
+ *signature_list = signatures;
+ *signature_size_list = signature_size;
+ *signature_list_entries = signature_entries;
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+grub_is_x509 (const grub_uuid_t *guid)
+{
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_X509_GUID, GRUB_UUID_SIZE) == 0)
+ return GRUB_ERR_NONE;
+
+ return GRUB_ERR_UNKNOWN_COMMAND;
+}
+
+static grub_err_t
+grub_is_cert_match (const struct x509_certificate *distrusted_cert,
+ const struct x509_certificate *db_cert)
+{
+
+ if (grub_memcmp (distrusted_cert->subject, db_cert->subject,
db_cert->subject_len) == 0
+ && grub_memcmp (distrusted_cert->serial, db_cert->serial,
db_cert->serial_len) == 0
+ && grub_memcmp (distrusted_cert->mpis[0], db_cert->mpis[0], sizeof
(db_cert->mpis[0])) == 0
+ && grub_memcmp (distrusted_cert->mpis[1], db_cert->mpis[1], sizeof
(db_cert->mpis[1])) == 0)
+ return GRUB_ERR_NONE;
+
+ return GRUB_ERR_UNKNOWN_COMMAND;
+}
+
+/*
+ * verify the certificate against the certificate from platform keystore
buffer's
+ * distrusted list, if it is present, return a bad signature.
+ * else, no errors.
+ */
+static grub_err_t
+grub_is_distrusted_cert (const struct x509_certificate *db_cert)
+{
+ grub_err_t rc = GRUB_ERR_NONE;
+ grub_size_t i = 0;
+ struct x509_certificate *distrusted_cert = NULL;
+
+ for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
+ {
+ if (grub_platform_keystore.dbx[i].data == NULL &&
+ grub_platform_keystore.dbx[i].data_size == 0)
+ continue;
+
+ if (grub_is_x509 (&grub_platform_keystore.dbx[i].guid) == GRUB_ERR_NONE)
+ {
+ distrusted_cert = grub_zalloc (sizeof (struct x509_certificate));
+ if (distrusted_cert == NULL)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
+
+ rc = parse_x509_certificate (grub_platform_keystore.dbx[i].data,
+
grub_platform_keystore.dbx[i].data_size, distrusted_cert);
+ if (rc != GRUB_ERR_NONE)
+ {
+ grub_free (distrusted_cert);
+ continue;
+ }
+
+ if (grub_is_cert_match (distrusted_cert, db_cert) == GRUB_ERR_NONE)
+ {
+ grub_printf ("Warning: a trusted certificate CN='%s' is ignored "
+ "because it is on the distrusted list (dbx).\n",
db_cert->subject);
+ grub_free (grub_platform_keystore.dbx[i].data);
+ grub_memset (&grub_platform_keystore.dbx[i], 0x00, sizeof
(grub_pks_sd_t));
+ certificate_release (distrusted_cert);
+ grub_free (distrusted_cert);
+ return GRUB_ERR_BAD_SIGNATURE;
+ }
+
+ certificate_release (distrusted_cert);
+ grub_free (distrusted_cert);
+ }
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+/* adding the certificate into the trusted/distrusted list */
+static grub_err_t
+grub_add_certificate (const grub_uint8_t *data, const grub_size_t data_size,
+ struct grub_database *database, const grub_size_t is_db)
+{
+ grub_err_t rc = GRUB_ERR_NONE;
+ grub_size_t key_entries = database->key_entries;
+ struct x509_certificate *cert = NULL;
+
+ if (data == NULL || data_size == 0)
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "certificate data/size is null");
+
+ cert = grub_zalloc (sizeof (struct x509_certificate));
+ if (cert == NULL)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
+
+ rc = parse_x509_certificate (data, data_size, cert);
+ if (rc != GRUB_ERR_NONE)
+ {
+ grub_printf ("Warning: skipping %s certificate (%d)\n",
+ (is_db ? "trusted":"distrused"), rc);
+ grub_free (cert);
+ return rc;
+ }
+
+ if (is_db)
+ {
+ rc = grub_is_distrusted_cert (cert);
+ if (rc != GRUB_ERR_NONE)
+ {
+ certificate_release (cert);
+ grub_free (cert);
+ return rc;
+ }
+ }
+
+ grub_dprintf ("appendedsig", "add a %s certificate CN='%s'\n",
+ (is_db ? "trusted":"distrused"), cert->subject);
+
+ key_entries++;
+ cert->next = database->keys;
+ database->keys = cert;
+ database->key_entries = key_entries;
+
+ return rc;
+}
+
+static grub_err_t
+grub_read_file (const grub_file_t file, grub_uint8_t **data, grub_ssize_t
*data_size)
+{
+ grub_uint8_t *buffer = NULL;
+ grub_ssize_t read_size = 0;
+ grub_off_t total_read_size = 0;
+ grub_off_t file_size = grub_file_size (file);
+
+ if (file_size == GRUB_FILE_SIZE_UNKNOWN)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
+ N_("could not parse the unknown size of the file."));
+
+ buffer = grub_zalloc (file_size);
+ if (buffer == NULL)
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
+
+ while (total_read_size < file_size)
+ {
+ read_size = grub_file_read (file, &buffer[total_read_size], file_size -
total_read_size);
+ if (read_size < 0)
+ {
+ grub_free (buffer);
+ return grub_error (GRUB_ERR_READ_ERROR, N_("unable to read the
file"));
+ }
+
+ total_read_size += read_size;
+ }
+
+ *data = buffer;
+ *data_size = total_read_size;
+
+ return GRUB_ERR_NONE;
+}
+
static const char *
grub_env_read_sec (struct grub_env_var *var __attribute__ ((unused)),
const char *val __attribute__ ((unused)))
@@ -248,7 +511,7 @@ grub_verify_appended_signature (const grub_uint8_t *buf,
grub_size_t bufsize)
struct pkcs7_signerInfo *si;
int i;
- if (!grub_trusted_key)
+ if (!grub_db.key_entries)
return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("No trusted keys to verify
against"));
err = extract_appended_signature (buf, bufsize, &sig);
@@ -279,7 +542,7 @@ grub_verify_appended_signature (const grub_uint8_t *buf,
grub_size_t bufsize)
datasize, i, hash[0], hash[1], hash[2], hash[3]);
err = GRUB_ERR_BAD_SIGNATURE;
- for (pk = grub_trusted_key; pk; pk = pk->next)
+ for (pk = grub_db.keys; pk; pk = pk->next)
{
rc = grub_crypto_rsa_pad (&hashmpi, hash, si->hash, pk->mpis[0]);
if (rc)
@@ -376,16 +639,16 @@ grub_cmd_distrust (grub_command_t cmd __attribute__
((unused)), int argc, char *
if (cert_num == 1)
{
- cert = grub_trusted_key;
- grub_trusted_key = cert->next;
+ cert = grub_db.keys;
+ grub_db.keys = cert->next;
certificate_release (cert);
grub_free (cert);
return GRUB_ERR_NONE;
}
i = 2;
- prev = grub_trusted_key;
- cert = grub_trusted_key->next;
+ prev = grub_db.keys;
+ cert = grub_db.keys->next;
while (cert)
{
if (i == cert_num)
@@ -432,8 +695,8 @@ grub_cmd_trust (grub_command_t cmd __attribute__
((unused)), int argc, char **ar
}
grub_dprintf ("appendedsig", "Loaded certificate with CN: %s\n",
cert->subject);
- cert->next = grub_trusted_key;
- grub_trusted_key = cert;
+ cert->next = grub_db.keys;
+ grub_db.keys = cert;
return GRUB_ERR_NONE;
}
@@ -446,7 +709,7 @@ grub_cmd_list (grub_command_t cmd __attribute__ ((unused)),
int argc __attribute
int cert_num = 1;
grub_size_t i;
- for (cert = grub_trusted_key; cert; cert = cert->next)
+ for (cert = grub_db.keys; cert; cert = cert->next)
{
grub_printf (N_("Certificate %d:\n"), cert_num);
@@ -539,6 +802,280 @@ static struct grub_fs pseudo_fs = { .name = "pseudo",
.fs_read = pseudo_read };
static grub_command_t cmd_verify, cmd_list, cmd_distrust, cmd_trust;
+/*
+ * verify the trusted certificate against the certificate hashes from platform
keystore buffer's
+ * distrusted list, if it is present, return a bad signature.
+ * else, no errors.
+ */
+static grub_err_t
+grub_is_distrusted_cert_hash (const grub_uint8_t *data, const grub_size_t
data_size)
+{
+ grub_err_t rc = GRUB_ERR_NONE;
+ grub_size_t i = 0, cert_hash_size = 0;
+ grub_uint8_t cert_hash[GRUB_MAX_HASH_SIZE] = { 0 };
+
+ if (data == NULL || data_size == 0)
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "trusted certificate data/size
is null");
+
+ for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
+ {
+ if (grub_platform_keystore.dbx[i].data == NULL &&
+ grub_platform_keystore.dbx[i].data_size == 0)
+ continue;
+
+ rc = grub_get_hash (&grub_platform_keystore.dbx[i].guid, data, data_size,
+ cert_hash, &cert_hash_size);
+ if (rc != GRUB_ERR_NONE)
+ continue;
+
+ if (cert_hash_size == grub_platform_keystore.dbx[i].data_size &&
+ grub_memcmp (grub_platform_keystore.dbx[i].data, cert_hash,
cert_hash_size) == 0)
+ {
+ grub_printf ("Warning: a trusted certificate (%02x%02x%02x%02x) is
ignored "
+ "because this certificate hash is on the distrusted
list (dbx).\n",
+ cert_hash[0], cert_hash[1], cert_hash[2], cert_hash[3]);
+ grub_free (grub_platform_keystore.dbx[i].data);
+ grub_memset (&grub_platform_keystore.dbx[i], 0x00, sizeof
(grub_pks_sd_t));
+ return GRUB_ERR_BAD_SIGNATURE;
+ }
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+/*
+ * verify the trusted binary hash against the platform keystore buffer's
+ * distrusted list, if it is present, return a bad signature.
+ * else, no errors.
+ */
+static grub_err_t
+grub_is_distrusted_binary_hash (const grub_uint8_t *binary_hash,
+ const grub_size_t binary_hash_size)
+{
+ grub_size_t i = 0;
+
+ for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
+ {
+ if (grub_platform_keystore.dbx[i].data == NULL &&
+ grub_platform_keystore.dbx[i].data_size == 0)
+ continue;
+
+ if (binary_hash_size == grub_platform_keystore.dbx[i].data_size &&
+ grub_memcmp (grub_platform_keystore.dbx[i].data, binary_hash,
binary_hash_size) == 0)
+ {
+ grub_printf ("Warning: a trusted binary hash (%02x%02x%02x%02x) is
ignored"
+ " because it is on the distrusted list (dbx).\n",
+ binary_hash[0], binary_hash[1], binary_hash[2],
binary_hash[3]);
+ grub_free (grub_platform_keystore.dbx[i].data);
+ grub_memset (&grub_platform_keystore.dbx[i], 0x00, sizeof
(grub_pks_sd_t));
+ return GRUB_ERR_BAD_SIGNATURE;
+ }
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+/*
+ * extracts the binary hashes from the platform keystore buffer,
+ * and adds it to the trusted list if not exists in distrusted list.
+ */
+static grub_err_t
+grub_add_trusted_binary_hash (const grub_uint8_t **data, const grub_size_t
data_size)
+{
+ grub_err_t rc = GRUB_ERR_NONE;
+
+ if (*data == NULL || data_size == 0)
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "trusted binary hash data/size
is null");
+
+ rc = grub_is_distrusted_binary_hash (*data, data_size);
+ if (rc != GRUB_ERR_NONE)
+ return rc;
+
+ rc = grub_add_hash (data, data_size, &grub_db.signatures,
&grub_db.signature_size,
+ &grub_db.signature_entries);
+ return rc;
+}
+
+static grub_err_t
+grub_is_hash (const grub_uuid_t *guid)
+{
+ /* GUID type of the binary hash */
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_SHA256_GUID, GRUB_UUID_SIZE) == 0 ||
+ grub_memcmp (guid, &GRUB_PKS_CERT_SHA384_GUID, GRUB_UUID_SIZE) == 0 ||
+ grub_memcmp (guid, &GRUB_PKS_CERT_SHA512_GUID, GRUB_UUID_SIZE) == 0)
+ return GRUB_ERR_NONE;
+
+ /* GUID type of the certificate hash */
+ if (grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA256_GUID, GRUB_UUID_SIZE) == 0
||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA384_GUID, GRUB_UUID_SIZE) == 0
||
+ grub_memcmp (guid, &GRUB_PKS_CERT_X509_SHA512_GUID, GRUB_UUID_SIZE) == 0)
+ return GRUB_ERR_NONE;
+
+ return GRUB_ERR_UNKNOWN_COMMAND;
+}
+
+/*
+ * extracts the x509 certificates/binary hashes from the platform keystore
buffer,
+ * parses it, and adds it to the trusted list.
+ */
+static grub_err_t
+grub_create_trusted_list (void)
+{
+ grub_err_t rc = GRUB_ERR_NONE;
+ grub_size_t i = 0;
+
+ for (i = 0; i < grub_platform_keystore.db_entries; i++)
+ {
+ if (grub_is_hash (&grub_platform_keystore.db[i].guid) == GRUB_ERR_NONE)
+ {
+ rc = grub_add_trusted_binary_hash ((const grub_uint8_t **)
+
&grub_platform_keystore.db[i].data,
+
grub_platform_keystore.db[i].data_size);
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
+ return rc;
+
+ continue;
+ }
+ else if (grub_is_x509 (&grub_platform_keystore.db[i].guid) ==
GRUB_ERR_NONE)
+ {
+
+ rc = grub_is_distrusted_cert_hash (grub_platform_keystore.db[i].data,
+
grub_platform_keystore.db[i].data_size);
+ if (rc != GRUB_ERR_NONE)
+ continue;
+
+ rc = grub_add_certificate (grub_platform_keystore.db[i].data,
+ grub_platform_keystore.db[i].data_size,
&grub_db, 1);
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
+ return rc;
+ else if (rc != GRUB_ERR_NONE)
+ continue;
+ }
+ else
+ grub_printf ("Warning: unsupported signature data type and "
+ "skipping trusted data (%" PRIuGRUB_SIZE ")\n", i + 1);
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+/*
+ * extracts the certificates, certificate/binary hashes out of the platform
keystore buffer,
+ * and adds it to the distrusted list.
+ */
+static grub_err_t
+grub_create_distrusted_list (void)
+{
+ grub_err_t rc = GRUB_ERR_NONE;
+ grub_size_t i = 0;
+
+ for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
+ {
+ if (grub_platform_keystore.dbx[i].data != NULL &&
+ grub_platform_keystore.dbx[i].data_size > 0)
+ {
+ if (grub_is_x509 (&grub_platform_keystore.dbx[i].guid) ==
GRUB_ERR_NONE)
+ {
+ rc = grub_add_certificate (grub_platform_keystore.dbx[i].data,
+
grub_platform_keystore.dbx[i].data_size, &grub_dbx, 0);
+ if (rc == GRUB_ERR_OUT_OF_MEMORY)
+ return rc;
+ }
+ else if (grub_is_hash (&grub_platform_keystore.dbx[i].guid) ==
GRUB_ERR_NONE)
+ {
+ rc = grub_add_hash ((const grub_uint8_t **)
&grub_platform_keystore.dbx[i].data,
+ grub_platform_keystore.dbx[i].data_size,
+ &grub_dbx.signatures,
&grub_dbx.signature_size,
+ &grub_dbx.signature_entries);
+ if (rc != GRUB_ERR_NONE)
+ return rc;
+ }
+ else
+ grub_printf ("Warning: unsupported signature data type and "
+ "skipping distrusted data (%" PRIuGRUB_SIZE ")\n", i
+ 1);
+ }
+ }
+
+ return rc;
+}
+
+/*
+ * extracts the x509 certificates from the ELF note header,
+ * parses it, and adds it to the trusted list.
+ */
+static grub_err_t
+grub_build_static_trusted_list (const struct grub_module_header *header)
+{
+ grub_err_t err = GRUB_ERR_NONE;
+ struct grub_file pseudo_file;
+ grub_uint8_t *cert_data = NULL;
+ grub_ssize_t cert_data_size = 0;
+
+ grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
+ pseudo_file.fs = &pseudo_fs;
+ pseudo_file.size = header->size - sizeof (struct grub_module_header);
+ pseudo_file.data = (char *) header + sizeof (struct grub_module_header);
+
+ grub_dprintf ("appendedsig", "found an x509 key, size=%" PRIuGRUB_UINT64_T
"\n",
+ pseudo_file.size);
+
+ err = grub_read_file (&pseudo_file, &cert_data, &cert_data_size);
+ if (err != GRUB_ERR_NONE)
+ return err;
+
+ err = grub_add_certificate (cert_data, cert_data_size, &grub_db, 1);
+ if (cert_data != NULL)
+ grub_free (cert_data);
+
+ return err;
+}
+
+/* releasing memory */
+static void
+grub_release_trusted_list (void)
+{
+ struct x509_certificate *cert;
+ grub_size_t i = 0;
+
+ while (grub_db.keys != NULL)
+ {
+ cert = grub_db.keys;
+ grub_db.keys = grub_db.keys->next;
+ certificate_release (cert);
+ grub_free (cert);
+ }
+
+ for (i = 0; i < grub_db.signature_entries; i++)
+ grub_free (grub_db.signatures[i]);
+
+ grub_free (grub_db.signatures);
+ grub_free (grub_db.signature_size);
+ grub_memset (&grub_db, 0x00, sizeof (grub_db));
+}
+
+/* releasing memory */
+static void
+grub_release_distrusted_list (void)
+{
+ struct x509_certificate *cert;
+ grub_size_t i = 0;
+
+ while (grub_dbx.keys != NULL)
+ {
+ cert = grub_dbx.keys;
+ grub_dbx.keys = grub_dbx.keys->next;
+ certificate_release (cert);
+ grub_free (cert);
+ }
+
+ for (i = 0; i < grub_dbx.signature_entries; i++)
+ grub_free (grub_dbx.signatures[i]);
+
+ grub_free (grub_dbx.signatures);
+ grub_free (grub_dbx.signature_size);
+ grub_memset (&grub_dbx, 0x00, sizeof (grub_dbx));
+}
+
GRUB_MOD_INIT (appendedsig)
{
int rc;
@@ -548,7 +1085,6 @@ GRUB_MOD_INIT (appendedsig)
if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED)
check_sigs = check_sigs_forced;
- grub_trusted_key = NULL;
grub_register_variable_hook ("check_appended_signatures", grub_env_read_sec,
grub_env_write_sec);
grub_env_export ("check_appended_signatures");
@@ -556,39 +1092,51 @@ GRUB_MOD_INIT (appendedsig)
if (rc)
grub_fatal ("Error initing ASN.1 data structures: %d: %s\n", rc,
asn1_strerror (rc));
- FOR_MODULES (header)
- {
- struct grub_file pseudo_file;
- struct x509_certificate *pk = NULL;
- grub_err_t err;
-
- /* Not an X.509 certificate, skip. */
- if (header->type != OBJ_TYPE_X509_PUBKEY)
- continue;
-
- grub_memset (&pseudo_file, 0, sizeof (pseudo_file));
- pseudo_file.fs = &pseudo_fs;
- pseudo_file.size = header->size - sizeof (struct grub_module_header);
- pseudo_file.data = (char *) header + sizeof (struct grub_module_header);
-
- grub_dprintf ("appendedsig", "Found an x509 key, size=%" PRIuGRUB_UINT64_T
"\n",
- pseudo_file.size);
-
- pk = grub_zalloc (sizeof (struct x509_certificate));
- if (!pk)
- {
- grub_fatal ("Out of memory loading initial certificates");
- }
-
- err = read_cert_from_file (&pseudo_file, pk);
- if (err != GRUB_ERR_NONE)
- grub_fatal ("Error loading initial key: %s", grub_errmsg);
+ if (!grub_use_platform_keystore && check_sigs == check_sigs_forced)
+ {
+ FOR_MODULES (header)
+ {
+ /* Not an ELF module, skip. */
+ if (header->type != OBJ_TYPE_X509_PUBKEY)
+ continue;
- grub_dprintf ("appendedsig", "loaded certificate CN='%s'\n", pk->subject);
+ rc = grub_build_static_trusted_list (header);
+ if (rc != GRUB_ERR_NONE)
+ {
+ grub_release_trusted_list ();
+ grub_error (rc, "static trusted list creation failed");
+ }
+ else
+ grub_printf ("appendedsig: the trusted list now has %"
PRIuGRUB_SIZE " static keys\n",
+ grub_db.key_entries);
+ }
+ }
+ else if (grub_use_platform_keystore && check_sigs == check_sigs_forced)
+ {
+ rc = grub_create_trusted_list ();
+ if (rc != GRUB_ERR_NONE)
+ {
+ grub_release_trusted_list ();
+ grub_error (rc, "trusted list creation failed");
+ }
+ else
+ {
+ rc = grub_create_distrusted_list ();
+ if (rc != GRUB_ERR_NONE)
+ {
+ grub_release_trusted_list ();
+ grub_release_distrusted_list ();
+ grub_error (rc, "distrusted list creation failed");
+ }
+ else
+ grub_printf ("appendedsig: the trusted list now has %"
PRIuGRUB_SIZE " keys.\n"
+ "appendedsig: the distrusted list now has %"
PRIuGRUB_SIZE " keys.\n",
+ grub_db.signature_entries + grub_db.key_entries,
+ grub_dbx.signature_entries);
+ }
- pk->next = grub_trusted_key;
- grub_trusted_key = pk;
- }
+ grub_release_platform_keystore ();
+ }
cmd_trust = grub_register_command ("trust_certificate", grub_cmd_trust,
N_("X509_CERTIFICATE"),
N_("Add X509_CERTIFICATE to trusted
certificates."));
--
2.43.5
- Re: [PATCH v1 15/21] ieee1275: Read the DB and DBX secure boot variables, (continued)
- [PATCH v1 10/21] appended signatures: support verifying appended signatures, Sudhakar Kuppusamy, 2024/12/18
- [PATCH v1 12/21] appended signatures: documentation, Sudhakar Kuppusamy, 2024/12/18
- [PATCH v1 11/21] appended signatures: verification tests, Sudhakar Kuppusamy, 2024/12/18
- [PATCH v1 13/21] ieee1275: enter lockdown based on /ibm,secure-boot, Sudhakar Kuppusamy, 2024/12/18
- [PATCH v1 16/21] appendedsig: The creation of trusted and distrusted lists,
Sudhakar Kuppusamy <=
- [PATCH v1 17/21] appendedsig: While verifying the kernel, use trusted and distrusted lists, Sudhakar Kuppusamy, 2024/12/18
- [PATCH v1 18/21] ieee1275: set use_static_keys flag, Sudhakar Kuppusamy, 2024/12/18
- [PATCH v1 19/21] appendedsig: Reads the default DB keys from ELF Note, Sudhakar Kuppusamy, 2024/12/18
- [PATCH v1 20/21] appendedsig: The grub command's trusted and distrusted support, Sudhakar Kuppusamy, 2024/12/18
- [PATCH v1 21/21] appendedsig: documentation, Sudhakar Kuppusamy, 2024/12/18