I've got what I thought would be a fairly simple app, in which I'm on debian Linux (doesn't have to be cross-platform) and I need to read a smart card to get the user's UID / LDAP username, which should be stored in the certificate that's on the card.
I did this kind of thing successfully on Windows using powershell, following something like this: View All Certificates On Smart Card
But I'm struggling to do the same in node. I've so far pulled in pcsclite, used the node-pcsclite example code to verify the environment works. Here's the code that I'm successfully running:
#!/usr/bin/env node
var pcsc = require('../index');
var pcsc = pcsc();
pcsc.on('reader', function(reader) {
console.log('New reader detected', reader.name);
reader.on('error', function(err) {
console.log('Error(', this.name, '):', err.message);
});
reader.on('status', function(status) {
console.log('Status(', this.name, '):', status);
/* check what has changed */
var changes = this.state ^ status.state;
if (changes) {
if ((changes & this.SCARD_STATE_EMPTY) && (status.state & this.SCARD_STATE_EMPTY)) {
console.log("card removed");/* card removed */
reader.disconnect(reader.SCARD_LEAVE_CARD, function(err) {
if (err) {
console.log(err);
} else {
console.log('Disconnected');
}
});
} else if ((changes & this.SCARD_STATE_PRESENT) && (status.state & this.SCARD_STATE_PRESENT)) {
console.log("card inserted");/* card inserted */
reader.connect({ share_mode : this.SCARD_SHARE_SHARED }, function(err, protocol) {
if (err) {
console.log(err);
} else {
console.log('Protocol(', reader.name, '):', protocol);
reader.transmit(new Buffer([0x00, 0xB0, 0x00, 0x00, 0x20]), 40, protocol, function(err, data) {
if (err) {
console.log(err);
} else {
console.log('Data received', data);
reader.close();
pcsc.close();
}
});
}
});
}
}
});
reader.on('end', function() {
console.log('Reader', this.name, 'removed');
});
});
pcsc.on('error', function(err) {
console.log('PCSC error', err.message);
});
So this works exactly as documented, no issues. If I insert my smart card I get the expected output.
What I'm not grokking is what exactly the 'data' in the .transmit()
callback represents. It's a buffer, an array of hex numbers (it looks like), but I'm not clear on how I'd go about turning that into something readable that I can compare for access approval (for this app, I just want to compare the user's UID against a whitelist).
I've tried reading the pcsc-lite docs and the PC/SC standard, but the actual meaning of the data is pretty opaque to me so far.
Of course I've tried a few simple things like calling data.toString()
with various encodings, without success thus far.
Any thoughts on how I can take what I've gotten so far from node-pcsclite and harvest any kind of human-readable information for use?