skkeysync: Add PK-handing code
Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
This commit is contained in:
parent
74153741c4
commit
03e6a4e2b3
1 changed files with 68 additions and 8 deletions
|
@ -76,11 +76,19 @@ struct key_database_type {
|
|||
};
|
||||
|
||||
struct key_database_type keydb_types[] = {
|
||||
{ "PK", EFI_GLOBAL_VARIABLE },
|
||||
{ "KEK", EFI_GLOBAL_VARIABLE },
|
||||
{ "db", EFI_IMAGE_SECURITY_DATABASE_GUID },
|
||||
{ "dbx", EFI_IMAGE_SECURITY_DATABASE_GUID },
|
||||
};
|
||||
|
||||
enum keydb_type {
|
||||
KEYDB_PK = 0,
|
||||
KEYDB_KEK = 1,
|
||||
KEYDB_DB = 2,
|
||||
KEYDB_DBX = 3,
|
||||
};
|
||||
|
||||
static const char *default_keystore_dirs[] = {
|
||||
"/etc/secureboot/keys",
|
||||
"/usr/share/secureboot/keys",
|
||||
|
@ -113,6 +121,7 @@ struct key_database {
|
|||
};
|
||||
|
||||
struct keyset {
|
||||
struct key_database pk;
|
||||
struct key_database kek;
|
||||
struct key_database db;
|
||||
struct key_database dbx;
|
||||
|
@ -142,6 +151,7 @@ struct sync_context {
|
|||
struct list_head new_keys;
|
||||
bool verbose;
|
||||
bool dry_run;
|
||||
bool set_pk;
|
||||
};
|
||||
|
||||
|
||||
|
@ -468,10 +478,12 @@ static int read_filesystem_keydb(struct sync_context *ctx,
|
|||
|
||||
static int read_keysets(struct sync_context *ctx)
|
||||
{
|
||||
read_firmware_keydb(ctx, &ctx->firmware_keys->pk);
|
||||
read_firmware_keydb(ctx, &ctx->firmware_keys->kek);
|
||||
read_firmware_keydb(ctx, &ctx->firmware_keys->db);
|
||||
read_firmware_keydb(ctx, &ctx->firmware_keys->dbx);
|
||||
|
||||
read_filesystem_keydb(ctx, &ctx->filesystem_keys->pk);
|
||||
read_filesystem_keydb(ctx, &ctx->filesystem_keys->kek);
|
||||
read_filesystem_keydb(ctx, &ctx->filesystem_keys->db);
|
||||
read_filesystem_keydb(ctx, &ctx->filesystem_keys->dbx);
|
||||
|
@ -479,10 +491,21 @@ static int read_keysets(struct sync_context *ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int check_pk(struct sync_context *ctx)
|
||||
{
|
||||
struct key *key;
|
||||
int i = 0;
|
||||
|
||||
list_for_each(&ctx->filesystem_keys->pk.keys, key, list)
|
||||
i++;
|
||||
|
||||
return (i <= 1) ? 0 : 1;
|
||||
}
|
||||
|
||||
static void print_keyset(struct keyset *keyset, const char *name)
|
||||
{
|
||||
struct key_database *kdbs[] =
|
||||
{ &keyset->kek, &keyset->db, &keyset->dbx };
|
||||
{ &keyset->pk, &keyset->kek, &keyset->db, &keyset->dbx };
|
||||
struct key *key;
|
||||
unsigned int i;
|
||||
|
||||
|
@ -636,6 +659,7 @@ static int find_new_keys(struct sync_context *ctx)
|
|||
struct {
|
||||
struct key_database *fs_kdb, *fw_kdb;
|
||||
} kdbs[] = {
|
||||
{ &ctx->filesystem_keys->pk, &ctx->firmware_keys->pk },
|
||||
{ &ctx->filesystem_keys->kek, &ctx->firmware_keys->kek },
|
||||
{ &ctx->filesystem_keys->db, &ctx->firmware_keys->db },
|
||||
{ &ctx->filesystem_keys->dbx, &ctx->firmware_keys->dbx },
|
||||
|
@ -684,7 +708,7 @@ static void print_new_keys(struct sync_context *ctx)
|
|||
{
|
||||
struct fs_keystore_entry *ke;
|
||||
|
||||
printf("New keys to be added:\n");
|
||||
printf("New keys in filesystem:\n");
|
||||
|
||||
list_for_each(&ctx->new_keys, ke, new_list)
|
||||
printf(" %s/%s\n", ke->root, ke->name);
|
||||
|
@ -753,14 +777,39 @@ out:
|
|||
|
||||
static int insert_new_keys(struct sync_context *ctx)
|
||||
{
|
||||
struct fs_keystore_entry *ke;
|
||||
int rc = 0;
|
||||
struct fs_keystore_entry *ke, *ke_pk;
|
||||
int pks, rc;
|
||||
|
||||
rc = 0;
|
||||
pks = 0;
|
||||
ke_pk = NULL;
|
||||
|
||||
list_for_each(&ctx->new_keys, ke, new_list) {
|
||||
|
||||
/* we handle PK last */
|
||||
if (ke->type == &keydb_types[KEYDB_PK]) {
|
||||
ke_pk = ke;
|
||||
pks++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (insert_key(ctx, ke))
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (pks == 0 || !ctx->set_pk)
|
||||
return 0;
|
||||
|
||||
if (pks > 1) {
|
||||
fprintf(stderr, "Skipping PK update due to mutiple PKs\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = insert_key(ctx, ke_pk);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -770,14 +819,17 @@ static struct keyset *init_keyset(struct sync_context *ctx)
|
|||
|
||||
keyset = talloc(ctx, struct keyset);
|
||||
|
||||
list_head_init(&keyset->pk.keys);
|
||||
keyset->pk.type = &keydb_types[KEYDB_PK];
|
||||
|
||||
list_head_init(&keyset->kek.keys);
|
||||
keyset->kek.type = &keydb_types[0];
|
||||
keyset->kek.type = &keydb_types[KEYDB_KEK];
|
||||
|
||||
list_head_init(&keyset->db.keys);
|
||||
keyset->db.type = &keydb_types[1];
|
||||
keyset->db.type = &keydb_types[KEYDB_DB];
|
||||
|
||||
list_head_init(&keyset->dbx.keys);
|
||||
keyset->dbx.type = &keydb_types[2];
|
||||
keyset->dbx.type = &keydb_types[KEYDB_DBX];
|
||||
|
||||
return keyset;
|
||||
}
|
||||
|
@ -788,6 +840,7 @@ static struct option options[] = {
|
|||
{ "efivars-path", required_argument, NULL, 'e' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "dry-run", no_argument, NULL, 'n' },
|
||||
{ "pk", no_argument, NULL, 'p' },
|
||||
{ "no-default-keystores", no_argument, NULL, 'd' },
|
||||
{ "keystore", required_argument, NULL, 'k' },
|
||||
{ NULL, 0, NULL, 0 },
|
||||
|
@ -803,6 +856,7 @@ static void usage(void)
|
|||
"\t (or regular directory for testing)\n"
|
||||
"\t--verbose Print verbose progress information\n"
|
||||
"\t--dry-run Don't update firmware key databases\n"
|
||||
"\t--pk Set PK\n"
|
||||
"\t--keystore <dir> Read keys from <dir>/{db,dbx,KEK}/*\n"
|
||||
"\t (can be specified multiple times,\n"
|
||||
"\t first dir takes precedence)\n"
|
||||
|
@ -837,7 +891,7 @@ int main(int argc, char **argv)
|
|||
|
||||
for (;;) {
|
||||
int idx, c;
|
||||
c = getopt_long(argc, argv, "e:dkvhV", options, &idx);
|
||||
c = getopt_long(argc, argv, "e:dpkvhV", options, &idx);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
|
@ -851,6 +905,9 @@ int main(int argc, char **argv)
|
|||
case 'k':
|
||||
add_keystore_dir(ctx, optarg);
|
||||
break;
|
||||
case 'p':
|
||||
ctx->set_pk = true;
|
||||
break;
|
||||
case 'v':
|
||||
ctx->verbose = true;
|
||||
break;
|
||||
|
@ -905,6 +962,9 @@ int main(int argc, char **argv)
|
|||
print_keyset(ctx->filesystem_keys, "filesystem");
|
||||
}
|
||||
|
||||
if (check_pk(ctx))
|
||||
fprintf(stderr, "WARNING: multiple PKs found in filesystem\n");
|
||||
|
||||
find_new_keys(ctx);
|
||||
|
||||
if (ctx->verbose)
|
||||
|
|
Loading…
Reference in a new issue