From d36479e9b942a324eb671d9f383266a2fd1b9fa7 Mon Sep 17 00:00:00 2001 From: Coelacanthus Date: Thu, 4 Jan 2024 10:38:23 +0800 Subject: [PATCH] feat(euiccinfo): add euiccCiPKIdListFor{Verification,Signing} (#29) * feat(euiccinfo): add euiccCiPKIdListFor{Verification,Signing} According to RFC3280 section 4.2.1.2, SubjectKeyIdentifier is byte array of SHA-1 or subset of SHA-1, so we print it as HEX string, just as InfiLPA does. Ref: https://datatracker.ietf.org/doc/html/rfc3280#section-4.2.1.2 Signed-off-by: Coelacanthus * fix: use euicc_hexutil_bin2hex() from hexutil.h Signed-off-by: Coelacanthus * fix: add null check for euiccCiPKListFor* Signed-off-by: Coelacanthus * fix: add es10cex_free_euiccinfo2 function and use it in applet/chip/info Change type of euiccinfo2 in applet/chip/info.c from struct to pointer to implement better euiccinfo release. Signed-off-by: Coelacanthus * chore: use Allman style indentation to match project style Hope lpac can have a .clang-format file to specify project code style. Signed-off-by: Coelacanthus * fix(applet/chip/info): fix euiccinfo2 init value Signed-off-by: Coelacanthus * refactor: use NULL-terminated array to store variable length array Signed-off-by: Coelacanthus * refactor(applet/chip/info): alloc euiccinfo2 on stack Signed-off-by: Coelacanthus * fix: should increse pointer after use it Signed-off-by: Coelacanthus --------- Signed-off-by: Coelacanthus --- euicc/es10cex.c | 44 ++++++++++++++++++++++++++++++++++++++++++ euicc/es10cex.h | 3 +++ src/applet/chip/info.c | 33 +++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) diff --git a/euicc/es10cex.c b/euicc/es10cex.c index 3e6f9d5..5127ba4 100644 --- a/euicc/es10cex.c +++ b/euicc/es10cex.c @@ -9,6 +9,7 @@ #include "asn1c/asn1/GetEuiccInfo2Request.h" #include "asn1c/asn1/EUICCInfo2.h" +#include "euicc/hexutil.h" static int _versiontype_to_string(char *out, int out_len, VersionType_t version) { @@ -95,6 +96,26 @@ int es10cex_get_euiccinfo2(struct euicc_ctx *ctx, struct es10cex_euiccinfo2 *inf _versiontype_to_string(info->global_platform_version, sizeof(info->global_platform_version), *asn1resp->globalplatformVersion); } + if (asn1resp->euiccCiPKIdListForVerification.list.count) + { + info->euicc_ci_public_key_id_list_for_verification = (char **)malloc(sizeof(char*) * (asn1resp->euiccCiPKIdListForVerification.list.count + 1)); + for (int i = 0; i < asn1resp->euiccCiPKIdListForVerification.list.count; i++) + { + euicc_hexutil_bin2hex(info->euicc_ci_public_key_id_list_for_verification[i], asn1resp->euiccCiPKIdListForVerification.list.array[i]->size * 2 + 1, + asn1resp->euiccCiPKIdListForVerification.list.array[i]->buf, asn1resp->euiccCiPKIdListForVerification.list.array[i]->size); + } + info->euicc_ci_public_key_id_list_for_verification[asn1resp->euiccCiPKIdListForVerification.list.count] = NULL; + } + if (asn1resp->euiccCiPKIdListForSigning.list.count) + { + info->euicc_ci_public_key_id_list_for_signing = (char **)malloc(sizeof(char*) * (asn1resp->euiccCiPKIdListForSigning.list.count + 1)); + for (int i = 0; i < asn1resp->euiccCiPKIdListForSigning.list.count; i++) + { + euicc_hexutil_bin2hex(info->euicc_ci_public_key_id_list_for_signing[i], asn1resp->euiccCiPKIdListForSigning.list.array[i]->size * 2 + 1, + asn1resp->euiccCiPKIdListForSigning.list.array[i]->buf, asn1resp->euiccCiPKIdListForSigning.list.array[i]->size); + } + info->euicc_ci_public_key_id_list_for_signing[asn1resp->euiccCiPKIdListForSigning.list.count] = NULL; + } memcpy(info->sas_accreditation_number, asn1resp->sasAcreditationNumber.buf, asn1resp->sasAcreditationNumber.size); @@ -111,3 +132,26 @@ exit: return fret; } + +int es10cex_free_euiccinfo2(struct es10cex_euiccinfo2 *info) +{ + if (info->euicc_ci_public_key_id_list_for_verification) + { + char **p = info->euicc_ci_public_key_id_list_for_verification; + while (*p) + { + free(*p++); + } + free(info->euicc_ci_public_key_id_list_for_verification); + } + if (info->euicc_ci_public_key_id_list_for_signing) + { + char **p = info->euicc_ci_public_key_id_list_for_signing; + while (*p) + { + free(*p++); + } + free(info->euicc_ci_public_key_id_list_for_signing); + } + free(info); +} diff --git a/euicc/es10cex.h b/euicc/es10cex.h index 3c69665..67dfc8b 100644 --- a/euicc/es10cex.h +++ b/euicc/es10cex.h @@ -9,6 +9,8 @@ struct es10cex_euiccinfo2 char euicc_firmware_version[16]; char uicc_firmware_version[16]; char global_platform_version[16]; + char **euicc_ci_public_key_id_list_for_verification; + char **euicc_ci_public_key_id_list_for_signing; char sas_accreditation_number[65]; char pp_version[16]; int free_nvram; @@ -16,3 +18,4 @@ struct es10cex_euiccinfo2 }; int es10cex_get_euiccinfo2(struct euicc_ctx *ctx, struct es10cex_euiccinfo2 *info); +int es10cex_free_euiccinfo2(struct es10cex_euiccinfo2 *info); diff --git a/src/applet/chip/info.c b/src/applet/chip/info.c index f7269e3..bb15a43 100644 --- a/src/applet/chip/info.c +++ b/src/applet/chip/info.c @@ -1,4 +1,5 @@ #include "info.h" +#include "cjson/cJSON.h" #include #include #include @@ -46,6 +47,38 @@ static int applet_main(int argc, char **argv) cJSON_AddStringOrNullToObject(jeuiccinfo2, "sas_accreditation_number", euiccinfo2.sas_accreditation_number); cJSON_AddNumberToObject(jeuiccinfo2, "free_nvram", euiccinfo2.free_nvram); cJSON_AddNumberToObject(jeuiccinfo2, "free_ram", euiccinfo2.free_ram); + if (euiccinfo2.euicc_ci_public_key_id_list_for_verification) + { + cJSON *a = cJSON_CreateArray(); + char **p = euiccinfo2.euicc_ci_public_key_id_list_for_verification; + while (*p) + { + cJSON_AddItemToArray(a, cJSON_CreateString(*p)); + free(*p++); + } + cJSON_AddItemToObject(jeuiccinfo2, "euicc_ci_public_key_id_list_for_verification", a); + free(euiccinfo2.euicc_ci_public_key_id_list_for_verification); + } + else + { + cJSON_AddNullToObject(jeuiccinfo2, "euicc_ci_public_key_id_list_for_verification"); + } + if (euiccinfo2.euicc_ci_public_key_id_list_for_signing) + { + cJSON *a = cJSON_CreateArray(); + char **p = euiccinfo2.euicc_ci_public_key_id_list_for_signing; + while (*p) + { + cJSON_AddItemToArray(a, cJSON_CreateString(*p)); + free(*p++); + } + cJSON_AddItemToObject(jeuiccinfo2, "euicc_ci_public_key_id_list_for_signing", a); + free(euiccinfo2.euicc_ci_public_key_id_list_for_signing); + } + else + { + cJSON_AddNullToObject(jeuiccinfo2, "euicc_ci_public_key_id_list_for_signing"); + } } cJSON_AddItemToObject(jdata, "euiccinfo2", jeuiccinfo2);