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