35
35
import im .status .keycard .applet .ApplicationStatus ;
36
36
import im .status .keycard .applet .BIP32KeyPair ;
37
37
import im .status .keycard .applet .Mnemonic ;
38
+ import im .status .keycard .applet .Metadata ;
38
39
import im .status .keycard .applet .CashCommandSet ;
39
40
import im .status .keycard .applet .KeycardCommandSet ;
40
41
import im .status .keycard .applet .Pairing ;
@@ -285,8 +286,11 @@ public WritableMap getApplicationInfo() throws IOException, APDUException {
285
286
286
287
if (info .isInitializedCard ()) {
287
288
String instanceUID = Hex .toHexString (info .getInstanceUID ());
289
+ String cardName = getCardNameOrDefault (cmdSet );
290
+ cardInfo .putString ("card-name" , cardName );
288
291
289
292
Log .i (TAG , "Instance UID: " + instanceUID );
293
+ Log .i (TAG , "Card name: " + cardName );
290
294
Log .i (TAG , "Key UID: " + Hex .toHexString (info .getKeyUID ()));
291
295
Log .i (TAG , "Secure channel public key: " + Hex .toHexString (info .getSecureChannelPubKey ()));
292
296
Log .i (TAG , "Application version: " + info .getAppVersionString ());
@@ -437,31 +441,37 @@ public WritableMap getKeys(final String pin) throws IOException, APDUException {
437
441
438
442
public WritableMap importKeys (final String pin ) throws IOException , APDUException {
439
443
KeycardCommandSet cmdSet = authenticatedCommandSet (pin );
444
+ ApplicationInfo info = cmdSet .getApplicationInfo ();
445
+
446
+ byte p2 = (info .getAppVersion () < 0x0310 ) ? KeycardCommandSet .EXPORT_KEY_P2_PUBLIC_ONLY : KeycardCommandSet .EXPORT_KEY_P2_EXTENDED_PUBLIC ;
440
447
441
448
byte [] tlvEncryption = cmdSet .exportKey (ENCRYPTION_PATH , false , false ).checkOK ().getData ();
442
449
BIP32KeyPair encryptionKeyPair = BIP32KeyPair .fromTLV (tlvEncryption );
443
450
444
451
byte [] tlvMaster = cmdSet .exportKey (MASTER_PATH , false , true ).checkOK ().getData ();
445
452
BIP32KeyPair masterPair = BIP32KeyPair .fromTLV (tlvMaster );
446
453
447
- byte [] tlvRoot = cmdSet .exportKey (ROOT_PATH , false , true ).checkOK ().getData ();
448
- BIP32KeyPair keyPair = BIP32KeyPair .fromTLV (tlvRoot );
454
+ byte [] tlvRoot = cmdSet .exportKey (ROOT_PATH , false , p2 ).checkOK ().getData ();
455
+ BIP32KeyPair rootKeyPair = BIP32KeyPair .fromTLV (tlvRoot );
449
456
450
457
byte [] tlvWhisper = cmdSet .exportKey (WHISPER_PATH , false , false ).checkOK ().getData ();
451
458
BIP32KeyPair whisperKeyPair = BIP32KeyPair .fromTLV (tlvWhisper );
452
459
453
- byte [] tlvWallet = cmdSet .exportKey (WALLET_PATH , false , true ).checkOK ().getData ();
454
- BIP32KeyPair walletKeyPair = BIP32KeyPair .fromTLV (tlvWallet );
455
-
456
- ApplicationInfo info = cmdSet .getApplicationInfo ();
457
-
458
460
WritableMap data = Arguments .createMap ();
459
461
data .putString ("address" , Hex .toHexString (masterPair .toEthereumAddress ()));
460
462
data .putString ("public-key" , Hex .toHexString (masterPair .getPublicKey ()));
461
- data .putString ("wallet-root-address" , Hex .toHexString (keyPair .toEthereumAddress ()));
462
- data .putString ("wallet-root-public-key" , Hex .toHexString (keyPair .getPublicKey ()));
463
- data .putString ("wallet-address" , Hex .toHexString (walletKeyPair .toEthereumAddress ()));
464
- data .putString ("wallet-public-key" , Hex .toHexString (walletKeyPair .getPublicKey ()));
463
+ data .putString ("wallet-root-address" , Hex .toHexString (rootKeyPair .toEthereumAddress ()));
464
+ data .putString ("wallet-root-public-key" , Hex .toHexString (rootKeyPair .getPublicKey ()));
465
+
466
+ if (rootKeyPair .isExtended ()) {
467
+ data .putString ("wallet-root-chain-code" , Hex .toHexString (rootKeyPair .getChainCode ()));
468
+ } //else { (for now we return both keys, because xpub support is not yet available)
469
+ byte [] tlvWallet = cmdSet .exportKey (WALLET_PATH , false , true ).checkOK ().getData ();
470
+ BIP32KeyPair walletKeyPair = BIP32KeyPair .fromTLV (tlvWallet );
471
+ data .putString ("wallet-address" , Hex .toHexString (walletKeyPair .toEthereumAddress ()));
472
+ data .putString ("wallet-public-key" , Hex .toHexString (walletKeyPair .getPublicKey ()));
473
+ //}
474
+
465
475
data .putString ("whisper-address" , Hex .toHexString (whisperKeyPair .toEthereumAddress ()));
466
476
data .putString ("whisper-public-key" , Hex .toHexString (whisperKeyPair .getPublicKey ()));
467
477
data .putString ("whisper-private-key" , Hex .toHexString (whisperKeyPair .getPrivateKey ()));
@@ -474,14 +484,15 @@ public WritableMap importKeys(final String pin) throws IOException, APDUExceptio
474
484
475
485
public WritableMap generateAndLoadKey (final String mnemonic , final String pin ) throws IOException , APDUException {
476
486
KeycardCommandSet cmdSet = authenticatedCommandSet (pin );
487
+ byte p2 = (cmdSet .getApplicationInfo ().getAppVersion () < 0x0310 ) ? KeycardCommandSet .EXPORT_KEY_P2_PUBLIC_ONLY : KeycardCommandSet .EXPORT_KEY_P2_EXTENDED_PUBLIC ;
477
488
478
489
byte [] seed = Mnemonic .toBinarySeed (mnemonic , "" );
479
490
BIP32KeyPair keyPair = BIP32KeyPair .fromBinarySeed (seed );
480
491
481
492
cmdSet .loadKey (keyPair ).checkOK ();
482
493
log ("keypair loaded to card" );
483
494
484
- byte [] tlvRoot = cmdSet .exportKey (ROOT_PATH , false , true ).checkOK ().getData ();
495
+ byte [] tlvRoot = cmdSet .exportKey (ROOT_PATH , false , p2 ).checkOK ().getData ();
485
496
Log .i (TAG , "Derived " + ROOT_PATH );
486
497
BIP32KeyPair rootKeyPair = BIP32KeyPair .fromTLV (tlvRoot );
487
498
@@ -493,23 +504,28 @@ public WritableMap generateAndLoadKey(final String mnemonic, final String pin) t
493
504
Log .i (TAG , "Derived " + ENCRYPTION_PATH );
494
505
BIP32KeyPair encryptionKeyPair = BIP32KeyPair .fromTLV (tlvEncryption );
495
506
496
- byte [] tlvWallet = cmdSet .exportKey (WALLET_PATH , false , true ).checkOK ().getData ();
497
- Log .i (TAG , "Derived " + WALLET_PATH );
498
- BIP32KeyPair walletKeyPair = BIP32KeyPair .fromTLV (tlvWallet );
499
-
500
- ApplicationInfo info = new ApplicationInfo (cmdSet .select ().checkOK ().getData ());
501
-
502
507
WritableMap data = Arguments .createMap ();
503
508
data .putString ("address" , Hex .toHexString (keyPair .toEthereumAddress ()));
504
509
data .putString ("public-key" , Hex .toHexString (keyPair .getPublicKey ()));
505
510
data .putString ("wallet-root-address" , Hex .toHexString (rootKeyPair .toEthereumAddress ()));
506
511
data .putString ("wallet-root-public-key" , Hex .toHexString (rootKeyPair .getPublicKey ()));
507
- data .putString ("wallet-address" , Hex .toHexString (walletKeyPair .toEthereumAddress ()));
508
- data .putString ("wallet-public-key" , Hex .toHexString (walletKeyPair .getPublicKey ()));
512
+
513
+ if (rootKeyPair .isExtended ()) {
514
+ data .putString ("wallet-root-chain-code" , Hex .toHexString (rootKeyPair .getChainCode ()));
515
+ } //else { (see note above)
516
+ byte [] tlvWallet = cmdSet .exportKey (WALLET_PATH , false , true ).checkOK ().getData ();
517
+ BIP32KeyPair walletKeyPair = BIP32KeyPair .fromTLV (tlvWallet );
518
+ data .putString ("wallet-address" , Hex .toHexString (walletKeyPair .toEthereumAddress ()));
519
+ data .putString ("wallet-public-key" , Hex .toHexString (walletKeyPair .getPublicKey ()));
520
+ //}
521
+
509
522
data .putString ("whisper-address" , Hex .toHexString (whisperKeyPair .toEthereumAddress ()));
510
523
data .putString ("whisper-public-key" , Hex .toHexString (whisperKeyPair .getPublicKey ()));
511
524
data .putString ("whisper-private-key" , Hex .toHexString (whisperKeyPair .getPrivateKey ()));
512
525
data .putString ("encryption-public-key" , Hex .toHexString (encryptionKeyPair .getPublicKey ()));
526
+
527
+ ApplicationInfo info = new ApplicationInfo (cmdSet .select ().checkOK ().getData ());
528
+
513
529
data .putString ("instance-uid" , Hex .toHexString (info .getInstanceUID ()));
514
530
data .putString ("key-uid" , Hex .toHexString (info .getKeyUID ()));
515
531
@@ -662,6 +678,19 @@ public String signPinless(final String message) throws IOException, APDUExceptio
662
678
return sig ;
663
679
}
664
680
681
+ public String getCardName () throws IOException , APDUException {
682
+ KeycardCommandSet cmdSet = new KeycardCommandSet (this .cardChannel );
683
+ cmdSet .select ().checkOK ();
684
+ return getCardNameOrDefault (cmdSet );
685
+ }
686
+
687
+ public void setCardName (final String pin , final String name ) throws IOException , APDUException {
688
+ KeycardCommandSet cmdSet = authenticatedCommandSet (pin );
689
+
690
+ Metadata m = new Metadata (name );
691
+ cmdSet .storeData (m .toByteArray (), KeycardCommandSet .STORE_DATA_P1_PUBLIC ).checkOK ();
692
+ }
693
+
665
694
public WritableMap verifyCard (final String challenge ) throws IOException , APDUException {
666
695
KeycardCommandSet cmdSet = new KeycardCommandSet (this .cardChannel );
667
696
cmdSet .select ().checkOK ();
@@ -714,6 +743,17 @@ private KeycardCommandSet securedCommandSet() throws IOException, APDUException
714
743
return cmdSet ;
715
744
}
716
745
746
+ private String getCardNameOrDefault (KeycardCommandSet cmdSet ) throws IOException , APDUException {
747
+ byte [] data = cmdSet .getData (KeycardCommandSet .STORE_DATA_P1_PUBLIC ).checkOK ().getData ();
748
+
749
+ try {
750
+ Metadata m = Metadata .fromData (data );
751
+ return m .getCardName ();
752
+ } catch (Exception e ) {
753
+ return "" ;
754
+ }
755
+ }
756
+
717
757
private void openSecureChannel (KeycardCommandSet cmdSet ) throws IOException , APDUException {
718
758
String instanceUID = Hex .toHexString (cmdSet .getApplicationInfo ().getInstanceUID ());
719
759
String pairingBase64 = pairings .get (instanceUID );
0 commit comments