EuiccCardTest.java revision 98a7a2b7cd8e0c4ea787e434ed9c6c6d5ddf8d5f
1/* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.internal.telephony.uicc.euicc; 18 19import static org.junit.Assert.assertArrayEquals; 20import static org.junit.Assert.assertEquals; 21import static org.junit.Assert.assertFalse; 22import static org.junit.Assert.assertTrue; 23import static org.junit.Assert.fail; 24import static org.mockito.ArgumentMatchers.any; 25import static org.mockito.ArgumentMatchers.eq; 26import static org.mockito.Mockito.times; 27import static org.mockito.Mockito.verify; 28import static org.mockito.Mockito.when; 29 30import android.content.res.Resources; 31import android.os.Handler; 32import android.os.HandlerThread; 33import android.os.Message; 34import android.service.carrier.CarrierIdentifier; 35import android.service.euicc.EuiccProfileInfo; 36import android.telephony.UiccAccessRule; 37import android.telephony.euicc.EuiccCardManager; 38import android.telephony.euicc.EuiccNotification; 39import android.telephony.euicc.EuiccRulesAuthTable; 40import android.util.ExceptionUtils; 41import android.util.Log; 42 43import com.android.internal.telephony.CommandsInterface; 44import com.android.internal.telephony.TelephonyTest; 45import com.android.internal.telephony.uicc.IccCardApplicationStatus; 46import com.android.internal.telephony.uicc.IccCardStatus; 47import com.android.internal.telephony.uicc.IccUtils; 48import com.android.internal.telephony.uicc.asn1.Asn1Node; 49import com.android.internal.telephony.uicc.asn1.InvalidAsn1DataException; 50import com.android.internal.telephony.uicc.asn1.TagNotFoundException; 51import com.android.internal.telephony.uicc.euicc.apdu.LogicalChannelMocker; 52import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback; 53 54import org.junit.After; 55import org.junit.Before; 56import org.junit.Test; 57import org.mockito.Mock; 58 59import java.util.Arrays; 60import java.util.concurrent.CountDownLatch; 61import java.util.concurrent.TimeUnit; 62 63public class EuiccCardTest extends TelephonyTest { 64 private static final long WAIT_TIMEOUT_MLLIS = 5000; 65 66 private static class ResultCaptor<T> extends AsyncResultCallback<T> { 67 public T result; 68 public Throwable exception; 69 70 private CountDownLatch mLatch; 71 72 private ResultCaptor() { 73 mLatch = new CountDownLatch(1); 74 } 75 76 public void await() { 77 try { 78 mLatch.await(WAIT_TIMEOUT_MLLIS, TimeUnit.MILLISECONDS); 79 } catch (InterruptedException e) { 80 fail("Execution is interrupted: " + e); 81 } 82 } 83 84 @Override 85 public void onResult(T r) { 86 result = r; 87 mLatch.countDown(); 88 } 89 90 @Override 91 public void onException(Throwable e) { 92 exception = e; 93 mLatch.countDown(); 94 } 95 } 96 97 private class UiccCardHandlerThread extends HandlerThread { 98 private UiccCardHandlerThread(String name) { 99 super(name); 100 } 101 102 @Override 103 public void onLooperPrepared() { 104 mEuiccCard = 105 new EuiccCard(mContextFixture.getTestDouble(), mMockCi, mMockIccCardStatus, 106 0 /* phoneId */, new Object()) { 107 @Override 108 protected byte[] getDeviceId() { 109 return IccUtils.bcdToBytes("987654321012345"); 110 } 111 112 @Override 113 protected void loadEidAndNotifyRegistrants() {} 114 115 @Override 116 protected Resources getResources() { 117 return mMockResources; 118 } 119 120 }; 121 mHandler = new Handler(mTestHandlerThread.getLooper()); 122 setReady(true); 123 } 124 } 125 126 @Mock 127 private CommandsInterface mMockCi; 128 @Mock 129 private IccCardStatus mMockIccCardStatus; 130 131 private UiccCardHandlerThread mTestHandlerThread; 132 private Handler mHandler; 133 134 private EuiccCard mEuiccCard; 135 136 @Mock 137 private Resources mMockResources; 138 139 @Before 140 public void setUp() throws Exception { 141 super.setUp(getClass().getSimpleName()); 142 143 mMockIccCardStatus.mApplications = new IccCardApplicationStatus[]{}; 144 mMockIccCardStatus.mCdmaSubscriptionAppIndex = 145 mMockIccCardStatus.mImsSubscriptionAppIndex = 146 mMockIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1; 147 mMockIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT; 148 149 mTestHandlerThread = new UiccCardHandlerThread(getClass().getSimpleName()); 150 mTestHandlerThread.start(); 151 152 waitUntilReady(); 153 } 154 155 @After 156 public void tearDown() throws Exception { 157 mTestHandlerThread.quit(); 158 super.tearDown(); 159 } 160 161 private void assertUnexpectedException(Throwable e) { 162 if (e != null) { 163 fail("Unexpected exception: " + ExceptionUtils.getCompleteMessage(e) + "\n-----\n" 164 + Log.getStackTraceString(e.getCause()) + "-----"); 165 } 166 } 167 168 @Test 169 public void testLoadEidAndNotifyRegistrants() throws InterruptedException { 170 int channel = mockLogicalChannelResponses("BF3E065A041A2B3C4D9000"); 171 172 { 173 final CountDownLatch latch = new CountDownLatch(1); 174 mHandler.post(() -> { 175 mEuiccCard = new EuiccCard(mContextFixture.getTestDouble(), mMockCi, 176 mMockIccCardStatus, 0 /* phoneId */, new Object()); 177 latch.countDown(); 178 }); 179 assertTrue(latch.await(WAIT_TIMEOUT_MLLIS, TimeUnit.MILLISECONDS)); 180 } 181 182 final int eventEidReady = 0; 183 final CountDownLatch latch = new CountDownLatch(1); 184 Handler handler = new Handler(mTestHandlerThread.getLooper()) { 185 @Override 186 public void handleMessage(Message msg) { 187 if (msg.what == eventEidReady) { 188 assertEquals("1A2B3C4D", mEuiccCard.getEid()); 189 latch.countDown(); 190 } 191 } 192 }; 193 194 mEuiccCard.registerForEidReady(handler, eventEidReady, null /* obj */); 195 assertTrue(latch.await(WAIT_TIMEOUT_MLLIS, TimeUnit.MILLISECONDS)); 196 197 verifyStoreData(channel, "BF3E035C015A"); 198 } 199 200 @Test 201 public void testGetAllProfiles() { 202 int channel = mockLogicalChannelResponses( 203 "BF2D14A012E3105A0A896700000000004523019F7001019000"); 204 205 ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>(); 206 mEuiccCard.getAllProfiles(resultCaptor, mHandler); 207 resultCaptor.await(); 208 209 assertUnexpectedException(resultCaptor.exception); 210 EuiccProfileInfo[] profiles = resultCaptor.result; 211 assertEquals(1, profiles.length); 212 assertEquals("98760000000000543210", profiles[0].getIccid()); 213 assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profiles[0].getState()); 214 verifyStoreData(channel, "BF2D0D5C0B5A909192B79F709599BF76"); 215 } 216 217 @Test 218 public void testFSuffix() { 219 // iccID is 987600000000005432FF. 220 int channel = mockLogicalChannelResponses( 221 "BF2D14A012E3105A0A896700000000004523FF9F7001019000"); 222 223 ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>(); 224 mEuiccCard.getAllProfiles(resultCaptor, mHandler); 225 resultCaptor.await(); 226 227 EuiccProfileInfo[] profiles = resultCaptor.result; 228 assertEquals(1, profiles.length); 229 assertEquals("987600000000005432", profiles[0].getIccid()); 230 assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profiles[0].getState()); 231 verifyStoreData(channel, "BF2D0D5C0B5A909192B79F709599BF76"); 232 } 233 234 @Test 235 public void testGetProfile() { 236 int channel = mockLogicalChannelResponses("BF2D8184A08181E37F" 237 + "5A0A89670000000000452301" // ICCID 238 + "90046E69636B" // Nickname 239 + "9103746D6F" // Service provider name 240 + "92027031" // Profile name 241 + "B70F800312F34581030102038203040506" // Operator id 242 + "9F700101" // Profile state 243 + "950101" // Profile class 244 + "990206C0" // Policy rules 245 + "BF7645E243E135C114ABCD92CBB156B280FA4E1429A6ECEEB6E5C1BFE4" 246 + "CA1D636F6D2E676F6F676C652E616E64726F69642E617070732E6D79617070" 247 + "E30ADB080000000000000001" // Carrier privilege rules 248 + "9000"); 249 250 ResultCaptor<EuiccProfileInfo> resultCaptor = new ResultCaptor<>(); 251 mEuiccCard.getProfile("98760000000000543210", resultCaptor, mHandler); 252 resultCaptor.await(); 253 254 EuiccProfileInfo profile = resultCaptor.result; 255 assertEquals("98760000000000543210", profile.getIccid()); 256 assertEquals("nick", profile.getNickname()); 257 assertEquals("tmo", profile.getServiceProviderName()); 258 assertEquals("p1", profile.getProfileName()); 259 assertEquals("213", profile.getCarrierIdentifier().getMcc()); 260 assertEquals("54", profile.getCarrierIdentifier().getMnc()); 261 assertEquals("010203", profile.getCarrierIdentifier().getGid1()); 262 assertEquals("040506", profile.getCarrierIdentifier().getGid2()); 263 assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profile.getState()); 264 assertEquals(EuiccProfileInfo.PROFILE_CLASS_PROVISIONING, profile.getProfileClass()); 265 assertEquals( 266 EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE 267 | EuiccProfileInfo.POLICY_RULE_DO_NOT_DISABLE, 268 profile.getPolicyRules()); 269 assertArrayEquals( 270 new UiccAccessRule[] { 271 new UiccAccessRule( 272 IccUtils.hexStringToBytes( 273 "ABCD92CBB156B280FA4E1429A6ECEEB6E5C1BFE4"), 274 "com.google.android.apps.myapp", 1) 275 }, 276 profile.getUiccAccessRules().toArray()); 277 verifyStoreData(channel, "BF2D1BA00C5A0A896700000000004523015C0B5A909192B79F709599BF76"); 278 } 279 280 @Test 281 public void testDisableProfile() { 282 int channel = mockLogicalChannelResponses("BF32038001009000"); 283 284 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 285 mEuiccCard.disableProfile("98760000000000543210", true, resultCaptor, mHandler); 286 resultCaptor.await(); 287 288 assertUnexpectedException(resultCaptor.exception); 289 verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF"); 290 } 291 292 @Test 293 public void testDisableProfile_SimRefresh() { 294 int channel = mockLogicalChannelResponses("6106", "6f00"); 295 296 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 297 mEuiccCard.disableProfile("98760000000000543210", true, resultCaptor, mHandler); 298 resultCaptor.await(); 299 300 assertUnexpectedException(resultCaptor.exception); 301 verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF"); 302 } 303 304 @Test 305 public void testDisableProfile_Error() { 306 int channel = mockLogicalChannelResponses("BF32038001039000"); 307 308 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 309 mEuiccCard.disableProfile("98760000000000543210", true, resultCaptor, mHandler); 310 resultCaptor.await(); 311 312 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 313 verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF"); 314 } 315 316 @Test 317 public void testSwitchToProfile() { 318 int channel = mockLogicalChannelResponses("BF31038001009000"); 319 320 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 321 mEuiccCard.switchToProfile("98760000000000543210", true, resultCaptor, mHandler); 322 resultCaptor.await(); 323 324 assertUnexpectedException(resultCaptor.exception); 325 verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF"); 326 } 327 328 @Test 329 public void testSwitchToProfile_SimRefresh() { 330 int channel = mockLogicalChannelResponses("6106", "6f00"); 331 332 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 333 mEuiccCard.switchToProfile("98760000000000543210", true, resultCaptor, mHandler); 334 resultCaptor.await(); 335 336 assertUnexpectedException(resultCaptor.exception); 337 verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF"); 338 } 339 340 @Test 341 public void testSwitchToProfile_Error() { 342 int channel = mockLogicalChannelResponses("BF31038001039000"); 343 344 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 345 mEuiccCard.switchToProfile("98760000000000543210", true, resultCaptor, mHandler); 346 resultCaptor.await(); 347 348 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 349 verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF"); 350 } 351 352 @Test 353 public void testGetEid() { 354 int channel = mockLogicalChannelResponses("BF3E065A041A2B3C4D9000"); 355 356 ResultCaptor<String> resultCaptor = new ResultCaptor<>(); 357 mEuiccCard.getEid(resultCaptor, mHandler); 358 resultCaptor.await(); 359 360 assertEquals("1A2B3C4D", resultCaptor.result); 361 verifyStoreData(channel, "BF3E035C015A"); 362 } 363 364 @Test 365 public void testSetNickname() { 366 int channel = mockLogicalChannelResponses("BF29038001009000"); 367 368 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 369 mEuiccCard.setNickname("98760000000000543210", "new nickname", resultCaptor, mHandler); 370 resultCaptor.await(); 371 372 assertUnexpectedException(resultCaptor.exception); 373 verifyStoreData(channel, "BF291A5A0A89670000000000452301900C6E6577206E69636B6E616D65"); 374 } 375 376 @Test 377 public void testDeleteProfile() { 378 int channel = mockLogicalChannelResponses("BF33038001009000"); 379 380 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 381 mEuiccCard.deleteProfile("98760000000000543210", resultCaptor, mHandler); 382 resultCaptor.await(); 383 384 assertUnexpectedException(resultCaptor.exception); 385 verifyStoreData(channel, "BF330C5A0A89670000000000452301"); 386 } 387 388 @Test 389 public void testDeleteProfile_Error() { 390 int channel = mockLogicalChannelResponses("BF33038001039000"); 391 392 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 393 mEuiccCard.deleteProfile("98760000000000543210", resultCaptor, mHandler); 394 resultCaptor.await(); 395 396 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 397 verifyStoreData(channel, "BF330C5A0A89670000000000452301"); 398 } 399 400 @Test 401 public void testGetDefaultSmdpAddress() { 402 int channel = mockLogicalChannelResponses( 403 "BF3C148008534D44502E434F4D8108736D64732E636F6D9000"); 404 405 ResultCaptor<String> resultCaptor = new ResultCaptor<>(); 406 mEuiccCard.getDefaultSmdpAddress(resultCaptor, mHandler); 407 resultCaptor.await(); 408 409 assertEquals("SMDP.COM", resultCaptor.result); 410 verifyStoreData(channel, "BF3C00"); 411 } 412 413 @Test 414 public void testGetSmdsAddress() { 415 int channel = mockLogicalChannelResponses( 416 "BF3C148008534D44502E434F4D8108736D64732E636F6D9000"); 417 418 ResultCaptor<String> resultCaptor = new ResultCaptor<>(); 419 mEuiccCard.getSmdsAddress(resultCaptor, mHandler); 420 resultCaptor.await(); 421 422 assertEquals("smds.com", resultCaptor.result); 423 verifyStoreData(channel, "BF3C00"); 424 } 425 426 @Test 427 public void testSetDefaultSmdpAddress() { 428 int channel = mockLogicalChannelResponses("BF3F038001009000"); 429 430 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 431 mEuiccCard.setDefaultSmdpAddress("smdp.gsma.com", resultCaptor, mHandler); 432 resultCaptor.await(); 433 434 assertUnexpectedException(resultCaptor.exception); 435 verifyStoreData(channel, "BF3F0F800D736D64702E67736D612E636F6D"); 436 } 437 438 @Test 439 public void testGetRulesAuthTable() { 440 int channel = mockLogicalChannelResponses("BF4347" 441 + "A021" // Rule #1 442 + "800206C0" // Policy rules: DO_NOT_DELETE | DO_NOT_DISABLE 443 + "A118" // Operator IDs 444 + "B70A800312F3458103010203" // ID #1: 213, 54, [1,2,3], null 445 + "B70A800312F3458203040506" // ID #2: 213, 54, null, [4,5,6] 446 + "820108" // Flag (no user consent) 447 + "A022" // Rule #2 448 + "80020780" // Policy rules: DO_NOT_DISABLE 449 + "A118" // Operator IDs 450 + "B70A800312E3458103010203" // ID #1: 213, 54E, [1,2,3], null 451 + "B70A8003EEEE458203040506" // ID #2: EEE, 54E, null, [4,5,6] 452 + "82020780" // Flag (user consent) 453 + "9000"); 454 455 ResultCaptor<EuiccRulesAuthTable> resultCaptor = new ResultCaptor<>(); 456 mEuiccCard.getRulesAuthTable(resultCaptor, mHandler); 457 resultCaptor.await(); 458 459 EuiccRulesAuthTable rat = resultCaptor.result; 460 assertEquals(-1, 461 rat.findIndex(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE, 462 new CarrierIdentifier(new byte[] {0x12, (byte) 0xF3, 0x45}, null, null))); 463 assertEquals(1, 464 rat.findIndex(EuiccProfileInfo.POLICY_RULE_DO_NOT_DISABLE, 465 new CarrierIdentifier(new byte[] {0x23, 0x67, 0x45}, null, "040506"))); 466 assertFalse(rat.hasPolicyRuleFlag(0, 467 EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED)); 468 assertTrue(rat.hasPolicyRuleFlag(1, 469 EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED)); 470 verifyStoreData(channel, "BF4300"); 471 } 472 473 @Test 474 public void testResetMemory() { 475 int channel = mockLogicalChannelResponses("BF34038001009000"); 476 477 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 478 mEuiccCard.resetMemory(EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES, 479 resultCaptor, mHandler); 480 resultCaptor.await(); 481 482 assertUnexpectedException(resultCaptor.exception); 483 verifyStoreData(channel, "BF340482020640"); 484 } 485 486 @Test 487 public void testResetMemory_SimRefresh() { 488 int channel = mockLogicalChannelResponses("6106", "6f00"); 489 490 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 491 mEuiccCard.resetMemory(EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES, 492 resultCaptor, mHandler); 493 resultCaptor.await(); 494 495 assertUnexpectedException(resultCaptor.exception); 496 verifyStoreData(channel, "BF340482020640"); 497 } 498 499 @Test 500 public void testGetEuiccChallenge() { 501 int channel = mockLogicalChannelResponses("BF2E0580030102039000"); 502 503 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 504 mEuiccCard.getEuiccChallenge(resultCaptor, mHandler); 505 resultCaptor.await(); 506 507 assertArrayEquals(new byte[] {1, 2, 3}, resultCaptor.result); 508 verifyStoreData(channel, "BF2E00"); 509 } 510 511 @Test 512 public void testGetEuiccInfo1() { 513 int channel = mockLogicalChannelResponses("BF20030102039000"); 514 515 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 516 mEuiccCard.getEuiccInfo1(resultCaptor, mHandler); 517 resultCaptor.await(); 518 519 assertEquals("BF2003010203", IccUtils.bytesToHexString(resultCaptor.result)); 520 verifyStoreData(channel, "BF2000"); 521 } 522 523 @Test 524 public void testGetEuiccInfo2() { 525 int channel = mockLogicalChannelResponses("BF22030102039000"); 526 527 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 528 mEuiccCard.getEuiccInfo2(resultCaptor, mHandler); 529 resultCaptor.await(); 530 531 assertEquals("BF2203010203", IccUtils.bytesToHexString(resultCaptor.result)); 532 verifyStoreData(channel, "BF2200"); 533 } 534 535 @Test 536 public void testAuthenticateServer() { 537 when(mMockResources.getStringArray( 538 com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities)) 539 .thenReturn(new String[] {}); 540 541 int channel = mockLogicalChannelResponses("BF3802A0009000"); 542 543 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 544 mEuiccCard.authenticateServer("A1B2C3-X4Y5Z6", // Matching id 545 Asn1Node.newBuilder(0xA0).build().toBytes(), 546 Asn1Node.newBuilder(0xA1).build().toBytes(), 547 Asn1Node.newBuilder(0xA2).build().toBytes(), 548 Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler); 549 resultCaptor.await(); 550 551 assertUnexpectedException(resultCaptor.exception); 552 assertEquals("BF3802A000", IccUtils.bytesToHexString(resultCaptor.result)); 553 verifyStoreData(channel, 554 "BF382D" + "A000" + "A100" + "A200" + "A300" + "A023" 555 + "800D4131423243332D583459355A36" // Matching id 556 + "A112800489674523" // TAC 557 + "A100" // Device capabilities 558 + "82088967452301214305"); // IMEI 559 } 560 561 @Test 562 public void testAuthenticateServer_Error() { 563 when(mMockResources.getStringArray( 564 com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities)) 565 .thenReturn(new String[] {}); 566 567 int channel = mockLogicalChannelResponses("BF38038101039000"); 568 569 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 570 mEuiccCard.authenticateServer("A1B2C3-X4Y5Z6", // Matching id 571 Asn1Node.newBuilder(0xA0).build().toBytes(), 572 Asn1Node.newBuilder(0xA1).build().toBytes(), 573 Asn1Node.newBuilder(0xA2).build().toBytes(), 574 Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler); 575 resultCaptor.await(); 576 577 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 578 verifyStoreData(channel, 579 "BF382D" + "A000" + "A100" + "A200" + "A300" + "A023" 580 + "800D4131423243332D583459355A36" // Matching id 581 + "A112800489674523" // TAC 582 + "A100" // Device capabilities 583 + "82088967452301214305"); // IMEI 584 } 585 586 @Test 587 public void testAuthenticateService_devCap() { 588 when(mMockResources.getStringArray( 589 com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities)) 590 .thenReturn(new String[] { 591 "gsm,11", 592 "utran,11", 593 "cdma1x,1", 594 "hrpd,3", 595 "ehrpd,12", 596 "eutran,11"}); 597 598 int channel = mockLogicalChannelResponses("BF3802A0009000"); 599 600 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 601 mEuiccCard.authenticateServer("A1B2C3-X4Y5Z6", // Matching id 602 Asn1Node.newBuilder(0xA0).build().toBytes(), 603 Asn1Node.newBuilder(0xA1).build().toBytes(), 604 Asn1Node.newBuilder(0xA2).build().toBytes(), 605 Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler); 606 resultCaptor.await(); 607 608 assertUnexpectedException(resultCaptor.exception); 609 assertEquals("BF3802A000", IccUtils.bytesToHexString(resultCaptor.result)); 610 verifyStoreData(channel, 611 "BF384B" + "A000" + "A100" + "A200" + "A300" + "A041" 612 + "800D4131423243332D583459355A36" // Matching id 613 + "A130800489674523" // TAC 614 // Device capabilities 615 + "A11E80030B000081030B00008203010000830303000084030C000085030B0000" 616 + "82088967452301214305"); // IMEI 617 } 618 619 @Test 620 public void testPrepareDownload() { 621 int channel = mockLogicalChannelResponses("BF2102A0009000"); 622 623 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 624 mEuiccCard.prepareDownload( 625 IccUtils.hexStringToBytes("4131423243332D583459355A36"), // hashCc 626 Asn1Node.newBuilder(0xA0).build().toBytes(), 627 Asn1Node.newBuilder(0xA1).build().toBytes(), 628 Asn1Node.newBuilder(0xA2).build().toBytes(), resultCaptor, mHandler); 629 resultCaptor.await(); 630 631 assertEquals("BF2102A000", IccUtils.bytesToHexString(resultCaptor.result)); 632 verifyStoreData(channel, 633 "BF2115" + "A000" + "A100" 634 + "040D4131423243332D583459355A36" // hashCc 635 + "A200"); 636 } 637 638 @Test 639 public void testPrepareDownload_Error() { 640 int channel = mockLogicalChannelResponses("BF2105A1030201039000"); 641 642 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 643 mEuiccCard.prepareDownload( 644 IccUtils.hexStringToBytes("4131423243332D583459355A36"), // hashCc 645 Asn1Node.newBuilder(0xA0).build().toBytes(), 646 Asn1Node.newBuilder(0xA1).build().toBytes(), 647 Asn1Node.newBuilder(0xA2).build().toBytes(), resultCaptor, mHandler); 648 resultCaptor.await(); 649 650 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 651 verifyStoreData(channel, 652 "BF2115" + "A000" + "A100" 653 + "040D4131423243332D583459355A36" // hashCc 654 + "A200"); 655 } 656 657 @Test 658 public void testLoadBoundProfilePackage() { 659 int channel = mockLogicalChannelResponses( 660 // For boundProfilePackage head + initialiseSecureChannelRequest 661 // (ES8+.InitialiseSecureChannel) 662 "9000", 663 // For firstSequenceOf87 (ES8+.ConfigureISDP) 664 "9000", 665 // For head of sequenceOf88 (ES8+.StoreMetadata) 666 "9000", 667 // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata) 668 "9000", 669 "9000", 670 // For head of sequenceOf86 (ES8+.LoadProfileElements) 671 "9000", 672 // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements) 673 "9000", 674 // Profile installation result (element 2 of sequenceOf86) 675 "BF37009000"); 676 677 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 678 mEuiccCard.loadBoundProfilePackage( 679 Asn1Node.newBuilder(0xBF36) 680 .addChild(Asn1Node.newBuilder(0xBF23)) 681 .addChild(Asn1Node.newBuilder(0xA0) 682 .addChildAsBytes(0x87, new byte[] {1, 2, 3})) 683 .addChild(Asn1Node.newBuilder(0xA1) 684 .addChildAsBytes(0x88, new byte[] {4, 5, 6})) 685 .addChild(Asn1Node.newBuilder(0xA2)) 686 .addChild(Asn1Node.newBuilder(0xA3) 687 .addChildAsBytes(0x86, new byte[] {7, 8, 9}) 688 .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC})) 689 .build().toBytes(), 690 resultCaptor, mHandler); 691 resultCaptor.await(); 692 693 assertEquals("BF3700", IccUtils.bytesToHexString(resultCaptor.result)); 694 verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel 695 verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP 696 verifyStoreData(channel, "A105"); // ES8+.StoreMetadata 697 verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata 698 verifyStoreData(channel, "A200"); 699 verifyStoreData(channel, "A30A"); // ES8+.LoadProfileElements 700 verifyStoreData(channel, "8603070809"); // ES8+.LoadProfileElements 701 verifyStoreData(channel, "86030A0B0C"); // ES8+.LoadProfileElements 702 } 703 704 @Test 705 public void testLoadBoundProfilePackage_Error() { 706 int channel = mockLogicalChannelResponses( 707 // For boundProfilePackage head + initialiseSecureChannelRequest 708 // (ES8+.InitialiseSecureChannel) 709 "9000", 710 // For firstSequenceOf87 (ES8+.ConfigureISDP) 711 "9000", 712 // For head of sequenceOf88 (ES8+.StoreMetadata) 713 "9000", 714 // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata) 715 "9000", 716 "9000", 717 // For head of sequenceOf86 (ES8+.LoadProfileElements) 718 "9000", 719 // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements) 720 "9000", 721 // Profile installation result (element 2 of sequenceOf86) 722 "BF370ABF2707A205A1038101039000"); 723 724 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 725 mEuiccCard.loadBoundProfilePackage( 726 Asn1Node.newBuilder(0xBF36) 727 .addChild(Asn1Node.newBuilder(0xBF23)) 728 .addChild(Asn1Node.newBuilder(0xA0) 729 .addChildAsBytes(0x87, new byte[] {1, 2, 3})) 730 .addChild(Asn1Node.newBuilder(0xA1) 731 .addChildAsBytes(0x88, new byte[] {4, 5, 6})) 732 .addChild(Asn1Node.newBuilder(0xA2)) 733 .addChild(Asn1Node.newBuilder(0xA3) 734 .addChildAsBytes(0x86, new byte[] {7, 8, 9}) 735 .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC})) 736 .build().toBytes(), 737 resultCaptor, mHandler); 738 resultCaptor.await(); 739 740 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 741 verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel 742 verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP 743 verifyStoreData(channel, "A105"); // ES8+.StoreMetadata 744 verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata 745 verifyStoreData(channel, "A200"); 746 verifyStoreData(channel, "A30A"); // ES8+.LoadProfileElements 747 verifyStoreData(channel, "8603070809"); // ES8+.LoadProfileElements 748 verifyStoreData(channel, "86030A0B0C"); // ES8+.LoadProfileElements 749 } 750 751 @Test 752 public void testCancelSession() { 753 int channel = mockLogicalChannelResponses("BF41009000"); 754 755 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 756 mEuiccCard.cancelSession(IccUtils.hexStringToBytes("A1B2C3"), 757 EuiccCardManager.CANCEL_REASON_POSTPONED, resultCaptor, mHandler); 758 resultCaptor.await(); 759 760 assertEquals("BF4100", IccUtils.bytesToHexString(resultCaptor.result)); 761 verifyStoreData(channel, "BF41088003A1B2C3810101"); 762 } 763 764 @Test 765 public void testCancelSession_Error() { 766 int channel = mockLogicalChannelResponses("BF41038101039000"); 767 768 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 769 mEuiccCard.cancelSession(IccUtils.hexStringToBytes("A1B2C3"), 770 EuiccCardManager.CANCEL_REASON_POSTPONED, resultCaptor, mHandler); 771 resultCaptor.await(); 772 773 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 774 verifyStoreData(channel, "BF41088003A1B2C3810101"); 775 } 776 777 @Test 778 public void testListNotifications() { 779 int channel = mockLogicalChannelResponses("BF282BA029" 780 + "BF2F118001010C08736D64702E636F6D81020410" // Notification #1 781 + "BF2F128001020C09736D6470322E636F6D81020420" // Notification #2 782 + "9000"); 783 784 ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>(); 785 mEuiccCard.listNotifications( 786 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE, 787 resultCaptor, mHandler); 788 resultCaptor.await(); 789 790 assertArrayEquals( 791 new EuiccNotification[] { 792 new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE, null), 793 new EuiccNotification(2, "smdp2.com", EuiccNotification.EVENT_DISABLE, null) 794 }, 795 resultCaptor.result); 796 verifyStoreData(channel, "BF280481020430"); 797 } 798 799 @Test 800 public void testListNotifications_Error() { 801 int channel = mockLogicalChannelResponses("BF28038101039000"); 802 803 ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>(); 804 mEuiccCard.listNotifications( 805 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE, 806 resultCaptor, mHandler); 807 resultCaptor.await(); 808 809 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 810 verifyStoreData(channel, "BF280481020430"); 811 } 812 813 @Test 814 public void testRetrieveNotificationList() { 815 int channel = mockLogicalChannelResponses("BF2B2FA02D" 816 // Notification #1 817 + "3014BF2F118001010C08736D64702E636F6D81020410" 818 // Notification #2 819 + "3015BF2F128001020C09736D6470322E636F6D81020420" 820 + "9000"); 821 822 ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>(); 823 mEuiccCard.retrieveNotificationList( 824 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE, 825 resultCaptor, mHandler); 826 resultCaptor.await(); 827 828 assertArrayEquals( 829 new EuiccNotification[] { 830 new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE, 831 IccUtils.hexStringToBytes( 832 "3014BF2F118001010C08736D64702E636F6D81020410")), 833 new EuiccNotification(2, "smdp2.com", EuiccNotification.EVENT_DISABLE, 834 IccUtils.hexStringToBytes( 835 "3015BF2F128001020C09736D6470322E636F6D81020420")) 836 }, 837 resultCaptor.result); 838 verifyStoreData(channel, "BF2B06A00481020430"); 839 } 840 841 @Test 842 public void testRetrieveNotificationList_Empty() { 843 int channel = mockLogicalChannelResponses("BF2B038101019000"); 844 845 ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>(); 846 mEuiccCard.retrieveNotificationList( 847 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE, 848 resultCaptor, mHandler); 849 resultCaptor.await(); 850 851 assertArrayEquals(new EuiccNotification[0], resultCaptor.result); 852 verifyStoreData(channel, "BF2B06A00481020430"); 853 } 854 855 @Test 856 public void testRetrieveNotificationList_Error() { 857 int channel = mockLogicalChannelResponses("BF2B038101039000"); 858 859 ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>(); 860 mEuiccCard.retrieveNotificationList( 861 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE, 862 resultCaptor, mHandler); 863 resultCaptor.await(); 864 865 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 866 verifyStoreData(channel, "BF2B06A00481020430"); 867 } 868 869 @Test 870 public void testRetrieveNotification() { 871 int channel = mockLogicalChannelResponses("BF2B18A016" 872 + "3014BF2F118001010C08736D64702E636F6D81020410" // Notification 873 + "9000"); 874 875 ResultCaptor<EuiccNotification> resultCaptor = new ResultCaptor<>(); 876 mEuiccCard.retrieveNotification(5, resultCaptor, mHandler); 877 resultCaptor.await(); 878 879 assertEquals( 880 new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE, 881 IccUtils.hexStringToBytes("3014BF2F118001010C08736D64702E636F6D81020410")), 882 resultCaptor.result); 883 verifyStoreData(channel, "BF2B05A003800105"); 884 } 885 886 @Test 887 public void testRetrieveNotification_Error() { 888 int channel = mockLogicalChannelResponses("BF2B038101019000"); 889 890 ResultCaptor<EuiccNotification> resultCaptor = new ResultCaptor<>(); 891 mEuiccCard.retrieveNotification(5, resultCaptor, mHandler); 892 resultCaptor.await(); 893 894 assertEquals(1, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 895 verifyStoreData(channel, "BF2B05A003800105"); 896 } 897 898 @Test 899 public void testRemoveNotificationFromList() { 900 int channel = mockLogicalChannelResponses("BF30038001009000"); 901 902 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 903 mEuiccCard.removeNotificationFromList(5, resultCaptor, mHandler); 904 resultCaptor.await(); 905 906 assertUnexpectedException(resultCaptor.exception); 907 verifyStoreData(channel, "BF3003800105"); 908 } 909 910 @Test 911 public void testAddDeviceCapability() throws InvalidAsn1DataException, TagNotFoundException { 912 Asn1Node.Builder devCapsBuilder = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1); 913 914 String devCapItem = "gsm,11"; 915 mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); 916 Asn1Node node = devCapsBuilder.build(); 917 918 assertTrue(node.hasChild(Tags.TAG_CTX_0)); 919 Asn1Node child = node.getChild(Tags.TAG_CTX_0); 920 assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes())); 921 922 devCapItem = "utran,11"; 923 mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); 924 node = devCapsBuilder.build(); 925 926 assertTrue(node.hasChild(Tags.TAG_CTX_1)); 927 child = node.getChild(Tags.TAG_CTX_1); 928 assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes())); 929 930 devCapItem = "cdma1x,1"; 931 mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); 932 node = devCapsBuilder.build(); 933 934 assertTrue(node.hasChild(Tags.TAG_CTX_2)); 935 child = node.getChild(Tags.TAG_CTX_2); 936 assertTrue(Arrays.equals(new byte[] {1, 0 , 0}, child.asBytes())); 937 938 devCapItem = "hrpd,1"; 939 mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); 940 node = devCapsBuilder.build(); 941 942 assertTrue(node.hasChild(Tags.TAG_CTX_3)); 943 child = node.getChild(Tags.TAG_CTX_3); 944 assertTrue(Arrays.equals(new byte[] {1, 0 , 0}, child.asBytes())); 945 946 devCapItem = "ehrpd,12"; 947 mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); 948 node = devCapsBuilder.build(); 949 950 assertTrue(node.hasChild(Tags.TAG_CTX_4)); 951 child = node.getChild(Tags.TAG_CTX_4); 952 assertTrue(Arrays.equals(new byte[] {12, 0 , 0}, child.asBytes())); 953 954 devCapItem = "eutran,11"; 955 mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); 956 node = devCapsBuilder.build(); 957 958 assertTrue(node.hasChild(Tags.TAG_CTX_5)); 959 child = node.getChild(Tags.TAG_CTX_5); 960 assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes())); 961 962 devCapItem = "nfc,0"; 963 mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); 964 node = devCapsBuilder.build(); 965 966 assertTrue(node.hasChild(Tags.TAG_CTX_6)); 967 child = node.getChild(Tags.TAG_CTX_6); 968 assertTrue(Arrays.equals(new byte[] {0, 0 , 0}, child.asBytes())); 969 970 devCapItem = "crl,0"; 971 mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem); 972 node = devCapsBuilder.build(); 973 974 assertTrue(node.hasChild(Tags.TAG_CTX_7)); 975 child = node.getChild(Tags.TAG_CTX_7); 976 assertTrue(Arrays.equals(new byte[] {0, 0 , 0}, child.asBytes())); 977 978 // Array length should not be 3. 979 Asn1Node.Builder devCapsBuilder2 = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1); 980 devCapItem = "gsm,1,1"; 981 mEuiccCard.addDeviceCapability(devCapsBuilder2, devCapItem); 982 node = devCapsBuilder2.build(); 983 984 assertFalse(node.hasChild(Tags.TAG_CTX_0)); 985 } 986 987 private void verifyStoreData(int channel, String command) { 988 verify(mMockCi, times(1)) 989 .iccTransmitApduLogicalChannel(eq(channel), eq(0x80 | channel), eq(0xE2), eq(0x91), 990 eq(0), eq(command.length() / 2), eq(command), any()); 991 } 992 993 private int mockLogicalChannelResponses(Object... responses) { 994 int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, 995 "E00582030200009000"); 996 LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, responses); 997 LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel); 998 return channel; 999 } 1000} 1001