@onekeyfe/react-native-lite-card 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +37 -0
- package/ReactNativeLiteCard.podspec +22 -0
- package/android/build.gradle +79 -0
- package/android/gradle.properties +5 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/config/command.json +205 -0
- package/android/src/main/cpp/CMakeLists.txt +19 -0
- package/android/src/main/cpp/validation.c +227 -0
- package/android/src/main/cpp/validation.h +19 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/LoggerManager.kt +35 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/ReactNativeLiteCardModule.kt +420 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/ReactNativeLiteCardPackage.kt +33 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/keys/KeysNativeProvider.kt +13 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/nfc/Exceptions.kt +58 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/nfc/NfcUtils.kt +142 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/nfc/broadcast/NfcStatusChangeBroadcastReceiver.kt +56 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/nfc/gpchannel/GPChannelNatives.kt +32 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/NfcConstant.kt +38 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/OnekeyLiteCard.kt +236 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/APDUParam.kt +17 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/CardInfo.java +84 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/CardResponse.java +37 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/CardState.kt +10 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/ParsedCertInfo.java +39 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/SecureChanelParam.java +113 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/SendResponse.kt +26 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/nfc/CommandGenerator.kt +178 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/nfc/Connection.kt +439 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/nfc/GPCAPDUGenerator.kt +56 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/utils/EventUtils.kt +14 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/utils/GpsUtil.kt +38 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/utils/HexUtils.java +93 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/utils/LogUtil.kt +11 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/utils/MiUtil.kt +93 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/utils/NfcPermissionUtils.kt +24 -0
- package/android/src/main/java/com/onekeyfe/reactnativelitecard/utils/Utils.java +437 -0
- package/android/src/main/jniLibs/arm64-v8a/libgpchannelNDK.so +0 -0
- package/android/src/main/jniLibs/armeabi-v7a/libgpchannelNDK.so +0 -0
- package/ios/Classes/OKLiteCommand/OKLiteCommandModal.h +39 -0
- package/ios/Classes/OKLiteCommand/OKLiteCommandModal.m +143 -0
- package/ios/Classes/OKLiteCommand/OKLiteCommandTool.h +28 -0
- package/ios/Classes/OKLiteCommand/OKLiteCommandTool.m +53 -0
- package/ios/Classes/OKNFCBridge.h +28 -0
- package/ios/Classes/OKNFCBridge.mm +221 -0
- package/ios/Classes/OKNFCLiteDefine.h +108 -0
- package/ios/Classes/OKNFTLite/OKLiteProtocol.h +37 -0
- package/ios/Classes/OKNFTLite/OKLiteV1.h +41 -0
- package/ios/Classes/OKNFTLite/OKLiteV1.m +609 -0
- package/ios/Classes/OKNFTLite/OKLiteV2.h +17 -0
- package/ios/Classes/OKNFTLite/OKLiteV2.m +132 -0
- package/ios/Classes/OKNFTLite/OKNFCManager.h +40 -0
- package/ios/Classes/OKNFTLite/OKNFCManager.m +330 -0
- package/ios/Classes/Utils/NFCConfig.h +19 -0
- package/ios/Classes/Utils/NFCConfig.m +18 -0
- package/ios/Classes/Utils/NSData+OKNFCHexData.h +17 -0
- package/ios/Classes/Utils/NSData+OKNFCHexData.m +24 -0
- package/ios/Classes/Utils/NSData+StringToData.h +12 -0
- package/ios/Classes/Utils/NSData+StringToData.m +25 -0
- package/ios/Classes/Utils/NSString+OKAdd.h +14 -0
- package/ios/Classes/Utils/NSString+OKAdd.m +40 -0
- package/ios/Classes/Utils/NSString+OKNFCHexStr.h +18 -0
- package/ios/Classes/Utils/NSString+OKNFCHexStr.m +38 -0
- package/ios/Classes/Utils/OKNFCUtility.h +18 -0
- package/ios/Classes/Utils/OKNFCUtility.m +22 -0
- package/ios/Classes/Utils/OKTools.h +17 -0
- package/ios/Classes/Utils/OKTools.m +21 -0
- package/ios/GPChannelSDKCore.xcframework/Info.plist +52 -0
- package/ios/GPChannelSDKCore.xcframework/ios-arm64/GPChannelSDKCore.framework/GPChannelSDKCore +0 -0
- package/ios/GPChannelSDKCore.xcframework/ios-arm64/GPChannelSDKCore.framework/Headers/GPChannelSDK.h +315 -0
- package/ios/GPChannelSDKCore.xcframework/ios-arm64/GPChannelSDKCore.framework/Headers/GPChannelSDKCore.h +19 -0
- package/ios/GPChannelSDKCore.xcframework/ios-arm64/GPChannelSDKCore.framework/Info.plist +0 -0
- package/ios/GPChannelSDKCore.xcframework/ios-arm64/GPChannelSDKCore.framework/Modules/module.modulemap +7 -0
- package/ios/GPChannelSDKCore.xcframework/ios-arm64/GPChannelSDKCore.framework/_CodeSignature/CodeResources +147 -0
- package/ios/GPChannelSDKCore.xcframework/ios-arm64_x86_64-simulator/GPChannelSDKCore.framework/GPChannelSDKCore +0 -0
- package/ios/GPChannelSDKCore.xcframework/ios-arm64_x86_64-simulator/GPChannelSDKCore.framework/Headers/GPChannelSDK.h +315 -0
- package/ios/GPChannelSDKCore.xcframework/ios-arm64_x86_64-simulator/GPChannelSDKCore.framework/Headers/GPChannelSDKCore.h +19 -0
- package/ios/GPChannelSDKCore.xcframework/ios-arm64_x86_64-simulator/GPChannelSDKCore.framework/Info.plist +0 -0
- package/ios/GPChannelSDKCore.xcframework/ios-arm64_x86_64-simulator/GPChannelSDKCore.framework/Modules/module.modulemap +7 -0
- package/ios/GPChannelSDKCore.xcframework/ios-arm64_x86_64-simulator/GPChannelSDKCore.framework/_CodeSignature/CodeResources +147 -0
- package/ios/ReactNativeLiteCard.h +5 -0
- package/ios/ReactNativeLiteCard.mm +222 -0
- package/lib/module/NativeReactNativeLiteCard.js +25 -0
- package/lib/module/NativeReactNativeLiteCard.js.map +1 -0
- package/lib/module/index.js +71 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeReactNativeLiteCard.d.ts +59 -0
- package/lib/typescript/src/NativeReactNativeLiteCard.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +23 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/package.json +168 -0
- package/src/NativeReactNativeLiteCard.ts +112 -0
- package/src/index.tsx +94 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
package so.onekey.app.wallet.lite.nfc.broadcast
|
|
2
|
+
|
|
3
|
+
import android.content.BroadcastReceiver
|
|
4
|
+
import android.content.Context
|
|
5
|
+
import android.content.Intent
|
|
6
|
+
import android.content.IntentFilter
|
|
7
|
+
import android.nfc.NfcAdapter
|
|
8
|
+
import android.util.Log
|
|
9
|
+
|
|
10
|
+
open class NfcStatusChangeBroadcastReceiver : BroadcastReceiver() {
|
|
11
|
+
|
|
12
|
+
override fun onReceive(context: Context, intent: Intent) {
|
|
13
|
+
val action = intent.action
|
|
14
|
+
if (NfcAdapter.ACTION_ADAPTER_STATE_CHANGED == action) {
|
|
15
|
+
val state =
|
|
16
|
+
intent.getIntExtra(NfcAdapter.EXTRA_ADAPTER_STATE, NfcAdapter.STATE_OFF)
|
|
17
|
+
|
|
18
|
+
Log.e(TAG, "nfc state broadcast receiver, state is $state")
|
|
19
|
+
when (state) {
|
|
20
|
+
NfcAdapter.STATE_OFF -> onNfcOff()
|
|
21
|
+
NfcAdapter.STATE_ON -> onNfcOn()
|
|
22
|
+
NfcAdapter.STATE_TURNING_OFF -> onNfcTurningOff()
|
|
23
|
+
NfcAdapter.STATE_TURNING_ON -> onNfcTurningOn()
|
|
24
|
+
5 -> onCardPayMode() //samsumg return 5 that minds card pay mode
|
|
25
|
+
else -> onNfcOff()
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
protected open fun onNfcTurningOn() {
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
protected open fun onNfcTurningOff() {
|
|
35
|
+
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
protected open fun onNfcOn() {
|
|
39
|
+
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
protected open fun onNfcOff() {
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
protected open fun onCardPayMode() {
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
companion object {
|
|
51
|
+
val TAG: String = NfcStatusChangeBroadcastReceiver::class.java.simpleName
|
|
52
|
+
|
|
53
|
+
val nfcBroadcastReceiverIntentFilter: IntentFilter
|
|
54
|
+
get() = IntentFilter("android.nfc.action.ADAPTER_STATE_CHANGED")
|
|
55
|
+
}
|
|
56
|
+
}
|
package/android/src/main/java/com/onekeyfe/reactnativelitecard/nfc/gpchannel/GPChannelNatives.kt
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
package org.haobtc.onekey.card.gpchannel
|
|
2
|
+
|
|
3
|
+
/** @Date 2020-07-09 16:29 @Author li @Version 1.0
|
|
4
|
+
*/
|
|
5
|
+
object GPChannelNatives {
|
|
6
|
+
/**
|
|
7
|
+
* 当native接口的返回值不是int时,需要调用该接口获取错误码
|
|
8
|
+
*
|
|
9
|
+
* @return
|
|
10
|
+
*/
|
|
11
|
+
external fun nativeGetErrorCode(): Int
|
|
12
|
+
external fun nativeGPCInitialize(json: String?): Int
|
|
13
|
+
external fun nativeGPCFinalize(): Int
|
|
14
|
+
external fun nativeGPCBuildMutualAuthData(): String
|
|
15
|
+
external fun nativeGPCOpenSecureChannel(response: String?): Int
|
|
16
|
+
external fun nativeGPCBuildAPDU(
|
|
17
|
+
cla: Long, ins: Long, p1: Long, p2: Long, data: String = ""
|
|
18
|
+
): String
|
|
19
|
+
|
|
20
|
+
external fun nativeGPCBuildSafeAPDU(
|
|
21
|
+
cla: Long, ins: Long, p1: Long, p2: Long, data: String = ""
|
|
22
|
+
): String
|
|
23
|
+
|
|
24
|
+
external fun nativeGPCParseSafeAPDUResponse(response: String?): String
|
|
25
|
+
external fun nativeGPCParseAPDUResponse(response: String?): String
|
|
26
|
+
external fun nativeGPCTLVDecode(apdu: String?): String
|
|
27
|
+
external fun nativeGPCParseCertificate(cert: String?): String
|
|
28
|
+
|
|
29
|
+
init {
|
|
30
|
+
System.loadLibrary("gpchannelNDK")
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
package so.onekey.app.wallet.lite.onekeyLite
|
|
2
|
+
|
|
3
|
+
import android.nfc.tech.IsoDep
|
|
4
|
+
import so.onekey.app.wallet.lite.utils.HexUtils
|
|
5
|
+
import java.io.IOException
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @Author: peter Qin
|
|
10
|
+
*/
|
|
11
|
+
object NfcConstant {
|
|
12
|
+
const val DEBUG = false
|
|
13
|
+
const val MNEMONIC = "mnemonics"
|
|
14
|
+
const val MODE = "statusMode"
|
|
15
|
+
const val SELECT_CARD_ID = "select_card_id"
|
|
16
|
+
const val VERIFY_SUCCESS = 100
|
|
17
|
+
const val INTERRUPT_STATUS = 1000
|
|
18
|
+
const val RESET_INTERRUPT_STATUS = 1001
|
|
19
|
+
const val GET_RETRY_NUM_INTERRUPT_STATUS = 1002
|
|
20
|
+
const val RESET_PIN_SUCCESS = -1
|
|
21
|
+
const val CHANGE_PIN_SUCCESS = -10
|
|
22
|
+
const val CHANGE_PIN_ERROR = -100
|
|
23
|
+
const val NEW_PIN = "029000"
|
|
24
|
+
const val MAX_RETRY_NUM = 10
|
|
25
|
+
const val NO_RETRY_NUM_RESET_CARD = 0
|
|
26
|
+
const val NOT_MATCH_DEVICE = "cannot_match_device"
|
|
27
|
+
const val INIT_CHANNEL_SUCCESS = 104
|
|
28
|
+
const val INIT_CHANNEL_FAILURE = 105
|
|
29
|
+
const val STATUS_SUCCESS = "9000"
|
|
30
|
+
const val STATUS_FAILURE = "FFFF"
|
|
31
|
+
const val HAS_BACK_UP = "029000"
|
|
32
|
+
|
|
33
|
+
const val LITE_VERSION = "01"
|
|
34
|
+
const val LITE_LANGUAGE = "00"// english
|
|
35
|
+
const val LITE_TAG = "ffff"
|
|
36
|
+
|
|
37
|
+
private const val RESPONSE_STATUS_LENGTH = 4
|
|
38
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
package so.onekey.app.wallet.lite.onekeyLite
|
|
2
|
+
|
|
3
|
+
import android.app.Activity
|
|
4
|
+
import android.nfc.tech.IsoDep
|
|
5
|
+
import android.util.Log
|
|
6
|
+
import androidx.fragment.app.FragmentActivity
|
|
7
|
+
import androidx.lifecycle.Lifecycle
|
|
8
|
+
import com.google.gson.Gson
|
|
9
|
+
import kotlinx.coroutines.Dispatchers
|
|
10
|
+
import kotlinx.coroutines.withContext
|
|
11
|
+
import so.onekey.app.wallet.lite.nfc.NFCExceptions
|
|
12
|
+
import so.onekey.app.wallet.lite.nfc.NfcUtils
|
|
13
|
+
import so.onekey.app.wallet.lite.onekeyLite.entitys.CardState
|
|
14
|
+
import so.onekey.app.wallet.lite.onekeyLite.nfc.AppleCardType
|
|
15
|
+
import so.onekey.app.wallet.lite.onekeyLite.nfc.Connection
|
|
16
|
+
import so.onekey.app.wallet.lite.onekeyLite.nfc.CommandGenerator
|
|
17
|
+
import so.onekey.app.wallet.lite.utils.LogUtil.printLog
|
|
18
|
+
import so.onekey.app.wallet.lite.utils.NfcPermissionUtils
|
|
19
|
+
|
|
20
|
+
object OneKeyLiteCard {
|
|
21
|
+
const val TAG = "OneKeyLiteCard"
|
|
22
|
+
|
|
23
|
+
private val mCommandGenerator by lazy(LazyThreadSafetyMode.NONE) {
|
|
24
|
+
CommandGenerator()
|
|
25
|
+
}
|
|
26
|
+
private var mCardConnection: Connection? = null
|
|
27
|
+
|
|
28
|
+
suspend fun startNfc(activity: FragmentActivity, callback: ((Boolean) -> Unit)? = null) =
|
|
29
|
+
withContext(Dispatchers.Main) {
|
|
30
|
+
if (NfcUtils.isNfcExits(activity)) {
|
|
31
|
+
val adapter = NfcUtils.init(activity)
|
|
32
|
+
if (adapter == null) {
|
|
33
|
+
printLog(TAG, "startNfc: NfcAdapter is null")
|
|
34
|
+
callback?.invoke(false)
|
|
35
|
+
return@withContext
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
printLog(TAG, "startNfc: ${NfcUtils.isNfcExits(activity)}")
|
|
39
|
+
|
|
40
|
+
NfcPermissionUtils.checkPermission(activity) {
|
|
41
|
+
printLog(TAG, "startNfc Have permission")
|
|
42
|
+
if (!activity.lifecycle.currentState.isAtLeast(Lifecycle.State.RESUMED)) {
|
|
43
|
+
return@checkPermission
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
NfcUtils.mNfcAdapter?.enableForegroundDispatch(
|
|
47
|
+
activity, NfcUtils.mPendingIntent, NfcUtils.mIntentFilter, NfcUtils.mTechList
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
printLog(TAG, "startNfc: enableForegroundDispatch")
|
|
51
|
+
|
|
52
|
+
callback?.invoke(true)
|
|
53
|
+
return@withContext
|
|
54
|
+
}
|
|
55
|
+
Log.e(TAG, "startNfc Not NFC permission")
|
|
56
|
+
callback?.invoke(false)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
fun stopNfc(activity: Activity) {
|
|
60
|
+
NfcUtils.mNfcAdapter?.disableForegroundDispatch(activity)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// first init channel ,can filter not match device
|
|
64
|
+
@Throws(NFCExceptions::class)
|
|
65
|
+
suspend fun initRequest(isoDep: IsoDep?) = withContext(Dispatchers.IO) {
|
|
66
|
+
if (isoDep == null) {
|
|
67
|
+
throw NFCExceptions.ConnectionFailException()
|
|
68
|
+
}
|
|
69
|
+
mCardConnection = Connection(isoDep, mCommandGenerator)
|
|
70
|
+
return@withContext mCardConnection?.getCardInfo()
|
|
71
|
+
?: throw NFCExceptions.InitChannelException()
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@Throws(NFCExceptions::class)
|
|
75
|
+
private fun setupNewPinRequest(isoDep: IsoDep, pin: String?): Boolean {
|
|
76
|
+
if (pin.isNullOrEmpty()) {
|
|
77
|
+
throw NFCExceptions.InputPasswordEmptyException()
|
|
78
|
+
}
|
|
79
|
+
return mCardConnection?.setupNewPin(pin) ?: false
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@Throws(NFCExceptions::class)
|
|
83
|
+
fun changePinRequest(isoDep: IsoDep, oldPwd: String?, newPwd: String?): Int {
|
|
84
|
+
if (oldPwd.isNullOrEmpty()) {
|
|
85
|
+
throw NFCExceptions.InputPasswordEmptyException()
|
|
86
|
+
}
|
|
87
|
+
return mCardConnection?.changePin(oldPwd, newPwd) ?: 0
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@Throws(NFCExceptions::class)
|
|
91
|
+
fun verifyPinBackupRequest(isoDep: IsoDep, verifyPin: String?): Int {
|
|
92
|
+
if (verifyPin.isNullOrEmpty()) {
|
|
93
|
+
throw NFCExceptions.InputPasswordEmptyException()
|
|
94
|
+
}
|
|
95
|
+
return mCardConnection?.startVerifyPin(verifyPin) ?: 0
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@Throws(NFCExceptions::class)
|
|
99
|
+
fun getCardInfo(isoDep: IsoDep): CardState {
|
|
100
|
+
return mCardConnection?.getCardInfo() ?: throw NFCExceptions.ConnectionFailException()
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@Throws(NFCExceptions::class)
|
|
104
|
+
fun setMnemonic(
|
|
105
|
+
cardState: CardState?,
|
|
106
|
+
isoDep: IsoDep,
|
|
107
|
+
mnemonic: String?,
|
|
108
|
+
pwd: String?,
|
|
109
|
+
overwrite: Boolean = false
|
|
110
|
+
): Boolean {
|
|
111
|
+
if (cardState == null) throw NFCExceptions.ConnectionFailException()
|
|
112
|
+
|
|
113
|
+
printLog(TAG, "--> setMnemonic: cardState:${Gson().toJson(cardState)}")
|
|
114
|
+
|
|
115
|
+
if (!overwrite) {
|
|
116
|
+
// 不是覆写要验证是否已经已经存有备份
|
|
117
|
+
if (!cardState.isNewCard || cardState.hasBackup) {
|
|
118
|
+
throw NFCExceptions.InitializedException()
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (overwrite && mCardConnection?.getCardType() == AppleCardType.V2) {
|
|
123
|
+
// Verify the password before clearing the card
|
|
124
|
+
val verifyPin = verifyPinBackupRequest(isoDep, pwd)
|
|
125
|
+
if (verifyPin != NfcConstant.VERIFY_SUCCESS) {
|
|
126
|
+
handlerVerifyPinError(cardState, verifyPin)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// 如果是覆写,并且是V2卡,直接使用 setupNewPinRequest 清空卡片
|
|
130
|
+
cardState.isNewCard = true
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (cardState.isNewCard) {
|
|
134
|
+
// 如果是新卡设置密码
|
|
135
|
+
if (!setupNewPinRequest(isoDep, pwd)) {
|
|
136
|
+
throw NFCExceptions.InitPasswordException()
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
val verifyPin = verifyPinBackupRequest(isoDep, pwd)
|
|
141
|
+
if (verifyPin != NfcConstant.VERIFY_SUCCESS) {
|
|
142
|
+
if (overwrite) {
|
|
143
|
+
handlerVerifyPinError(cardState, verifyPin)
|
|
144
|
+
} else {
|
|
145
|
+
throw NFCExceptions.InitPasswordException()
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return mCardConnection?.backupData(mnemonic ?: "") == true
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@Throws(NFCExceptions::class)
|
|
153
|
+
fun getMnemonicWithPin(cardState: CardState?, isoDep: IsoDep, pwd: String): String {
|
|
154
|
+
if (cardState == null) throw NFCExceptions.ConnectionFailException()
|
|
155
|
+
|
|
156
|
+
if (cardState.isNewCard || !cardState.hasBackup) {
|
|
157
|
+
throw NFCExceptions.NotInitializedException()
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
val verifyPin = verifyPinBackupRequest(isoDep, pwd)
|
|
161
|
+
if (verifyPin != NfcConstant.VERIFY_SUCCESS) {
|
|
162
|
+
handlerVerifyPinError(cardState, verifyPin)
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
val result = mCardConnection?.exportData()
|
|
166
|
+
|
|
167
|
+
if (result.isNullOrEmpty()) {
|
|
168
|
+
throw NFCExceptions.NotInitializedException()
|
|
169
|
+
}
|
|
170
|
+
return result
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@Throws(NFCExceptions::class)
|
|
174
|
+
fun changPin(cardState: CardState?, isoDep: IsoDep, oldPwd: String, newPwd: String): Boolean {
|
|
175
|
+
if (cardState == null) throw NFCExceptions.ConnectionFailException()
|
|
176
|
+
|
|
177
|
+
if (cardState.isNewCard || !cardState.hasBackup) {
|
|
178
|
+
throw NFCExceptions.NotInitializedException()
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
val result = changePinRequest(isoDep, oldPwd, newPwd)
|
|
182
|
+
handlerVerifyPinError(cardState, result, true)
|
|
183
|
+
|
|
184
|
+
return when (result) {
|
|
185
|
+
NfcConstant.CHANGE_PIN_SUCCESS -> {
|
|
186
|
+
true
|
|
187
|
+
}
|
|
188
|
+
NfcConstant.CHANGE_PIN_ERROR -> {
|
|
189
|
+
false
|
|
190
|
+
}
|
|
191
|
+
else -> {
|
|
192
|
+
// 密码错误
|
|
193
|
+
cardState.pinRetryCount = result
|
|
194
|
+
throw NFCExceptions.PasswordWrongException()
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
fun reset(isoDep: IsoDep): Boolean {
|
|
200
|
+
return mCardConnection?.resetCard() == NfcConstant.RESET_PIN_SUCCESS
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private fun handlerVerifyPinError(
|
|
204
|
+
cardState: CardState, status: Int, ignoreDefault: Boolean = false
|
|
205
|
+
) {
|
|
206
|
+
when (status) {
|
|
207
|
+
NfcConstant.RESET_INTERRUPT_STATUS -> {
|
|
208
|
+
// Reset 卡片错误,已经锁定
|
|
209
|
+
throw NFCExceptions.CardLockException()
|
|
210
|
+
}
|
|
211
|
+
NfcConstant.GET_RETRY_NUM_INTERRUPT_STATUS -> {
|
|
212
|
+
// 密码错误
|
|
213
|
+
cardState.pinRetryCount = cardState.pinRetryCount - 1
|
|
214
|
+
if (cardState.pinRetryCount <= 0) {
|
|
215
|
+
throw NFCExceptions.CardLockException()
|
|
216
|
+
} else {
|
|
217
|
+
throw NFCExceptions.PasswordWrongException()
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
NfcConstant.RESET_PIN_SUCCESS -> {
|
|
221
|
+
// Reset 卡片成功
|
|
222
|
+
throw NFCExceptions.UpperErrorAutoResetException()
|
|
223
|
+
}
|
|
224
|
+
NfcConstant.INTERRUPT_STATUS -> {
|
|
225
|
+
throw NFCExceptions.ConnectionFailException()
|
|
226
|
+
}
|
|
227
|
+
else -> {
|
|
228
|
+
if (!ignoreDefault) {
|
|
229
|
+
// 密码错误
|
|
230
|
+
cardState.pinRetryCount = status
|
|
231
|
+
throw NFCExceptions.PasswordWrongException()
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/APDUParam.kt
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
package so.onekey.app.wallet.lite.onekeyLite.entitys
|
|
2
|
+
|
|
3
|
+
data class APDUParam(
|
|
4
|
+
val cla: Long,
|
|
5
|
+
val ins: Long,
|
|
6
|
+
val p1: Long,
|
|
7
|
+
val p2: Long,
|
|
8
|
+
val data: String = ""
|
|
9
|
+
) {
|
|
10
|
+
constructor(command: LongArray, data: String) : this(
|
|
11
|
+
command[0],
|
|
12
|
+
command[1],
|
|
13
|
+
command[2],
|
|
14
|
+
command[3],
|
|
15
|
+
data
|
|
16
|
+
)
|
|
17
|
+
}
|
package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/CardInfo.java
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
package so.onekey.app.wallet.lite.onekeyLite.entitys;
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
import com.google.gson.Gson;
|
|
5
|
+
import com.google.gson.annotations.SerializedName;
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
public class CardInfo {
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* bleVersion :
|
|
12
|
+
* firmwareVersion :
|
|
13
|
+
* label :
|
|
14
|
+
* pinMaxRetry : 10
|
|
15
|
+
* pinRetry : 10
|
|
16
|
+
* sn : BXNFC20052500001
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
@SerializedName("bleVersion")
|
|
20
|
+
private String bleVersion;
|
|
21
|
+
@SerializedName("firmwareVersion")
|
|
22
|
+
private String firmwareVersion;
|
|
23
|
+
@SerializedName("label")
|
|
24
|
+
private String label;
|
|
25
|
+
@SerializedName("pinMaxRetry")
|
|
26
|
+
private int pinMaxRetry;
|
|
27
|
+
@SerializedName("pinRetry")
|
|
28
|
+
private int pinRetry;
|
|
29
|
+
@SerializedName("sn")
|
|
30
|
+
private String sn;
|
|
31
|
+
|
|
32
|
+
public static CardInfo objectFromData(String str) {
|
|
33
|
+
|
|
34
|
+
return new Gson().fromJson(str, CardInfo.class);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public String getBleVersion() {
|
|
38
|
+
return bleVersion;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public void setBleVersion(String bleVersion) {
|
|
42
|
+
this.bleVersion = bleVersion;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public String getFirmwareVersion() {
|
|
46
|
+
return firmwareVersion;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public void setFirmwareVersion(String firmwareVersion) {
|
|
50
|
+
this.firmwareVersion = firmwareVersion;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public String getLabel() {
|
|
54
|
+
return label;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public void setLabel(String label) {
|
|
58
|
+
this.label = label;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public int getPinMaxRetry() {
|
|
62
|
+
return pinMaxRetry;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public void setPinMaxRetry(int pinMaxRetry) {
|
|
66
|
+
this.pinMaxRetry = pinMaxRetry;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public int getPinRetry() {
|
|
70
|
+
return pinRetry;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public void setPinRetry(int pinRetry) {
|
|
74
|
+
this.pinRetry = pinRetry;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public String getSn() {
|
|
78
|
+
return sn;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public void setSn(String sn) {
|
|
82
|
+
this.sn = sn;
|
|
83
|
+
}
|
|
84
|
+
}
|
package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/CardResponse.java
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
package so.onekey.app.wallet.lite.onekeyLite.entitys;
|
|
2
|
+
|
|
3
|
+
import com.google.gson.Gson;
|
|
4
|
+
import com.google.gson.annotations.SerializedName;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @author liyan
|
|
8
|
+
* @date 2020/7/15
|
|
9
|
+
*/
|
|
10
|
+
//
|
|
11
|
+
public class CardResponse {
|
|
12
|
+
|
|
13
|
+
@SerializedName(value = "response", alternate = "value")
|
|
14
|
+
private String response;
|
|
15
|
+
@SerializedName(value = "wRet", alternate = "tag")
|
|
16
|
+
private int wRet;
|
|
17
|
+
|
|
18
|
+
public static CardResponse objectFromData(String str) {
|
|
19
|
+
return new Gson().fromJson(str, CardResponse.class);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public String getResponse() {
|
|
23
|
+
return response;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public void setResponse(String response) {
|
|
27
|
+
this.response = response;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public int getWRet() {
|
|
31
|
+
return wRet;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public void setWRet(int wRet) {
|
|
35
|
+
this.wRet = wRet;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
package so.onekey.app.wallet.lite.onekeyLite.entitys;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @author liyan
|
|
5
|
+
* @date 2/23/21
|
|
6
|
+
*/
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
import com.google.gson.Gson;
|
|
10
|
+
import com.google.gson.annotations.SerializedName;
|
|
11
|
+
|
|
12
|
+
/** sn : subjectID: */
|
|
13
|
+
public class ParsedCertInfo {
|
|
14
|
+
@SerializedName("sn")
|
|
15
|
+
public String sn;
|
|
16
|
+
|
|
17
|
+
@SerializedName("subjectID")
|
|
18
|
+
public String subjectID;
|
|
19
|
+
|
|
20
|
+
public static ParsedCertInfo objectFromData(String str) {
|
|
21
|
+
return new Gson().fromJson(str, ParsedCertInfo.class);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public String getSn() {
|
|
25
|
+
return sn;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
public void setSn(String sn) {
|
|
29
|
+
this.sn = sn;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public String getSubjectID() {
|
|
33
|
+
return subjectID;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public void setSubjectID(String subjectID) {
|
|
37
|
+
this.subjectID = subjectID;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
package so.onekey.app.wallet.lite.onekeyLite.entitys;
|
|
2
|
+
|
|
3
|
+
import androidx.annotation.NonNull;
|
|
4
|
+
|
|
5
|
+
import com.google.gson.Gson;
|
|
6
|
+
import com.google.gson.annotations.SerializedName;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @author liyan
|
|
10
|
+
* @date 2020/7/18
|
|
11
|
+
*/
|
|
12
|
+
//
|
|
13
|
+
public class SecureChanelParam {
|
|
14
|
+
|
|
15
|
+
@SerializedName("scpID")
|
|
16
|
+
private String scpID;
|
|
17
|
+
|
|
18
|
+
@SerializedName("keyUsage")
|
|
19
|
+
private String keyUsage;
|
|
20
|
+
|
|
21
|
+
@SerializedName("keyType")
|
|
22
|
+
private String keyType;
|
|
23
|
+
|
|
24
|
+
@SerializedName("keyLength")
|
|
25
|
+
private int keyLength;
|
|
26
|
+
|
|
27
|
+
@SerializedName("hostID")
|
|
28
|
+
private String hostID;
|
|
29
|
+
|
|
30
|
+
@SerializedName("crt")
|
|
31
|
+
private String crt;
|
|
32
|
+
|
|
33
|
+
@SerializedName("sk")
|
|
34
|
+
private String sk;
|
|
35
|
+
|
|
36
|
+
@SerializedName("cardGroupID")
|
|
37
|
+
private String cardGroupID;
|
|
38
|
+
|
|
39
|
+
public static SecureChanelParam objectFromData(String str) {
|
|
40
|
+
|
|
41
|
+
return new Gson().fromJson(str, SecureChanelParam.class);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public String getScpID() {
|
|
45
|
+
return scpID;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public void setScpID(String scpID) {
|
|
49
|
+
this.scpID = scpID;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public String getKeyUsage() {
|
|
53
|
+
return keyUsage;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public void setKeyUsage(String keyUsage) {
|
|
57
|
+
this.keyUsage = keyUsage;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public String getKeyType() {
|
|
61
|
+
return keyType;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public void setKeyType(String keyType) {
|
|
65
|
+
this.keyType = keyType;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public int getKeyLength() {
|
|
69
|
+
return keyLength;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public void setKeyLength(int keyLength) {
|
|
73
|
+
this.keyLength = keyLength;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public String getHostID() {
|
|
77
|
+
return hostID;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public void setHostID(String hostID) {
|
|
81
|
+
this.hostID = hostID;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public String getCrt() {
|
|
85
|
+
return crt;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public void setCrt(String crt) {
|
|
89
|
+
this.crt = crt;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public String getSk() {
|
|
93
|
+
return sk;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public void setSk(String sk) {
|
|
97
|
+
this.sk = sk;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public String getCardGroupID() {
|
|
101
|
+
return cardGroupID;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public void setCardGroupID(String cardGroupID) {
|
|
105
|
+
this.cardGroupID = cardGroupID;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@NonNull
|
|
109
|
+
@Override
|
|
110
|
+
public String toString() {
|
|
111
|
+
return new Gson().toJson(this);
|
|
112
|
+
}
|
|
113
|
+
}
|
package/android/src/main/java/com/onekeyfe/reactnativelitecard/onekeyLite/entitys/SendResponse.kt
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
package so.onekey.app.wallet.lite.onekeyLite.entitys
|
|
2
|
+
|
|
3
|
+
import so.onekey.app.wallet.lite.utils.HexUtils
|
|
4
|
+
|
|
5
|
+
data class SendResponse(
|
|
6
|
+
// Original return result
|
|
7
|
+
val rawResponse: String,
|
|
8
|
+
val sw1: Byte,
|
|
9
|
+
val sw2: Byte,
|
|
10
|
+
val data: String? = null,
|
|
11
|
+
// Processed result
|
|
12
|
+
var result: String? = null
|
|
13
|
+
) {
|
|
14
|
+
fun isSuccess() = sw1 == 0x90.toByte() && sw2 == 0x00.toByte()
|
|
15
|
+
|
|
16
|
+
fun isConnectFailure() = sw1 == 0x6F.toByte() && sw2 == 0x00.toByte()
|
|
17
|
+
|
|
18
|
+
fun isEmptyData() = data.isNullOrEmpty()
|
|
19
|
+
|
|
20
|
+
fun getCodeBytes(): ByteArray = byteArrayOf(sw1, sw2)
|
|
21
|
+
|
|
22
|
+
fun getCode(): String = HexUtils.byteArr2HexStr(byteArrayOf(sw1, sw2))
|
|
23
|
+
|
|
24
|
+
fun getDataBytes(): ByteArray? =
|
|
25
|
+
if (isEmptyData()) null else HexUtils.hexString2Bytes(data)
|
|
26
|
+
}
|