@digitalshieldfe/react-native-backup-card-sdk 0.1.4 → 0.1.6
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/android/build.gradle +33 -49
- package/android/libs/backupcardsdk.aar +0 -0
- package/android/src/main/AndroidManifest.xml +1 -4
- package/android/src/main/java/com/ziancube/reactnativebackupcardsdk/BackupCardSdkModule.kt +244 -74
- package/android/src/main/java/com/ziancube/reactnativebackupcardsdk/BackupCardSdkPackage.kt +1 -1
- package/android/src/main/java/com/ziancube/reactnativebackupcardsdk/nfc/NfcExceptions.kt +11 -0
- package/android/src/main/java/com/ziancube/reactnativebackupcardsdk/nfc/NfcUtils.kt +30 -0
- package/android/src/main/java/com/ziancube/reactnativebackupcardsdk/utils/MiUtil.kt +74 -0
- package/android/src/main/java/com/ziancube/reactnativebackupcardsdk/utils/NfcPermissionUtils.kt +23 -0
- package/lib/module/NativeBackupCardSdk.js +3 -0
- package/lib/module/NativeBackupCardSdk.js.map +1 -1
- package/lib/module/cardOperations.js +27 -0
- package/lib/module/cardOperations.js.map +1 -0
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/nfc.js +75 -0
- package/lib/module/nfc.js.map +1 -0
- package/lib/typescript/src/NativeBackupCardSdk.d.ts +50 -4
- package/lib/typescript/src/NativeBackupCardSdk.d.ts.map +1 -1
- package/lib/typescript/src/cardOperations.d.ts +7 -0
- package/lib/typescript/src/cardOperations.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +5 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/nfc.d.ts +28 -0
- package/lib/typescript/src/nfc.d.ts.map +1 -0
- package/package.json +7 -5
- package/src/NativeBackupCardSdk.ts +62 -4
- package/src/cardOperations.ts +61 -0
- package/src/index.tsx +22 -2
- package/src/nfc.ts +74 -0
- package/android/consumer-rules.pro +0 -0
- package/android/proguard-rules.pro +0 -21
- package/android/src/main/java/com/ziancube/backupcardsdk/BackupCardSdk.kt +0 -478
- package/android/src/main/java/com/ziancube/backupcardsdk/GPChannelNatives.java +0 -41
- package/android/src/main/java/com/ziancube/backupcardsdk/listener/ApiAsyncListener.java +0 -13
- package/android/src/main/java/com/ziancube/backupcardsdk/nfc/ApiNfc.java +0 -173
- package/android/src/main/java/com/ziancube/backupcardsdk/nfc/ImplNfc.java +0 -39
- package/android/src/main/java/com/ziancube/backupcardsdk/nfc/NfcComm.java +0 -115
- package/android/src/main/java/com/ziancube/backupcardsdk/utils/ApduParam.java +0 -67
- package/android/src/main/java/com/ziancube/backupcardsdk/utils/CommList.java +0 -41
- package/android/src/main/java/com/ziancube/backupcardsdk/utils/Utils.java +0 -109
- package/android/src/main/jni/CMakeLists.txt +0 -60
- package/android/src/main/jni/GPChannel/include/GPChannelSDK.h +0 -306
- package/android/src/main/jni/GPChannel/include/context/BaseContext.h +0 -56
- package/android/src/main/jni/GPChannel/include/device/ApduBuilder.hpp +0 -72
- package/android/src/main/jni/GPChannel/include/utility/Apdu.hpp +0 -166
- package/android/src/main/jni/GPChannel/include/utility/Debug.hpp +0 -59
- package/android/src/main/jni/GPChannel/include/utility/Singleton.h +0 -34
- package/android/src/main/jni/GPChannel/include/utility/mutex.h +0 -24
- package/android/src/main/jni/GPChannel/include/utility/trim.hpp +0 -155
- package/android/src/main/jni/GPChannel/include/utility/util.h +0 -104
- package/android/src/main/jni/GPChannel/include/utility/xFactory.hpp +0 -26
- package/android/src/main/jni/GPChannel/include/utility/xManager.hpp +0 -84
- package/android/src/main/jni/GPChannel/src/arm64-v8a/libJUB_GPC_APDU_SDK.a +0 -0
- package/android/src/main/jni/GPChannel/src/arm64-v8a/libTrezorCrypto.a +0 -0
- package/android/src/main/jni/GPChannel/src/armeabi-v7a/libJUB_GPC_APDU_SDK.a +0 -0
- package/android/src/main/jni/GPChannel/src/armeabi-v7a/libTrezorCrypto.a +0 -0
- package/android/src/main/jni/GPChannel/src/x86/libJUB_GPC_APDU_SDK.a +0 -0
- package/android/src/main/jni/GPChannel/src/x86/libTrezorCrypto.a +0 -0
- package/android/src/main/jni/src/implJni.cpp +0 -313
- package/android/src/main/jni/src/implJni.h +0 -9
- package/android/src/main/jni/utils/jsoncpp/AUTHORS +0 -111
- package/android/src/main/jni/utils/jsoncpp/CMakeLists.txt +0 -159
- package/android/src/main/jni/utils/jsoncpp/LICENSE +0 -55
- package/android/src/main/jni/utils/jsoncpp/README.md +0 -135
- package/android/src/main/jni/utils/jsoncpp/amalgamate.py +0 -155
- package/android/src/main/jni/utils/jsoncpp/appveyor.yml +0 -22
- package/android/src/main/jni/utils/jsoncpp/dev.makefile +0 -35
- package/android/src/main/jni/utils/jsoncpp/devtools/__init__.py +0 -6
- package/android/src/main/jni/utils/jsoncpp/devtools/agent_vmw7.json +0 -33
- package/android/src/main/jni/utils/jsoncpp/devtools/agent_vmxp.json +0 -26
- package/android/src/main/jni/utils/jsoncpp/devtools/antglob.py +0 -205
- package/android/src/main/jni/utils/jsoncpp/devtools/batchbuild.py +0 -278
- package/android/src/main/jni/utils/jsoncpp/devtools/fixeol.py +0 -70
- package/android/src/main/jni/utils/jsoncpp/devtools/licenseupdater.py +0 -94
- package/android/src/main/jni/utils/jsoncpp/devtools/tarball.py +0 -52
- package/android/src/main/jni/utils/jsoncpp/doxybuild.py +0 -189
- package/android/src/main/jni/utils/jsoncpp/include/CMakeLists.txt +0 -2
- package/android/src/main/jni/utils/jsoncpp/include/json/allocator.h +0 -98
- package/android/src/main/jni/utils/jsoncpp/include/json/assertions.h +0 -54
- package/android/src/main/jni/utils/jsoncpp/include/json/autolink.h +0 -25
- package/android/src/main/jni/utils/jsoncpp/include/json/config.h +0 -187
- package/android/src/main/jni/utils/jsoncpp/include/json/features.h +0 -61
- package/android/src/main/jni/utils/jsoncpp/include/json/forwards.h +0 -37
- package/android/src/main/jni/utils/jsoncpp/include/json/json.h +0 -15
- package/android/src/main/jni/utils/jsoncpp/include/json/reader.h +0 -411
- package/android/src/main/jni/utils/jsoncpp/include/json/value.h +0 -888
- package/android/src/main/jni/utils/jsoncpp/include/json/version.h +0 -20
- package/android/src/main/jni/utils/jsoncpp/include/json/writer.h +0 -357
- package/android/src/main/jni/utils/jsoncpp/makefiles/vs71/jsontest.vcproj +0 -119
- package/android/src/main/jni/utils/jsoncpp/makefiles/vs71/lib_json.vcproj +0 -205
- package/android/src/main/jni/utils/jsoncpp/makefiles/vs71/test_lib_json.vcproj +0 -130
- package/android/src/main/jni/utils/jsoncpp/makerelease.py +0 -390
- package/android/src/main/jni/utils/jsoncpp/meson.build +0 -103
- package/android/src/main/jni/utils/jsoncpp/pkg-config/jsoncpp.pc.in +0 -9
- package/android/src/main/jni/utils/jsoncpp/src/CMakeLists.txt +0 -5
- package/android/src/main/jni/utils/jsoncpp/src/jsontestrunner/CMakeLists.txt +0 -25
- package/android/src/main/jni/utils/jsoncpp/src/jsontestrunner/main.cpp +0 -333
- package/android/src/main/jni/utils/jsoncpp/src/lib_json/CMakeLists.txt +0 -117
- package/android/src/main/jni/utils/jsoncpp/src/lib_json/json_reader.cpp +0 -2060
- package/android/src/main/jni/utils/jsoncpp/src/lib_json/json_tool.h +0 -114
- package/android/src/main/jni/utils/jsoncpp/src/lib_json/json_value.cpp +0 -1661
- package/android/src/main/jni/utils/jsoncpp/src/lib_json/json_valueiterator.inl +0 -167
- package/android/src/main/jni/utils/jsoncpp/src/lib_json/json_writer.cpp +0 -1233
- package/android/src/main/jni/utils/jsoncpp/src/lib_json/version.h.in +0 -20
- package/android/src/main/jni/utils/jsoncpp/src/test_lib_json/CMakeLists.txt +0 -38
- package/android/src/main/jni/utils/jsoncpp/src/test_lib_json/jsontest.cpp +0 -457
- package/android/src/main/jni/utils/jsoncpp/src/test_lib_json/jsontest.h +0 -286
- package/android/src/main/jni/utils/jsoncpp/src/test_lib_json/main.cpp +0 -2606
- package/android/src/main/jni/utils/jsoncpp/travis.sh +0 -23
- package/android/src/main/jni/utils/jsoncpp/version +0 -1
- package/android/src/main/jni/utils/jsoncpp/version.in +0 -1
- package/android/src/main/jni/utils/logUtils.cpp +0 -108
- package/android/src/main/jni/utils/logUtils.h +0 -87
- package/android/src/main/jni/utils/mSIGNA/stdutils/uchar_vector.h +0 -614
|
@@ -1,478 +0,0 @@
|
|
|
1
|
-
package com.ziancube.backupcardsdk
|
|
2
|
-
|
|
3
|
-
import android.app.Activity
|
|
4
|
-
import android.app.Application
|
|
5
|
-
import android.text.TextUtils;
|
|
6
|
-
import android.content.Intent
|
|
7
|
-
import android.nfc.NfcAdapter
|
|
8
|
-
import android.os.Bundle
|
|
9
|
-
import androidx.core.util.Consumer
|
|
10
|
-
import com.ziancube.backupcardsdk.listener.ApiAsyncListener
|
|
11
|
-
import com.ziancube.backupcardsdk.nfc.ApiNfc
|
|
12
|
-
import org.json.JSONObject
|
|
13
|
-
import kotlin.coroutines.resume
|
|
14
|
-
import kotlin.coroutines.suspendCoroutine
|
|
15
|
-
import com.ziancube.backupcardsdk.utils.ApduParam
|
|
16
|
-
import com.ziancube.backupcardsdk.utils.Utils
|
|
17
|
-
|
|
18
|
-
interface ApduLogger {
|
|
19
|
-
fun log(message: String, isSent: Boolean, isSuccess: Boolean = true)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
interface NfcTouchListener {
|
|
23
|
-
fun onTouch(isBackupCard: Boolean)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
data class ApduResult(val resultCode: Int, val data: String?)
|
|
27
|
-
data class CardInfo(val serialNumber: String?, val pinRetryCount: Int?, val isNewCard: Boolean?)
|
|
28
|
-
|
|
29
|
-
class BackupCardSdk(
|
|
30
|
-
private val activity: Activity,
|
|
31
|
-
private val apduLogger: ApduLogger,
|
|
32
|
-
private val nfcTouchListener: NfcTouchListener
|
|
33
|
-
) {
|
|
34
|
-
private val apiNfc = ApiNfc.getInstance(activity)
|
|
35
|
-
private val OCE_CRT =
|
|
36
|
-
"7f2181bc93036170704209646576656c6f7065725f2003617070950200805f2504202605265f24042036052653007f4946b041044f07c304cd5ff2d89bfc28771fe08be408563c58108cb8010e8788c6683bf693d70f62fb7c1f9195b18972b6cf6b91f45ba15818ea72533500a06deb55306400f001005f3746304402204cfd10dd22babed4c1a422a4cfadd02df9ac89436c309cf51ea64526c48a2afb022033ca1b474f3915c44739ed40bc30d8f4aa442718c042f2c3054675ed9df61215";
|
|
37
|
-
private val AID = "6469676974736869656c64" // digitalshield
|
|
38
|
-
private var needReconnect = true;
|
|
39
|
-
private val application = activity.application
|
|
40
|
-
|
|
41
|
-
private val lifecycleCallbacks =
|
|
42
|
-
object : Application.ActivityLifecycleCallbacks {
|
|
43
|
-
override fun onActivityResumed(target: Activity) {
|
|
44
|
-
if (target === activity) {
|
|
45
|
-
apiNfc.onResume()
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
override fun onActivityPaused(target: Activity) {
|
|
50
|
-
if (target === activity) {
|
|
51
|
-
apiNfc.onPause()
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
override fun onActivityDestroyed(target: Activity) {
|
|
56
|
-
if (target === activity) {
|
|
57
|
-
apiNfc.onDestroy()
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
override fun onActivityCreated(a: Activity, b: Bundle?) {}
|
|
62
|
-
override fun onActivityStarted(a: Activity) {}
|
|
63
|
-
override fun onActivityStopped(a: Activity) {}
|
|
64
|
-
override fun onActivitySaveInstanceState(a: Activity, b: Bundle) {}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
init {
|
|
68
|
-
handleIntent(activity.intent)
|
|
69
|
-
application.registerActivityLifecycleCallbacks(lifecycleCallbacks)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
fun release() {
|
|
73
|
-
application.unregisterActivityLifecycleCallbacks(lifecycleCallbacks)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
fun handleIntent(intent: Intent?) {
|
|
77
|
-
if (intent == null || !isNfcIntent(intent)) {
|
|
78
|
-
return
|
|
79
|
-
}
|
|
80
|
-
needReconnect = true
|
|
81
|
-
val re = apiNfc.setCardTag(intent)
|
|
82
|
-
if (re == 0) {
|
|
83
|
-
nfcTouchListener.onTouch(true)
|
|
84
|
-
} else {
|
|
85
|
-
nfcTouchListener.onTouch(false)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
private fun isNfcIntent(intent: Intent): Boolean {
|
|
90
|
-
return intent.action == NfcAdapter.ACTION_TAG_DISCOVERED ||
|
|
91
|
-
intent.action == NfcAdapter.ACTION_NDEF_DISCOVERED ||
|
|
92
|
-
intent.action == NfcAdapter.ACTION_TECH_DISCOVERED
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
private fun buildApdu(cla: Long,ins: Long,p1: Long,p2: Long,data: String,isSecureChannel: Boolean): ByteArray? {
|
|
96
|
-
if (isSecureChannel) {
|
|
97
|
-
val safeApdu = GPChannelNatives.nativeGPCBuildSafeAPDU(cla, ins, p1, p2, data)
|
|
98
|
-
apduLogger.log(safeApdu, true)
|
|
99
|
-
return Utils.hexString2Bytes(safeApdu)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
val apdu = GPChannelNatives.nativeGPCBuildAPDU(cla, ins, p1, p2, data)
|
|
103
|
-
apduLogger.log(apdu, true)
|
|
104
|
-
return Utils.hexString2Bytes(apdu)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
private fun parseResponse(resp: String, isSecureChannel: Boolean): ApduResult? {
|
|
108
|
-
val res = if (isSecureChannel) {
|
|
109
|
-
GPChannelNatives.nativeGPCParseSafeAPDUResponse(resp)
|
|
110
|
-
} else {
|
|
111
|
-
GPChannelNatives.nativeGPCParseAPDUResponse(resp)
|
|
112
|
-
}
|
|
113
|
-
val apdu_result = toApduResult(res, -1)
|
|
114
|
-
apduLogger.log(resp, false, apdu_result.resultCode == 0x9000)
|
|
115
|
-
return apdu_result
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
private fun toApduResult(parsedResponse: String?, fallbackCode: Int): ApduResult {
|
|
119
|
-
if (parsedResponse.isNullOrBlank()) {
|
|
120
|
-
return ApduResult(fallbackCode, null)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return runCatching {
|
|
124
|
-
val json = JSONObject(parsedResponse)
|
|
125
|
-
val response = json.optString("response").takeIf { it.isNotEmpty() }
|
|
126
|
-
val wRet = json.optInt("wRet", fallbackCode)
|
|
127
|
-
ApduResult(wRet, response)
|
|
128
|
-
}.getOrElse {
|
|
129
|
-
ApduResult(fallbackCode, parsedResponse)
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
suspend private fun sendApdu(apduParam: ApduParam): ApduResult {
|
|
134
|
-
val apdu_bytes = buildApdu(
|
|
135
|
-
apduParam.cla,
|
|
136
|
-
apduParam.ins,
|
|
137
|
-
apduParam.p1,
|
|
138
|
-
apduParam.p2,
|
|
139
|
-
apduParam.data,
|
|
140
|
-
apduParam.isSecureChannel
|
|
141
|
-
) ?: run {
|
|
142
|
-
apduLogger.log("Failed to build APDU", false)
|
|
143
|
-
return ApduResult(-1, null)
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return suspendCoroutine { continuation ->
|
|
147
|
-
apiNfc.transInstructions(
|
|
148
|
-
apdu_bytes,
|
|
149
|
-
object : ApiAsyncListener<String> {
|
|
150
|
-
override fun onUiChange() {}
|
|
151
|
-
|
|
152
|
-
override fun onResult(resultCode: Int, result: String?) {
|
|
153
|
-
if (resultCode == 0 && result != null) {
|
|
154
|
-
var apdu_result = parseResponse(result, apduParam.isSecureChannel)
|
|
155
|
-
if (apdu_result != null) {
|
|
156
|
-
continuation.resume(apdu_result)
|
|
157
|
-
} else {
|
|
158
|
-
needReconnect = true
|
|
159
|
-
continuation.resume(ApduResult(-1, null))
|
|
160
|
-
}
|
|
161
|
-
} else {
|
|
162
|
-
needReconnect = true
|
|
163
|
-
continuation.resume(ApduResult(resultCode, null))
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
)
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
suspend private fun selectApplet(): Boolean {
|
|
172
|
-
val apduSelectMf = ApduParam(0x00, 0xa4, 0x04, 0x00, "", false)
|
|
173
|
-
var result = sendApdu(apduSelectMf)
|
|
174
|
-
if(result.resultCode !=0x9000) {
|
|
175
|
-
return false
|
|
176
|
-
}
|
|
177
|
-
val apduSelectApplet = ApduParam(0x00, 0xa4, 0x04, 0x00, AID, false)
|
|
178
|
-
result = sendApdu(apduSelectApplet)
|
|
179
|
-
return result.resultCode == 0x9000
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
suspend private fun openSecureChannel(): Boolean {
|
|
183
|
-
val apdu1 = ApduParam(0x80, 0xCA, 0xBF, 0x21, "A60483021518", false)
|
|
184
|
-
var result = sendApdu(apdu1)
|
|
185
|
-
if (result.resultCode != 0x9000 || result.data == null) {
|
|
186
|
-
return false
|
|
187
|
-
}
|
|
188
|
-
runCatching {
|
|
189
|
-
val cert = GPChannelNatives.nativeGPCTLVDecode(result.data)
|
|
190
|
-
if (!TextUtils.isEmpty(cert)) {
|
|
191
|
-
val certJson = JSONObject(cert)
|
|
192
|
-
val subject = GPChannelNatives.nativeGPCParseCertificate(certJson.getString("value"))
|
|
193
|
-
if (!TextUtils.isEmpty(subject)) {
|
|
194
|
-
val subjectJson = JSONObject(subject)
|
|
195
|
-
val conf = JSONObject().apply {
|
|
196
|
-
put("scpID", 0x1107)
|
|
197
|
-
put("keyUsage", 0x3C)
|
|
198
|
-
put("keyType", 0x88)
|
|
199
|
-
put("keyLength", 16)
|
|
200
|
-
put("hostID", "8080808080808080")
|
|
201
|
-
put("cardGroupID", subjectJson.getString("subjectID"))
|
|
202
|
-
}
|
|
203
|
-
val initResult = GPChannelNatives.nativeGPCInitialize(conf.toString())
|
|
204
|
-
if (initResult !=0) {
|
|
205
|
-
return false
|
|
206
|
-
}
|
|
207
|
-
} else {
|
|
208
|
-
return false
|
|
209
|
-
}
|
|
210
|
-
} else {
|
|
211
|
-
return false
|
|
212
|
-
}
|
|
213
|
-
}.onFailure {
|
|
214
|
-
return false
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
var apdu2 = ApduParam(0x80, 0x2A, 0x18, 0x10, "", false)
|
|
218
|
-
apdu2.setData(OCE_CRT)
|
|
219
|
-
result = sendApdu(apdu2)
|
|
220
|
-
if (result.resultCode != 0x9000) {
|
|
221
|
-
return false
|
|
222
|
-
}
|
|
223
|
-
val authData = GPChannelNatives.nativeGPCBuildMutualAuthData()
|
|
224
|
-
|
|
225
|
-
var aupd3 = ApduParam(0x80, 0x82, 0x18, 0x15, "", false)
|
|
226
|
-
aupd3.setData(authData)
|
|
227
|
-
result = sendApdu(aupd3)
|
|
228
|
-
if (result.resultCode != 0x9000) {
|
|
229
|
-
return false
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
val open_ret = GPChannelNatives.nativeGPCOpenSecureChannel(result.data);
|
|
233
|
-
if (open_ret != 0) {
|
|
234
|
-
return false
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return true
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
suspend private fun getSerialNumber(): String? {
|
|
241
|
-
|
|
242
|
-
val apduGetSn = ApduParam(0x80, 0xCB, 0x80, 0x00, "DFFF028101", true)
|
|
243
|
-
val result = sendApdu(apduGetSn)
|
|
244
|
-
if (result.resultCode != 0x9000 || result.data == null) {
|
|
245
|
-
return null
|
|
246
|
-
}
|
|
247
|
-
val serialBytes = Utils.hexString2Bytes(result.data) ?: return null
|
|
248
|
-
return String(serialBytes, Charsets.UTF_8)
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
suspend private fun getPinRetryCount(): Int? {
|
|
252
|
-
|
|
253
|
-
val apduGetPin = ApduParam(0x80, 0xCB, 0x80, 0x00, "DFFF028102", true)
|
|
254
|
-
val result = sendApdu(apduGetPin)
|
|
255
|
-
if (result.resultCode != 0x9000 || result.data == null) {
|
|
256
|
-
return null
|
|
257
|
-
}
|
|
258
|
-
val pinBytes = Utils.hexString2Bytes(result.data) ?: return null
|
|
259
|
-
if (pinBytes.isEmpty()) {
|
|
260
|
-
return null
|
|
261
|
-
}
|
|
262
|
-
return pinBytes[0].toInt() and 0xFF
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
suspend private fun getPinStatus(): Boolean? {
|
|
266
|
-
val apduGetStatus = ApduParam(0x80, 0xCB, 0x80, 0x00, "DFFF028105", true)
|
|
267
|
-
val result = sendApdu(apduGetStatus)
|
|
268
|
-
if (result.resultCode != 0x9000 || result.data == null) {
|
|
269
|
-
return null
|
|
270
|
-
}
|
|
271
|
-
val statusBytes = Utils.hexString2Bytes(result.data) ?: return null
|
|
272
|
-
if (statusBytes.isEmpty()) {
|
|
273
|
-
return null
|
|
274
|
-
}
|
|
275
|
-
return statusBytes[0].toInt() == 0x02
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
suspend fun getCardInfo(): CardInfo? {
|
|
279
|
-
if(needReconnect) {
|
|
280
|
-
GPChannelNatives.nativeGPCFinalize()
|
|
281
|
-
if (!selectApplet()) return null
|
|
282
|
-
if (!openSecureChannel()) return null
|
|
283
|
-
needReconnect = false
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
val serialNumber = getSerialNumber()
|
|
287
|
-
val pinRetryCount = getPinRetryCount()
|
|
288
|
-
val isNewCard = getPinStatus()
|
|
289
|
-
return CardInfo(serialNumber, pinRetryCount, isNewCard)
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
suspend fun resetCard():Boolean{
|
|
293
|
-
if(needReconnect){
|
|
294
|
-
GPChannelNatives.nativeGPCFinalize()
|
|
295
|
-
if (!selectApplet()) return false
|
|
296
|
-
if (!openSecureChannel()) return false
|
|
297
|
-
needReconnect = false
|
|
298
|
-
}
|
|
299
|
-
var apduReset = ApduParam(0x80, 0xCB, 0x80, 0x00, "DFFE028205", true);
|
|
300
|
-
val result = sendApdu(apduReset)
|
|
301
|
-
if (result.resultCode != 0x9000) {
|
|
302
|
-
return false
|
|
303
|
-
}
|
|
304
|
-
needReconnect = true
|
|
305
|
-
return true
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
suspend fun activateCard(pwd:String):Boolean{
|
|
309
|
-
if(needReconnect){
|
|
310
|
-
GPChannelNatives.nativeGPCFinalize()
|
|
311
|
-
if (!selectApplet()) return false
|
|
312
|
-
if (!openSecureChannel()) return false
|
|
313
|
-
needReconnect = false
|
|
314
|
-
}
|
|
315
|
-
val pinTLV = "00" + Utils.buildTLV(null, Utils.stringToHexString(pwd))
|
|
316
|
-
val dataTLV = Utils.buildTLV("8204", pinTLV)
|
|
317
|
-
val apduTLV = Utils.buildTLV("DFFE", dataTLV)
|
|
318
|
-
var apduActivate = ApduParam(0x80, 0xCB, 0x80, 0x00, apduTLV, true);
|
|
319
|
-
val result = sendApdu(apduActivate)
|
|
320
|
-
if (result.resultCode != 0x9000) {
|
|
321
|
-
return false
|
|
322
|
-
}
|
|
323
|
-
return true
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
suspend fun changePin(oldPin: String, newPin: String): Boolean {
|
|
327
|
-
if(needReconnect){
|
|
328
|
-
GPChannelNatives.nativeGPCFinalize()
|
|
329
|
-
if (!selectApplet()) return false
|
|
330
|
-
if (!openSecureChannel()) return false
|
|
331
|
-
needReconnect = false
|
|
332
|
-
}
|
|
333
|
-
val oldPinTLV = Utils.buildTLV(null, Utils.stringToHexString(oldPin))
|
|
334
|
-
val newPinTLV = Utils.buildTLV(null, Utils.stringToHexString(newPin))
|
|
335
|
-
val dataTLV = Utils.buildTLV("8204", oldPinTLV + newPinTLV)
|
|
336
|
-
val apduTLV = Utils.buildTLV("DFFE", dataTLV)
|
|
337
|
-
var apduChangePin = ApduParam(0x80, 0xCB, 0x80, 0x00, apduTLV, true);
|
|
338
|
-
val result = sendApdu(apduChangePin)
|
|
339
|
-
if (result.resultCode != 0x9000) {
|
|
340
|
-
return false
|
|
341
|
-
}
|
|
342
|
-
return true
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
suspend private fun verifyPin(pin: String): Boolean {
|
|
346
|
-
if(needReconnect){
|
|
347
|
-
GPChannelNatives.nativeGPCFinalize()
|
|
348
|
-
if (!selectApplet()) return false
|
|
349
|
-
if (!openSecureChannel()) return false
|
|
350
|
-
needReconnect = false
|
|
351
|
-
}
|
|
352
|
-
val pinTLV = Utils.buildTLV(null, Utils.stringToHexString(pin))
|
|
353
|
-
var apduVerifyPin = ApduParam(0x80, 0x20, 0x00, 0x00, pinTLV, true);
|
|
354
|
-
val result = sendApdu(apduVerifyPin)
|
|
355
|
-
if (result.resultCode != 0x9000) {
|
|
356
|
-
return false
|
|
357
|
-
}
|
|
358
|
-
return true
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
suspend private fun logout(): Boolean {
|
|
362
|
-
if(needReconnect){
|
|
363
|
-
GPChannelNatives.nativeGPCFinalize()
|
|
364
|
-
if (!selectApplet()) return false
|
|
365
|
-
if (!openSecureChannel()) return false
|
|
366
|
-
needReconnect = false
|
|
367
|
-
}
|
|
368
|
-
var apduLogout = ApduParam(0x80, 0x21, 0x00, 0x00, "", true);
|
|
369
|
-
val result = sendApdu(apduLogout)
|
|
370
|
-
if (result.resultCode != 0x9000) {
|
|
371
|
-
return false
|
|
372
|
-
}
|
|
373
|
-
return true
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
suspend fun checkSlotEmpty(slotIndex: Int, pwd: String): Boolean? {
|
|
377
|
-
if (slotIndex !in 0..39) {
|
|
378
|
-
return null
|
|
379
|
-
}
|
|
380
|
-
if(needReconnect){
|
|
381
|
-
GPChannelNatives.nativeGPCFinalize()
|
|
382
|
-
if (!selectApplet()) return null
|
|
383
|
-
if (!openSecureChannel()) return null
|
|
384
|
-
needReconnect = false
|
|
385
|
-
}
|
|
386
|
-
if (!verifyPin(pwd)) {
|
|
387
|
-
return null
|
|
388
|
-
}
|
|
389
|
-
val apduCheck = ApduParam(0x80, 0x6A, 0x00, 0x00, "", true);
|
|
390
|
-
val result = sendApdu(apduCheck)
|
|
391
|
-
if (result.resultCode != 0x9000 || result.data == null) {
|
|
392
|
-
return null
|
|
393
|
-
}
|
|
394
|
-
val checkBytes = Utils.hexString2Bytes(result.data) ?: return null
|
|
395
|
-
if (checkBytes.size < 5) {
|
|
396
|
-
return null
|
|
397
|
-
}
|
|
398
|
-
val byteIndex = slotIndex / 8
|
|
399
|
-
val bitIndex = slotIndex % 8
|
|
400
|
-
val value = checkBytes[byteIndex].toInt() and 0xFF
|
|
401
|
-
return ((value ushr bitIndex) and 0x01) == 0x00
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
suspend fun writeSlot(slotIndex: Int, data: ByteArray,pwd: String): Boolean {
|
|
405
|
-
if (slotIndex !in 0..39) {
|
|
406
|
-
return false
|
|
407
|
-
}
|
|
408
|
-
if (data.size > 231) {
|
|
409
|
-
return false
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
if(needReconnect){
|
|
413
|
-
GPChannelNatives.nativeGPCFinalize()
|
|
414
|
-
if (!selectApplet()) return false
|
|
415
|
-
if (!openSecureChannel()) return false
|
|
416
|
-
needReconnect = false
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
return try {
|
|
420
|
-
if(!verifyPin(pwd)) {
|
|
421
|
-
return false
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
var apduWrite = ApduParam(0x80, 0x3B, 0x00, slotIndex.toLong(), Utils.bytesToHexString(data), true);
|
|
425
|
-
val result = sendApdu(apduWrite)
|
|
426
|
-
if (result.resultCode != 0x9000) {
|
|
427
|
-
return false
|
|
428
|
-
}
|
|
429
|
-
true
|
|
430
|
-
} catch (e: Exception) {
|
|
431
|
-
false
|
|
432
|
-
} finally {
|
|
433
|
-
runCatching { logout() }
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
suspend fun readSlot(slotIndex: Int, pwd: String): ByteArray? {
|
|
438
|
-
if (slotIndex !in 0..39) {
|
|
439
|
-
return null
|
|
440
|
-
}
|
|
441
|
-
if (needReconnect) {
|
|
442
|
-
GPChannelNatives.nativeGPCFinalize()
|
|
443
|
-
if (!selectApplet()) return null
|
|
444
|
-
if (!openSecureChannel()) return null
|
|
445
|
-
needReconnect = false
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
return try {
|
|
449
|
-
if (!verifyPin(pwd)) {
|
|
450
|
-
null
|
|
451
|
-
} else {
|
|
452
|
-
val apduRead = ApduParam(0x80, 0x4B, 0x00, slotIndex.toLong(), "", true)
|
|
453
|
-
val result = sendApdu(apduRead)
|
|
454
|
-
if (result.resultCode != 0x9000 || result.data == null) {
|
|
455
|
-
null
|
|
456
|
-
} else {
|
|
457
|
-
Utils.hexString2Bytes(result.data)
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
} catch (e: Exception) {
|
|
461
|
-
null
|
|
462
|
-
} finally {
|
|
463
|
-
runCatching { logout() }
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
fun onActivityResumed(){
|
|
467
|
-
apiNfc.onResume()
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
fun onActivityPaused(){
|
|
471
|
-
apiNfc.onPause()
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
fun onActivityDestroyed(){
|
|
475
|
-
apiNfc.onDestroy()
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
package com.ziancube.backupcardsdk;
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @Date 2020-07-09 16:29
|
|
5
|
-
* @Author ZJF
|
|
6
|
-
* @Version 1.0
|
|
7
|
-
*/
|
|
8
|
-
public class GPChannelNatives {
|
|
9
|
-
|
|
10
|
-
static {
|
|
11
|
-
System.loadLibrary("gpchannelNDK");
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* 当native接口的返回值不是int时,需要调用该接口获取错误码
|
|
16
|
-
*
|
|
17
|
-
* @return
|
|
18
|
-
*/
|
|
19
|
-
public static native int nativeGetErrorCode();
|
|
20
|
-
|
|
21
|
-
public static native int nativeGPCInitialize(String json);
|
|
22
|
-
|
|
23
|
-
public static native int nativeGPCFinalize();
|
|
24
|
-
|
|
25
|
-
public static native String nativeGPCBuildMutualAuthData();
|
|
26
|
-
|
|
27
|
-
public static native int nativeGPCOpenSecureChannel(String response);
|
|
28
|
-
|
|
29
|
-
public static native String nativeGPCBuildAPDU(long cla, long ins, long p1, long p2, String data);
|
|
30
|
-
|
|
31
|
-
public static native String nativeGPCBuildSafeAPDU(long cla, long ins, long p1, long p2, String data);
|
|
32
|
-
|
|
33
|
-
public static native String nativeGPCParseSafeAPDUResponse(String response);
|
|
34
|
-
|
|
35
|
-
public static native String nativeGPCParseAPDUResponse(String response);
|
|
36
|
-
|
|
37
|
-
public static native String nativeGPCTLVDecode(String apdu);
|
|
38
|
-
|
|
39
|
-
public static native String nativeGPCParseCertificate(String cert);
|
|
40
|
-
|
|
41
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
package com.ziancube.backupcardsdk.listener;
|
|
2
|
-
|
|
3
|
-
import org.json.JSONException;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Created by lxl on 2019/4/22.
|
|
7
|
-
*/
|
|
8
|
-
public interface ApiAsyncListener<T> {
|
|
9
|
-
|
|
10
|
-
public void onUiChange();
|
|
11
|
-
|
|
12
|
-
public void onResult(int errorCode, T result) throws JSONException;
|
|
13
|
-
}
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
package com.ziancube.backupcardsdk.nfc;
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import android.app.Activity;
|
|
5
|
-
import android.app.PendingIntent;
|
|
6
|
-
import android.content.Context;
|
|
7
|
-
import android.content.Intent;
|
|
8
|
-
import android.content.IntentFilter;
|
|
9
|
-
import android.nfc.NfcAdapter;
|
|
10
|
-
import android.nfc.Tag;
|
|
11
|
-
import android.nfc.tech.IsoDep;
|
|
12
|
-
import android.nfc.tech.NfcA;
|
|
13
|
-
import android.os.AsyncTask;
|
|
14
|
-
import android.os.Build;
|
|
15
|
-
import android.util.Log;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
import com.ziancube.backupcardsdk.listener.ApiAsyncListener;
|
|
19
|
-
|
|
20
|
-
import static android.nfc.NfcAdapter.EXTRA_TAG;
|
|
21
|
-
|
|
22
|
-
import org.json.JSONException;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Created by lxl on 2019/4/22.
|
|
26
|
-
*/
|
|
27
|
-
public class ApiNfc {
|
|
28
|
-
private static ApiNfc mApiNfcardOTP;
|
|
29
|
-
private static ImplNfc apiImplNfcardOTP;
|
|
30
|
-
private NfcAdapter nfcAdapter;
|
|
31
|
-
private PendingIntent pendingIntent;
|
|
32
|
-
private static Context apiContext;
|
|
33
|
-
private Activity apiActivity;
|
|
34
|
-
|
|
35
|
-
private IsoDep apiIsodep = null;
|
|
36
|
-
private static String[][] TECHLISTS;
|
|
37
|
-
private static IntentFilter[] TAGFILTERS;
|
|
38
|
-
static {
|
|
39
|
-
try {
|
|
40
|
-
TECHLISTS = new String[][]{{IsoDep.class.getName()},
|
|
41
|
-
{NfcA.class.getName()},};
|
|
42
|
-
|
|
43
|
-
TAGFILTERS = new IntentFilter[]{new IntentFilter(
|
|
44
|
-
NfcAdapter.ACTION_TECH_DISCOVERED, "*/*")};
|
|
45
|
-
} catch (Exception e) {
|
|
46
|
-
e.printStackTrace();
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
private ApiNfc(Activity mActivity) {
|
|
51
|
-
apiContext = mActivity;
|
|
52
|
-
apiActivity = mActivity;
|
|
53
|
-
|
|
54
|
-
nfcAdapter = NfcAdapter.getDefaultAdapter(apiActivity);
|
|
55
|
-
int pendingIntentFlags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
|
|
56
|
-
? PendingIntent.FLAG_MUTABLE
|
|
57
|
-
: 0;
|
|
58
|
-
pendingIntent = PendingIntent.getActivity(apiActivity, 0, new Intent(
|
|
59
|
-
apiActivity, apiActivity.getClass())
|
|
60
|
-
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), pendingIntentFlags);
|
|
61
|
-
|
|
62
|
-
apiImplNfcardOTP = new ImplNfc(apiContext);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
public synchronized static ApiNfc getInstance(Activity mActivity) {
|
|
66
|
-
if (mApiNfcardOTP == null) {
|
|
67
|
-
mApiNfcardOTP = new ApiNfc(mActivity);
|
|
68
|
-
}
|
|
69
|
-
return mApiNfcardOTP;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
public void onPause() {
|
|
73
|
-
if (nfcAdapter != null)
|
|
74
|
-
nfcAdapter.disableForegroundDispatch(apiActivity);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
public void onResume() {
|
|
78
|
-
if (nfcAdapter != null)
|
|
79
|
-
nfcAdapter.enableForegroundDispatch(apiActivity, pendingIntent,
|
|
80
|
-
TAGFILTERS, TECHLISTS);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
public int getNfcState() {
|
|
84
|
-
return (nfcAdapter == null) ? -1 : nfcAdapter.isEnabled() ? 1 : 0;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
public String getSdkVersion() {
|
|
88
|
-
return apiImplNfcardOTP.getVersion();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
public int setCardTag(Intent intent) {
|
|
92
|
-
Tag tag = (Tag) intent.getParcelableExtra(EXTRA_TAG);
|
|
93
|
-
if (tag != null) {
|
|
94
|
-
apiIsodep = IsoDep.get(tag);
|
|
95
|
-
apiImplNfcardOTP.ImplsetIsoDepTag(apiIsodep);
|
|
96
|
-
return 0;
|
|
97
|
-
}
|
|
98
|
-
return -1;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
public void transInstructions(byte[] instructions, ApiAsyncListener<String> listener) {
|
|
102
|
-
TransInstructionsTask transInstructionsTask = new TransInstructionsTask(instructions, listener);
|
|
103
|
-
transInstructionsTask.execute();
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
static class TransInstructionsTask extends AsyncTask<Void, Void, Integer> {
|
|
107
|
-
private byte[] transInstru;
|
|
108
|
-
private byte[] resultInput = new byte[1024];
|
|
109
|
-
private byte[] result;
|
|
110
|
-
private int[] resultLen = new int[1];
|
|
111
|
-
private ApiAsyncListener<String> mListener;
|
|
112
|
-
|
|
113
|
-
public TransInstructionsTask(byte[] instru, ApiAsyncListener<String> listener) {
|
|
114
|
-
mListener = listener;
|
|
115
|
-
transInstru = instru;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
@Override
|
|
119
|
-
protected void onPreExecute() {
|
|
120
|
-
mListener.onUiChange();
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
@Override
|
|
124
|
-
protected Integer doInBackground(Void... params) {
|
|
125
|
-
int re;
|
|
126
|
-
re = apiImplNfcardOTP.connect();
|
|
127
|
-
if (re != 0) {
|
|
128
|
-
Log.e("connect error", String.valueOf(re));
|
|
129
|
-
return re;
|
|
130
|
-
}
|
|
131
|
-
re = apiImplNfcardOTP.transInstructions(transInstru, resultInput, resultLen);
|
|
132
|
-
//apiImplNfcardOTP.disConnect();
|
|
133
|
-
return re;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
@Override
|
|
137
|
-
protected void onPostExecute(Integer res) {
|
|
138
|
-
|
|
139
|
-
if (resultLen[0] != 0) {
|
|
140
|
-
result = new byte[resultLen[0]];
|
|
141
|
-
System.arraycopy(resultInput, 0, result, 0, resultLen[0]);
|
|
142
|
-
try {
|
|
143
|
-
mListener.onResult(res.intValue(), Bytes2HexString(result));
|
|
144
|
-
} catch (JSONException e) {
|
|
145
|
-
e.printStackTrace();
|
|
146
|
-
}
|
|
147
|
-
} else {
|
|
148
|
-
try {
|
|
149
|
-
mListener.onResult(res.intValue(), null);
|
|
150
|
-
} catch (JSONException e) {
|
|
151
|
-
e.printStackTrace();
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
public static String Bytes2HexString(byte[] b) {
|
|
158
|
-
String ret = "";
|
|
159
|
-
for (int i = 0; i < b.length; i++) {
|
|
160
|
-
String hex = Integer.toHexString(b[i] & 0xFF);
|
|
161
|
-
if (hex.length() == 1) {
|
|
162
|
-
hex = "0".concat(hex) ;
|
|
163
|
-
}
|
|
164
|
-
ret =ret.concat(hex.toUpperCase());
|
|
165
|
-
}
|
|
166
|
-
return ret;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
public void onDestroy() {
|
|
170
|
-
mApiNfcardOTP = null;
|
|
171
|
-
apiContext = null;
|
|
172
|
-
}
|
|
173
|
-
}
|