Created
August 23, 2014 12:21
-
-
Save zmajstor/af52f7b0f1c5f9ab2b98 to your computer and use it in GitHub Desktop.
SmartCard adapter using smartcard gem with demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# http://www.rdoc.info/github/costan/smartcard/master/Smartcard | |
require 'smartcard' | |
class SmartCardAdapter | |
# scope of the smart-card connection; valid values are :system, :user, and :terminal | |
# (see the SCARD_SCOPE_ constants in the PC/SC API) | |
def connect(scope = :system) | |
@context = Smartcard::PCSC::Context.new(scope) | |
end | |
def readers | |
@context.readers | |
end | |
def disconnect | |
@card.disconnect if @card | |
@context.release if @context | |
end | |
def select_card_in_the_first_reader | |
@card = @context.card(@context.readers.first) if @context && @context.readers.any? | |
end | |
def send_APDU_to_current_card(bytes_array) | |
# send_data is a string containing the APDU bytes to be sent to the card | |
send_data = bytes_array.pack('C*') | |
response = @card.transmit(send_data) | |
# hex(response[-2, 2]) | |
hex(response) | |
end | |
def dump_current_card_info | |
puts "Dumping Card state and data:" | |
puts "card protocol: #{@card.protocol}" | |
puts "card sharing mode: #{@card.sharing_mode}" | |
info = @card.info | |
# puts "\ncard info: #{info}" | |
puts "card ATR (hex): #{hex(info[:atr])}" | |
puts "card state: #{info[:state].to_a.join(' ')}" | |
end | |
private | |
def hex(input) | |
input.unpack('C*').map{ |e| e.to_s(16).upcase }.join(' ') | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require_relative 'smart_card_adapter' | |
begin # demo | |
print "Searching for Smart Card..." | |
adapter = SmartCardAdapter.new | |
readers = adapter.readers if adapter.connect | |
abort("No Smart Card readers found") if adapter.nil? || readers.empty? | |
puts " found: #{readers}" | |
print "connecting to the first reader..." | |
card = adapter.select_card_in_the_first_reader | |
puts " connected!" if card | |
adapter.dump_current_card_info | |
apdu_bytes = [0x80, 0xC0, 0x02, 0xA1] | |
puts "response: #{adapter.send_APDU_to_current_card(apdu_bytes)}" | |
puts "\n" | |
rescue Smartcard::PCSC::Exception => e | |
puts "Ooops: #{e}" | |
ensure | |
adapter.disconnect if adapter | |
end | |
# how to format proper APDU bytes string? | |
# http://web.archive.org/web/20090630004017/http://cheef.ru/docs/HowTo/APDU.info | |
# http://www.wrankl.de/SCTables/SCTables.html | |
# apdu_bytes = [0x00, 0xA4, 0x04, 0x00, 0x00] | |
# apdu_bytes = [0xFF, 0xCA, 0x00, 0x00, 0x00] # get UID | |
# apdu_bytes = [0xAF, 0x03, 0x16, 0x78] # BH | |
# apdu_bytes = [0x20, 0x00, 0x82, 0x04, 0x01, 0x02, 0x03, 0x04, 0x00] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment