2011-02-04 16:29:21 +00:00
|
|
|
#!/usr/bin/env ruby
|
2011-05-02 10:34:31 +00:00
|
|
|
=begin
|
2011-05-06 08:36:22 +00:00
|
|
|
This file is part of softSIM.
|
2011-05-02 10:34:31 +00:00
|
|
|
|
2011-05-06 08:36:22 +00:00
|
|
|
softSIM is free software: you can redistribute it and/or modify
|
2011-05-02 10:34:31 +00:00
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
2011-05-06 08:36:22 +00:00
|
|
|
softSIM is distributed in the hope that it will be useful,
|
2011-05-02 10:34:31 +00:00
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2011-05-06 08:36:22 +00:00
|
|
|
along with sofSIM. If not, see <http://www.gnu.org/licenses/>.
|
2011-05-02 10:34:31 +00:00
|
|
|
|
|
|
|
Copyright (C) 2011 Kevin "tsaitgaist" Redon kevredon@mail.tsaitgaist.info
|
|
|
|
=end
|
2011-05-02 09:39:55 +00:00
|
|
|
require 'lib/server'
|
|
|
|
require 'rubygems'
|
|
|
|
require 'smartcard'
|
2011-02-07 10:17:13 +00:00
|
|
|
=begin
|
|
|
|
need to install
|
|
|
|
sudo aptitude install ruby ruby-dev rubygems
|
|
|
|
sudo aptitude install libpcsclite1 libpcsclite-dev libruby
|
|
|
|
sudo gem install smartcard (http://www.rubygems.org/gems/smartcard)
|
|
|
|
=end
|
2011-02-04 16:29:21 +00:00
|
|
|
|
|
|
|
# SAP server using PCSC for the card
|
|
|
|
class PCSCServer < Server
|
|
|
|
|
|
|
|
# provide the io to listen to
|
2011-05-03 12:05:56 +00:00
|
|
|
# TODO : choose which reader to use
|
2011-02-04 16:29:21 +00:00
|
|
|
def initialize(io)
|
|
|
|
super(io)
|
2011-02-07 10:17:13 +00:00
|
|
|
|
|
|
|
# get PCSC context
|
2011-05-03 12:05:56 +00:00
|
|
|
begin
|
|
|
|
@context = Smartcard::PCSC::Context.new
|
|
|
|
rescue Smartcard::PCSC::Exception => e
|
|
|
|
puts "PCSC not available. please start PCSC"
|
|
|
|
sleep 1
|
|
|
|
retry
|
|
|
|
end
|
|
|
|
|
2011-02-07 10:17:13 +00:00
|
|
|
# get all readers
|
2011-04-12 22:12:18 +00:00
|
|
|
begin
|
2011-05-03 12:05:56 +00:00
|
|
|
readers = @context.readers
|
2011-04-12 22:12:18 +00:00
|
|
|
rescue Smartcard::PCSC::Exception => e
|
|
|
|
puts "no reader available. please connect a card reader"
|
2011-05-03 12:05:56 +00:00
|
|
|
sleep 1
|
|
|
|
retry
|
2011-04-12 22:12:18 +00:00
|
|
|
end
|
2011-05-03 12:05:56 +00:00
|
|
|
|
2011-02-07 10:17:13 +00:00
|
|
|
# one reader required
|
2011-05-03 12:05:56 +00:00
|
|
|
while readers.size==0 do
|
2011-02-07 10:17:13 +00:00
|
|
|
puts "no reader available. connect a reader"
|
2011-05-03 12:05:56 +00:00
|
|
|
sleep 1
|
|
|
|
readers = @context.readers
|
2011-02-07 10:17:13 +00:00
|
|
|
end
|
2011-05-03 12:05:56 +00:00
|
|
|
|
2011-02-07 10:17:13 +00:00
|
|
|
# use the first reader
|
2011-05-03 12:05:56 +00:00
|
|
|
@reader = readers.first
|
|
|
|
puts "using reader : #{@reader}"
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
# connect to card
|
|
|
|
def connect
|
2011-02-07 10:17:13 +00:00
|
|
|
|
|
|
|
# connect to the card
|
|
|
|
begin
|
2011-05-03 12:05:56 +00:00
|
|
|
@card = Smartcard::PCSC::Card.new(@context,@reader,:exclusive,:t0)
|
2011-02-07 10:17:13 +00:00
|
|
|
rescue Smartcard::PCSC::Exception => e
|
|
|
|
# wait for a card
|
2011-04-12 22:12:18 +00:00
|
|
|
puts "no card available. insert card"
|
2011-05-03 12:05:56 +00:00
|
|
|
sleep 1
|
|
|
|
retry
|
2011-02-07 10:17:13 +00:00
|
|
|
end
|
|
|
|
|
2011-05-03 12:05:56 +00:00
|
|
|
return true
|
2011-02-07 10:17:13 +00:00
|
|
|
end
|
2011-05-06 16:44:05 +00:00
|
|
|
|
|
|
|
def disconnect
|
|
|
|
@card.disconnect
|
|
|
|
@context.release
|
|
|
|
end
|
2011-02-07 10:17:13 +00:00
|
|
|
|
|
|
|
# get ATR
|
|
|
|
def atr
|
|
|
|
raise "connect to card to get ATR" unless @card
|
|
|
|
return @card.info[:atr].unpack("C*")
|
|
|
|
end
|
|
|
|
|
2011-02-07 14:53:56 +00:00
|
|
|
# send APDU and get response
|
|
|
|
def apdu(request)
|
|
|
|
raise "connect to card to send APDU" unless @card
|
|
|
|
response = @card.transmit(request.pack('C*')).unpack("C*")
|
|
|
|
return response
|
|
|
|
end
|
|
|
|
|
2011-02-04 16:29:21 +00:00
|
|
|
end
|