static int attestation_responder_get_digests()

in core/attestation/attestation_responder.c [12:121]


static int attestation_responder_get_digests (struct attestation_responder *attestation,
	uint8_t slot_num, uint8_t *buf, size_t buf_len, uint8_t *num_cert)
{
	const struct riot_keys *keys;
	const struct der_cert *root_ca;
	const struct der_cert *int_ca;
	const struct der_cert *aux_cert = NULL;
	size_t offset = 0;
	int status;

	if ((attestation == NULL) || (buf == NULL) || (num_cert == NULL)) {
		return ATTESTATION_INVALID_ARGUMENT;
	}

	if (slot_num > ATTESTATION_AUX_SLOT_NUM) {
		return ATTESTATION_INVALID_SLOT_NUM;
	}

#ifdef ATTESTATION_SUPPORT_RSA_UNSEAL
	aux_cert = aux_attestation_get_certificate (attestation->aux);
#endif
	if (slot_num == ATTESTATION_AUX_SLOT_NUM) {
		if (attestation->aux == NULL) {
			return ATTESTATION_INVALID_SLOT_NUM;
		}
		else if (aux_cert == NULL) {
			return ATTESTATION_CERT_NOT_AVAILABLE;
		}
	}

	keys = riot_key_manager_get_riot_keys (attestation->riot);
	if ((keys->devid_cert == NULL) || (keys->devid_cert_length == 0)) {
		status = ATTESTATION_CERT_NOT_AVAILABLE;
		goto exit;
	}
	else if ((slot_num == ATTESTATION_RIOT_SLOT_NUM) &&
		((keys->alias_cert == NULL) || (keys->alias_cert_length == 0))) {
		status = ATTESTATION_CERT_NOT_AVAILABLE;
		goto exit;
	}

	root_ca = riot_key_manager_get_root_ca (attestation->riot);
	int_ca = riot_key_manager_get_intermediate_ca (attestation->riot);

	*num_cert = 2;
	if (root_ca != NULL) {
		*num_cert += 1;
	}
	if (int_ca != NULL) {
		*num_cert += 1;
	}
	if (buf_len < (SHA256_HASH_LENGTH * (*num_cert))) {
		status = ATTESTATION_BUF_TOO_SMALL;
		goto exit;
	}

	platform_mutex_lock (&attestation->lock);

	if (root_ca != NULL) {
		status = attestation->hash->calculate_sha256 (attestation->hash, root_ca->cert,
			root_ca->length, buf, SHA256_HASH_LENGTH);
		if (status != 0) {
			goto unlock;
		}

		offset += SHA256_HASH_LENGTH;
	}

	if (int_ca != NULL) {
		status = attestation->hash->calculate_sha256 (attestation->hash, int_ca->cert,
			int_ca->length, &buf[offset], SHA256_HASH_LENGTH);
		if (status != 0) {
			goto unlock;
		}

		offset += SHA256_HASH_LENGTH;
	}

	status = attestation->hash->calculate_sha256 (attestation->hash, keys->devid_cert,
		keys->devid_cert_length, &buf[offset], SHA256_HASH_LENGTH);
	if (status != 0) {
		goto unlock;
	}

	offset += SHA256_HASH_LENGTH;

	switch (slot_num) {
		case ATTESTATION_RIOT_SLOT_NUM:
			status = attestation->hash->calculate_sha256 (attestation->hash, keys->alias_cert,
				keys->alias_cert_length, &buf[offset], SHA256_HASH_LENGTH);
			break;

		case ATTESTATION_AUX_SLOT_NUM:
			status = attestation->hash->calculate_sha256 (attestation->hash, aux_cert->cert,
				aux_cert->length, &buf[offset], SHA256_HASH_LENGTH);
			break;
	}
	if (status != 0) {
		goto unlock;
	}

	status = offset + SHA256_HASH_LENGTH;

unlock:
	platform_mutex_unlock (&attestation->lock);
exit:
	riot_key_manager_release_riot_keys (attestation->riot, keys);

	return status;
}