EuiccCardTest.java revision 4d59805cd9a6ad9e0f5a5dc87c1fd2a619150b36
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; 28 29import android.os.Handler; 30import android.os.HandlerThread; 31import android.service.carrier.CarrierIdentifier; 32import android.service.euicc.EuiccProfileInfo; 33import android.telephony.UiccAccessRule; 34import android.telephony.euicc.EuiccCardManager; 35import android.telephony.euicc.EuiccNotification; 36import android.telephony.euicc.EuiccRulesAuthTable; 37import android.util.ExceptionUtils; 38import android.util.Log; 39 40import com.android.internal.telephony.CommandsInterface; 41import com.android.internal.telephony.TelephonyTest; 42import com.android.internal.telephony.uicc.IccCardApplicationStatus; 43import com.android.internal.telephony.uicc.IccCardStatus; 44import com.android.internal.telephony.uicc.IccUtils; 45import com.android.internal.telephony.uicc.asn1.Asn1Node; 46import com.android.internal.telephony.uicc.euicc.apdu.LogicalChannelMocker; 47import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback; 48 49import org.junit.After; 50import org.junit.Before; 51import org.junit.Test; 52import org.mockito.Mock; 53 54import java.util.concurrent.CountDownLatch; 55import java.util.concurrent.TimeUnit; 56 57public class EuiccCardTest extends TelephonyTest { 58 private static final long WAIT_TIMEOUT_MLLIS = 5000; 59 60 private static class ResultCaptor<T> extends AsyncResultCallback<T> { 61 public T result; 62 public Throwable exception; 63 64 private CountDownLatch mLatch; 65 66 private ResultCaptor() { 67 mLatch = new CountDownLatch(1); 68 } 69 70 public void await() { 71 try { 72 mLatch.await(WAIT_TIMEOUT_MLLIS, TimeUnit.MILLISECONDS); 73 } catch (InterruptedException e) { 74 fail("Execution is interrupted: " + e); 75 } 76 } 77 78 @Override 79 public void onResult(T r) { 80 result = r; 81 mLatch.countDown(); 82 } 83 84 @Override 85 public void onException(Throwable e) { 86 exception = e; 87 mLatch.countDown(); 88 } 89 } 90 91 private class UiccCardHandlerThread extends HandlerThread { 92 private UiccCardHandlerThread(String name) { 93 super(name); 94 } 95 96 @Override 97 public void onLooperPrepared() { 98 mEuiccCard = 99 new EuiccCard(mContextFixture.getTestDouble(), mMockCi, mMockIccCardStatus, 100 0 /* phoneId */) { 101 @Override 102 protected byte[] getDeviceId() { 103 return IccUtils.bcdToBytes("987654321012345"); 104 } 105 }; 106 mHandler = new Handler(mTestHandlerThread.getLooper()); 107 setReady(true); 108 } 109 } 110 111 @Mock 112 private CommandsInterface mMockCi; 113 @Mock 114 private IccCardStatus mMockIccCardStatus; 115 116 private UiccCardHandlerThread mTestHandlerThread; 117 private Handler mHandler; 118 119 private EuiccCard mEuiccCard; 120 121 @Before 122 public void setUp() throws Exception { 123 super.setUp(getClass().getSimpleName()); 124 125 mMockIccCardStatus.mApplications = new IccCardApplicationStatus[]{}; 126 mMockIccCardStatus.mCdmaSubscriptionAppIndex = 127 mMockIccCardStatus.mImsSubscriptionAppIndex = 128 mMockIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1; 129 mMockIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT; 130 131 mTestHandlerThread = new UiccCardHandlerThread(getClass().getSimpleName()); 132 mTestHandlerThread.start(); 133 134 waitUntilReady(); 135 } 136 137 @After 138 public void tearDown() throws Exception { 139 mTestHandlerThread.quit(); 140 super.tearDown(); 141 } 142 143 private void assertUnexpectedException(Throwable e) { 144 if (e != null) { 145 fail("Unexpected exception: " + ExceptionUtils.getCompleteMessage(e) + "\n-----\n" 146 + Log.getStackTraceString(e.getCause()) + "-----"); 147 } 148 } 149 150 @Test 151 public void testGetAllProfiles() { 152 int channel = mockLogicalChannelResponses( 153 "BF2D14A012E3105A0A896700000000004523019F7001019000"); 154 155 ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>(); 156 mEuiccCard.getAllProfiles(resultCaptor, mHandler); 157 resultCaptor.await(); 158 159 assertUnexpectedException(resultCaptor.exception); 160 EuiccProfileInfo[] profiles = resultCaptor.result; 161 assertEquals(1, profiles.length); 162 assertEquals("98760000000000543210", profiles[0].getIccid()); 163 assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profiles[0].getState()); 164 verifyStoreData(channel, "BF2D0D5C0B5A909192B79F709599BF76"); 165 } 166 167 @Test 168 public void testFSuffix() { 169 // iccID is 987600000000005432FF. 170 int channel = mockLogicalChannelResponses( 171 "BF2D14A012E3105A0A896700000000004523FF9F7001019000"); 172 173 ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>(); 174 mEuiccCard.getAllProfiles(resultCaptor, mHandler); 175 resultCaptor.await(); 176 177 EuiccProfileInfo[] profiles = resultCaptor.result; 178 assertEquals(1, profiles.length); 179 assertEquals("987600000000005432", profiles[0].getIccid()); 180 assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profiles[0].getState()); 181 verifyStoreData(channel, "BF2D0D5C0B5A909192B79F709599BF76"); 182 } 183 184 @Test 185 public void testGetProfile() { 186 int channel = mockLogicalChannelResponses("BF2D8184A08181E37F" 187 + "5A0A89670000000000452301" // ICCID 188 + "90046E69636B" // Nickname 189 + "9103746D6F" // Service provider name 190 + "92027031" // Profile name 191 + "B70F800312F34581030102038203040506" // Operator id 192 + "9F700101" // Profile state 193 + "950101" // Profile class 194 + "990206C0" // Policy rules 195 + "BF7645E243E135C114ABCD92CBB156B280FA4E1429A6ECEEB6E5C1BFE4" 196 + "CA1D636F6D2E676F6F676C652E616E64726F69642E617070732E6D79617070" 197 + "E30ADB080000000000000001" // Carrier privilege rules 198 + "9000"); 199 200 ResultCaptor<EuiccProfileInfo> resultCaptor = new ResultCaptor<>(); 201 mEuiccCard.getProfile("98760000000000543210", resultCaptor, mHandler); 202 resultCaptor.await(); 203 204 EuiccProfileInfo profile = resultCaptor.result; 205 assertEquals("98760000000000543210", profile.getIccid()); 206 assertEquals("nick", profile.getNickname()); 207 assertEquals("tmo", profile.getServiceProviderName()); 208 assertEquals("p1", profile.getProfileName()); 209 assertEquals("213", profile.getCarrierIdentifier().getMcc()); 210 assertEquals("54", profile.getCarrierIdentifier().getMnc()); 211 assertEquals("010203", profile.getCarrierIdentifier().getGid1()); 212 assertEquals("040506", profile.getCarrierIdentifier().getGid2()); 213 assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profile.getState()); 214 assertEquals(EuiccProfileInfo.PROFILE_CLASS_PROVISIONING, profile.getProfileClass()); 215 assertEquals( 216 EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE 217 | EuiccProfileInfo.POLICY_RULE_DO_NOT_DISABLE, 218 profile.getPolicyRules()); 219 assertArrayEquals( 220 new UiccAccessRule[] { 221 new UiccAccessRule( 222 IccUtils.hexStringToBytes( 223 "ABCD92CBB156B280FA4E1429A6ECEEB6E5C1BFE4"), 224 "com.google.android.apps.myapp", 1) 225 }, 226 profile.getUiccAccessRules().toArray()); 227 verifyStoreData(channel, "BF2D195A0A896700000000004523015C0B5A909192B79F709599BF76"); 228 } 229 230 @Test 231 public void testDisableProfile() { 232 int channel = mockLogicalChannelResponses("BF32038001009000"); 233 234 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 235 mEuiccCard.disableProfile("98760000000000543210", true, resultCaptor, mHandler); 236 resultCaptor.await(); 237 238 assertUnexpectedException(resultCaptor.exception); 239 verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF"); 240 } 241 242 @Test 243 public void testDisableProfile_SimRefresh() { 244 int channel = mockLogicalChannelResponses("6106", "6f00"); 245 246 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 247 mEuiccCard.disableProfile("98760000000000543210", true, resultCaptor, mHandler); 248 resultCaptor.await(); 249 250 assertUnexpectedException(resultCaptor.exception); 251 verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF"); 252 } 253 254 @Test 255 public void testDisableProfile_Error() { 256 int channel = mockLogicalChannelResponses("BF32038001039000"); 257 258 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 259 mEuiccCard.disableProfile("98760000000000543210", true, resultCaptor, mHandler); 260 resultCaptor.await(); 261 262 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 263 verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF"); 264 } 265 266 @Test 267 public void testSwitchToProfile() { 268 int channel = mockLogicalChannelResponses("BF31038001009000"); 269 270 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 271 mEuiccCard.switchToProfile("98760000000000543210", true, resultCaptor, mHandler); 272 resultCaptor.await(); 273 274 assertUnexpectedException(resultCaptor.exception); 275 verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF"); 276 } 277 278 @Test 279 public void testSwitchToProfile_SimRefresh() { 280 int channel = mockLogicalChannelResponses("6106", "6f00"); 281 282 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 283 mEuiccCard.switchToProfile("98760000000000543210", true, resultCaptor, mHandler); 284 resultCaptor.await(); 285 286 assertUnexpectedException(resultCaptor.exception); 287 verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF"); 288 } 289 290 @Test 291 public void testSwitchToProfile_Error() { 292 int channel = mockLogicalChannelResponses("BF31038001039000"); 293 294 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 295 mEuiccCard.switchToProfile("98760000000000543210", true, resultCaptor, mHandler); 296 resultCaptor.await(); 297 298 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 299 verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF"); 300 } 301 302 @Test 303 public void testGetEid() { 304 int channel = mockLogicalChannelResponses("BF3E065A041A2B3C4D9000"); 305 306 ResultCaptor<String> resultCaptor = new ResultCaptor<>(); 307 mEuiccCard.getEid(resultCaptor, mHandler); 308 resultCaptor.await(); 309 310 assertEquals("1A2B3C4D", resultCaptor.result); 311 verifyStoreData(channel, "BF3E035C015A"); 312 } 313 314 @Test 315 public void testSetNickname() { 316 int channel = mockLogicalChannelResponses("BF29038001009000"); 317 318 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 319 mEuiccCard.setNickname("98760000000000543210", "new nickname", resultCaptor, mHandler); 320 resultCaptor.await(); 321 322 assertUnexpectedException(resultCaptor.exception); 323 verifyStoreData(channel, "BF291A5A0A89670000000000452301900C6E6577206E69636B6E616D65"); 324 } 325 326 @Test 327 public void testDeleteProfile() { 328 int channel = mockLogicalChannelResponses("BF33038001009000"); 329 330 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 331 mEuiccCard.deleteProfile("98760000000000543210", resultCaptor, mHandler); 332 resultCaptor.await(); 333 334 assertUnexpectedException(resultCaptor.exception); 335 verifyStoreData(channel, "BF330C5A0A89670000000000452301"); 336 } 337 338 @Test 339 public void testDeleteProfile_Error() { 340 int channel = mockLogicalChannelResponses("BF33038001039000"); 341 342 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 343 mEuiccCard.deleteProfile("98760000000000543210", resultCaptor, mHandler); 344 resultCaptor.await(); 345 346 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 347 verifyStoreData(channel, "BF330C5A0A89670000000000452301"); 348 } 349 350 @Test 351 public void testGetDefaultSmdpAddress() { 352 int channel = mockLogicalChannelResponses( 353 "BF3C148008534D44502E434F4D8108736D64732E636F6D9000"); 354 355 ResultCaptor<String> resultCaptor = new ResultCaptor<>(); 356 mEuiccCard.getDefaultSmdpAddress(resultCaptor, mHandler); 357 resultCaptor.await(); 358 359 assertEquals("SMDP.COM", resultCaptor.result); 360 verifyStoreData(channel, "BF3C00"); 361 } 362 363 @Test 364 public void testGetSmdsAddress() { 365 int channel = mockLogicalChannelResponses( 366 "BF3C148008534D44502E434F4D8108736D64732E636F6D9000"); 367 368 ResultCaptor<String> resultCaptor = new ResultCaptor<>(); 369 mEuiccCard.getSmdsAddress(resultCaptor, mHandler); 370 resultCaptor.await(); 371 372 assertEquals("smds.com", resultCaptor.result); 373 verifyStoreData(channel, "BF3C00"); 374 } 375 376 @Test 377 public void testSetDefaultSmdpAddress() { 378 int channel = mockLogicalChannelResponses("BF3F038001009000"); 379 380 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 381 mEuiccCard.setDefaultSmdpAddress("smdp.gsma.com", resultCaptor, mHandler); 382 resultCaptor.await(); 383 384 assertUnexpectedException(resultCaptor.exception); 385 verifyStoreData(channel, "BF3F0F800D736D64702E67736D612E636F6D"); 386 } 387 388 @Test 389 public void testGetRulesAuthTable() { 390 int channel = mockLogicalChannelResponses("BF4347" 391 + "A021" // Rule #1 392 + "800206C0" // Policy rules: DO_NOT_DELETE | DO_NOT_DISABLE 393 + "A118" // Operator IDs 394 + "B70A800312F3458103010203" // ID #1: 213, 54, [1,2,3], null 395 + "B70A800312F3458203040506" // ID #2: 213, 54, null, [4,5,6] 396 + "820108" // Flag (no user consent) 397 + "A022" // Rule #2 398 + "80020780" // Policy rules: DO_NOT_DISABLE 399 + "A118" // Operator IDs 400 + "B70A800312E3458103010203" // ID #1: 213, 54E, [1,2,3], null 401 + "B70A8003EEEE458203040506" // ID #2: EEE, 54E, null, [4,5,6] 402 + "82020780" // Flag (user consent) 403 + "9000"); 404 405 ResultCaptor<EuiccRulesAuthTable> resultCaptor = new ResultCaptor<>(); 406 mEuiccCard.getRulesAuthTable(resultCaptor, mHandler); 407 resultCaptor.await(); 408 409 EuiccRulesAuthTable rat = resultCaptor.result; 410 assertEquals(-1, 411 rat.findIndex(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE, 412 new CarrierIdentifier(new byte[] {0x12, (byte) 0xF3, 0x45}, null, null))); 413 assertEquals(1, 414 rat.findIndex(EuiccProfileInfo.POLICY_RULE_DO_NOT_DISABLE, 415 new CarrierIdentifier(new byte[] {0x23, 0x67, 0x45}, null, "040506"))); 416 assertFalse(rat.hasPolicyRuleFlag(0, 417 EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED)); 418 assertTrue(rat.hasPolicyRuleFlag(1, 419 EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED)); 420 verifyStoreData(channel, "BF4300"); 421 } 422 423 @Test 424 public void testResetMemory() { 425 int channel = mockLogicalChannelResponses("BF34038001009000"); 426 427 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 428 mEuiccCard.resetMemory(EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES, 429 resultCaptor, mHandler); 430 resultCaptor.await(); 431 432 assertUnexpectedException(resultCaptor.exception); 433 verifyStoreData(channel, "BF340482020640"); 434 } 435 436 @Test 437 public void testResetMemory_SimRefresh() { 438 int channel = mockLogicalChannelResponses("6106", "6f00"); 439 440 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 441 mEuiccCard.resetMemory(EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES, 442 resultCaptor, mHandler); 443 resultCaptor.await(); 444 445 assertUnexpectedException(resultCaptor.exception); 446 verifyStoreData(channel, "BF340482020640"); 447 } 448 449 @Test 450 public void testGetEuiccChallenge() { 451 int channel = mockLogicalChannelResponses("BF2E0580030102039000"); 452 453 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 454 mEuiccCard.getEuiccChallenge(resultCaptor, mHandler); 455 resultCaptor.await(); 456 457 assertArrayEquals(new byte[] {1, 2, 3}, resultCaptor.result); 458 verifyStoreData(channel, "BF2E00"); 459 } 460 461 @Test 462 public void testGetEuiccInfo1() { 463 int channel = mockLogicalChannelResponses("BF20030102039000"); 464 465 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 466 mEuiccCard.getEuiccInfo1(resultCaptor, mHandler); 467 resultCaptor.await(); 468 469 assertEquals("BF2003010203", IccUtils.bytesToHexString(resultCaptor.result)); 470 verifyStoreData(channel, "BF2000"); 471 } 472 473 @Test 474 public void testGetEuiccInfo2() { 475 int channel = mockLogicalChannelResponses("BF22030102039000"); 476 477 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 478 mEuiccCard.getEuiccInfo2(resultCaptor, mHandler); 479 resultCaptor.await(); 480 481 assertEquals("BF2203010203", IccUtils.bytesToHexString(resultCaptor.result)); 482 verifyStoreData(channel, "BF2200"); 483 } 484 485 @Test 486 public void testAuthenticateServer() { 487 int channel = mockLogicalChannelResponses("BF3802A0009000"); 488 489 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 490 mEuiccCard.authenticateServer("A1B2C3-X4Y5Z6", // Matching id 491 Asn1Node.newBuilder(0xA0).build().toBytes(), 492 Asn1Node.newBuilder(0xA1).build().toBytes(), 493 Asn1Node.newBuilder(0xA2).build().toBytes(), 494 Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler); 495 resultCaptor.await(); 496 497 assertUnexpectedException(resultCaptor.exception); 498 assertEquals("BF3802A000", IccUtils.bytesToHexString(resultCaptor.result)); 499 verifyStoreData(channel, 500 "BF382D" + "A000" + "A100" + "A200" + "A300" + "A023" 501 + "800D4131423243332D583459355A36" // Matching id 502 + "A112800489674523" // TAC 503 + "A100" // Device capabilities 504 + "82088967452301214305"); // IMEI 505 } 506 507 @Test 508 public void testAuthenticateServer_Error() { 509 int channel = mockLogicalChannelResponses("BF38038101039000"); 510 511 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 512 mEuiccCard.authenticateServer("A1B2C3-X4Y5Z6", // Matching id 513 Asn1Node.newBuilder(0xA0).build().toBytes(), 514 Asn1Node.newBuilder(0xA1).build().toBytes(), 515 Asn1Node.newBuilder(0xA2).build().toBytes(), 516 Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler); 517 resultCaptor.await(); 518 519 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 520 verifyStoreData(channel, 521 "BF382D" + "A000" + "A100" + "A200" + "A300" + "A023" 522 + "800D4131423243332D583459355A36" // Matching id 523 + "A112800489674523" // TAC 524 + "A100" // Device capabilities 525 + "82088967452301214305"); // IMEI 526 } 527 528 @Test 529 public void testPrepareDownload() { 530 int channel = mockLogicalChannelResponses("BF2102A0009000"); 531 532 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 533 mEuiccCard.prepareDownload( 534 IccUtils.hexStringToBytes("4131423243332D583459355A36"), // hashCc 535 Asn1Node.newBuilder(0xA0).build().toBytes(), 536 Asn1Node.newBuilder(0xA1).build().toBytes(), 537 Asn1Node.newBuilder(0xA2).build().toBytes(), resultCaptor, mHandler); 538 resultCaptor.await(); 539 540 assertEquals("BF2102A000", IccUtils.bytesToHexString(resultCaptor.result)); 541 verifyStoreData(channel, 542 "BF2115" + "A000" + "A100" 543 + "040D4131423243332D583459355A36" // hashCc 544 + "A200"); 545 } 546 547 @Test 548 public void testPrepareDownload_Error() { 549 int channel = mockLogicalChannelResponses("BF2105A1030201039000"); 550 551 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 552 mEuiccCard.prepareDownload( 553 IccUtils.hexStringToBytes("4131423243332D583459355A36"), // hashCc 554 Asn1Node.newBuilder(0xA0).build().toBytes(), 555 Asn1Node.newBuilder(0xA1).build().toBytes(), 556 Asn1Node.newBuilder(0xA2).build().toBytes(), resultCaptor, mHandler); 557 resultCaptor.await(); 558 559 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 560 verifyStoreData(channel, 561 "BF2115" + "A000" + "A100" 562 + "040D4131423243332D583459355A36" // hashCc 563 + "A200"); 564 } 565 566 @Test 567 public void testLoadBoundProfilePackage() { 568 int channel = mockLogicalChannelResponses( 569 // For boundProfilePackage head + initialiseSecureChannelRequest 570 // (ES8+.InitialiseSecureChannel) 571 "9000", 572 // For firstSequenceOf87 (ES8+.ConfigureISDP) 573 "9000", 574 // For head of sequenceOf88 (ES8+.StoreMetadata) 575 "9000", 576 // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata) 577 "9000", 578 "9000", 579 // For head of sequenceOf86 (ES8+.LoadProfileElements) 580 "9000", 581 // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements) 582 "9000", 583 // Profile installation result (element 2 of sequenceOf86) 584 "BF37009000"); 585 586 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 587 mEuiccCard.loadBoundProfilePackage( 588 Asn1Node.newBuilder(0xBF36) 589 .addChild(Asn1Node.newBuilder(0xBF23)) 590 .addChild(Asn1Node.newBuilder(0xA0) 591 .addChildAsBytes(0x87, new byte[] {1, 2, 3})) 592 .addChild(Asn1Node.newBuilder(0xA1) 593 .addChildAsBytes(0x88, new byte[] {4, 5, 6})) 594 .addChild(Asn1Node.newBuilder(0xA2)) 595 .addChild(Asn1Node.newBuilder(0xA3) 596 .addChildAsBytes(0x86, new byte[] {7, 8, 9}) 597 .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC})) 598 .build().toBytes(), 599 resultCaptor, mHandler); 600 resultCaptor.await(); 601 602 assertEquals("BF3700", IccUtils.bytesToHexString(resultCaptor.result)); 603 verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel 604 verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP 605 verifyStoreData(channel, "A105"); // ES8+.StoreMetadata 606 verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata 607 verifyStoreData(channel, "A200"); 608 verifyStoreData(channel, "A30A"); // ES8+.LoadProfileElements 609 verifyStoreData(channel, "8603070809"); // ES8+.LoadProfileElements 610 verifyStoreData(channel, "86030A0B0C"); // ES8+.LoadProfileElements 611 } 612 613 @Test 614 public void testLoadBoundProfilePackage_Error() { 615 int channel = mockLogicalChannelResponses( 616 // For boundProfilePackage head + initialiseSecureChannelRequest 617 // (ES8+.InitialiseSecureChannel) 618 "9000", 619 // For firstSequenceOf87 (ES8+.ConfigureISDP) 620 "9000", 621 // For head of sequenceOf88 (ES8+.StoreMetadata) 622 "9000", 623 // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata) 624 "9000", 625 "9000", 626 // For head of sequenceOf86 (ES8+.LoadProfileElements) 627 "9000", 628 // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements) 629 "9000", 630 // Profile installation result (element 2 of sequenceOf86) 631 "BF370ABF2707A205A1038101039000"); 632 633 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 634 mEuiccCard.loadBoundProfilePackage( 635 Asn1Node.newBuilder(0xBF36) 636 .addChild(Asn1Node.newBuilder(0xBF23)) 637 .addChild(Asn1Node.newBuilder(0xA0) 638 .addChildAsBytes(0x87, new byte[] {1, 2, 3})) 639 .addChild(Asn1Node.newBuilder(0xA1) 640 .addChildAsBytes(0x88, new byte[] {4, 5, 6})) 641 .addChild(Asn1Node.newBuilder(0xA2)) 642 .addChild(Asn1Node.newBuilder(0xA3) 643 .addChildAsBytes(0x86, new byte[] {7, 8, 9}) 644 .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC})) 645 .build().toBytes(), 646 resultCaptor, mHandler); 647 resultCaptor.await(); 648 649 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 650 verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel 651 verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP 652 verifyStoreData(channel, "A105"); // ES8+.StoreMetadata 653 verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata 654 verifyStoreData(channel, "A200"); 655 verifyStoreData(channel, "A30A"); // ES8+.LoadProfileElements 656 verifyStoreData(channel, "8603070809"); // ES8+.LoadProfileElements 657 verifyStoreData(channel, "86030A0B0C"); // ES8+.LoadProfileElements 658 } 659 660 @Test 661 public void testCancelSession() { 662 int channel = mockLogicalChannelResponses("BF41009000"); 663 664 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 665 mEuiccCard.cancelSession(IccUtils.hexStringToBytes("A1B2C3"), 666 EuiccCardManager.CANCEL_REASON_POSTPONED, resultCaptor, mHandler); 667 resultCaptor.await(); 668 669 assertEquals("BF4100", IccUtils.bytesToHexString(resultCaptor.result)); 670 verifyStoreData(channel, "BF41088003A1B2C3810101"); 671 } 672 673 @Test 674 public void testCancelSession_Error() { 675 int channel = mockLogicalChannelResponses("BF41038101039000"); 676 677 ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>(); 678 mEuiccCard.cancelSession(IccUtils.hexStringToBytes("A1B2C3"), 679 EuiccCardManager.CANCEL_REASON_POSTPONED, resultCaptor, mHandler); 680 resultCaptor.await(); 681 682 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 683 verifyStoreData(channel, "BF41088003A1B2C3810101"); 684 } 685 686 @Test 687 public void testListNotifications() { 688 int channel = mockLogicalChannelResponses("BF282BA029" 689 + "BF2F118001010C08736D64702E636F6D81020410" // Notification #1 690 + "BF2F128001020C09736D6470322E636F6D81020420" // Notification #2 691 + "9000"); 692 693 ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>(); 694 mEuiccCard.listNotifications( 695 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE, 696 resultCaptor, mHandler); 697 resultCaptor.await(); 698 699 assertArrayEquals( 700 new EuiccNotification[] { 701 new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE, null), 702 new EuiccNotification(2, "smdp2.com", EuiccNotification.EVENT_DISABLE, null) 703 }, 704 resultCaptor.result); 705 verifyStoreData(channel, "BF280481020430"); 706 } 707 708 @Test 709 public void testListNotifications_Error() { 710 int channel = mockLogicalChannelResponses("BF28038101039000"); 711 712 ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>(); 713 mEuiccCard.listNotifications( 714 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE, 715 resultCaptor, mHandler); 716 resultCaptor.await(); 717 718 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 719 verifyStoreData(channel, "BF280481020430"); 720 } 721 722 @Test 723 public void testRetrieveNotificationList() { 724 int channel = mockLogicalChannelResponses("BF2B2FA02D" 725 // Notification #1 726 + "3014BF2F118001010C08736D64702E636F6D81020410" 727 // Notification #2 728 + "3015BF2F128001020C09736D6470322E636F6D81020420" 729 + "9000"); 730 731 ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>(); 732 mEuiccCard.retrieveNotificationList( 733 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE, 734 resultCaptor, mHandler); 735 resultCaptor.await(); 736 737 assertArrayEquals( 738 new EuiccNotification[] { 739 new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE, 740 IccUtils.hexStringToBytes( 741 "3014BF2F118001010C08736D64702E636F6D81020410")), 742 new EuiccNotification(2, "smdp2.com", EuiccNotification.EVENT_DISABLE, 743 IccUtils.hexStringToBytes( 744 "3015BF2F128001020C09736D6470322E636F6D81020420")) 745 }, 746 resultCaptor.result); 747 verifyStoreData(channel, "BF2B06A00481020430"); 748 } 749 750 @Test 751 public void testRetrieveNotificationList_Empty() { 752 int channel = mockLogicalChannelResponses("BF2B038101019000"); 753 754 ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>(); 755 mEuiccCard.retrieveNotificationList( 756 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE, 757 resultCaptor, mHandler); 758 resultCaptor.await(); 759 760 assertArrayEquals(new EuiccNotification[0], resultCaptor.result); 761 verifyStoreData(channel, "BF2B06A00481020430"); 762 } 763 764 @Test 765 public void testRetrieveNotificationList_Error() { 766 int channel = mockLogicalChannelResponses("BF2B038101039000"); 767 768 ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>(); 769 mEuiccCard.retrieveNotificationList( 770 EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE, 771 resultCaptor, mHandler); 772 resultCaptor.await(); 773 774 assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 775 verifyStoreData(channel, "BF2B06A00481020430"); 776 } 777 778 @Test 779 public void testRetrieveNotification() { 780 int channel = mockLogicalChannelResponses("BF2B18A016" 781 + "3014BF2F118001010C08736D64702E636F6D81020410" // Notification 782 + "9000"); 783 784 ResultCaptor<EuiccNotification> resultCaptor = new ResultCaptor<>(); 785 mEuiccCard.retrieveNotification(5, resultCaptor, mHandler); 786 resultCaptor.await(); 787 788 assertEquals( 789 new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE, 790 IccUtils.hexStringToBytes("3014BF2F118001010C08736D64702E636F6D81020410")), 791 resultCaptor.result); 792 verifyStoreData(channel, "BF2B05A003800105"); 793 } 794 795 @Test 796 public void testRetrieveNotification_Error() { 797 int channel = mockLogicalChannelResponses("BF2B038101019000"); 798 799 ResultCaptor<EuiccNotification> resultCaptor = new ResultCaptor<>(); 800 mEuiccCard.retrieveNotification(5, resultCaptor, mHandler); 801 resultCaptor.await(); 802 803 assertEquals(1, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode()); 804 verifyStoreData(channel, "BF2B05A003800105"); 805 } 806 807 @Test 808 public void testRemoveNotificationFromList() { 809 int channel = mockLogicalChannelResponses("BF30038001009000"); 810 811 ResultCaptor<Void> resultCaptor = new ResultCaptor<>(); 812 mEuiccCard.removeNotificationFromList(5, resultCaptor, mHandler); 813 resultCaptor.await(); 814 815 assertUnexpectedException(resultCaptor.exception); 816 verifyStoreData(channel, "BF3003800105"); 817 } 818 819 private void verifyStoreData(int channel, String command) { 820 verify(mMockCi, times(1)) 821 .iccTransmitApduLogicalChannel(eq(channel), eq(0x80 | channel), eq(0xE2), eq(0x91), 822 eq(0), eq(command.length() / 2), eq(command), any()); 823 } 824 825 private int mockLogicalChannelResponses(Object... responses) { 826 int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, 827 "E00582030200009000"); 828 LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, responses); 829 LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel); 830 return channel; 831 } 832} 833