Important!

Blog moved to https://blog.apdu.fr/

I moved my blog from https://ludovicrousseau.blogspot.com/ to https://blog.apdu.fr/ . Why? I wanted to move away from Blogger (owne...

Tuesday, April 7, 2020

PCSC sample in Kotlin

Here is a new PCSC sample in Kotlin language I promised in PC/SC sample in different languages.

JetBrains IntelliJ IDEA provides a way to convert a source file from Java to Kotlin. I just used this possibility from the previous Java source code presented in "PCSC sample in Java using intarsys smartcard-io".

The same PC/SC wrapper can be used for Kotlin as for Java.

intarsys smartcard-io

The project intarsys smartcard-io is hosted at https://github.com/intarsys/smartcard-io.
The licence is 3-Clause BSD.

Installation

Installation is easy. Just get the provided is-smartcard-io.jar file from deploy/ directory and the 3 runtime dependencies from lib/ directory.

I have not tried to rebuild the library from source.

Source code

The API is easy to use since it is a direct mapping to the PC/SC WinScard API.


package com.company

import de.intarsys.security.smartcard.pcsc.PCSCContextFactory
import de.intarsys.security.smartcard.pcsc.nativec._IPCSC

object Blog {
    @JvmStatic
    fun main(args: Array<String>) {
        try {
            /* Establish context */
            val context = PCSCContextFactory.get().establishContext()

            /* Display the list of readers */
            val readers = context.listReaders()
            for (reader in readers) {
                println("found " + reader + " named " + reader.name)
            }

            /* Use the first reader */
            val reader = readers[0]

            /* Connect to the card */
            val connection = context.connect(
                    reader.name, _IPCSC.SCARD_SHARE_SHARED,
                    _IPCSC.SCARD_PROTOCOL_Tx)

            /* Send Select Applet command */
            val select = byteArrayOf(0x00, 0xA4.toByte(), 0x04, 0x00, 10, 0xA0.toByte(), 0x00, 0x00, 0x00, 0x62, 0x03, 0x01, 0x0C, 0x06, 0x01)
            var answer: ByteArray
            answer = connection.transmit(select, 0, select.size, 256, false)
            println("answer: " + answer.size + " bytes")
            for (i in answer.indices) {
                print(String.format("%02X ", answer[i]))
            }
            println()

            /* Send test command */
            val command = byteArrayOf(0x00, 0x00, 0x00, 0x00)
            answer = connection.transmit(command, 0, command.size, 256, false)
            println("answer: " + answer.size + " bytes")
            for (i in answer.indices) {
                print(String.format("%02X ", answer[i]))
            }
            println()
            for (i in 0 until answer.size - 2) {
                print(answer[i].toChar())
            }
            println()

            /* Disconnect */
            connection.disconnect(_IPCSC.SCARD_LEAVE_CARD)

            /* Release context */
            context.dispose()
        } catch (e: Exception) {
            println("Ouch: $e")
        }
    }
}

Output

found pcscreader 0 named Cherry KC 1000 SC Z
answer: 2 bytes
90 00 
answer: 14 bytes
48 65 6C 6C 6F 20 77 6F 72 6C 64 21 90 00 
Hello world!

Conclusion

I have no real merit with this code. I did not write it myself and it is a direct translation from Java to Kotlin.

This PC/SC wrapper is easy to use and provides access to all the PC/SC functions.