Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d53ea4792 | ||
|
|
8b46a646c5 | ||
|
|
a11a103620 | ||
|
|
02e6471c10 | ||
|
|
d2168418ee | ||
|
|
d74b800bfa | ||
|
|
52d43a71dd | ||
|
|
2594577503 | ||
|
|
e0b97ae471 |
@@ -8,7 +8,6 @@ import android.content.Intent;
|
|||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.nfc.NfcAdapter;
|
import android.nfc.NfcAdapter;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.util.EventLog;
|
import android.util.EventLog;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -207,6 +206,22 @@ public class SmartCard extends BroadcastReceiver implements CardListener {
|
|||||||
log("seed loaded to card");
|
log("seed loaded to card");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean tryDefaultPairing(KeycardCommandSet cmdSet, String instanceUID, WritableMap cardInfo) throws IOException {
|
||||||
|
try {
|
||||||
|
cmdSet.autoPair("KeycardDefaultPairing");
|
||||||
|
|
||||||
|
Pairing pairing = cmdSet.getPairing();
|
||||||
|
pairings.put(instanceUID, pairing.toBase64());
|
||||||
|
cardInfo.putString("new-pairing", pairing.toBase64());
|
||||||
|
|
||||||
|
openSecureChannel(cmdSet);
|
||||||
|
return true;
|
||||||
|
} catch(APDUException e) {
|
||||||
|
Log.i(TAG, "autoOpenSecureChannel failed: " + e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public WritableMap getApplicationInfo() throws IOException, APDUException {
|
public WritableMap getApplicationInfo() throws IOException, APDUException {
|
||||||
KeycardCommandSet cmdSet = new KeycardCommandSet(this.cardChannel);
|
KeycardCommandSet cmdSet = new KeycardCommandSet(this.cardChannel);
|
||||||
ApplicationInfo info = new ApplicationInfo(cmdSet.select().checkOK().getData());
|
ApplicationInfo info = new ApplicationInfo(cmdSet.select().checkOK().getData());
|
||||||
@@ -227,23 +242,25 @@ public class SmartCard extends BroadcastReceiver implements CardListener {
|
|||||||
|
|
||||||
Boolean isPaired = false;
|
Boolean isPaired = false;
|
||||||
|
|
||||||
if (pairings.containsKey(instanceUID)) {
|
if (!pairings.containsKey(instanceUID)) {
|
||||||
|
isPaired = tryDefaultPairing(cmdSet, instanceUID, cardInfo);
|
||||||
|
} else {
|
||||||
try {
|
try {
|
||||||
openSecureChannel(cmdSet);
|
openSecureChannel(cmdSet);
|
||||||
isPaired = true;
|
isPaired = true;
|
||||||
} catch(APDUException e) {
|
} catch(APDUException e) {
|
||||||
Log.i(TAG, "autoOpenSecureChannel failed: " + e.getMessage());
|
isPaired = tryDefaultPairing(cmdSet, instanceUID, cardInfo);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isPaired) {
|
if (isPaired) {
|
||||||
ApplicationStatus status = new ApplicationStatus(cmdSet.getStatus(KeycardCommandSet.GET_STATUS_P1_APPLICATION).checkOK().getData());
|
ApplicationStatus status = new ApplicationStatus(cmdSet.getStatus(KeycardCommandSet.GET_STATUS_P1_APPLICATION).checkOK().getData());
|
||||||
|
|
||||||
Log.i(TAG, "PIN retry counter: " + status.getPINRetryCount());
|
Log.i(TAG, "PIN retry counter: " + status.getPINRetryCount());
|
||||||
Log.i(TAG, "PUK retry counter: " + status.getPUKRetryCount());
|
Log.i(TAG, "PUK retry counter: " + status.getPUKRetryCount());
|
||||||
|
|
||||||
cardInfo.putInt("pin-retry-counter", status.getPINRetryCount());
|
cardInfo.putInt("pin-retry-counter", status.getPINRetryCount());
|
||||||
cardInfo.putInt("puk-retry-counter", status.getPUKRetryCount());
|
cardInfo.putInt("puk-retry-counter", status.getPUKRetryCount());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cardInfo.putBoolean("has-master-key?", info.hasMasterKey());
|
cardInfo.putBoolean("has-master-key?", info.hasMasterKey());
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package im.status.ethereum.keycard;
|
package im.status.ethereum.keycard;
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
|
|
||||||
import static android.util.Base64.NO_PADDING;
|
import static android.util.Base64.NO_PADDING;
|
||||||
@@ -29,9 +28,8 @@ public class SmartCardSecrets {
|
|||||||
this.pairingPassword = pairingPassword;
|
this.pairingPassword = pairingPassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public static SmartCardSecrets generate(final String userPin) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
public static SmartCardSecrets generate(final String userPin) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||||
String pairingPassword = randomToken(5);
|
String pairingPassword = "KeycardDefaultPairing";
|
||||||
long pinNumber = randomLong(PIN_BOUND);
|
long pinNumber = randomLong(PIN_BOUND);
|
||||||
long pukNumber = randomLong(PUK_BOUND);
|
long pukNumber = randomLong(PUK_BOUND);
|
||||||
|
|
||||||
|
|||||||
+31
-11
@@ -20,11 +20,11 @@ class SmartCard {
|
|||||||
|
|
||||||
func initialize(channel: CardChannel, pin: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) throws -> Void {
|
func initialize(channel: CardChannel, pin: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) throws -> Void {
|
||||||
let puk = self.randomPUK()
|
let puk = self.randomPUK()
|
||||||
let pairingPassword = self.randomPairingPassword();
|
let pairingPassword = "KeycardDefaultPairing"
|
||||||
|
|
||||||
let cmdSet = KeycardCommandSet(cardChannel: channel)
|
let cmdSet = KeycardCommandSet(cardChannel: channel)
|
||||||
try cmdSet.select().checkOK()
|
try cmdSet.select().checkOK()
|
||||||
try cmdSet.initialize(pin: pin, puk: puk, pairingPassword: pairingPassword).checkOK();
|
try cmdSet.initialize(pin: pin, puk: puk, pairingPassword: pairingPassword).checkOK()
|
||||||
|
|
||||||
resolve(["pin": pin, "puk": puk, "password": pairingPassword])
|
resolve(["pin": pin, "puk": puk, "password": pairingPassword])
|
||||||
}
|
}
|
||||||
@@ -129,19 +129,21 @@ class SmartCard {
|
|||||||
try openSecureChannel(cmdSet: cmdSet)
|
try openSecureChannel(cmdSet: cmdSet)
|
||||||
isPaired = true
|
isPaired = true
|
||||||
} catch let error as CardError {
|
} catch let error as CardError {
|
||||||
os_log("autoOpenSecureChannel failed: %@", String(describing: error));
|
isPaired = try tryDefaultPairing(cmdSet: cmdSet, cardInfo: &cardInfo)
|
||||||
} catch let error as StatusWord {
|
} catch let error as StatusWord {
|
||||||
os_log("autoOpenSecureChannel failed: %@", String(describing: error));
|
isPaired = try tryDefaultPairing(cmdSet: cmdSet, cardInfo: &cardInfo)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
isPaired = try tryDefaultPairing(cmdSet: cmdSet, cardInfo: &cardInfo)
|
||||||
|
}
|
||||||
|
|
||||||
if (isPaired) {
|
if (isPaired) {
|
||||||
let status = try ApplicationStatus(cmdSet.getStatus(info: GetStatusP1.application.rawValue).checkOK().data);
|
let status = try ApplicationStatus(cmdSet.getStatus(info: GetStatusP1.application.rawValue).checkOK().data);
|
||||||
os_log("PIN retry counter: %d", status.pinRetryCount)
|
os_log("PIN retry counter: %d", status.pinRetryCount)
|
||||||
os_log("PUK retry counter: %d", status.pukRetryCount)
|
os_log("PUK retry counter: %d", status.pukRetryCount)
|
||||||
|
|
||||||
cardInfo["pin-retry-counter"] = status.pinRetryCount
|
cardInfo["pin-retry-counter"] = status.pinRetryCount
|
||||||
cardInfo["puk-retry-counter"] = status.pukRetryCount
|
cardInfo["puk-retry-counter"] = status.pukRetryCount
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cardInfo["paired?"] = isPaired
|
cardInfo["paired?"] = isPaired
|
||||||
@@ -369,6 +371,24 @@ class SmartCard {
|
|||||||
return cmdSet
|
return cmdSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tryDefaultPairing(cmdSet: KeycardCommandSet, cardInfo: inout [String: Any]) throws -> Bool {
|
||||||
|
do {
|
||||||
|
try cmdSet.autoPair(password: "KeycardDefaultPairing")
|
||||||
|
let pairing = Data(cmdSet.pairing!.bytes).base64EncodedString()
|
||||||
|
self.pairings[bytesToHex(cmdSet.info!.instanceUID)] = pairing
|
||||||
|
cardInfo["new-pairing"] = pairing
|
||||||
|
|
||||||
|
try openSecureChannel(cmdSet: cmdSet)
|
||||||
|
return true
|
||||||
|
} catch let error as CardError {
|
||||||
|
os_log("autoOpenSecureChannel failed: %@", String(describing: error));
|
||||||
|
} catch let error as StatusWord {
|
||||||
|
os_log("autoOpenSecureChannel failed: %@", String(describing: error));
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func openSecureChannel(cmdSet: KeycardCommandSet) throws -> Void {
|
func openSecureChannel(cmdSet: KeycardCommandSet) throws -> Void {
|
||||||
if let pairingBase64 = self.pairings[bytesToHex(cmdSet.info!.instanceUID)] {
|
if let pairingBase64 = self.pairings[bytesToHex(cmdSet.info!.instanceUID)] {
|
||||||
cmdSet.pairing = try base64ToPairing(pairingBase64)
|
cmdSet.pairing = try base64ToPairing(pairingBase64)
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "react-native-status-keycard",
|
"name": "react-native-status-keycard",
|
||||||
"homepage": "https://keycard.status.im/",
|
"homepage": "https://keycard.status.im/",
|
||||||
"version": "2.5.35",
|
"version": "2.5.36",
|
||||||
"description": "React Native library to interact with Status Keycard using NFC connection",
|
"description": "React Native library to interact with Status Keycard using NFC connection",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Reference in New Issue
Block a user