sbkeysync: Find keys missing from firmware key databases

Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
This commit is contained in:
Jeremy Kerr 2012-08-23 14:13:38 +08:00
parent 60586e122f
commit 37d838a43d

View file

@ -111,6 +111,7 @@ struct fs_keystore_entry {
uint8_t *data; uint8_t *data;
size_t len; size_t len;
struct list_node keystore_list; struct list_node keystore_list;
struct list_node new_list;
}; };
struct fs_keystore { struct fs_keystore {
@ -125,6 +126,7 @@ struct sync_context {
struct fs_keystore *fs_keystore; struct fs_keystore *fs_keystore;
const char **keystore_dirs; const char **keystore_dirs;
unsigned int n_keystore_dirs; unsigned int n_keystore_dirs;
struct list_head new_keys;
bool verbose; 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); 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, static void init_key_database(struct sync_context *ctx,
struct key_database **kdb_p, struct key_database **kdb_p,
const struct key_database_type *type) const struct key_database_type *type)
@ -684,6 +770,7 @@ int main(int argc, char **argv)
use_default_keystore_dirs = true; use_default_keystore_dirs = true;
ctx = talloc_zero(NULL, struct sync_context); ctx = talloc_zero(NULL, struct sync_context);
list_head_init(&ctx->new_keys);
for (;;) { for (;;) {
int idx, c; int idx, c;
@ -750,5 +837,10 @@ int main(int argc, char **argv)
print_keystore(ctx->fs_keystore); print_keystore(ctx->fs_keystore);
} }
find_new_keys(ctx);
if (ctx->verbose)
print_new_keys(ctx);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }