Compare commits

..
6 changed files with 77 additions and 8 deletions
@@ -218,7 +218,6 @@ public class RNStatusKeycardModule extends ReactContextBaseJavaModule implements
}).start();
}
@ReactMethod
public void getKeys(final String pairing, final String pin, final Promise promise) {
new Thread(new Runnable() {
@@ -233,6 +232,20 @@ public class RNStatusKeycardModule extends ReactContextBaseJavaModule implements
}).start();
}
@ReactMethod
public void importKeys(final String pairing, final String pin, final Promise promise) {
new Thread(new Runnable() {
public void run() {
try {
promise.resolve(smartCard.importKeys(pairing, pin));
} catch (IOException | APDUException e) {
Log.d(TAG, e.getMessage());
promise.reject(e);
}
}
}).start();
}
@ReactMethod
public void sign(final String pairing, final String pin, final String hash, final Promise promise) {
new Thread(new Runnable() {
@@ -446,5 +459,5 @@ public class RNStatusKeycardModule extends ReactContextBaseJavaModule implements
@ReactMethod
public void setNFCMessage(String message, final Promise promise) {
promise.resolve(true);
}
}
}
@@ -341,6 +341,38 @@ public class SmartCard extends BroadcastReceiver implements CardListener {
cmdSet.verifyPIN(pin).checkOK();
Log.i(TAG, "pin verified");
byte[] tlvWhisper = cmdSet.exportKey(WHISPER_PATH, false, false).checkOK().getData();
BIP32KeyPair whisperKeyPair = BIP32KeyPair.fromTLV(tlvWhisper);
byte[] tlvEncryption = cmdSet.exportKey(ENCRYPTION_PATH, false, false).checkOK().getData();
BIP32KeyPair encryptionKeyPair = BIP32KeyPair.fromTLV(tlvEncryption);
ApplicationInfo info = cmdSet.getApplicationInfo();
WritableMap data = Arguments.createMap();
data.putString("whisper-address", Hex.toHexString(whisperKeyPair.toEthereumAddress()));
data.putString("whisper-public-key", Hex.toHexString(whisperKeyPair.getPublicKey()));
data.putString("whisper-private-key", Hex.toHexString(whisperKeyPair.getPrivateKey()));
data.putString("encryption-public-key", Hex.toHexString(encryptionKeyPair.getPublicKey()));
data.putString("instance-uid", Hex.toHexString(info.getInstanceUID()));
data.putString("key-uid", Hex.toHexString(info.getKeyUID()));
return data;
}
public WritableMap importKeys(final String pairingBase64, final String pin) throws IOException, APDUException {
KeycardCommandSet cmdSet = new KeycardCommandSet(this.cardChannel);
cmdSet.select().checkOK();
Pairing pairing = new Pairing(pairingBase64);
cmdSet.setPairing(pairing);
cmdSet.autoOpenSecureChannel();
Log.i(TAG, "secure channel opened");
cmdSet.verifyPIN(pin).checkOK();
Log.i(TAG, "pin verified");
byte[] tlvEncryption = cmdSet.exportKey(ENCRYPTION_PATH, false, false).checkOK().getData();
BIP32KeyPair encryptionKeyPair = BIP32KeyPair.fromTLV(tlvEncryption);
@@ -353,10 +385,10 @@ public class SmartCard extends BroadcastReceiver implements CardListener {
byte[] tlvWhisper = cmdSet.exportKey(WHISPER_PATH, false, false).checkOK().getData();
BIP32KeyPair whisperKeyPair = BIP32KeyPair.fromTLV(tlvWhisper);
byte[] tlvWallet = cmdSet.exportKey(WALLET_PATH, true, true).checkOK().getData();
byte[] tlvWallet = cmdSet.exportKey(WALLET_PATH, false, true).checkOK().getData();
BIP32KeyPair walletKeyPair = BIP32KeyPair.fromTLV(tlvWallet);
ApplicationInfo info = new ApplicationInfo(cmdSet.select().checkOK().getData());
ApplicationInfo info = cmdSet.getApplicationInfo();
WritableMap data = Arguments.createMap();
data.putString("address", Hex.toHexString(masterPair.toEthereumAddress()));
@@ -406,7 +438,7 @@ public class SmartCard extends BroadcastReceiver implements CardListener {
Log.i(TAG, "Derived " + ENCRYPTION_PATH);
BIP32KeyPair encryptionKeyPair = BIP32KeyPair.fromTLV(tlvEncryption);
byte[] tlvWallet = cmdSet.exportKey(WALLET_PATH, true, true).checkOK().getData();
byte[] tlvWallet = cmdSet.exportKey(WALLET_PATH, false, true).checkOK().getData();
Log.i(TAG, "Derived " + WALLET_PATH);
BIP32KeyPair walletKeyPair = BIP32KeyPair.fromTLV(tlvWallet);
+20 -2
View File
@@ -156,7 +156,7 @@ class SmartCard {
resolve(bytesToHex(key))
}
func getKeys(channel: CardChannel, pairingBase64: String, pin: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) throws -> Void {
func importKeys(channel: CardChannel, pairingBase64: String, pin: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) throws -> Void {
let cmdSet = try authenticatedCommandSet(channel: channel, pairingBase64: pairingBase64, pin: pin)
let encryptionKeyPair = try exportKey(cmdSet: cmdSet, path: .encryptionPath, makeCurrent: false, publicOnly: false)
@@ -165,7 +165,7 @@ class SmartCard {
let whisperKeyPair = try exportKey(cmdSet: cmdSet, path: .whisperPath, makeCurrent: false, publicOnly: false)
let walletKeyPair = try exportKey(cmdSet: cmdSet, path: .walletPath, makeCurrent: false, publicOnly: true)
let info = try ApplicationInfo(cmdSet.select().checkOK().data)
let info = cmdSet.info!
resolve([
"address": bytesToHex(masterPair.toEthereumAddress()),
@@ -183,6 +183,24 @@ class SmartCard {
])
}
func getKeys(channel: CardChannel, pairingBase64: String, pin: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) throws -> Void {
let cmdSet = try authenticatedCommandSet(channel: channel, pairingBase64: pairingBase64, pin: pin)
let whisperKeyPair = try exportKey(cmdSet: cmdSet, path: .whisperPath, makeCurrent: false, publicOnly: false)
let encryptionKeyPair = try exportKey(cmdSet: cmdSet, path: .encryptionPath, makeCurrent: false, publicOnly: false)
let info = cmdSet.info!
resolve([
"whisper-address": bytesToHex(whisperKeyPair.toEthereumAddress()),
"whisper-public-key": bytesToHex(whisperKeyPair.publicKey),
"whisper-private-key": bytesToHex(whisperKeyPair.privateKey!),
"encryption-public-key": bytesToHex(encryptionKeyPair.publicKey),
"instance-uid": bytesToHex(info.instanceUID),
"key-uid": bytesToHex(info.keyUID)
])
}
func sign(channel: CardChannel, pairingBase64: String, pin: String, message: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) throws -> Void {
let cmdSet = try authenticatedCommandSet(channel: channel, pairingBase64: pairingBase64, pin: pin)
let sig = try processSignature(message) { return try cmdSet.sign(hash: $0) }
+1
View File
@@ -15,6 +15,7 @@ RCT_EXTERN_METHOD(getApplicationInfo:(NSString *)pairingBase64 resolve:(RCTPromi
RCT_EXTERN_METHOD(deriveKey:(NSString *)path pairing: (NSString *)pairing pin:(NSString *)pin resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(exportKey:(NSString *)pairing pin:(NSString *)pin resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(exportKeyWithPath:(NSString *)pairing pin:(NSString *)pin path:(NSString *)path resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(importKeys:(NSString *)pairing pin:(NSString *)pin resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(getKeys:(NSString *)pairing pin:(NSString *)pin resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(sign:(NSString *)pairing pin:(NSString *)pin hash:(NSString *)hash resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(signWithPath:(NSString *)pairing pin:(NSString *)pin path:(NSString *)path hash:(NSString *)hash resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
+5
View File
@@ -78,6 +78,11 @@ class StatusKeycard: RCTEventEmitter {
keycardInvokation(reject) { [unowned self] channel in try self.smartCard.exportKeyWithPath(channel: channel, pairingBase64: pairing, pin: pin, path: path, resolve: resolve, reject: reject) }
}
@objc
func importKeys(_ pairing: String, pin: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
keycardInvokation(reject) { [unowned self] channel in try self.smartCard.importKeys(channel: channel, pairingBase64: pairing, pin: pin, resolve: resolve, reject: reject) }
}
@objc
func getKeys(_ pairing: String, pin: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
keycardInvokation(reject) { [unowned self] channel in try self.smartCard.getKeys(channel: channel, pairingBase64: pairing, pin: pin, resolve: resolve, reject: reject) }
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "react-native-status-keycard",
"homepage": "https://keycard.status.im/",
"version": "2.5.29",
"version": "2.5.31",
"description": "React Native library to interact with Status Keycard using NFC connection (Android only)",
"main": "index.js",
"scripts": {