1
- // import { OperationCanceled, NoTransport } from '../error/index';
2
- import { COMMAND } from '../config/command' ;
1
+ import { CommandType , commands } from './command' ;
3
2
import * as util from './utils' ;
4
- import { CODE } from '../config/apduStatus/code'
3
+ import { error as Errors } from '../index' ;
5
4
import { SHA256 } from '../crypto/hash' ;
6
5
import Transport from '../transport/index' ;
7
6
import { SDKError , APDUError } from '../error/errorHandle' ;
7
+ import { CODE } from '../config/apduStatus/code' ;
8
8
9
9
10
10
/**
@@ -13,35 +13,46 @@ import { SDKError, APDUError } from '../error/errorHandle';
13
13
* @param {{command:string, data:string} } apdu
14
14
* @param {string } commandType SE or MCU
15
15
*/
16
- const executeAPDU = async ( commandName : string , transport : Transport , apdu : { command : string , data : string } , commandType : string ) : Promise < { status : string , msg : string , outputData : string } > => {
16
+ const executeAPDU = async (
17
+ commandName : string ,
18
+ transport : Transport ,
19
+ apdu : { command : string , data : string } ,
20
+ executedTarget : string
21
+ ) : Promise < {
22
+ status : string ,
23
+ msg : string ,
24
+ outputData : string
25
+ } > => {
17
26
if ( typeof transport . request !== 'function' ) {
18
27
throw new SDKError ( executeAPDU . name , `Transport not specified or no connection established.` ) ;
19
28
}
20
- /* console.log ("{")
21
- console.log (" command: " + apdu.command)
22
- console.log (" data: " + apdu.data)
23
- console.log ("}")*/
24
- // TODO app transport
29
+ console . debug ( "{" )
30
+ console . debug ( " command: " + apdu . command )
31
+ console . debug ( " data: " + apdu . data )
32
+ console . debug ( "}" )
33
+
25
34
try {
35
+ // TODO app transport
26
36
if ( transport . requestAPDUV2 ) {
27
37
return await transport . requestAPDUV2 ( apdu ) ;
28
38
}
29
39
let msg = ''
30
40
const response = await transport . request ( apdu . command , apdu . data ) ;
31
- if ( commandType === 'SE' ) {
41
+ if ( executedTarget === 'SE' ) {
32
42
const status = response . slice ( - 4 ) ;
33
43
const outputData = response . slice ( 0 , - 4 ) ;
34
44
msg = util . getReturnMsg ( status )
35
45
return { status, msg, outputData } ;
46
+ } else {
47
+ const status = response . slice ( 4 , 6 ) ;
48
+ const outputData = response . slice ( 6 ) ;
49
+ msg = util . getReturnMsg ( status )
50
+ return { status, msg, outputData } ;
36
51
}
37
- const status = response . slice ( 4 , 6 ) ;
38
- const outputData = response . slice ( 6 ) ;
39
- msg = util . getReturnMsg ( status )
40
- return { status, msg, outputData } ;
52
+
41
53
} catch ( error ) {
42
54
throw new SDKError ( executeAPDU . name , `executeAPDU error: ${ error } ` ) ;
43
55
}
44
-
45
56
} ;
46
57
47
58
/**
@@ -58,31 +69,31 @@ const executeAPDU = async (commandName: string, transport: Transport, apdu: { co
58
69
*/
59
70
export const executeCommand = async (
60
71
transport : Transport ,
61
- commandName : string ,
62
- commandType : string = 'SE' ,
72
+ command : CommandType ,
73
+ executedTarget : string = 'SE' ,
63
74
data : string = '' ,
64
75
params1 : string | undefined = undefined ,
65
76
params2 : string | undefined = undefined ,
66
77
supportSC : boolean = false ,
67
78
forceUseSC : boolean = false ,
68
79
) : Promise < { status : string , msg : string , outputData : string } > => {
69
- const commandParams = COMMAND [ commandName ] ;
80
+ const P1 = params1 || command . P1 ;
81
+ const P2 = params2 || command . P2 ;
70
82
71
- const P1 = params1 || commandParams . P1 ;
72
- const P2 = params2 || commandParams . P2 ;
83
+ if ( ( typeof ( P1 ) == undefined ) || ( typeof ( P2 ) == undefined ) ) {
84
+ throw new Errors . SDKError ( 'Unknown' , command . toString ( ) )
85
+ }
73
86
74
87
let response ;
75
-
76
88
// data too long: divide and send with SECURE CHANNEL
77
89
if ( forceUseSC || ( supportSC && data . length > 500 ) ) {
78
- const apduHeader = commandParams . CLA + commandParams . INS + P1 + P2 ;
90
+ const apduHeader = command . CLA + command . INS + P1 + P2 ;
79
91
response = await sendWithSecureChannel ( transport , apduHeader , data , forceUseSC ) ;
80
92
} else {
81
- const apdu = util . assemblyCommandAndData ( commandParams . CLA , commandParams . INS , P1 , P2 , data ) ;
82
-
93
+ const apdu = util . assemblyCommandAndData ( command . CLA , command . INS , P1 , P2 , data ) ;
83
94
// eslint-disable-next-line no-console
84
- console . debug ( `Execute Command: ${ commandName } ` ) ;
85
- response = await executeAPDU ( commandName , transport , apdu , commandType ) ;
95
+ console . debug ( `Execute Command: ${ command } ` ) ;
96
+ response = await executeAPDU ( command . toString ( ) , transport , apdu , executedTarget ) ;
86
97
}
87
98
return response ;
88
99
@@ -101,7 +112,7 @@ export const sendWithSecureChannel = async (transport: Transport, apduHeader: st
101
112
const dataToHash = apduHeader . concat ( salt , apduData ) ;
102
113
const hash = SHA256 ( dataToHash ) . toString ( 'hex' ) ;
103
114
const packedData = apduHeader . concat ( hash , salt , apduData ) ;
104
- // console.log ("Before Secure channel: " + packedData)
115
+ console . debug ( "Before Secure channel: " + packedData )
105
116
const channelVersion = '01' ;
106
117
const useSecure = '00' ;
107
118
const useSign = forceUseSC ? '01' : '00' ;
@@ -116,7 +127,6 @@ export const sendWithSecureChannel = async (transport: Transport, apduHeader: st
116
127
}
117
128
const totalPackages = chunks . length ;
118
129
119
-
120
130
// Send Data
121
131
let result ;
122
132
for ( let i = 0 ; i < totalPackages ; i ++ ) {
@@ -128,22 +138,22 @@ export const sendWithSecureChannel = async (transport: Transport, apduHeader: st
128
138
// Uncaught error in SC_SEND_SEGMENT command. Return to parent executeCommand
129
139
if ( status !== CODE . _9000 ) {
130
140
return result ;
131
- }
141
+ } else {
142
+ const confirmHash = result . outputData . slice ( 4 , 68 ) ;
143
+ const confirmSalt = result . outputData . slice ( 68 , 76 ) ;
144
+ const apduReturn = result . outputData . slice ( 76 ) ;
132
145
133
- const confirmHash = result . outputData . slice ( 4 , 68 ) ;
134
- const confirmSalt = result . outputData . slice ( 68 , 76 ) ;
135
- const apduReturn = result . outputData . slice ( 76 ) ;
146
+ if ( confirmSalt !== salt ) {
147
+ throw new SDKError ( sendWithSecureChannel . name , 'SC: Returned salt check failed' ) ;
148
+ }
136
149
137
- if ( confirmSalt !== salt ) {
138
- throw new SDKError ( sendWithSecureChannel . name , 'SC: Returned salt check failed' ) ;
139
- }
150
+ const returnedDataHash = SHA256 ( confirmSalt + apduReturn ) . toString ( 'hex' ) ;
151
+ if ( returnedDataHash !== confirmHash ) {
152
+ throw new SDKError ( sendWithSecureChannel . name , 'SC: Returned hash check failed' ) ;
153
+ }
140
154
141
- const returnedDataHash = SHA256 ( confirmSalt + apduReturn ) . toString ( 'hex' ) ;
142
- if ( returnedDataHash !== confirmHash ) {
143
- throw new SDKError ( sendWithSecureChannel . name , 'SC: Returned hash check failed' ) ;
155
+ return { status : status , msg : util . getReturnMsg ( status ) , outputData : apduReturn } ;
144
156
}
145
-
146
- return { status : status , msg :util . getReturnMsg ( status ) , outputData : apduReturn } ;
147
157
} else {
148
158
throw new SDKError ( sendWithSecureChannel . name , 'sendWithSecureChannel failed' )
149
159
}
@@ -160,5 +170,5 @@ export const sendWithSecureChannel = async (transport: Transport, apduHeader: st
160
170
const sendFragment = async ( transport : Transport , data : string , index : number , totalPackages : number ) : Promise < { status : string , msg : string , outputData : string } > => {
161
171
const P1 = index . toString ( 16 ) . padStart ( 2 , '0' ) ;
162
172
const P2 = totalPackages . toString ( 16 ) . padStart ( 2 , '0' ) ;
163
- return executeCommand ( transport , ' SC_SEND_SEGMENT' , 'SE' , data , P1 , P2 , false ) ;
173
+ return executeCommand ( transport , commands . SC_SEND_SEGMENT , 'SE' , data , P1 , P2 , false ) ;
164
174
} ;
0 commit comments