lpac-jni: Uprev lpac
All checks were successful
/ build-debug (push) Successful in 3m56s

This commit is contained in:
Peter Cai 2024-02-24 15:53:58 -05:00
parent 2b972badaa
commit 5aed27513f
6 changed files with 106 additions and 61 deletions

View file

@ -8,9 +8,8 @@ internal object LpacJni {
external fun createContext(apduInterface: ApduInterface, httpInterface: HttpInterface): Long
external fun destroyContext(handle: Long)
// es10x
external fun es10xInit(handle: Long): Int
external fun es10xFini(handle: Long)
external fun euiccInit(handle: Long): Int
external fun euiccFini(handle: Long)
// es10c
// null returns signify errors

View file

@ -23,7 +23,7 @@ class LocalProfileAssistantImpl(
private var contextHandle: Long = LpacJni.createContext(apduInterface, httpInterface)
init {
if (LpacJni.es10xInit(contextHandle) < 0) {
if (LpacJni.euiccInit(contextHandle) < 0) {
throw IllegalArgumentException("Failed to initialize LPA")
}
@ -34,7 +34,7 @@ class LocalProfileAssistantImpl(
private fun tryReconnect(timeoutMillis: Long) = runBlocking {
withTimeout(timeoutMillis) {
try {
LpacJni.es10xFini(contextHandle)
LpacJni.euiccFini(contextHandle)
LpacJni.destroyContext(contextHandle)
contextHandle = -1
} catch (e: Exception) {
@ -51,7 +51,7 @@ class LocalProfileAssistantImpl(
try {
apduInterface.connect()
contextHandle = LpacJni.createContext(apduInterface, httpInterface)
check(LpacJni.es10xInit(contextHandle) >= 0) { "Reconnect attempt failed" }
check(LpacJni.euiccInit(contextHandle) >= 0) { "Reconnect attempt failed" }
// Validate that we can actually use the APDU channel by trying to read eID and profiles
check(valid) { "Reconnected channel is invalid" }
break
@ -59,7 +59,7 @@ class LocalProfileAssistantImpl(
e.printStackTrace()
if (contextHandle != -1L) {
try {
LpacJni.es10xFini(contextHandle)
LpacJni.euiccFini(contextHandle)
LpacJni.destroyContext(contextHandle)
contextHandle = -1
} catch (e: Exception) {
@ -133,7 +133,7 @@ class LocalProfileAssistantImpl(
}
override fun close() {
LpacJni.es10xFini(contextHandle)
LpacJni.euiccFini(contextHandle)
LpacJni.destroyContext(contextHandle)
}
}

@ -1 +1 @@
Subproject commit c9180539164521d491e63395b25538b80ad8b883
Subproject commit d06a2a0e1f9bd29d86bc4f0881a84f67cd708aa3

View file

@ -42,13 +42,13 @@ Java_net_typeblog_lpac_1jni_LpacJni_downloadProfile(JNIEnv *env, jobject thiz, j
jstring imei, jstring confirmation_code,
jobject callback) {
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
struct es9p_get_bound_profile_package_resp es9p_get_bound_profile_package_resp;
struct es9p_initiate_authentication_resp es9p_initiate_authentication_resp;
struct es9p_ctx es9p_ctx = { 0 };
struct es10b_load_bound_profile_package_result es10b_load_bound_profile_package_result;
struct es10b_authenticate_server_param es10b_authenticate_server_param;
struct es9p_authenticate_client_resp es9p_authenticate_client_resp;
struct es10b_prepare_download_param es10b_prepare_download_param;
char *b64_authenticate_server_response = NULL;
char *b64_prepare_download_response = NULL;
char *b64_bound_profile_package = NULL;
char *b64_euicc_challenge = NULL;
char *b64_euicc_info_1 = NULL;
char *transaction_id = NULL;
@ -66,6 +66,9 @@ Java_net_typeblog_lpac_1jni_LpacJni_downloadProfile(JNIEnv *env, jobject thiz, j
if (imei != NULL)
_imei = (*env)->GetStringUTFChars(env, imei, NULL);
es9p_ctx.euicc_ctx = ctx;
es9p_ctx.address = _smdp;
(*env)->CallVoidMethod(env, callback, on_state_update, download_state_preparing);
ret = es10b_get_euicc_challenge(ctx, &b64_euicc_challenge);
if (ret < 0)
@ -76,45 +79,36 @@ Java_net_typeblog_lpac_1jni_LpacJni_downloadProfile(JNIEnv *env, jobject thiz, j
goto out;
(*env)->CallVoidMethod(env, callback, on_state_update, download_state_connecting);
ret = es9p_initiate_authentication(ctx, _smdp, b64_euicc_challenge, b64_euicc_info_1, &es9p_initiate_authentication_resp);
ret = es9p_initiate_authentication(&es9p_ctx, &es10b_authenticate_server_param, b64_euicc_challenge, b64_euicc_info_1);
if (ret < 0)
goto out;
transaction_id = strdup(es9p_initiate_authentication_resp.transaction_id);
es10b_authenticate_server_param.b64_server_signed_1 = es9p_initiate_authentication_resp.b64_server_signed_1;
es10b_authenticate_server_param.b64_server_signature_1 = es9p_initiate_authentication_resp.b64_server_signature_1;
es10b_authenticate_server_param.b64_euicc_ci_pkid_to_be_used = es9p_initiate_authentication_resp.b64_euicc_ci_pkid_to_be_used;
es10b_authenticate_server_param.b64_server_certificate = es9p_initiate_authentication_resp.b64_server_certificate;
es10b_authenticate_server_param.matchingId = _matching_id;
es10b_authenticate_server_param.imei = _imei;
es10b_authenticate_server_param.tac = NULL;
(*env)->CallVoidMethod(env, callback, on_state_update, download_state_authenticating);
ret = es10b_authenticate_server(ctx, &b64_authenticate_server_response, &es10b_authenticate_server_param);
if (ret < 0)
goto out;
ret = es9p_authenticate_client(ctx, _smdp, transaction_id, b64_authenticate_server_response, &es9p_authenticate_client_resp);
ret = es9p_authenticate_client(&es9p_ctx, &es10b_prepare_download_param, b64_authenticate_server_response);
if (ret < 0)
goto out;
es10b_prepare_download_param.b64_smdp_signed_2 = es9p_authenticate_client_resp.b64_smdp_signed_2;
es10b_prepare_download_param.b64_smdp_signature_2 = es9p_authenticate_client_resp.b64_smdp_signature_2;
es10b_prepare_download_param.b64_smdp_certificate = es9p_authenticate_client_resp.b64_smdp_certificate;
es10b_prepare_download_param.hexstr_transcation_id = transaction_id;
es10b_prepare_download_param.str_checkcode = _confirmation_code;
es10b_prepare_download_param.confirmationCode = _confirmation_code;
(*env)->CallVoidMethod(env, callback, on_state_update, download_state_downloading);
ret = es10b_prepare_download(ctx, &b64_prepare_download_response, &es10b_prepare_download_param);
if (ret < 0)
goto out;
ret = es9p_get_bound_profile_package(ctx, _smdp, transaction_id, b64_prepare_download_response, &es9p_get_bound_profile_package_resp);
ret = es9p_get_bound_profile_package(&es9p_ctx, &b64_bound_profile_package, b64_prepare_download_response);
if (ret < 0)
goto out;
(*env)->CallVoidMethod(env, callback, on_state_update, download_state_finalizing);
ret = es10b_load_bound_profile_package(ctx, es9p_get_bound_profile_package_resp.b64_bpp);
// TODO: Expose error code as Java-side exceptions?
ret = es10b_load_bound_profile_package(ctx, &es10b_load_bound_profile_package_result, b64_bound_profile_package);
out:
free(b64_authenticate_server_response);

View file

@ -1,4 +1,6 @@
#include <euicc/es10x.h>
#include <euicc/euicc.h>
#include <euicc/es10c.h>
#include <euicc/es10c_ex.h>
#include <euicc/interface.h>
#include <malloc.h>
#include <string.h>
@ -93,15 +95,15 @@ Java_net_typeblog_lpac_1jni_LpacJni_destroyContext(JNIEnv *env, jobject thiz, jl
}
JNIEXPORT jint JNICALL
Java_net_typeblog_lpac_1jni_LpacJni_es10xInit(JNIEnv *env, jobject thiz, jlong handle) {
Java_net_typeblog_lpac_1jni_LpacJni_euiccInit(JNIEnv *env, jobject thiz, jlong handle) {
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
return es10x_init(ctx);
return euicc_init(ctx);
}
JNIEXPORT void JNICALL
Java_net_typeblog_lpac_1jni_LpacJni_es10xFini(JNIEnv *env, jobject thiz, jlong handle) {
Java_net_typeblog_lpac_1jni_LpacJni_euiccFini(JNIEnv *env, jobject thiz, jlong handle) {
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
es10x_fini(ctx);
euicc_fini(ctx);
}
jstring toJString(JNIEnv *env, const char *pat) {
@ -137,7 +139,9 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10cGetEid(JNIEnv *env, jobject thiz, jlong
return ret;
}
jobject profile_info_native_to_java(JNIEnv *env, struct es10c_profile_info *info) {
jobject profile_info_native_to_java(JNIEnv *env, struct es10c_profile_info_list *info) {
const char *profileStateStr = NULL;
const char *profileClassStr = NULL;
jstring serviceProvider = NULL;
jstring nickName = NULL;
jstring isdpAid = NULL;
@ -153,13 +157,40 @@ jobject profile_info_native_to_java(JNIEnv *env, struct es10c_profile_info *info
nickName = toJString(env, info->profileNickname);
serviceProvider = toJString(env, info->serviceProviderName);
// TODO: Maybe we should pass a Java object directly here?
switch (info->profileState) {
case ES10C_PROFILE_STATE_ENABLED:
profileStateStr = "enabled";
break;
case ES10C_PROFILE_STATE_DISABLED:
profileStateStr = "disabled";
break;
default:
profileStateStr = "unknown";
}
state = (*env)->CallStaticObjectMethod(env, local_profile_state_class,
local_profile_state_from_string,
toJString(env, info->profileState));
toJString(env, profileStateStr));
switch (info->profileClass) {
case ES10C_PROFILE_CLASS_TEST:
profileClassStr = "test";
break;
case ES10C_PROFILE_CLASS_PROVISIONING:
profileClassStr = "provisioning";
break;
case ES10C_PROFILE_CLASS_OPERATIONAL:
profileClassStr = "operational";
break;
default:
profileClassStr = "unknown";
break;
}
class = (*env)->CallStaticObjectMethod(env, local_profile_class_class,
local_profile_class_from_string,
toJString(env, info->profileClass));
toJString(env, profileClassStr));
jinfo = (*env)->NewObject(env, local_profile_info_class, local_profile_info_constructor,
iccid, state, name, nickName, serviceProvider, isdpAid, class);
@ -178,8 +209,8 @@ jobject profile_info_native_to_java(JNIEnv *env, struct es10c_profile_info *info
JNIEXPORT jobjectArray JNICALL
Java_net_typeblog_lpac_1jni_LpacJni_es10cGetProfilesInfo(JNIEnv *env, jobject thiz, jlong handle) {
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
struct es10c_profile_info *info = NULL;
struct es10c_profile_info *curr = NULL;
struct es10c_profile_info_list *info = NULL;
struct es10c_profile_info_list *curr = NULL;
jobjectArray ret = NULL;
jobject jinfo = NULL;
int count = 0;
@ -211,7 +242,7 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10cEnableProfile(JNIEnv *env, jobject thiz
int ret;
_iccid = (*env)->GetStringUTFChars(env, iccid, NULL);
ret = es10c_enable_profile_iccid(ctx, _iccid, 1);
ret = es10c_enable_profile(ctx, _iccid, 1);
(*env)->ReleaseStringUTFChars(env, iccid, _iccid);
return ret;
}
@ -224,7 +255,7 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10cDisableProfile(JNIEnv *env, jobject thi
int ret;
_iccid = (*env)->GetStringUTFChars(env, iccid, NULL);
ret = es10c_disable_profile_iccid(ctx, _iccid, 1);
ret = es10c_disable_profile(ctx, _iccid, 1);
(*env)->ReleaseStringUTFChars(env, iccid, _iccid);
return ret;
}
@ -253,7 +284,7 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10cDeleteProfile(JNIEnv *env, jobject thiz
int ret;
_iccid = (*env)->GetStringUTFChars(env, iccid, NULL);
ret = es10c_delete_profile_iccid(ctx, _iccid);
ret = es10c_delete_profile(ctx, _iccid);
(*env)->ReleaseStringUTFChars(env, iccid, _iccid);
return ret;
}
@ -261,7 +292,7 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10cDeleteProfile(JNIEnv *env, jobject thiz
JNIEXPORT jobject JNICALL
Java_net_typeblog_lpac_1jni_LpacJni_es10cexGetEuiccInfo2(JNIEnv *env, jobject thiz, jlong handle) {
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
struct es10cex_euiccinfo2 * info;
struct es10c_ex_euiccinfo2 info = { 0 };
jobjectArray euiccCiPKIdListForVerification = NULL;
jobjectArray euiccCiPKIdListForSigning = NULL;
jstring sas_accreditation_number = NULL;
@ -273,24 +304,24 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10cexGetEuiccInfo2(JNIEnv *env, jobject th
char **curr = NULL;
int count = 0;
if (es10cex_get_euiccinfo2(ctx, &info) < 0)
if (es10c_ex_get_euiccinfo2(ctx, &info) < 0)
goto out;
profile_version = toJString(env, info->profileVersion);
euicc_firmware_version = toJString(env, info->euiccFirmwareVer);
global_platform_version = toJString(env, info->globalplatformVersion);
sas_accreditation_number = toJString(env, info->sasAcreditationNumber);
pp_version = toJString(env, info->ppVersion);
profile_version = toJString(env, info.profileVersion);
euicc_firmware_version = toJString(env, info.euiccFirmwareVer);
global_platform_version = toJString(env, info.globalplatformVersion);
sas_accreditation_number = toJString(env, info.sasAcreditationNumber);
pp_version = toJString(env, info.ppVersion);
count = LPAC_JNI_NULL_TERM_LIST_COUNT(info->euiccCiPKIdListForSigning, curr);
count = LPAC_JNI_NULL_TERM_LIST_COUNT(info.euiccCiPKIdListForSigning, curr);
euiccCiPKIdListForSigning = (*env)->NewObjectArray(env, count, string_class, NULL);
LPAC_JNI_NULL_TERM_LIST_FOREACH(info->euiccCiPKIdListForSigning, curr, {
LPAC_JNI_NULL_TERM_LIST_FOREACH(info.euiccCiPKIdListForSigning, curr, {
(*env)->SetObjectArrayElement(env, euiccCiPKIdListForSigning, i, toJString(env, *curr));
});
count = LPAC_JNI_NULL_TERM_LIST_COUNT(info->euiccCiPKIdListForVerification, curr);
count = LPAC_JNI_NULL_TERM_LIST_COUNT(info.euiccCiPKIdListForVerification, curr);
euiccCiPKIdListForVerification = (*env)->NewObjectArray(env, count, string_class, NULL);
LPAC_JNI_NULL_TERM_LIST_FOREACH(info->euiccCiPKIdListForVerification, curr, {
LPAC_JNI_NULL_TERM_LIST_FOREACH(info.euiccCiPKIdListForVerification, curr, {
(*env)->SetObjectArrayElement(env, euiccCiPKIdListForVerification, i, toJString(env, *curr));
});
@ -298,8 +329,8 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10cexGetEuiccInfo2(JNIEnv *env, jobject th
profile_version, euicc_firmware_version,
global_platform_version,
sas_accreditation_number, pp_version,
info->extCardResource.freeNonVolatileMemory,
info->extCardResource.freeVolatileMemory,
info.extCardResource.freeNonVolatileMemory,
info.extCardResource.freeVolatileMemory,
euiccCiPKIdListForSigning,
euiccCiPKIdListForVerification);
@ -309,7 +340,6 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10cexGetEuiccInfo2(JNIEnv *env, jobject th
(*env)->DeleteLocalRef(env, global_platform_version);
(*env)->DeleteLocalRef(env, sas_accreditation_number);
(*env)->DeleteLocalRef(env, pp_version);
if (info != NULL)
es10cex_free_euiccinfo2(info);
es10c_ex_euiccinfo2_free(&info);
return ret;
}

View file

@ -33,8 +33,9 @@ void lpac_notifications_init() {
JNIEXPORT jobject JNICALL
Java_net_typeblog_lpac_1jni_LpacJni_es10bListNotification(JNIEnv *env, jobject thiz, jlong handle) {
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
struct es10b_notification_metadata *info = NULL;
struct es10b_notification_metadata *curr = NULL;
struct es10b_notification_metadata_list *info = NULL;
struct es10b_notification_metadata_list *curr = NULL;
const char *profileManagementOperationStr = NULL;
jobject notification = NULL;
jobject operation = NULL;
jobjectArray ret = NULL;
@ -48,10 +49,27 @@ Java_net_typeblog_lpac_1jni_LpacJni_es10bListNotification(JNIEnv *env, jobject t
ret = (*env)->NewObjectArray(env, count, local_profile_notification_class, NULL);
LPAC_JNI_LINKED_LIST_FOREACH(info, curr, {
switch (curr->profileManagementOperation) {
case ES10B_PROFILE_MANAGEMENT_OPERATION_INSTALL:
profileManagementOperationStr = "install";
break;
case ES10B_PROFILE_MANAGEMENT_OPERATION_DELETE:
profileManagementOperationStr = "delete";
break;
case ES10B_PROFILE_MANAGEMENT_OPERATION_ENABLE:
profileManagementOperationStr = "enable";
break;
case ES10B_PROFILE_MANAGEMENT_OPERATION_DISABLE:
profileManagementOperationStr = "disable";
break;
default:
profileManagementOperationStr = "unknown";
}
operation =
(*env)->CallStaticObjectMethod(env, local_profile_notification_operation_class,
local_profile_notification_operation_from_string,
toJString(env, curr->profileManagementOperation));
toJString(env, profileManagementOperationStr));
notification =
(*env)->NewObject(env, local_profile_notification_class,
@ -73,15 +91,19 @@ JNIEXPORT jint JNICALL
Java_net_typeblog_lpac_1jni_LpacJni_handleNotification(JNIEnv *env, jobject thiz, jlong handle,
jlong seq_number) {
struct euicc_ctx *ctx = (struct euicc_ctx *) handle;
struct es10b_notification notification;
struct es9p_ctx es9p_ctx = { 0 };
struct es10b_pending_notification notification;
int res;
res = es10b_retrieve_notification(ctx, &notification, (unsigned long) seq_number);
res = es10b_retrieve_notifications_list(ctx, &notification, (unsigned long) seq_number);
syslog(LOG_DEBUG, "es10b_retrieve_notification = %d", res);
if (res < 0)
goto out;
res = es9p_handle_notification(ctx, notification.receiver, notification.b64_payload);
es9p_ctx.euicc_ctx = ctx;
es9p_ctx.address = notification.notificationAddress;
res = es9p_handle_notification(&es9p_ctx, notification.b64_PendingNotification);
syslog(LOG_DEBUG, "es9p_handle_notification = %d", res);
if (res < 0)
goto out;