Compare commits

...

2 commits

Author SHA1 Message Date
936444f162 Handle APDU responses with stripped status code better
This is still pretty hacky. Ideally we should return structured data (at
least separate the status code from the payload, or better, just do
everything in binary) from ApduTransmitter / ApduChannel.
2022-05-19 22:38:57 -04:00
cbe3fd1458 Fix matchingId encoding when authenticating server to eUICC
Because the library uses hex-encoded string internally for all APDU
commands, the matchingId itself also needs to be encoded. This is done
by `setMatchingId` and we should also use that when generating
CtxParams1 ourselves.
2022-05-19 22:30:58 -04:00
4 changed files with 21 additions and 33 deletions

View file

@ -74,7 +74,6 @@ internal class DownloadProfileWorker(
)
authenticatingPhaseWorker.initiateAuthentication(
initialAuthenticationKeys,
matchingId,
imei
)
downloadAndInstallProfilePackage(

View file

@ -39,6 +39,10 @@ class ApduTransmitter(private val apduChannel: ApduChannel) {
)
}
if (apduResponse.length < 4) {
throw RuntimeException("APDU response should at least contain a status code")
}
// Last 2 bytes are the status code (should be 0x9000)
// TODO: Do this properly
return apduResponse.substring(0, apduResponse.length - 4)
@ -57,6 +61,10 @@ class ApduTransmitter(private val apduChannel: ApduChannel) {
)
}
if (apduResponse.length < 4) {
throw RuntimeException("APDU response should at least contain a status code")
}
// Last 2 bytes are the status code (should be 0x9000)
// TODO: Do this properly
return apduResponse.substring(0, apduResponse.length - 4)

View file

@ -125,7 +125,7 @@ public class AuthenticatingPhaseWorker {
}
}
public void initiateAuthentication(InitialAuthenticationKeys initialAuthenticationKeys, String matchingId, String imei) {
public void initiateAuthentication(InitialAuthenticationKeys initialAuthenticationKeys, String imei) {
progress.stepExecuted(DOWNLOAD_PROFILE_INITIATE_AUTHENTICATION, "initiateAuthentication retrieving...");
@ -141,14 +141,14 @@ public class AuthenticatingPhaseWorker {
setServerCertificate(initialAuthenticationKeys, initiateAuthenticationResp);
setTransactionId(initialAuthenticationKeys, initiateAuthenticationResp);
setMatchingId(initialAuthenticationKeys);
setCtxParams1(initialAuthenticationKeys, matchingId, imei);
setCtxParams1(initialAuthenticationKeys, imei);
progress.stepExecuted(DOWNLOAD_PROFILE_INITIATED_AUTHENTICATION, "initiateAuthentication initiated...");
}
private void setCtxParams1(InitialAuthenticationKeys initialAuthenticationKeys, String matchingId, String imei) {
private void setCtxParams1(InitialAuthenticationKeys initialAuthenticationKeys, String imei) {
initialAuthenticationKeys.setCtxParams1(ApduUtils.generateCtxParams1(matchingId, imei));
initialAuthenticationKeys.setCtxParams1(ApduUtils.generateCtxParams1(initialAuthenticationKeys.getMatchingId(), imei));
if (LogStub.getInstance().isDebugEnabled()) {
LogStub.getInstance().logDebug(LOG, LogStub.getInstance().getTag() + " - ctxParams1: " + initialAuthenticationKeys.getCtxParams1());

View file

@ -98,10 +98,8 @@ public class InstallationPhaseWorker {
String profileInstallationResult = apduTransmitter.transmitApdus(sbpp);
if (StringUtils.isNotBlank(profileInstallationResult) && profileInstallationResult.length() > 4) {
if (StringUtils.isNotBlank(profileInstallationResult)) {
checkProfileInstallationResult(profileInstallationResult);
} else {
throw new RuntimeException("Unexpected response on loadBoundProfilePackage");
}
}
@ -112,12 +110,8 @@ public class InstallationPhaseWorker {
String profileInstallationResult = apduTransmitter.transmitApdus(sbpp);
if (profileInstallationResult.compareTo("9000") != 0) {
if (StringUtils.isNotBlank(profileInstallationResult) && profileInstallationResult.length() > 4) {
if (StringUtils.isNotBlank(profileInstallationResult)) {
checkProfileInstallationResult(profileInstallationResult);
} else {
throw new RuntimeException("Unexpected response on loadStoreMetadata");
}
}
}
@ -128,12 +122,8 @@ public class InstallationPhaseWorker {
String profileInstallationResult = apduTransmitter.transmitApdus(sbpp);
if (profileInstallationResult.compareTo("9000") != 0) {
if (StringUtils.isNotBlank(profileInstallationResult) && profileInstallationResult.length() > 4) {
if (StringUtils.isNotBlank(profileInstallationResult)) {
checkProfileInstallationResult(profileInstallationResult);
} else {
throw new RuntimeException("Unexpected response on loadConfigureIsdpa");
}
}
}
@ -144,12 +134,8 @@ public class InstallationPhaseWorker {
String profileInstallationResult = apduTransmitter.transmitApdus(sbpp);
if (profileInstallationResult.compareTo("9000") != 0) {
if (StringUtils.isNotBlank(profileInstallationResult) && profileInstallationResult.length() > 4) {
if (StringUtils.isNotBlank(profileInstallationResult)) {
checkProfileInstallationResult(profileInstallationResult);
} else {
throw new RuntimeException("Unexpected response on loadInitialiseSecureChannel");
}
}
}
@ -237,13 +223,8 @@ public class InstallationPhaseWorker {
"loadReplaceSessionsKeys...");
String profileInstallationResult = apduTransmitter.transmitApdus(sbpp);
if (profileInstallationResult.compareTo("9000") != 0) {
if (StringUtils.isNotBlank(profileInstallationResult) && profileInstallationResult.length() > 4) {
if (StringUtils.isNotBlank(profileInstallationResult)) {
checkProfileInstallationResult(profileInstallationResult);
} else {
throw new RuntimeException("Unexpected response on loadReplaceSessionsKeys");
}
}
}
}