/* test card reader: call this program at the same time with 2 different readers */ package main import ( "fmt" "flag" "os" "strings" "encoding/hex" "github.com/ebfe/scard" ) /* ----------------------------------------------------------------------------------------------- */ func H2b (h string) ([]byte) { decoded, err := hex.DecodeString (h) if err != nil {fmt.Printf ("Error: H2b: not a hex string <%s>\n", h); os.Exit (-1)} return decoded } /* ----------------------------------------------------------------------------------------------- */ func B2h (b []byte) (string) { s := hex.EncodeToString(b) return strings.ToUpper (s) } /* ----------------------------------------------------------------------------------------------- */ func send (card *scard.Card, apdu string) (string) { // remove dots apdu = strings.Replace(apdu, ".", "", -1) Bcmd := H2b (apdu) fmt.Println (">: ", apdu) Brsp, err := card.Transmit (Bcmd) if err != nil {fmt.Println ("Error: Transmit: ", err); os.Exit (-1)} rsp := B2h (Brsp) fmt.Println ("<: ", rsp) return rsp } /* ------------------------------------------------------------------------------------------------ */ func main() { var readerno int // selected number of reader flag.IntVar (&readerno, "cardreader", 0, "Card Reader No") flag.Parse() context, err1 := scard.EstablishContext() if err1 != nil {fmt.Println ("Error: EstablishContext: ", err1); os.Exit (-1)} reader_list, err2 := context.ListReaders() if err2 != nil {fmt.Println ("Error: ListReaders: ", err2); os.Exit (-1)} fmt.Println ("Available Readers:") for i, r := range reader_list { fmt.Println ("- ", i, ": ", r) } reader := reader_list[readerno] card, err3 := context.Connect (reader, scard.ShareShared, scard.ProtocolAny) if err3 != nil { fmt.Println ("Error: Connect failed"); os.Exit (-1)} status, err4 := card.Status() if err4 != nil { fmt.Println ("Error: Status failed"); os.Exit (-1)} fmt.Println ("ATR: ", status.Atr) apdu := "A020.0001.08.30303030FFFFFFFF" // Verify PIN (0000) send (card, apdu) send (card, "A0A40000023F0000") // select Root send (card, "A0C0000022") // GET RESPONSE // Finish err5 := card.Disconnect (scard.ResetCard) if err5 != nil { fmt.Println ("Error: Disconnect failed"); os.Exit (-1)} context.Release() }