PCSC sample in JavaScript (Node.js)
To continue the list of PC/SC wrappers initiated more than four years ago with "PC/SC sample in different languages" I now present a PC/SC sample written in JavaScript using Node.js.
node-pcsclite project
The node-pcsclite project is hosted at github and is quiet active. Support of Windows is not yet available. Support of Mac OS X is now correct after I proposed some patches.The installation on a Debian unstable or testing (Jessie) system is easy. Just follow the project documentation. Debian stable (Whezzy) do not have the nodejs packages but these packages are available in wheezy-backports.
One potential problem is that the Node.js binary is called
nodejs
on Debian to avoid a conflict with another node
binary. To have a node
binary corresponding to Node.js you need to install the Debian package nodejs-legacy
. It is not difficult but may be the source of some difficulties at the beginning.PC/SC accesses from node-pcsclite
The wrapper provides access the following PC/SC functions:- connect
- disconnect
- transmit
- control
A reader event (reader removed) is reported as an event.
The card status change is reported as an event.
The reconnect function is missing. A bug #10 is open requesting its addition.
Sample source code
#!/usr/bin/env node var pcsc = require('./lib/pcsclite'); var pcsc = pcsc(); pcsc.on('reader', function(reader) { function exit() { reader.close(); pcsc.close(); } cmd_select = new Buffer([0x00, 0xA4, 0x04, 0x00, 0x0A, 0xA0, 0x00, 0x00, 0x00, 0x62, 0x03, 0x01, 0x0C, 0x06, 0x01]); cmd_command = new Buffer([0x00, 0x00, 0x00, 0x00]); console.log('Using:', reader.name); reader.connect(function(err, protocol) { if (err) { console.log(err); return exit(); } reader.transmit(cmd_select, 255, protocol, function(err, data) { if (err) { console.log(err); return exit(); } console.log('Data received', data); reader.transmit(cmd_command, 255, protocol, function(err, data) { if (err) { console.log(err); } else { console.log('Data received', data); console.log('Data received', data.toString()); } return exit(); }); }); }); }); pcsc.on('error', function(err) { console.log('PCSC error', err.message); });
Remarks
Node.js is an asynchronous framework. So a typical Node.js design pattern is to use a call-back instead of blocking the execution of a function.The code can be complex to follow since you have a cascade of call-backs if you need to send a sequence of APDU. In the sample we only need to send 2 consecutive APDU.
The program is not sequential but event based. So without the explicit exit after 1 second the program never terminates and you need to stop it using Control-C. It is strange for me.
Output
Using: Gemalto PC Twin Reader 00 00 Data received <SlowBuffer 90 00> Data received <SlowBuffer 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 90 00> Data received Hello world!�
Similar projects
Two other similar projects are also found at github. They have both the same name node-pcsc but are not the same project:coolbong node-pcsc
The node-pcsc interface from coolbong uses a synchronous API so no call-back are involved for PC/SC calls. You can send a sequence of APDU as you would do in C.This wrapper is for Windows only and need some work to port it to Unix. I opened a bug #1 requesting Unix support.
jokesterfr node-pcsc
This wrapper is not yet able to send arbitrary APDU to a card. It looks like a work in progress that stopped in November 2013.Conclusion
If you want to use a smart card from a JavaScript program using Node.js the best choice may be the node-pcsclite project. The project maintainer is nice and reactive.If you know a PC/SC wrapper that is not yet in my list then please contact me.
Edit, October 3rd 2014
After discussing with Santiago Gimeno (node-pcsclite author) and fixing Mac OS X bugs in node-pcsclite I modified the sample source code to add the clean upexit()
function and exit properly from the program when no more callbacks are waiting.