lpac/euicc/es10cex.c
2023-11-26 19:13:33 +08:00

114 lines
3.4 KiB
C

#include "es10cex.h"
#include "es10x.private.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "derutil.h"
#include "asn1c/asn1/GetEuiccInfo2Request.h"
#include "asn1c/asn1/EUICCInfo2.h"
static int _versiontype_to_string(char *out, int out_len, VersionType_t version)
{
if (version.size != 3)
return -1;
return snprintf(out, out_len, "%d.%d.%d", version.buf[0], version.buf[1], version.buf[2]);
}
static int _read_ext_resource(uint8_t *buf, int len, uint16_t tag)
{
int ret;
uint8_t *value;
int value_len;
value_len = euicc_derutil_tag_find(&value, buf, len, &tag, 0);
if (value_len == -1)
{
return -1;
}
ret = 0;
for (int i = 0; i < value_len; i++)
{
ret |= (value[i] << (8 * (value_len - i - 1)));
}
return ret;
}
int es10cex_get_euiccinfo2(struct euicc_ctx *ctx, struct es10cex_euiccinfo2 *info)
{
int fret = 0;
uint8_t *respbuf = NULL;
unsigned resplen;
asn_enc_rval_t asn1erval;
asn_dec_rval_t asn1drval;
GetEuiccInfo2Request_t *asn1req = NULL;
EUICCInfo2_t *asn1resp = NULL;
asn1req = malloc(sizeof(GetEuiccInfo2Request_t));
if (!asn1req)
{
goto err;
}
memset(asn1req, 0, sizeof(*asn1req));
asn1erval = der_encode_to_buffer(&asn_DEF_GetEuiccInfo2Request, asn1req, ctx->g_asn1_der_request_buf,
sizeof(ctx->g_asn1_der_request_buf));
ASN_STRUCT_FREE(asn_DEF_GetEuiccInfo2Request, asn1req);
asn1req = NULL;
if (asn1erval.encoded == -1)
{
goto err;
}
if (es10x_command(ctx, &respbuf, &resplen, ctx->g_asn1_der_request_buf, asn1erval.encoded) < 0)
{
goto err;
}
asn1drval = ber_decode(NULL, &asn_DEF_EUICCInfo2, (void **)&asn1resp, respbuf, resplen);
free(respbuf);
respbuf = NULL;
if (asn1drval.code != RC_OK)
{
goto err;
}
memset(info, 0, sizeof(*info));
_versiontype_to_string(info->profile_version, sizeof(info->profile_version), asn1resp->profileVersion);
_versiontype_to_string(info->sgp22_version, sizeof(info->sgp22_version), asn1resp->svn);
_versiontype_to_string(info->euicc_firmware_version, sizeof(info->euicc_firmware_version), asn1resp->euiccFirmwareVer);
_versiontype_to_string(info->pp_version, sizeof(info->pp_version), asn1resp->ppVersion);
if (asn1resp->javacardVersion)
{
_versiontype_to_string(info->uicc_firmware_version, sizeof(info->uicc_firmware_version),
*asn1resp->javacardVersion);
}
if (asn1resp->globalplatformVersion)
{
_versiontype_to_string(info->global_platform_version, sizeof(info->global_platform_version),
*asn1resp->globalplatformVersion);
}
memcpy(info->sas_accreditation_number, asn1resp->sasAcreditationNumber.buf,
asn1resp->sasAcreditationNumber.size);
info->installed_app = _read_ext_resource(asn1resp->extCardResource.buf, asn1resp->extCardResource.size, 0x81);
info->free_nvram = _read_ext_resource(asn1resp->extCardResource.buf, asn1resp->extCardResource.size, 0x82);
info->free_ram = _read_ext_resource(asn1resp->extCardResource.buf, asn1resp->extCardResource.size, 0x83);
goto exit;
err:
fret = -1;
exit:
free(respbuf);
ASN_STRUCT_FREE(asn_DEF_GetEuiccInfo2Request, asn1req);
ASN_STRUCT_FREE(asn_DEF_EUICCInfo2, asn1resp);
return fret;
}