Skip to content

Commit

Permalink
add factory reset (#41)
Browse files Browse the repository at this point in the history
add factory reset
  • Loading branch information
bitgamma authored Apr 30, 2021
1 parent 9679ae2 commit 8cf7cbf
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,20 @@ public void run() {
}).start();
}

@ReactMethod
public void factoryReset(final Promise promise) {
new Thread(new Runnable() {
public void run() {
try {
promise.resolve(smartCard.factoryReset());
} catch (IOException | APDUException e) {
Log.d(TAG, e.getMessage());
promise.reject(e);
}
}
}).start();
}

@ReactMethod
public void deriveKey(final String path, final String pin, final Promise promise) {
new Thread(new Runnable() {
Expand Down
24 changes: 24 additions & 0 deletions android/src/main/java/im/status/ethereum/keycard/SmartCard.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import im.status.keycard.applet.RecoverableSignature;
import im.status.keycard.globalplatform.GlobalPlatformCommandSet;
import im.status.keycard.io.APDUException;
import im.status.keycard.io.APDUResponse;
import im.status.keycard.io.CardChannel;
import im.status.keycard.io.CardListener;
import im.status.keycard.android.NFCCardManager;
Expand Down Expand Up @@ -257,6 +258,29 @@ public WritableMap getApplicationInfo() throws IOException, APDUException {
return cardInfo;
}

public WritableMap factoryReset() throws IOException, APDUException {
GlobalPlatformCommandSet cmdSet = new GlobalPlatformCommandSet(this.cardChannel);
cmdSet.select().checkOK();
Log.i(TAG, "ISD selected");

cmdSet.openSecureChannel();
Log.i(TAG, "SecureChannel opened");

cmdSet.deleteKeycardInstance().checkSW(APDUResponse.SW_OK, APDUResponse.SW_REFERENCED_DATA_NOT_FOUND);
Log.i(TAG, "Keycard applet instance deleted");

cmdSet.installKeycardApplet().checkOK();
Log.i(TAG, "Keycard applet instance re-installed");

ApplicationInfo info = new ApplicationInfo(new KeycardCommandSet(this.cardChannel).select().checkOK().getData());
Log.i(TAG, "Selecting the newly installed Keycard applet succeeded");

WritableMap cardInfo = Arguments.createMap();
cardInfo.putBoolean("initialized?", info.isInitializedCard());

return cardInfo;
}

public void deriveKey(final String path, final String pin) throws IOException, APDUException {
KeycardCommandSet cmdSet = authenticatedCommandSet(pin);

Expand Down
23 changes: 23 additions & 0 deletions ios/SmartCard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,29 @@ class SmartCard {
resolve(true)
}

func factoryReset(channel: CardChannel, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) throws -> Void {
let cmdSet: GlobalPlatformCommandSet = GlobalPlatformCommandSet(cardChannel: channel);
try cmdSet.select().checkOK()
os_log("ISD selected")

try cmdSet.openSecureChannel()
os_log("SecureChannel opened")

try cmdSet.deleteKeycardInstance().checkSW(StatusWord.ok, StatusWord.referencedDataNotFound)
os_log("Keycard applet instance deleted")

try cmdSet.installKeycardInstance().checkOK()
os_log("Keycard applet instance re-installed")

let info = try ApplicationInfo(KeycardCommandSet(cardChannel: channel).select().checkOK().data)
os_log("Selecting the newly installed Keycard applet succeeded")

var cardInfo = [String: Any]()
cardInfo["initialized?"] = info.initializedCard

resolve(cardInfo)
}

func getApplicationInfo(channel: CardChannel, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) throws -> Void {
let cmdSet = KeycardCommandSet(cardChannel: channel)
let info = try ApplicationInfo(cmdSet.select().checkOK().data)
Expand Down
1 change: 1 addition & 0 deletions ios/StatusKeycard.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ @interface RCT_EXTERN_REMAP_MODULE(RNStatusKeycard, StatusKeycard, RCTEventEmitt
RCT_EXTERN_METHOD(generateAndLoadKey:(NSString *)mnemonic pin:(NSString *)pin resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(saveMnemonic:(NSString *)mnemonic pin:(NSString *)pin resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(getApplicationInfo:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(factoryReset:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(deriveKey:(NSString *)path pin:(NSString *)pin resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(exportKey:(NSString *)pin resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
RCT_EXTERN_METHOD(exportKeyWithPath:(NSString *)pin path:(NSString *)path resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject)
Expand Down
5 changes: 5 additions & 0 deletions ios/StatusKeycard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ class StatusKeycard: RCTEventEmitter {
keycardInvokation(reject) { [unowned self] channel in try self.smartCard.saveMnemonic(channel: channel, mnemonic: mnemonic, pin: pin, resolve: resolve, reject: reject) }
}

@objc
func factoryReset(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
keycardInvokation(reject) { [unowned self] channel in try self.smartCard.factoryReset(channel: channel, resolve: resolve, reject: reject) }
}

@objc
func getApplicationInfo(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) -> Void {
keycardInvokation(reject) { [unowned self] channel in try self.smartCard.getApplicationInfo(channel: channel, resolve: resolve, reject: reject) }
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "react-native-status-keycard",
"homepage": "https://keycard.status.im/",
"version": "2.5.34",
"description": "React Native library to interact with Status Keycard using NFC connection (Android only)",
"version": "2.5.35",
"description": "React Native library to interact with Status Keycard using NFC connection",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
Expand Down

0 comments on commit 8cf7cbf

Please sign in to comment.