To continue the list of PC/SC wrappers initiated in 2010 with "PC/SC sample in different languages" I now present a new sample code in Deno a modern runtime for JavaScript and TypeScript.
pcsc-deno
The wrapper is available at https://github.com/cryptographix/pcsc-deno and https://deno.land/x/pcsc
The author is
Sean Michael Wykes.
The license is MIT.
I used version
0.4.
This version includes the fixes I proposed for GNU/Linux.
Deno
From Wikipedia Deno article:
Deno is a runtime for JavaScript, TypeScript, and WebAssembly that is based on the V8 JavaScript engine and the Rust programming language. Deno was co-created by Ryan Dahl, who also created Node.js.
Deno explicitly takes on the role of both runtime and package manager within a single executable, rather than requiring a separate package-management program.
Installation
Installation is very easy. First install Deno as documented in https://deno.land/#installation
The PC/SC wrapper will be downloaded and installed automatically at run
time.
Source code
import {
CommandAPDU,
ContextProvider,
ISO7816,
PCSC,
} from 'https://deno.land/x/pcsc/mod.ts';
try {
// establish a PC/SC context
const context = ContextProvider.establishContext();
// get all available readers
const readers = context.listReaders();
for (const reader of readers) {
console.log(`Using reader: ${reader.name}`);
if (reader.isMute) {
console.log(`Reader ${reader.name}: MUTE`);
} else if (reader.isPresent) {
// connect
const card = await reader.connect();
// send Select Applet APDU
const selectApplet = CommandAPDU
.from([ISO7816.CLA.ISO, ISO7816.INS.SelectFile, 0x04, 0x00]) // ISO SELECT
.setData([0xA0, 0x00, 0x00, 0x00, 0x62, 0x03, 0x01, 0x0C, 0x06, 0x01]);
const resp = await card.transmitAPDU(selectApplet);
// check for 0x90 0x00
if (resp.SW == ISO7816.SW.SUCCESS) {
// success ..
console.log(`Reader ${reader.name}: applet successfully selected`);
// send Test APDU
const command = CommandAPDU
.from([ISO7816.CLA.ISO, 0, 0, 0]);
const resp = await card.transmitAPDU(command);
if (resp.SW == ISO7816.SW.SUCCESS) {
// success ..
console.log(`Reader ${reader.name}: Test command successful`);
// convert from bytes to string and display
console.log(String.fromCharCode.apply(null, resp.data));
} else {
// something went wrong ..
console.error(
`Reader ${reader.name}: error SW=${resp.SW.toString(16)}`,
);
}
} else {
// something went wrong ..
console.error(
`Reader ${reader.name}: error SW=${resp.SW.toString(16)}`,
);
}
// unpower and disconnect
await card.disconnect(PCSC.Disposition.UnpowerCard);
} else {
console.log(`Reader ${reader.name}: NO CARD`);
}
}
// release the PC/SC context
context.shutdown();
} catch (e: PCSCException) {
console.log(e, "error");
}
Output
$ deno run --unstable --allow-ffi blog.ts Using reader: Gemalto PC Twin Reader (F8345B4A) 00 00 Reader Gemalto PC Twin Reader (F8345B4A) 00 00: applet successfully selected Reader Gemalto PC Twin Reader (F8345B4A) 00 00: command successful Hello world!
Conclusion
Nothing special to say. Thanks Sean for the wrapper.
If you work on a Free Software PC/SC wrapper that is not yet in my list please let me know.