keycard-pro/app/keycard/application_info.c

95 lines
2.5 KiB
C

#include <string.h>
#include "application_info.h"
#include "util/tlv.h"
#define TLV_APPLICATION_INFO_TEMPLATE 0xa4
#define TLV_APPLICATION_STATUS_TEMPLATE 0xa3
#define TLV_PUB_KEY 0x80
#define TLV_UID 0x8f
#define TLV_KEY_UID 0x8e
#define TLV_BOOL 0x01
#define TLV_INT 0x02
app_err_t application_info_parse(uint8_t* buf, app_info_t* info) {
uint16_t tag;
uint16_t off = tlv_read_tag(buf, &tag);
if (tag == TLV_APPLICATION_INFO_TEMPLATE) {
uint16_t len;
off += tlv_read_length(&buf[off], &len);
if ((len = tlv_read_fixed_primitive(TLV_UID, APP_INFO_INSTANCE_UID_LEN, &buf[off], info->instance_uid)) == TLV_INVALID) {
return ERR_DATA;
}
off += len;
if ((len = tlv_read_fixed_primitive(TLV_PUB_KEY, APP_INFO_PUBKEY_LEN, &buf[off], info->sc_key)) == TLV_INVALID) {
return ERR_DATA;
}
off += len;
if ((len = tlv_read_fixed_primitive(TLV_INT, sizeof(uint16_t), &buf[off], (uint8_t*)(&info->version))) == TLV_INVALID) {
return ERR_DATA;
}
info->version = (info->version >> 8) | (info->version << 8);
off += len;
if ((len = tlv_read_fixed_primitive(TLV_INT, sizeof(uint8_t), &buf[off], &info->free_pairing)) == TLV_INVALID) {
return ERR_DATA;
}
off += len;
if (tlv_read_primitive(TLV_KEY_UID, APP_INFO_KEY_UID_LEN, &buf[off], info->key_uid, &len) == TLV_INVALID) {
return ERR_DATA;
}
if (len == 0) {
info->status = INIT_NO_KEYS;
} else if (len == APP_INFO_KEY_UID_LEN) {
info->status = INIT_WITH_KEYS;
} else {
return ERR_DATA;
}
} else if (tag == TLV_PUB_KEY) {
if (tlv_read_fixed_primitive(TLV_PUB_KEY, APP_INFO_PUBKEY_LEN, buf, info->sc_key) == TLV_INVALID) {
return ERR_DATA;
}
info->status = NOT_INITIALIZED;
} else {
return ERR_DATA;
}
return ERR_OK;
}
app_err_t application_status_parse(uint8_t* buf, app_status_t* status) {
uint16_t tag;
uint16_t off = tlv_read_tag(buf, &tag);
if (tag != TLV_APPLICATION_STATUS_TEMPLATE) {
return ERR_DATA;
}
uint16_t len;
off += tlv_read_length(&buf[off], &len);
if ((len = tlv_read_fixed_primitive(TLV_INT, sizeof(uint8_t), &buf[off], &status->pin_retries)) == TLV_INVALID) {
return ERR_DATA;
}
off += len;
if ((len = tlv_read_fixed_primitive(TLV_INT, sizeof(uint8_t), &buf[off], &status->puk_retries)) == TLV_INVALID) {
return ERR_DATA;
}
off += len;
if ((len = tlv_read_fixed_primitive(TLV_BOOL, sizeof(uint8_t), &buf[off], &status->has_key)) == TLV_INVALID) {
return ERR_DATA;
}
off += len;
return ERR_OK;
}