A USB smartcard driver and development platform. Simple synchronous design, multiple slots but one transaction at a time, with a Python interface. Includes a command-line smartcard shell with searchable history, useful both for smartcard development and for reverse-engineering APDU formats.
Also includes tools for reading GSM SIM cards (basic — can read SMS messages) and EMV credit/debit cards, including an example command-line tool that's boilerplate for the EMV C API, plus a graphical interface for reading EMV cards. Source documentation is browsable online.
Screenshots
Application main window and application selection
Cardholder Verification (PIN)
Transaction processing (input)
Transaction processing (results)
Downloads
GNU GPL v3. Copyright © 2008–2010 Gianni Tedesco.
ccid-utils-0.3.tar.gz — chip and pin is broken
ccid-utils-0.2.tar.gz
ccid-utils-0.1.tar.gz — initial release
Follow development:
git clone git://github.com/giannitedesco/ccid-utils.git
Shell command reference
- ? / help — print a help message
- ber — enable/disable BER TLV decoding of responses
- brute_cla — brute-force CLA
- brute_fs — brute-force file IDs
- brute_get — brute-force data objects
- brute_ins — brute-force INS
- challenge — retrieve a random number from the card
- cla — set CLA
- get — get a data object
- hex — enable/disable HEX decoding of responses
- quit — exit the shell
- read_rec — read a record from the currently selected file
- rx_len — set RX length
- select — select a file by ID, name, or path
- slot_off — power off the slot
- slot_on — power on the slot and retrieve ATR
- status — display hardware status
- transmit — transmit a raw APDU (except CLA)
- tx_len — set TX length
- wait — wait for card insertion
Example credit card session
This is my own credit card — please don't rip me off!
ccid-# slot_on
ccid> Got 18 bytes ATR:
| 00000 : ;n...1.q.e...... 3b 6e 00 00 00 31 c0 71 d6 65 a3 03 01 80 00 83
| 00010 : .. 90 00
ccid-# brute_cla
ccid> Found 2 classes, SW1=6d SW2=00: Bad INS
ccid> o CLA 00
ccid> o CLA 80
ccid-# brute_ins
INS 6d made card freak
INS 92 made card freak
ccid> Found 1 objects, SW1=69 SW2=85: Permission.... DENIED
ccid> o INS c0 (GET_RESPONSE)
ccid> Found 3 objects, SW1=6a SW2=86: Bad parameters P1-P2
ccid> o INS a4 (SELECT_FILE)
ccid> o INS b2 (READ_RECORDS)
ccid> o INS dc (UPDATE_DATA)
ccid> Found 3 objects, SW1=69 SW2=86: Permission.... DENIED
ccid> o INS b0 (READ_BINARY)
ccid> o INS d6 (UPDATE_BINARY)
ccid> o INS e2 (APPEND_RECORD)
ccid-# select name 1PAY.SYS.DDF01
ccid> SW1 = 0x90 : SW2 = 0x00 : Success (47 bytes)
| 00000 : o-..1PAY.SYS.DDF 6f 2d 84 0e 31 50 41 59 2e 53 59 53 2e 44 44 46
| 00010 : 01....._-.en.... 30 31 a5 1b 88 01 01 5f 2d 02 65 6e 9f 11 01 01
| 00020 : .......?....... bf 0c 0c c5 0a ff ff 3f 00 00 00 02 ff ff 02
ccid-# hex off
ccid> HEX decoding: off
ccid-# ber on
ccid> BER TLV decoding: on
ccid-# read_rec 1 0
ccid> SW1 = 0x90 : SW2 = 0x00 : Success (29 bytes)
.tag = 16 (0x10)
.len = 29 (0x1d) {
.tag = 1 (0x1)
.len = 27 (0x1b) {
.tag = 15 (0xf)
.len = 25 (0x19)
00000 : ....).. a0 00 00 00 29 10 10
.tag = 16 (0x10)
.len = 25 (0x19)
00000 : LINK 4c 49 4e 4b
.tag = 18 (0x12)
.len = 25 (0x19)
00000 : LINK 4c 49 4e 4b
.tag = 7 (0x7)
.len = 25 (0x19)
00000 : . 01
}
}
ccid-# read_rec 2 0
ccid> SW1 = 0x90 : SW2 = 0x00 : Success (41 bytes)
.tag = 16 (0x10)
.len = 41 (0x29) {
.tag = 1 (0x1)
.len = 39 (0x27) {
.tag = 15 (0xf)
.len = 37 (0x25)
00000 : ....... a0 00 00 00 03 10 10
.tag = 16 (0x10)
.len = 37 (0x25)
00000 : VISA DEBIT 56 49 53 41 20 44 45 42 49 54
.tag = 18 (0x12)
.len = 37 (0x25)
00000 : VISA DEBIT 56 49 53 41 20 44 45 42 49 54
.tag = 7 (0x7)
.len = 37 (0x25)
00000 : . 02
}
}
ccid-# select name a0 00 00 00 03 10 10
ccid> SW1 = 0x90 : SW2 = 0x00 : Success (65 bytes)
.tag = 15 (0xf)
.len = 65 (0x41) {
.tag = 4 (0x4)
.len = 63 (0x3f)
00000 : ....... a0 00 00 00 03 10 10
.tag = 5 (0x5)
.len = 63 (0x3f) {
.tag = 16 (0x10)
.len = 52 (0x34)
00000 : VISA DEBIT 56 49 53 41 20 44 45 42 49 54
.tag = 7 (0x7)
.len = 52 (0x34)
00000 : . 02
.tag = 45 (0x2d)
.len = 52 (0x34)
00000 : en 65 6e
.tag = 17 (0x11)
.len = 52 (0x34)
00000 : . 01
.tag = 18 (0x12)
.len = 52 (0x34)
00000 : VISA DEBIT 56 49 53 41 20 44 45 42 49 54
.tag = 12 (0xc)
.len = 52 (0x34) {
.tag = 5 (0x5)
.len = 12 (0xc)
00000 : ...QG..... 01 01 7f 51 47 00 03 0f ff 03
}
}
}
ccid-# read_rec 1 1
ccid> SW1 = 0x90 : SW2 = 0x00 : Success (79 bytes)
.tag = 16 (0x10)
.len = 79 (0x4f) {
.tag = 32 (0x20)
.len = 77 (0x4d)
00000 : MR G TEDESCO 4d 52 20 47 20 54 45 44 45 53 43 4f 20 20 20 20
00010 : 20 20 20 20 20 20 20 20 20 20
.tag = 23 (0x17)
.len = 77 (0x4d)
00000 : XXXXXXXX.......A XX XX XX XX XX XX XX XX d1 01 02 01 00 00 01 41
00010 : @.. 40 00 0f
.tag = 31 (0x1f)
.len = 77 (0x4d)
00000 : 0000010000000004 30 30 30 30 30 31 30 30 30 30 30 30 30 30 30 34
00010 : 14000000 31 34 30 30 30 30 30 30
}
ccid-# read_rec 1 2
ccid> SW1 = 0x90 : SW2 = 0x00 : Success (80 bytes)
.tag = 16 (0x10)
.len = 80 (0x50) {
.tag = 37 (0x25)
.len = 78 (0x4e)
00000 : XX. YY MM 01
.tag = 36 (0x24)
.len = 78 (0x4e)
00000 : XX1 YY MM 31
.tag = 26 (0x1a)
.len = 78 (0x4e)
00000 : XXXXXXXX XX XX XX XX XX XX XX XX
.tag = 52 (0x34)
.len = 78 (0x4e)
00000 : . 01
.tag = 7 (0x7)
.len = 78 (0x4e)
00000 : .. ff c0
.tag = 14 (0xe)
.len = 78 (0x4e)
00000 : ........A....... 00 00 00 00 00 00 00 00 41 03 1e 03 02 03 1f 00
.tag = 13 (0xd)
.len = 78 (0x4e)
00000 : ..|.. f0 00 7c 08 00
.tag = 14 (0xe)
.len = 78 (0x4e)
00000 : .p... 00 70 80 00 00
.tag = 15 (0xf)
.len = 78 (0x4e)
00000 : ..|.. f0 00 7c 98 00
.tag = 40 (0x28)
.len = 78 (0x4e)
00000 : .& 08 26
}
License
GNU GPL v3. Copyright © 2008–2010 Gianni Tedesco.