smartcard 1.0.46 → 2.0.0

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/README.MD DELETED
@@ -1,371 +0,0 @@
1
- # smartcard
2
-
3
-
4
- Smartcard library.
5
-
6
- This is a simple wrapper around [Santiago Gimeno's](https://www.npmjs.org/~sgimeno) great [pcsclite](https://github.com/santigimeno/node-pcsclite) library.
7
-
8
- Used by [Card Spy](http://card-spy.surge.sh)
9
-
10
- ## API
11
-
12
- The following objects are defined by the `smartcard` library, each contains its own set of methods and events.
13
-
14
- ### Class: Devices
15
- A general object that provides access to all smartcard related devices.
16
-
17
- #### Events
18
- The `devices` object emits the following events
19
-
20
- ##### Event: 'device-activated'
21
- Emitted when a card reader is attached.
22
- Returns:
23
- * `Object`
24
- * `Device`
25
- * `Array`: List of all devices, returned via `devices.listDevices()`
26
-
27
- ##### Event: 'device-deactivated'
28
- Emitted when a card reader is detached.
29
- Returns:
30
- * `Object`
31
- * `Device`
32
- * `Array`: List of all devices, returned via `devices.listDevices()`
33
-
34
- ##### Event: 'error'
35
- Emitted when an error occurs
36
- Returns `Object`:
37
- * _error_ `Error`
38
-
39
- #### Methods
40
- The following methods are available within the `devices` class.
41
-
42
- ##### Constructor
43
- The constructor for a devices object takes no arguments,
44
- ```javascript
45
- devices = new Devices();
46
- ```
47
- ##### `devices.onActivated()`
48
- Returns `Promise`
49
- * Resolves with activation _event_
50
-
51
- ##### `devices.onDeactivated()`
52
- Returns `Promise`
53
- * Resolves with deactivation _event_
54
-
55
- ##### `devices.listDevices()`
56
- Returns `Object` a list of the different devices attached, each a `device` object
57
-
58
- ##### `devices.lookup(name)`
59
- * _name_ `String`: The text name of a device
60
-
61
- * Returns `Device`
62
-
63
-
64
-
65
- ### Class: Device
66
- An object representing a specific card reader (device).
67
-
68
- #### Methods
69
- The following methods are available within the `device` class.
70
-
71
- ##### `device.getName()`
72
- Returns the name of the attached device.
73
-
74
- ##### `device.transmit(data, res_len, protocol, cb)`
75
- Sends a command to the connected device
76
- * _data_ `Buffer`: data to be transmitted
77
- * _res_len_ `Number`: Maximum length of the expected response, includes the 2 byte response (sw1 and sw2)
78
- * _protocol_ `Number`: Protocol to be used in the transmission
79
- * _cb(error,response)_ `Function`: Called when transmit function completes
80
- * _error_ `Error`
81
- * _output_ `Buffer`
82
-
83
- #### Events
84
- The `device` object emits the following events
85
-
86
- ##### Event: 'card-inserted'
87
- Emitted when a smartcard is inserted into a card reader
88
-
89
- Returns `Object`:
90
- * _device_ `Device`
91
- * _card_ `Card`
92
-
93
- ##### Event: 'card-removed'
94
- Emitted when a smartcard is removed from a card reader
95
-
96
- Returns `Object`:
97
- * _name_ `String`
98
- * _card_ `Card`
99
-
100
- ### Class: Card
101
- An object representing an attached smart card.
102
-
103
- #### Methods
104
- The following methods are available within the `card` class.
105
-
106
- ##### `card.getAtr()`
107
- Returns `String` containing the atr of the card
108
-
109
- ##### `card.issueCommand(commandApdu, callback)`
110
- Sends a command to the card
111
- * _commandApdu_: The command to be sent to the card
112
- * `String`
113
- * `Buffer`
114
- * `Array`
115
- * `CommandApdu`
116
- * _callback(error,response)_: (optional) Function to call upon completion of the command
117
- * _error_ `Error`
118
- * _response_ `Buffer`
119
-
120
- Returns `Promise`
121
- * Resolves with _response_ `Buffer`
122
- * Rejects with _error_ `Error`
123
-
124
- If no callback is specified, returns a `Promise`
125
- *
126
- #### Events
127
- The `card` object emits the following events
128
-
129
- ##### Event: 'command-issued'
130
- Emitted when a command is sent to the smartcard.
131
-
132
- Returns `Object`:
133
- * _card_ `Card`
134
- * _command_ `Buffer`
135
-
136
- ##### Event: 'response-received'
137
- Emitted when a response is received from the card.
138
-
139
- Returns `Object`:
140
- * _card_ `Card`
141
- * _command_ `Buffer`
142
- * _response_ `ResponseApdu`
143
-
144
- ### Class: CommandApdu
145
- An object representing a command to send to a smart card
146
-
147
- #### Methods
148
- The `CommandApdu` class has the following methods.
149
-
150
- ##### Constructor `CommandApdu(obj)`
151
- Creates a new instance and sets the appropriate items
152
- * _obj_ `Object`
153
- * _cla_ `Number`: The class of the command, typically 0
154
- * _ins_ `Number`: The instruction
155
- * _p1_ `Number`: The value of p1
156
- * _p2_ `Number`: The value of p2
157
- * _data_ `Array` (optional): The value of data
158
- * _le_ `Number` (optional): The value of le
159
-
160
- OR
161
- * _obj_ `Array`: Byte array representing the whole command
162
-
163
- ##### `CommandApdu.toBuffer()`
164
- Converts the command to a Buffer
165
- * Returns `Buffer`
166
-
167
- ##### `CommandApdu.toString()`
168
- Converts the command to a hex string
169
- * Returns `String`
170
-
171
- ##### `CommandApdu.toByteArray()`
172
- Converts the command to a byte array
173
- * Returns `Array`
174
-
175
- ##### `CommandApdu.setLe(le)`
176
- Updates the le value of the command
177
- * _le_ `Number`: The new le value
178
-
179
- ### Class: ResponseApdu
180
- Class representing a response from the card
181
-
182
- #### Methods
183
- The `ResponseApdu` class has the following methods.
184
-
185
- ##### Constructor
186
-
187
- ##### `ResponseApdu.meaning()`
188
- Interprets the return code and attempts to provide a text translation.
189
- * Returns `String`
190
-
191
- ##### `ResponseApdu.getDataOnly()`
192
- Returns the response data without including the status code
193
- * Returns `String`
194
-
195
- ##### `ResponseApdu.getStatusCode()`
196
- Returns only the status code
197
- * Returns `String`
198
-
199
- ##### `ResponseApdu.isOk()`
200
- Check if the status code is 9000
201
- * Returns `Boolean`
202
-
203
- ##### `ResponseApdu.buffer()`
204
- Returns the whole buffer, status code and data
205
- * Returns `Buffer`
206
-
207
- ##### `ResponseApdu.hasMoreBytesAvailable()`
208
- Reads the status code and looks for a 61 as sw1, meaning more data is available
209
- * Returns `Boolean`
210
-
211
- ##### `ResponseApdu.numberOfBytesAvailable()`
212
- Reads sw2 staus code to return number of bytes left, when sw1 is 61. A value of 0 means there are more than 256 bytes remaining.
213
- * Returns `Number`
214
-
215
- ##### `ResponseApdu.isWrongLength()`
216
- Checks status code for 6c as sw1
217
- * Returns `Boolean`
218
-
219
- ##### `ResponseApdu.correctLength()`
220
- If sw1 is 6c, returns the correct length from sw2. A value of 0 means there are more than 256 bytes remaining.
221
- * Returns `Number`
222
-
223
- ### Class: Iso7816Application
224
- An object offering general commands to most ISO7816 compliant smart cards.
225
-
226
- #### Methods
227
-
228
- ##### Constructor `Iso7816Application(card)`
229
- Sets up the `Iso7816Application` object
230
- * _card_ `Card`: The card to communicate with using ISO7816 standards
231
-
232
- ##### `Iso7816Application.issueCommand(commandApdu)`
233
- Sends the provided command to the card. Automatically retrieve the full response, even if it requires multiple GET_RESPONSE commands
234
- * _commandApdu_ `CommandApdu`: Command to send to the card
235
-
236
- Returns
237
- * `ResponseApdu` Complete response from card
238
-
239
- ##### `Iso7816Application.selectFile(bytes, p1, p2)`
240
- Sends the SELECT command to the card, often called selecting an application
241
- * _bytes_ `Buffer`: The resource locater (AID, etc)
242
- * _p1_ `Number`: Value to specify as the p1 value
243
- * _p2_ `Number`: Value to specify as the p2 value
244
-
245
- Returns
246
- * `ResponseApdu` Complete response from card
247
-
248
- ##### `Iso7816Application.getResponse(length)`
249
- Sends a single GET_RESPONSE command to the card
250
- * _length_ `Number`: The length of the response expected, maximum is 0xFF
251
-
252
- Returns
253
- * `ResponseApdu` Complete response from card
254
-
255
- ##### `Iso7816Application.getResponse(sfi,record)`
256
- Sends a READ_RECORD command to the card
257
- * _sfi_ `Number`: The sfi
258
- * _record_ `Number`: The record
259
-
260
- Returns
261
- * `ResponseApdu` Complete response from card
262
-
263
- ##### `Iso7816Application.getData(p1, p2)`
264
- Sends a GET_DATA command to the card
265
- * _p1_ `Number`: Value to specify as the p1 value
266
- * _p2_ `Number`: Value to specify as the p2 value
267
-
268
- Returns
269
- * `ResponseApdu` Complete response from card
270
-
271
- #### Events
272
- The `Iso7816Application` class emits the following events
273
-
274
- ##### Event: 'application-selected'
275
- Emitted when a successful reply to a `selectFile()` command is received.
276
-
277
- Returns `Object`:
278
- * _application_ `String`
279
-
280
- ## Examples
281
-
282
-
283
- ### With event emitter
284
-
285
- ```javascript
286
- 'use strict';
287
-
288
- const smartcard = require('smartcard');
289
- const Devices = smartcard.Devices;
290
- const devices = new Devices();
291
-
292
-
293
- devices.on('device-activated', (event => {
294
- console.log(`Device '${event.device}' activated`);
295
- event.devices.map((device, index) => {
296
- console.log(`Device #${index + 1}: '${device.name}'`);
297
- });
298
- }));
299
- ```
300
-
301
-
302
- ### Using promises
303
-
304
- ```javascript
305
- 'use strict';
306
-
307
- const smartcard = require('smartcard');
308
- const Devices = smartcard.Devices;
309
- const devices = new Devices();
310
-
311
-
312
- devices.onActivated().then(event => {
313
- console.log(`Device '${event.device}' activated`);
314
- event.devices.map((device, index) => {
315
- console.log(`Device #${index + 1}: '${device.name}'`);
316
- });
317
- });
318
- ```
319
-
320
-
321
- ### Selecting the Payment Systems Environment on an EMV (Chip & Pin) card
322
-
323
-
324
- ```javascript
325
- 'use strict';
326
-
327
- const smartcard = require('smartcard');
328
- const Devices = smartcard.Devices;
329
- const Iso7816Application = smartcard.Iso7816Application;
330
-
331
- const devices = new Devices();
332
-
333
- devices.on('device-activated', event => {
334
- const currentDevices = event.devices;
335
- let device = event.device;
336
- console.log(`Device '${device}' activated, devices: ${currentDevices}`);
337
- for (let prop in currentDevices) {
338
- console.log("Devices: " + currentDevices[prop]);
339
- }
340
-
341
- device.on('card-inserted', event => {
342
- let card = event.card;
343
- console.log(`Card '${card.getAtr()}' inserted into '${event.device}'`);
344
-
345
- card.on('command-issued', event => {
346
- console.log(`Command '${event.command}' issued to '${event.card}' `);
347
- });
348
-
349
- card.on('response-received', event => {
350
- console.log(`Response '${event.response}' received from '${event.card}' in response to '${event.command}'`);
351
- });
352
-
353
- const application = new Iso7816Application(card);
354
- application.selectFile([0x31, 0x50, 0x41, 0x59, 0x2E, 0x53, 0x59, 0x53, 0x2E, 0x44, 0x44, 0x46, 0x30, 0x31])
355
- .then(response => {
356
- console.info(`Select PSE Response: '${response}' '${response.meaning()}'`);
357
- }).catch(error => {
358
- console.error('Error:', error, error.stack);
359
- });
360
-
361
- });
362
- device.on('card-removed', event => {
363
- console.log(`Card removed from '${event.name}' `);
364
- });
365
-
366
- });
367
-
368
- devices.on('device-deactivated', event => {
369
- console.log(`Device '${event.device}' deactivated, devices: [${event.devices}]`);
370
- });
371
- ```
package/babel.config.json DELETED
@@ -1,3 +0,0 @@
1
- {
2
- "presets": ["@babel/preset-env"]
3
- }
@@ -1,12 +0,0 @@
1
- 'use strict';
2
-
3
- const smartcard = require('../lib/index');
4
- const Devices = smartcard.Devices;
5
- const devices = new Devices();
6
-
7
- devices.onActivated().then((event) => {
8
- console.log(`Device '${event.device}' activated`);
9
- event.devices.map((device, index) => {
10
- console.log(`Device #${index + 1}: '${device.name}'`);
11
- });
12
- });
@@ -1,12 +0,0 @@
1
- 'use strict';
2
-
3
- const smartcard = require('../lib/index');
4
- const Devices = smartcard.Devices;
5
- const devices = new Devices();
6
-
7
- devices.on('device-activated', (event) => {
8
- console.log(`Device '${event.device}' activated`);
9
- event.devices.map((device, index) => {
10
- console.log(`Device #${index + 1}: '${device.name}'`);
11
- });
12
- });
@@ -1,12 +0,0 @@
1
- 'use strict';
2
-
3
- const smartcard = require('../lib/index');
4
- const Devices = smartcard.Devices;
5
- const devices = new Devices();
6
-
7
- devices.onDeactivated().then((event) => {
8
- console.log(`Device '${event.device}' deactivated`);
9
- event.devices.map((device, index) => {
10
- console.log(`Device #${index + 1}: ${device.name}`);
11
- });
12
- });
@@ -1,12 +0,0 @@
1
- 'use strict';
2
-
3
- const smartcard = require('../lib/index');
4
- const Devices = smartcard.Devices;
5
- const devices = new Devices();
6
-
7
- devices.on('device-deactivated', (event) => {
8
- console.log(`Device '${event.device}' deactivated`);
9
- event.devices.map((device, index) => {
10
- console.log(`Device #${index + 1}: ${device.name}`);
11
- });
12
- });
@@ -1,100 +0,0 @@
1
- 'use strict';
2
-
3
- const hexify = require('hexify');
4
-
5
- const api = require('../lib/index');
6
- const Devices = api.Devices;
7
- const Iso7816Application = api.Iso7816Application;
8
- const CommandApdu = api.CommandApdu;
9
-
10
- const devices = new Devices();
11
-
12
- devices.on('device-activated', (event) => {
13
- const currentDevices = event.devices;
14
- let device = event.device;
15
- console.log(`Device '${device}' activated, devices: ${currentDevices}`);
16
- currentDevices.map((device, index) => {
17
- console.log(`Device #${index + 1}: ${device.name}`);
18
- });
19
-
20
- device.on('card-inserted', (event) => {
21
- let card = event.card;
22
- console.log(`\nCard '${card.getAtr()}' inserted into '${event.device}'`);
23
-
24
- card.on('command-issued', (event) => {
25
- console.log(`Command '${event.command}' issued to '${event.card}' `);
26
- });
27
-
28
- card.on('response-received', (event) => {
29
- console.log(
30
- `Response '${event.response}' received from '${event.card}' in response to '${event.command}'`
31
- );
32
- });
33
-
34
- // card
35
- // .issueCommand('00A404000E315041592E5359532E444446303100')
36
- // .then((response) => {
37
- // console.log(`Response '${response.toString('hex')}`);
38
- // }).catch((error) => {
39
- // console.error(error);
40
- // });
41
-
42
- const application = new Iso7816Application(card);
43
-
44
- application.on('application-selected', (event) => {
45
- console.log(`Application Selected ${event.application}`);
46
- });
47
-
48
- application
49
- .selectFile([
50
- 0x31,
51
- 0x50,
52
- 0x41,
53
- 0x59,
54
- 0x2e,
55
- 0x53,
56
- 0x59,
57
- 0x53,
58
- 0x2e,
59
- 0x44,
60
- 0x44,
61
- 0x46,
62
- 0x30,
63
- 0x31,
64
- ])
65
- .then((response) => {
66
- console.info(
67
- `Select PSE Response: '${response}' '${response.meaning()}'`
68
- );
69
- return application.selectFile(hexify.toByteArray('a0000000041010'));
70
- })
71
- .then((response) => {
72
- console.info(
73
- `Select Application Response: '${response}' '${response.meaning()}'`
74
- );
75
- return application.issueCommand(
76
- new CommandApdu({
77
- bytes: [0x80, 0xa8, 0x00, 0x00, 0x02, 0x83, 0x00, 0x00],
78
- })
79
- );
80
- })
81
- .then((response) => {
82
- console.info(
83
- `Get Processing Options Response: '${response}' '${response.meaning()}'`
84
- );
85
- return response;
86
- })
87
- .catch((error) => {
88
- console.error('Error:', error, error.stack);
89
- });
90
- });
91
- device.on('card-removed', (event) => {
92
- console.log(`Card ${event.card} removed from '${event.name}' `);
93
- });
94
- });
95
-
96
- devices.on('device-deactivated', (event) => {
97
- console.log(
98
- `Device '${event.device}' deactivated, devices: [${event.devices}]`
99
- );
100
- });
package/lib/Card.js DELETED
@@ -1,129 +0,0 @@
1
- 'use strict';
2
-
3
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
4
-
5
- Object.defineProperty(exports, "__esModule", {
6
- value: true
7
- });
8
- exports["default"] = void 0;
9
-
10
- var _events = require("events");
11
-
12
- var _hexify = _interopRequireDefault(require("hexify"));
13
-
14
- var _ResponseApdu = _interopRequireDefault(require("./ResponseApdu"));
15
-
16
- var _pino = _interopRequireDefault(require("pino"));
17
-
18
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
19
-
20
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
21
-
22
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
23
-
24
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
25
-
26
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
27
-
28
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
29
-
30
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
31
-
32
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
33
-
34
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
35
-
36
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
37
-
38
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
39
-
40
- var logger = (0, _pino["default"])({
41
- name: 'Card'
42
- });
43
-
44
- var Card = /*#__PURE__*/function (_EventEmitter) {
45
- _inherits(Card, _EventEmitter);
46
-
47
- var _super = _createSuper(Card);
48
-
49
- function Card(device, atr, protocol) {
50
- var _this;
51
-
52
- _classCallCheck(this, Card);
53
-
54
- _this = _super.call(this);
55
- logger.debug("new Card(".concat(device, ")"));
56
- _this.device = device;
57
- _this.protocol = protocol;
58
- _this.atr = atr.toString('hex');
59
- return _this;
60
- }
61
-
62
- _createClass(Card, [{
63
- key: "getAtr",
64
- value: function getAtr() {
65
- return this.atr;
66
- }
67
- }, {
68
- key: "toString",
69
- value: function toString() {
70
- return "Card(atr:'".concat(this.atr, "')");
71
- }
72
- }, {
73
- key: "issueCommand",
74
- value: function issueCommand(commandApdu, callback) {
75
- var _this2 = this;
76
-
77
- var buffer;
78
-
79
- if (Array.isArray(commandApdu)) {
80
- buffer = new Buffer(commandApdu);
81
- } else if (typeof commandApdu === 'string') {
82
- buffer = new Buffer(_hexify["default"].toByteArray(commandApdu));
83
- } else if (Buffer.isBuffer(commandApdu)) {
84
- buffer = commandApdu;
85
- } else if (typeof commandApdu === 'string') {
86
- buffer = new Buffer(_hexify["default"].toByteArray(commandApdu));
87
- } else {
88
- buffer = commandApdu.toBuffer();
89
- }
90
-
91
- var protocol = this.protocol;
92
- this.emit('command-issued', {
93
- card: this,
94
- command: commandApdu
95
- });
96
-
97
- if (callback) {
98
- this.device.transmit(buffer, 0x102, protocol, function (err, response) {
99
- _this2.emit('response-received', {
100
- card: _this2,
101
- command: commandApdu,
102
- response: new _ResponseApdu["default"](response)
103
- });
104
-
105
- callback(err, response);
106
- });
107
- } else {
108
- return new Promise(function (resolve, reject) {
109
- _this2.device.transmit(buffer, 0x102, protocol, function (err, response) {
110
- if (err) reject(err);else {
111
- _this2.emit('response-received', {
112
- card: _this2,
113
- command: commandApdu,
114
- response: new _ResponseApdu["default"](response)
115
- });
116
-
117
- resolve(response);
118
- }
119
- });
120
- });
121
- }
122
- }
123
- }]);
124
-
125
- return Card;
126
- }(_events.EventEmitter);
127
-
128
- var _default = Card;
129
- exports["default"] = _default;