diff options
author | Jeremy Kerr <jeremy.kerr@canonical.com> | 2012-08-23 14:13:38 +0800 |
---|---|---|
committer | Jeremy Kerr <jeremy.kerr@canonical.com> | 2012-08-24 20:03:32 +0800 |
commit | 37d838a43d496da9a6bb8d97e088f6cce842e3c2 (patch) | |
tree | 603e4f985b0325176fa1b9c4589c05d3839b930f | |
parent | 60586e122f48c2282e84a34f6f6e78f4c1f55bc9 (diff) | |
download | sbsigntools-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.c | 92 |
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; } |