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