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, September 13, 2016

PC/SC sample in go

To continue the list of PC/SC wrappers initiated in 2010 with "PC/SC sample in different languages" I now present a sample in go.

scard go wrapper

I used the scard go wrapper from Michael Gehring.

The github project does not provide any documentation. You can get some help from a previous project go.pcsclite also from Michael Gehring.

The scard wrapper API has a nice godoc page.

Installation

The installation is quiet simple.
$ cd foobar
$ export GOPATH=$(pwd)

$ go get github.com/ebfe/scard

I used the default golang-go package on Debian stable (jessie 8.5).
$ go version
go version go1.3.3 linux/amd64

Sample source code


package main

import (
    "fmt"
    "github.com/ebfe/scard"
)

func main() {
    // Establish a PC/SC context
    context, err := scard.EstablishContext()
    if err != nil {
        fmt.Println("Error EstablishContext:", err)
        return
    }

    // Release the PC/SC context (when needed)
    defer context.Release()

    // List available readers
    readers, err := context.ListReaders()
    if err != nil {
        fmt.Println("Error ListReaders:", err)
        return
    }

    // Use the first reader
    reader := readers[0]
    fmt.Println("Using reader:", reader)

    // Connect to the card
    card, err := context.Connect(reader, scard.ShareShared, scard.ProtocolAny)
    if err != nil {
        fmt.Println("Error Connect:", err)
        return
    }

    // Disconnect (when needed)
    defer card.Disconnect(scard.LeaveCard)

    // Send select APDU
    var cmd_select = []byte{0x00, 0xa4, 0x04, 0x00, 0x0A, 0xA0,
  0x00, 0x00, 0x00, 0x62, 0x03, 0x01, 0x0C, 0x06, 0x01}
    rsp, err := card.Transmit(cmd_select)
    if err != nil {
        fmt.Println("Error Transmit:", err)
        return
    }
    fmt.Println(rsp)

    // Send command APDU
    var cmd_command = []byte{0x00, 0x00, 0x00, 0x00}
    rsp, err = card.Transmit(cmd_command)
    if err != nil {
        fmt.Println("Error Transmit:", err)
        return
    }
    fmt.Println(rsp)
    for i := 0; i < len(rsp)-2; i++ {
        fmt.Printf("%c", rsp[i])
    }
    fmt.Println()
}

Remarks

You can get another sample code example_test.go in the scard project. This sample code greatly helped me implement my own sample code.

Results

$ go run hello_world.go
Using reader: Gemalto PC Twin Reader (70D7E2EE) 00 00
[144 0]
[72 101 108 108 111 32 119 111 114 108 100 33 144 0]
Hello world!

Conclusion

The github project scard has no documentation or README file. After discussion with Michael Gehring it is on purpose.

This blog article should give more visibility to the project.