int manifest_verification_init_state()

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;
}