use of android.telephony.UiccAccessRule in project android_frameworks_opt_telephony by LineageOS.
the class UiccCarrierPrivilegeRules method handleMessage.
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
switch(msg.what) {
case EVENT_OPEN_LOGICAL_CHANNEL_DONE:
log("EVENT_OPEN_LOGICAL_CHANNEL_DONE");
ar = (AsyncResult) msg.obj;
if (ar.exception == null && ar.result != null) {
mChannelId = ((int[]) ar.result)[0];
mUiccCard.iccTransmitApduLogicalChannel(mChannelId, CLA, COMMAND, P1, P2, P3, DATA, obtainMessage(EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE, mChannelId));
} else {
// so we retry up to MAX_RETRY times, with an interval of RETRY_INTERVAL_MS.
if (ar.exception instanceof CommandException && mRetryCount < MAX_RETRY && ((CommandException) (ar.exception)).getCommandError() == CommandException.Error.MISSING_RESOURCE) {
mRetryCount++;
removeCallbacks(mRetryRunnable);
postDelayed(mRetryRunnable, RETRY_INTERVAL_MS);
} else {
// if rules cannot be read from ARA applet,
// fallback to PKCS15-based ARF.
log("No ARA, try ARF next.");
mUiccPkcs15 = new UiccPkcs15(mUiccCard, obtainMessage(EVENT_PKCS15_READ_DONE));
}
}
break;
case EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE:
log("EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE");
ar = (AsyncResult) msg.obj;
if (ar.exception == null && ar.result != null) {
IccIoResult response = (IccIoResult) ar.result;
if (response.sw1 == 0x90 && response.sw2 == 0x00 && response.payload != null && response.payload.length > 0) {
try {
mRules += IccUtils.bytesToHexString(response.payload).toUpperCase(Locale.US);
if (isDataComplete()) {
mAccessRules = parseRules(mRules);
updateState(STATE_LOADED, "Success!");
} else {
mUiccCard.iccTransmitApduLogicalChannel(mChannelId, CLA, COMMAND, P1, P2_EXTENDED_DATA, P3, DATA, obtainMessage(EVENT_TRANSMIT_LOGICAL_CHANNEL_DONE, mChannelId));
break;
}
} catch (IllegalArgumentException | IndexOutOfBoundsException ex) {
updateState(STATE_ERROR, "Error parsing rules: " + ex);
}
} else {
String errorMsg = "Invalid response: payload=" + response.payload + " sw1=" + response.sw1 + " sw2=" + response.sw2;
updateState(STATE_ERROR, errorMsg);
}
} else {
updateState(STATE_ERROR, "Error reading value from SIM.");
}
mUiccCard.iccCloseLogicalChannel(mChannelId, obtainMessage(EVENT_CLOSE_LOGICAL_CHANNEL_DONE));
mChannelId = -1;
break;
case EVENT_CLOSE_LOGICAL_CHANNEL_DONE:
log("EVENT_CLOSE_LOGICAL_CHANNEL_DONE");
break;
case EVENT_PKCS15_READ_DONE:
log("EVENT_PKCS15_READ_DONE");
if (mUiccPkcs15 == null || mUiccPkcs15.getRules() == null) {
updateState(STATE_ERROR, "No ARA or ARF.");
} else {
for (String cert : mUiccPkcs15.getRules()) {
UiccAccessRule accessRule = new UiccAccessRule(IccUtils.hexStringToBytes(cert), "", 0x00);
mAccessRules.add(accessRule);
}
updateState(STATE_LOADED, "Success!");
}
break;
default:
Rlog.e(LOG_TAG, "Unknown event " + msg.what);
}
}
use of android.telephony.UiccAccessRule in project android_frameworks_opt_telephony by LineageOS.
the class UiccCarrierPrivilegeRules method dump.
/**
* Dumps info to Dumpsys - useful for debugging.
*/
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("UiccCarrierPrivilegeRules: " + this);
pw.println(" mState=" + getStateString(mState.get()));
pw.println(" mStatusMessage='" + mStatusMessage + "'");
if (mAccessRules != null) {
pw.println(" mAccessRules: ");
for (UiccAccessRule ar : mAccessRules) {
pw.println(" rule='" + ar + "'");
}
} else {
pw.println(" mAccessRules: null");
}
if (mUiccPkcs15 != null) {
pw.println(" mUiccPkcs15: " + mUiccPkcs15);
mUiccPkcs15.dump(fd, pw, args);
} else {
pw.println(" mUiccPkcs15: null");
}
pw.flush();
}
use of android.telephony.UiccAccessRule in project android_frameworks_opt_telephony by LineageOS.
the class UiccCarrierPrivilegeRules method parseRefArdo.
/*
* Parses a single rule.
*/
private static UiccAccessRule parseRefArdo(String rule) {
log("Got rule: " + rule);
String certificateHash = null;
String packageName = null;
String tmp = null;
long accessType = 0;
while (!rule.isEmpty()) {
if (rule.startsWith(TAG_REF_DO)) {
// E1
TLV refDo = new TLV(TAG_REF_DO);
rule = refDo.parse(rule, false);
// Allow 4F tag with a default value "FF FF FF FF FF FF" to be compatible with
// devices having GP access control enforcer:
// - If no 4F tag is present, it's a CP rule.
// - If 4F tag has value "FF FF FF FF FF FF", it's a CP rule.
// - If 4F tag has other values, it's not a CP rule and Android should ignore it.
// C1
TLV deviceDo = new TLV(TAG_DEVICE_APP_ID_REF_DO);
if (refDo.value.startsWith(TAG_AID_REF_DO)) {
// 4F
TLV cpDo = new TLV(TAG_AID_REF_DO);
String remain = cpDo.parse(refDo.value, false);
if (!cpDo.lengthBytes.equals("06") || !cpDo.value.equals(CARRIER_PRIVILEGE_AID) || remain.isEmpty() || !remain.startsWith(TAG_DEVICE_APP_ID_REF_DO)) {
return null;
}
tmp = deviceDo.parse(remain, false);
certificateHash = deviceDo.value;
} else if (refDo.value.startsWith(TAG_DEVICE_APP_ID_REF_DO)) {
tmp = deviceDo.parse(refDo.value, false);
certificateHash = deviceDo.value;
} else {
return null;
}
if (!tmp.isEmpty()) {
if (!tmp.startsWith(TAG_PKG_REF_DO)) {
return null;
}
// CA
TLV pkgDo = new TLV(TAG_PKG_REF_DO);
pkgDo.parse(tmp, true);
packageName = new String(IccUtils.hexStringToBytes(pkgDo.value));
} else {
packageName = null;
}
} else if (rule.startsWith(TAG_AR_DO)) {
// E3
TLV arDo = new TLV(TAG_AR_DO);
rule = arDo.parse(rule, false);
// Skip all the irrelevant tags (All the optional tags here are two bytes
// according to the spec GlobalPlatform Secure Element Access Control).
String remain = arDo.value;
while (!remain.isEmpty() && !remain.startsWith(TAG_PERM_AR_DO)) {
TLV tmpDo = new TLV(remain.substring(0, 2));
remain = tmpDo.parse(remain, false);
}
if (remain.isEmpty()) {
return null;
}
// DB
TLV permDo = new TLV(TAG_PERM_AR_DO);
permDo.parse(remain, true);
} else {
// Spec requires it must be either TAG_REF_DO or TAG_AR_DO.
throw new RuntimeException("Invalid Rule type");
}
}
UiccAccessRule accessRule = new UiccAccessRule(IccUtils.hexStringToBytes(certificateHash), packageName, accessType);
return accessRule;
}
use of android.telephony.UiccAccessRule in project android_frameworks_opt_telephony by LineageOS.
the class UiccCarrierPrivilegeRules method parseRules.
/*
* Parses the rules from the input string.
*/
private static List<UiccAccessRule> parseRules(String rules) {
log("Got rules: " + rules);
// FF40
TLV allRefArDo = new TLV(TAG_ALL_REF_AR_DO);
allRefArDo.parse(rules, true);
String arDos = allRefArDo.value;
List<UiccAccessRule> accessRules = new ArrayList<>();
while (!arDos.isEmpty()) {
// E2
TLV refArDo = new TLV(TAG_REF_AR_DO);
arDos = refArDo.parse(arDos, false);
UiccAccessRule accessRule = parseRefArdo(refArDo.value);
if (accessRule != null) {
accessRules.add(accessRule);
} else {
Rlog.e(LOG_TAG, "Skip unrecognized rule." + refArDo.value);
}
}
return accessRules;
}
use of android.telephony.UiccAccessRule in project android_frameworks_opt_telephony by LineageOS.
the class EuiccControllerTest method prepareOperationSubscription.
private void prepareOperationSubscription(boolean hasPrivileges) throws Exception {
SubscriptionInfo subInfo = new SubscriptionInfo(SUBSCRIPTION_ID, ICC_ID, 0, "", "", 0, 0, "", 0, null, 0, 0, "", true, /* isEmbedded */
hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null);
when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(Collections.singletonList(subInfo));
}
Aggregations