Now that we can run the provided samples in Go, let's try and understand what they do. I'm going to start with show-atr because I think I basically understand what it's trying to do and it works by itself, without requiring me to figure out how to ask it to do what I want it to do.
I managed to find out on Google back in Episode 1 that ATR was an abbreviation for Answer to Reset and looking at that reference, it seems that when the card is first detected, the "reset" command is sent from the reader to the card and it "responds with a dozen or more bytes of data known as the Answer To Reset (ATR). This is usually a fixed sequence for any particular make and model of card, and is intended to tell the reader/system some (limited) information about the card and its capabilities, for example the maximum speed it can operate at, and its preferred voltage and clock frequency".
Main Code
So here's the code for show-atr:func main() {So, ignoring the error handling and the fact that Release is called in defer, we have:
ctx, err := smartcard.EstablishContext()
if err != nil {
panic(err)
}
defer ctx.Release()
fmt.Printf("\nWaiting for card...")
reader, err := ctx.WaitForCardPresent()
if err != nil {
panic(err)
}
card, err := reader.Connect()
if err != nil {
panic(err)
}
fmt.Printf("\n\nATR: %s\n\n", card.ATR())
card.Disconnect()
fmt.Printf("Please remove card")
reader.WaitUntilCardRemoved()
fmt.Printf("\n\n")
}
ctx := smartcard.EstablishContext()In other words:
reader := ctx.WaitForCardPresent()
card := reader.Connect()
atr := card.ATR()
card.Disconnect()
reader.WaitUntilCardRemoved()
ctx.Release()
- Establish a "context"
- Wait for a card to be present, then we have a "reader"
- Ask the reader to "Connect"
- Read the "Answer to Reset"
- Disconnect the card (reversing "Connect")
- Wait for the card to be "removed"
- Release the "context"
Build Constraints
Looking around the code, I notice that there are two different implementations of the function EstablishContext in smartcard. Which one gets called? It turns out that there are two different "builds" here, one for Windows (using WINSCard) and one for Linux (using PCSC-Lite and the pcscd daemon). Which is used depends on the operating system that the application is being compiled for, which in turn, is determined by a comment at the top of the file:// +build windowsAfter some googling, I discovered this description in the Go documentation which doesn't seem to exactly match what was done here, but close enough.
ATR data
Digging through the code in the smartcard package didn't enlighten me that much. It seems to be a reasonably defined wrapper around a (unix) socket connection to the pcscd. For some reason, it seems to need to use unsafe pointers; it's not obvious why, but I think it may have something to do with optimising the protocol which depends on sending fixed-size blocks with a size and an overlarge buffer.So, instead I'm going to turn to what's in the ATR data. Googling turns up a Wikipedia Page which really doesn't enlighten me very much. Given that the ATR is about communicating basic information about how to interact with the card, and much of the information here is at a very low level, I'm going to assume that I don't need to know any of this. But before I go any further, I'm going to see what happens when I try and use my phone with the reader since that, after all, is why I'm here.
Waiting for card...In my investigations, I came across this website which can parse out the ATR and "explain" what it means. For my phone, it gives this output.
ATR: 3b80800101
Please remove card
No comments:
Post a Comment