sbkeysync: read keystore into kdb->filesystem_keys
Signed-off-by: Jeremy Kerr <jeremy.kerr@canonical.com>
This commit is contained in:
parent
5527ef2db4
commit
54e1fbed30
1 changed files with 138 additions and 13 deletions
135
src/sbkeysync.c
135
src/sbkeysync.c
|
@ -89,10 +89,10 @@ struct key {
|
||||||
int id_len;
|
int id_len;
|
||||||
uint8_t *id;
|
uint8_t *id;
|
||||||
|
|
||||||
size_t len;
|
|
||||||
uint8_t *data;
|
|
||||||
|
|
||||||
struct list_node list;
|
struct list_node list;
|
||||||
|
|
||||||
|
/* set for keys loaded from a filesystem keystore */
|
||||||
|
struct fs_keystore_entry *keystore_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct key_database {
|
struct key_database {
|
||||||
|
@ -102,6 +102,7 @@ struct key_database {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fs_keystore_entry {
|
struct fs_keystore_entry {
|
||||||
|
const struct key_database_type *type;
|
||||||
const char *root;
|
const char *root;
|
||||||
const char *name;
|
const char *name;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
|
@ -318,7 +319,129 @@ static int read_firmware_key_database(struct key_database *kdb,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_firmware_key_databases(struct sync_context *ctx)
|
struct keystore_add_ctx {
|
||||||
|
struct fs_keystore *keystore;
|
||||||
|
struct fs_keystore_entry *ke;
|
||||||
|
struct key_database *kdb;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int keystore_add_key(EFI_SIGNATURE_DATA *sigdata, int len,
|
||||||
|
const EFI_GUID *type, void *arg)
|
||||||
|
{
|
||||||
|
struct keystore_add_ctx *add_ctx = arg;
|
||||||
|
struct key *key;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
key = talloc(add_ctx->kdb, struct key);
|
||||||
|
key->keystore_entry = add_ctx->ke;
|
||||||
|
key->type = *type;
|
||||||
|
|
||||||
|
rc = key_id(key, type, sigdata->SignatureData, len,
|
||||||
|
&key->id, &key->id_len);
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
talloc_free(key);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add a reference to the data: we don't want it to be
|
||||||
|
* deallocated if the keystore is deallocated before the
|
||||||
|
* struct key. */
|
||||||
|
talloc_reference(key, add_ctx->ke->data);
|
||||||
|
list_add(&add_ctx->kdb->filesystem_keys, &key->list);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __attribute__((format(printf, 2, 3))) print_keystore_key_error(
|
||||||
|
struct fs_keystore_entry *ke, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
char *errstr;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
errstr = talloc_vasprintf(ke, fmt, ap);
|
||||||
|
|
||||||
|
fprintf(stderr, "Invalid key %s/%s\n - %s\n", ke->root, ke->name,
|
||||||
|
errstr);
|
||||||
|
|
||||||
|
talloc_free(errstr);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_keystore_key_database(struct key_database *kdb,
|
||||||
|
struct fs_keystore *keystore)
|
||||||
|
{
|
||||||
|
EFI_GUID cert_type_pkcs7 = EFI_CERT_TYPE_PKCS7_GUID;
|
||||||
|
EFI_VARIABLE_AUTHENTICATION_2 *auth;
|
||||||
|
struct keystore_add_ctx add_ctx;
|
||||||
|
struct fs_keystore_entry *ke;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
add_ctx.keystore = keystore;
|
||||||
|
add_ctx.kdb = kdb;
|
||||||
|
|
||||||
|
list_for_each(&keystore->keys, ke, list) {
|
||||||
|
unsigned int len;
|
||||||
|
void *buf;
|
||||||
|
|
||||||
|
if (ke->len == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ke->type != kdb->type)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* parse the three data structures:
|
||||||
|
* EFI_VARIABLE_AUTHENTICATION_2 token
|
||||||
|
* EFI_SIGNATURE_LIST
|
||||||
|
* EFI_SIGNATURE_DATA
|
||||||
|
* ensuring that we have enough data for each
|
||||||
|
*/
|
||||||
|
|
||||||
|
buf = ke->data;
|
||||||
|
len = ke->len;
|
||||||
|
|
||||||
|
if (len < sizeof(*auth)) {
|
||||||
|
print_keystore_key_error(ke, "does not contain an "
|
||||||
|
"EFI_VARIABLE_AUTHENTICATION_2 descriptor");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auth = buf;
|
||||||
|
|
||||||
|
if (guidcmp(&auth->AuthInfo.CertType, &cert_type_pkcs7)) {
|
||||||
|
print_keystore_key_error(ke, "unknown cert type");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (auth->AuthInfo.Hdr.dwLength > len) {
|
||||||
|
print_keystore_key_error(ke,
|
||||||
|
"invalid WIN_CERTIFICATE length");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the dwLength field includes the size of the WIN_CERTIFICATE,
|
||||||
|
* but not the other data in the EFI_VARIABLE_AUTHENTICATION_2
|
||||||
|
* descriptor */
|
||||||
|
buf += sizeof(*auth) - sizeof(auth->AuthInfo) +
|
||||||
|
auth->AuthInfo.Hdr.dwLength;
|
||||||
|
len -= sizeof(*auth) - sizeof(auth->AuthInfo) +
|
||||||
|
auth->AuthInfo.Hdr.dwLength;
|
||||||
|
|
||||||
|
add_ctx.ke = ke;
|
||||||
|
rc = sigdb_iterate(buf, len, keystore_add_key, &add_ctx);
|
||||||
|
if (rc) {
|
||||||
|
print_keystore_key_error(ke, "error parsing "
|
||||||
|
"EFI_SIGNATURE_LIST");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_key_databases(struct sync_context *ctx)
|
||||||
{
|
{
|
||||||
struct key_database *kdbs[] = {
|
struct key_database *kdbs[] = {
|
||||||
ctx->kek,
|
ctx->kek,
|
||||||
|
@ -330,6 +453,7 @@ static int read_firmware_key_databases(struct sync_context *ctx)
|
||||||
for (i = 0; i < ARRAY_SIZE(kdbs); i++) {
|
for (i = 0; i < ARRAY_SIZE(kdbs); i++) {
|
||||||
struct key_database *kdb = kdbs[i];
|
struct key_database *kdb = kdbs[i];
|
||||||
read_firmware_key_database(kdb, ctx->efivars_dir);
|
read_firmware_key_database(kdb, ctx->efivars_dir);
|
||||||
|
read_keystore_key_database(kdb, ctx->fs_keystore);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -441,6 +565,7 @@ static int update_keystore(struct fs_keystore *keystore, const char *root)
|
||||||
ke = talloc(keystore, struct fs_keystore_entry);
|
ke = talloc(keystore, struct fs_keystore_entry);
|
||||||
ke->name = filename;
|
ke->name = filename;
|
||||||
ke->root = root;
|
ke->root = root;
|
||||||
|
ke->type = &keydb_types[i];
|
||||||
talloc_steal(ke, ke->name);
|
talloc_steal(ke, ke->name);
|
||||||
|
|
||||||
if (keystore_entry_read(ke))
|
if (keystore_entry_read(ke))
|
||||||
|
@ -604,8 +729,8 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
read_firmware_key_databases(ctx);
|
|
||||||
read_keystore(ctx);
|
read_keystore(ctx);
|
||||||
|
read_key_databases(ctx);
|
||||||
|
|
||||||
if (ctx->verbose) {
|
if (ctx->verbose) {
|
||||||
print_key_databases(ctx);
|
print_key_databases(ctx);
|
||||||
|
|
Loading…
Reference in a new issue