static int attestation_responder_get_certificate()

in core/attestation/attestation_responder.c [151:258]


static int attestation_responder_get_certificate (struct attestation_responder *attestation,
	uint8_t slot_num, uint8_t cert_num, struct der_cert *cert)
{
	const struct riot_keys *keys;
	const struct der_cert *int_ca;
	const struct der_cert *root_ca;
	const struct der_cert *aux_cert = NULL;
	int status = 0;

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

	if (slot_num > ATTESTATION_AUX_SLOT_NUM) {
		return ATTESTATION_INVALID_SLOT_NUM;
	}

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

	if (int_ca) {
		if (cert_num > 3) {
			return ATTESTATION_INVALID_CERT_NUM;
		}
	}
	else if (root_ca) {
		if (cert_num > 2) {
			return ATTESTATION_INVALID_CERT_NUM;
		}
	}
	else if (cert_num > 1) {
		return ATTESTATION_INVALID_CERT_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;
	}

	memset (cert, 0, sizeof (struct der_cert));

	switch (cert_num) {
		case 0:
			if (root_ca) {
				cert->cert = root_ca->cert;
				cert->length = root_ca->length;
			}
			else {
				cert->cert = keys->devid_cert;
				cert->length = keys->devid_cert_length;
			}
			break;

		case 1:
			if (int_ca) {
				cert->cert = int_ca->cert;
				cert->length = int_ca->length;
			}
			else if (root_ca) {
				cert->cert = keys->devid_cert;
				cert->length = keys->devid_cert_length;
			}
			else {
				attestation_responder_get_last_certificate (attestation, slot_num, keys, aux_cert,
					cert);
			}
			break;

		case 2:
			if (int_ca) {
				cert->cert = keys->devid_cert;
				cert->length = keys->devid_cert_length;
			}
			else {
				attestation_responder_get_last_certificate (attestation, slot_num, keys, aux_cert,
					cert);
			}
			break;

		case 3:
			attestation_responder_get_last_certificate (attestation, slot_num, keys, aux_cert,
				cert);
			break;
	}

exit:
	riot_key_manager_release_riot_keys (attestation->riot, keys);

	return status;
}