aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Kerr <jeremy.kerr@canonical.com>2012-08-23 14:13:38 +0800
committerJeremy Kerr <jeremy.kerr@canonical.com>2012-08-24 20:03:32 +0800
commit37d838a43d496da9a6bb8d97e088f6cce842e3c2 (patch)
tree603e4f985b0325176fa1b9c4589c05d3839b930f
parent60586e122f48c2282e84a34f6f6e78f4c1f55bc9 (diff)
downloadsbsigntools-37d838a43d496da9a6bb8d97e088f6cce842e3c2.tar.gz
sbkeysync: Find keys missing from firmware key databases
Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
-rw-r--r--src/sbkeysync.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/sbkeysync.c b/src/sbkeysync.c
index 299df05..063de8d 100644
--- a/src/sbkeysync.c
+++ b/src/sbkeysync.c
@@ -111,6 +111,7 @@ struct fs_keystore_entry {
uint8_t *data;
size_t len;
struct list_node keystore_list;
+ struct list_node new_list;
};
struct fs_keystore {
@@ -125,6 +126,7 @@ struct sync_context {
struct fs_keystore *fs_keystore;
const char **keystore_dirs;
unsigned int n_keystore_dirs;
+ struct list_head new_keys;
bool verbose;
};
@@ -620,6 +622,90 @@ static void print_keystore(struct fs_keystore *keystore)
printf(" %s/%s [%zd bytes]\n", ke->root, ke->name, ke->len);
}
+static int key_cmp(struct key *a, struct key *b)
+{
+ if (a->id_len != b->id_len)
+ return a->id_len - b->id_len;
+
+ return memcmp(a->id, b->id, a->id_len);
+}
+
+static int find_new_keys_in_kdb(struct sync_context *ctx,
+ struct key_database *kdb)
+{
+ struct fs_keystore_entry *ke;
+ struct key *fs_key, *fw_key;
+ bool found;
+ int n = 0;
+
+ list_for_each(&kdb->filesystem_keys, fs_key, list) {
+ found = false;
+ list_for_each(&kdb->firmware_keys, fw_key, list) {
+ if (!key_cmp(fs_key, fw_key)) {
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ continue;
+
+ /* add the keystore entry if it's not already present */
+ found = false;
+ list_for_each(&ctx->new_keys, ke, new_list) {
+ if (fs_key->keystore_entry == ke) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ continue;
+
+ list_add(&ctx->new_keys, &fs_key->keystore_entry->new_list);
+ n++;
+ }
+
+ return n;
+}
+
+/* Find the keys that are present in the filesystem, but not the firmware.
+ * Returns:
+ * 0 if there are no new keys to add
+ * >0 if there are keys to add
+ * -1 on error
+ */
+static int find_new_keys(struct sync_context *ctx)
+{
+ struct key_database *kdbs[] = {
+ ctx->kek,
+ ctx->db,
+ ctx->dbx,
+ };
+ unsigned int n, i;
+ int rc;
+
+ n = 0;
+
+ for (i = 0; i < ARRAY_SIZE(kdbs); i++) {
+ rc = find_new_keys_in_kdb(ctx, kdbs[i]);
+ if (rc < 0)
+ return rc;
+ n += rc;
+ }
+
+ return n;
+}
+
+static void print_new_keys(struct sync_context *ctx)
+{
+ struct fs_keystore_entry *ke;
+
+ printf("New keys to be added:\n");
+
+ list_for_each(&ctx->new_keys, ke, new_list)
+ printf(" %s/%s\n", ke->root, ke->name);
+}
+
static void init_key_database(struct sync_context *ctx,
struct key_database **kdb_p,
const struct key_database_type *type)
@@ -684,6 +770,7 @@ int main(int argc, char **argv)
use_default_keystore_dirs = true;
ctx = talloc_zero(NULL, struct sync_context);
+ list_head_init(&ctx->new_keys);
for (;;) {
int idx, c;
@@ -750,5 +837,10 @@ int main(int argc, char **argv)
print_keystore(ctx->fs_keystore);
}
+ find_new_keys(ctx);
+
+ if (ctx->verbose)
+ print_new_keys(ctx);
+
return EXIT_SUCCESS;
}