in core/manifest/manifest_verification.c [273:362]
int manifest_verification_init_state (const struct manifest_verification *verification,
const uint8_t *root_key, size_t root_key_length)
{
int status;
if ((verification == NULL) || (root_key == NULL) || (root_key_length == 0) ||
(verification->state == NULL) || (verification->hash == NULL) ||
(verification->manifest_verify == NULL) || (verification->default_key == NULL) ||
(verification->keystore == NULL)) {
return MANIFEST_VERIFICATION_INVALID_ARGUMENT;
}
memset (verification->state, 0, sizeof (struct manifest_verification_state));
status = manifest_verification_verify_key (verification, verification->default_key, root_key,
root_key_length);
if (status != 0) {
return status;
}
verification->state->default_valid = true;
status = verification->keystore->load_key (verification->keystore, verification->key_id,
(uint8_t**) &verification->state->stored_key.key_data,
&verification->state->stored_key.key_data_length);
if ((status != 0) && (status != KEYSTORE_NO_KEY) && (status != KEYSTORE_BAD_KEY)) {
return status;
}
if (status == 0) {
/* Set up the manifest_verification_key structure for the key loaded from the keystore.
* Lengths and hash type are determined from the values set in the default manifest key. */
verification->state->stored_key.key =
(struct manifest_verification_key_header*) verification->state->stored_key.key_data;
verification->state->stored_key.pub_key_length = verification->default_key->pub_key_length;
verification->state->stored_key.signature = verification->state->stored_key.key_data +
sizeof (uint32_t) + verification->state->stored_key.pub_key_length;
verification->state->stored_key.sig_length = verification->default_key->sig_length;
verification->state->stored_key.sig_hash = verification->default_key->sig_hash;
if (verification->state->stored_key.key_data_length ==
verification->default_key->key_data_length) {
status = manifest_verification_verify_key (verification,
&verification->state->stored_key, root_key, root_key_length);
}
else {
status = MANIFEST_VERIFICATION_INVALID_STORED_KEY;
}
if (status != 0) {
platform_free ((void*) verification->state->stored_key.key_data);
if ((status == SIG_VERIFICATION_BAD_SIGNATURE) ||
(status == SIG_VERIFICATION_INVALID_KEY) ||
(status == MANIFEST_VERIFICATION_INVALID_STORED_KEY)) {
verification->state->stored_key.key_data = NULL;
}
else {
return status;
}
}
}
if (!verification->state->stored_key.key_data) {
debug_log_create_entry (DEBUG_LOG_SEVERITY_INFO, DEBUG_LOG_COMPONENT_MANIFEST,
MANIFEST_LOGGING_NO_STORED_MANIFEST_KEY, verification->key_id, status);
status = verification->keystore->save_key (verification->keystore, verification->key_id,
verification->default_key->key_data, verification->default_key->key_data_length);
if (status != 0) {
return status;
}
}
else if (verification->state->stored_key.key->id >= verification->default_key->key->id) {
debug_log_create_entry (DEBUG_LOG_SEVERITY_INFO, DEBUG_LOG_COMPONENT_MANIFEST,
MANIFEST_LOGGING_MANIFEST_KEY_REVOKED, verification->key_id,
verification->state->stored_key.key->id);
verification->state->default_valid = false;
}
status = platform_mutex_init (&verification->state->lock);
if (status != 0) {
platform_free ((void*) verification->state->stored_key.key_data);
return status;
}
return 0;
}