Android 5.1 引入了一种机制,用于为与通用集成电路卡 (UICC) 应用所有者相关的 API 授予特殊权限。Android 平台会加载存储在 UICC 上的证书,并向由这些证书签名的应用授予权限,使其能够调用少量特殊 API。
Android 7.0 扩展了此功能,以支持 UICC 运营商权限规则的其他存储源,从而大大增加了可以使用 API 的运营商数量。如需 API 参考,请参阅 CarrierConfigManager;如需说明,请参阅运营商配置。
运营商可以完全控制 UICC,因此这种机制提供了一种安全灵活的方式来管理来自移动网络运营商 (MNO) 的应用(托管在通用应用分发渠道(例如 Google Play)上),同时保留设备上的特殊权限,而无需使用按设备平台证书对应用进行签名或作为系统应用预安装。
UICC 上的规则
UICC 上的存储空间与 GlobalPlatform 安全元件访问控制规范兼容。卡上的应用标识符 (AID) 为 A00000015141434C00
,标准 GET DATA
命令用于获取存储在卡上的规则。您可以通过卡空中下载 (OTA) 更新来更新这些规则。
数据层级结构
UICC 规则使用以下数据层级结构(括号中的两位字母和数字组合是对象标记)。每条规则都是 REF-AR-DO
(E2
),由 REF-DO
和 AR-DO
的串联组成
REF-DO
(E1
) 包含DeviceAppID-REF-DO
或DeviceAppID-REF-DO
和PKG-REF-DO
的串联。DeviceAppID-REF-DO
(C1
) 存储证书的 SHA-1(20 字节)或 SHA-256(32 字节)签名。PKG-REF-DO
(CA
) 是清单中定义的完整软件包名称字符串,采用 ASCII 编码,最大长度为 127 字节。
AR-DO
(E3
) 扩展为包含PERM-AR-DO
(DB
),后者是一个 8 字节的位掩码,表示 64 个不同的权限。
如果不存在 PKG-REF-DO
,则会向任何由该证书签名的应用授予访问权限;否则,证书和软件包名称都需要匹配。
规则示例
应用名称为 com.google.android.apps.myapp
,十六进制字符串格式的 SHA-1 证书为
AB:CD:92:CB:B1:56:B2:80:FA:4E:14:29:A6:EC:EE:B6:E5:C1:BF:E4
UICC 上的十六进制字符串格式的规则为
E243 <= 43 is value length in hex E135 C114 ABCD92CBB156B280FA4E1429A6ECEEB6E5C1BFE4 CA1D 636F6D2E676F6F676C652E616E64726F69642E617070732E6D79617070 E30A DB08 0000000000000001
访问规则文件支持
Android 7.0 添加了对从访问规则文件 (ARF) 读取运营商权限规则的支持。
Android 平台首先尝试选择访问规则应用程序 (ARA) AID A00000015141434C00
。如果在 UICC 上找不到该 AID,则会回退到 ARF,选择 PKCS15 AID A000000063504B43532D3135
。然后,Android 会读取地址 0x4300
处的访问控制规则文件 (ACRF),并查找 AID 为 FFFFFFFFFFFF
的条目。系统会忽略具有不同 AID 的条目,因此其他用例的规则可以共存。
ACRF 内容示例(十六进制字符串格式)
30 10 A0 08 04 06 FF FF FF FF FF FF 30 04 04 02 43 10
访问控制条件文件 (ACCF) 内容示例
30 16 04 14 61 ED 37 7E 85 D3 86 A8 DF EE 6B 86 4B D8 5B 0B FA A5 AF 81
在上面的示例中,0x4310
是 ACCF 的地址,其中包含证书哈希值 61:ED:37:7E:85:D3:86:A8:DF:EE:6B:86:4B:D8:5B:0B:FA:A5:AF:81
。由该证书签名的应用将被授予运营商权限。
已启用的 API
Android 支持以下 API。
TelephonyManager
- 允许运营商应用向 UICC 请求质询/响应的方法:
getIccAuthentication
。 - 检查调用应用是否已被授予运营商权限的方法:
hasCarrierPrivileges
。 - 用于替换品牌和号码的方法
- 用于直接 UICC 通信的方法
- 将设备模式设置为全局模式的方法:
setPreferredNetworkTypeToGlobal
。 - 用于获取设备或网络标识的方法
- 国际移动设备识别码 (IMEI):
getImei
- 移动设备标识符 (MEID):
getMeid
- 网络接入标识符 (NAI):
getNai
- SIM 卡序列号:
getSimSerialNumber
- 国际移动设备识别码 (IMEI):
- 获取运营商配置的方法:
getCarrierConfig
- 获取数据传输网络类型的方法:
getDataNetworkType
- 获取语音服务网络类型的方法:
getVoiceNetworkType
- 用于获取有关 UICC SIM (USIM) 应用信息的方法
- SIM 卡序列号:
getSimSerialNumber
- 卡信息:
getUiccCardsInfo
- GID1(组 ID 级别 1):
getGroupIdLevel1
- 线路 1 的电话号码字符串:
getLine1Number
- 禁止的公共陆地移动网络 (PLMN):
getForbiddenPlmns
- 等效的归属 PLMN:
getEquivalentHomePlmns
- SIM 卡序列号:
- 用于获取或设置语音信箱号码的方法
- 发送特殊拨号器代码的方法:
sendDialerSpecialCode
- 重置无线调制解调器的方法:
rebootModem
- 用于获取或设置网络选择模式的方法
- 请求网络扫描的方法:
requestNetworkScan
- 用于获取或设置允许/首选网络类型的方法
- 用于检查是否已根据用户设置启用移动数据或漫游的方法
- 用于检查或设置具有原因的数据连接的方法
- 获取紧急号码列表的方法:
getEmergencyNumberList
- 用于控制机会网络的方法
- 用于设置或清除蜂窝信号强度更新请求的方法
TelephonyCallback
TelephonyCallback
具有一些接口,这些接口包含一个回调方法,用于在注册状态更改时通知调用应用
- 消息等待指示符已更改:
onMessageWaitingIndicatorChanged
- 呼叫转移指示符已更改:
onCallForwardingIndicatorChanged
- IP 多媒体子系统 (IMS) 呼叫断开连接原因已更改:
onImsCallDisconnectCauseChanged
- 精确数据连接状态已更改:
onPreciseDataConnectionStateChanged
- 当前紧急号码列表已更改:
onEmergencyNumberListChanged
- 活动数据订阅 ID 已更改:
onActiveDataSubscriptionIdChanged
- 运营商网络已更改:
onCarrierNetworkChange
- 网络注册或位置/路由/跟踪区域更新失败:
onRegistrationFailed
- 阻止信息更改:
onBarringInfoChanged
- 当前物理信道配置已更改:
onPhysicalChannelConfigChanged
SubscriptionManager
- 用于获取各种订阅信息的方法
- 获取活动订阅数的方法:
getActiveSubscriptionInfoCount
- 用于管理订阅组的方法
- 用于获取或设置运营商与特定订阅者之间计费关系计划描述的方法
- 临时替换运营商与特定订阅者之间的计费关系计划以视为不限量的方法:
setSubscriptionOverrideUnmetered
- 临时替换运营商与特定订阅者之间的计费关系计划以视为拥塞的方法:
setSubscriptionOverrideCongested
- 检查具有给定上下文的应用是否有权根据其元数据管理给定订阅的方法:
canManageSubscription
SmsManager
- 允许调用方创建新的传入 SMS 消息的方法:
injectSmsPdu
。 - 发送基于文本的 SMS 消息而不写入 SMS 提供程序的方法:
sendTextMessageWithoutPersisting
CarrierConfigManager
- 通知配置已更改的方法:
notifyConfigChangedForSubId
。 - 获取默认订阅的运营商配置的方法:
getConfig
- 获取指定订阅的运营商配置的方法:
getConfigForSubId
有关说明,请参阅运营商配置。
BugreportManager
启动连接 bug 报告的方法,这是一个特殊版本的 bug 报告,仅包含用于调试连接相关问题的信息: startConnectivityBugreport
NetworkStatsManager
- 查询网络用量摘要的方法:
querySummary
- 查询网络用量历史记录的方法:
queryDetails
- 用于注册或注销网络用量回调的方法
ImsMmTelManager
- 用于注册或注销 IMS MmTel 注册回调的方法
ImsRcsManager
- 用于注册或注销 IMS RCS 注册回调的方法
- 用于获取 IMS 注册状态或传输类型的方法
ProvisioningManager
- 用于注册和注销 IMS 功能配置更新回调的方法
- 与 IMS MmTel 或 RCS 功能的配置状态相关的方法
EuiccManager
切换到(启用)给定订阅的方法: switchToSubscription
CarrierMessagingService
用于接收系统在发送或接收新的 SMS 和 MMS 时发出的调用的服务。要扩展此类,请在清单文件中声明服务,并使用 android.Manifest.permission#BIND_CARRIER_MESSAGING_SERVICE
权限,并包含带有 #SERVICE_INTERFACE
操作的 intent 过滤器。方法包括
- 用于过滤入站 SMS 消息的方法:
onFilterSms
- 用于拦截从设备发送的文本 SMS 消息的方法:
onSendTextSms
- 用于拦截从设备发送的二进制 SMS 消息的方法:
onSendDataSms
- 用于拦截从设备发送的长 SMS 消息的方法:
onSendMultipartTextSms
- 用于拦截从设备发送的 MMS 消息的方法:
onSendMms
- 用于下载收到的 MMS 消息的方法:
onDownloadMms
CarrierService
向系统公开运营商特定功能的服务。要扩展此类,请在应用清单文件中声明服务,并使用 android.Manifest.permission#BIND_CARRIER_SERVICES
权限,并包含带有 CARRIER_SERVICE_INTERFACE
操作的 intent 过滤器。如果该服务具有长期绑定,请在服务的元数据中将 android.service.carrier.LONG_LIVED_BINDING
设置为 true
。
平台使用特殊标记绑定 CarrierService
,以使运营商服务进程在特殊的 应用待机存储分区中运行。这使运营商服务应用免受应用空闲限制,并使其在设备内存不足时更有可能保持活动状态。但是,如果运营商服务应用因任何原因崩溃,它将失去所有上述权限,直到应用重启并且重新建立绑定。因此,保持运营商服务应用的稳定性至关重要。
CarrierService
中的方法包括
- 用于替换和设置运营商特定配置:
onLoadConfig
- 用于告知系统运营商应用即将进行的运营商网络更改:
notifyCarrierNetworkChange
Telephony provider
内容提供程序 API,允许修改(插入、删除、更新、查询)电话数据库。 Telephony.Carriers
中定义了值字段;有关更多详细信息,请参阅 Telephony
类参考
WifiNetworkSuggestion
构建 WifiNetworkSuggestion
对象时,请使用以下方法设置订阅 ID 或订阅组
- 设置订阅 ID 的方法:
setSubscriptionId
- 设置订阅组的方法:
setSubscriptionGroup
Android 平台
在检测到 UICC 时,平台会构建内部 UICC 对象,其中包括作为 UICC 一部分的运营商权限规则。 UiccCarrierPrivilegeRules.java
加载规则,从 UICC 卡解析规则,并将它们缓存在内存中。当需要权限检查时,UiccCarrierPrivilegeRules
会将调用方证书与其自身的规则逐一进行比较。如果 UICC 被移除,则规则会随 UICC 对象一起销毁。
验证
要通过 兼容性测试套件 (CTS) 使用 CtsCarrierApiTestCases.apk
验证实现,您必须具有带有正确 UICC 规则或 ARF 支持的开发者 UICC。请咨询您选择的 SIM 卡供应商,让他们准备一个带有本节所述正确 ARF 的开发者 UICC,并使用该 UICC 运行测试。UICC 不需要有效的蜂窝网络服务即可通过 CTS 测试。
准备 UICC
对于 Android 11 及更低版本,CtsCarrierApiTestCases.apk
由 aosp-testkey
签名,哈希值为 61:ED:37:7E:85:D3:86:A8:DF:EE:6B:86:4B:D8:5B:0B:FA:A5:AF:81
。
从 Android 12 开始,CtsCarrierApiTestCases.apk
由 cts-uicc-2021-testkey
签名,哈希值为 CE:7B:2B:47:AE:2B:75:52:C8:F9:2C:C2:91:24:27:98:83:04:1F:B6:23:A5:F1:94:A8:2C:9B:F1:5D:49:2A:A0
。
要在 Android 12 中运行 CTS 运营商 API 测试,设备需要使用具有 CTS 运营商权限的 SIM 卡,该 SIM 卡满足第三方 GSMA TS.48 测试配置文件规范最新版本中指定的要求。
相同的 SIM 卡也可用于 Android 12 之前的版本。
修改 CTS SIM 配置文件
- 添加:访问规则应用主文件 (ARA-M) 或 ARF 中的 CTS 运营商权限。两个签名都必须在运营商权限规则中编码
- 哈希 1 (SHA1):
61:ED:37:7E:85:D3:86:A8:DF:EE:6B:86:4B:D8:5B:0B:FA:A5:AF:81
- 哈希 2 (SHA256):
CE:7B:2B:47:AE:2B:75:52:C8:F9:2C:C2:91:24:27:98:83:04:1F:B6:23:A5:F1:94:A8:2C:9B:F1:5D:49:2A:A0
- 哈希 1 (SHA1):
- 创建:TS.48 中不存在且 CTS 所需的 ADF USIM 基本文件 (EF)
- EF_MBDN (6FC7),记录大小:28,记录号:4
- 内容
- 记录 1:566F696365204D61696CFFFFFFFF06915155555555FF…FF
- 记录 2-n:FF…FF
- 内容
- EF_EXT6 (6FC8),记录大小:13,记录号:1
- 内容:00FF…FF
- EF_MBI (6FC9),记录大小:4,记录号:1
- 内容:记录 1:01010101
- EF_MWIS (6FCA),记录大小:5,记录号:1
- 内容:0000000000
- 内容:00FF…FF
- EF_MBDN (6FC7),记录大小:28,记录号:4
- 修改:USIM 服务表:启用服务编号 47、编号 48
- EF_UST (6F38)
- 内容:
9EFFBF1DFFFE0083410310010400406E01
- 内容:
- EF_UST (6F38)
- 修改:DF-5GS 和 DF-SAIP 文件
- DF-5GS - EF_5GS3GPPLOCI (USIM/5FC0/4F01)
- 内容:
FFFFFFFFFFFFFFFFFFFFFFFFFF42F618FFFFFE01
- 内容:
- DF-5GS - EF_5GSN3GPPLOCI (USIM/5FC0/4F02)
- 内容:
FFFFFFFFFFFFFFFFFFFFFFFFFF42F618FFFFFE01
- 内容:
- DF-5GS - EF SUCI_Calc_Info (USIM/5FC0/4F07)
- 内容:
A0020000FF…FF
- 内容:
- DF-SAIP - EF SUCI_Calc_Info_USIM (USIM/5FD0/4F01)
- 内容:
A0020000FF…FF
- 内容:
- DF-5GS - EF_5GS3GPPLOCI (USIM/5FC0/4F01)
- 修改:在包含此名称的相应 EF 中使用运营商名称字符串 Android CTS
- EF_SPN (USIM/6F46)
- 内容:
01416E64726F696420435453FF..FF
- 内容:
- EF_PNN (USIM/6FC5)
- 内容:
Rec1 430B83413759FE4E934143EA14FF..FF
- 内容:
- EF_SPN (USIM/6F46)
匹配测试配置文件结构
下载并匹配以下通用测试配置文件结构的最新版本。这些配置文件将不包含 CTS 运营商权限规则个性化设置或上面列出的其他修改。
运行测试
为方便起见,CTS 支持设备令牌,该令牌将测试限制为仅在配置了相同令牌的设备上运行。运营商 API CTS 测试支持设备令牌 sim-card-with-certs
。例如,以下设备令牌将运营商 API 测试限制为仅在设备 abcd1234
上运行
cts-tradefed run cts --device-token abcd1234:sim-card-with-certs
在不使用设备令牌的情况下运行测试时,测试将在所有设备上运行。
常见问题解答
如何在 UICC 上更新证书?
答:使用现有的卡 OTA 更新机制。
UICC 可以与其他规则共存吗?
答:在同一 AID 下在 UICC 上拥有其他安全规则是可以的;平台会自动将其过滤掉。
当依赖 UICC 上证书的应用移除 UICC 时会发生什么?
答:应用会失去其权限,因为与 UICC 关联的规则在 UICC 移除时会被销毁。
UICC 上的证书数量是否有限制?
答:平台不限制证书的数量;但是由于检查是线性的,因此规则过多可能会导致检查延迟。
我们可以使用此方法支持的 API 数量是否有限制?
答:没有,但我们将范围限制为与运营商相关的 API。
是否禁止某些 API 使用此方法?如果是,您如何强制执行它们?(也就是说,您是否有测试来验证哪些 API 通过此方法受支持?)
答:请参阅 Android 兼容性定义文档 (CDD) 的 API 行为兼容性部分。我们有一些 CTS 测试来确保 API 的权限模型没有更改。
这如何与多 SIM 卡功能配合使用?
答:使用用户指定的默认 SIM 卡。
这是否以任何方式与其他 SE 访问技术(例如 SEEK)交互或重叠?
答:例如,SEEK 使用与 UICC 上相同的 AID。因此,规则共存并由 SEEK 或 UiccCarrierPrivileges
过滤。
何时是检查运营商权限的好时机?
答:在 SIM 卡状态加载广播之后。
OEM 可以禁用部分运营商 API 吗?
答:不可以。我们认为当前的 API 是最小集合,并且我们计划在将来使用位掩码进行更精细的粒度控制。
setOperatorBrandOverride
是否会覆盖所有其他形式的运营商名称字符串?例如,SE13、UICC SPN 或基于网络的 NITZ?
是的,运营商品牌替换具有最高优先级。设置后,它将覆盖所有其他形式的运营商名称字符串。
injectSmsPdu
方法调用有什么作用?
答:此方法有助于云端 SMS 备份/恢复。injectSmsPdu
调用启用恢复功能。
对于 SMS 过滤,onFilterSms
调用是否基于 SMS UDH 端口过滤?或者运营商应用是否可以访问所有传入的 SMS?
答:运营商可以访问所有 SMS 数据。
DeviceAppID-REF-DO
的扩展以支持 32 字节似乎与当前的 GP 规范(仅允许 0 或 20 字节)不兼容,那么您为什么要引入此更改?SHA-1 是否足以避免冲突?您是否已向 GP 提出此更改,因为这可能与现有的 ARA-M/ARF 向后不兼容?
答:为了提供面向未来的安全性,除了 SHA-1(目前是 GP SEAC 标准中的唯一选项)之外,此扩展还为 DeviceAppID-REF-DO
引入了 SHA-256。我们强烈建议使用 SHA-256。
如果 DeviceAppID
为 0(空),您是否将该规则应用于特定规则未涵盖的所有设备应用?
答:运营商 API 要求填充 DeviceAppID-REF-DO
。为空旨在用于测试目的,不建议用于运营部署。
根据您的规范,仅单独使用 PKG-REF-DO
而不使用 DeviceAppID-REF-DO
是不应接受的。但它仍在规范的表 6-4 中描述为扩展 REF-DO
的定义。这是故意的吗?当仅在 REF-DO
中使用 PKG-REF-DO
时,代码的行为如何?
答:在最新版本中,已删除将 PKG-REF-DO
作为 REF-DO
中的单个值项的选项。PKG-REF-DO
应该仅与 DeviceAppID-REF-DO
结合使用。
我们假设我们可以授予对所有基于运营商的权限的访问权限,或者进行更精细的控制。如果是这样,那么位掩码与实际权限之间的映射关系是什么定义的?每个类一个权限?每个方法一个权限?从长远来看,64 个单独的权限是否足够?
答:这为将来保留,我们欢迎提出建议。
您能否进一步定义 Android 特定的 DeviceAppID
?这是用于签署给定应用的发布商证书的 SHA-1(20 字节)哈希值,那么名称是否应反映该用途?(对于许多读者来说,该名称可能会造成混淆,因为该规则随后适用于所有使用同一发布商证书签名的应用。)
答:现有规范支持存储证书的 DeviceAppID
。我们尝试最大程度地减少规范更改,以降低采用门槛。有关详细信息,请参阅UICC 上的规则。