smartcard 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,5 @@
1
+ v0.5.1. Work around drivers that don't honor PROTOCOL_ANY.
2
+
1
3
  v0.5.0. Dropped C extension in favor of FFI. Hello, jruby and rbx!
2
4
 
3
5
  v0.4.11. Support for GlobalPlatform's SC01 (Secure Channel 1) protocol.
@@ -35,11 +35,16 @@ class Card
35
35
  raise Smartcard::PCSC::Exception, status unless status == :success
36
36
 
37
37
  @context = context
38
+ @sharing_mode = sharing_mode
39
+ @_handle = handle_ptr[:value]
38
40
  set_protocol FFILib::Protocol[protocol_ptr[:value]]
39
- @_handle = handle_ptr[:value]
40
41
  end
41
42
 
42
- # Updates internal buffers to reflect a change in the communication protocol.
43
+ # Updates internal buffers to reflect a change in the communication protocol.
44
+ #
45
+ # Args:
46
+ # protocol:: the protocol to change to; if invalid, the card's ATR will be
47
+ # used to guess a valid protocol
43
48
  def set_protocol(protocol)
44
49
  @protocol = protocol
45
50
 
@@ -50,12 +55,16 @@ class Card
50
55
  @send_pci = @recv_pci = FFILib::PCI_T1
51
56
  when :raw
52
57
  @send_pci = @recv_pci = FFILib::PCI_RAW
58
+ else
59
+ reconnect sharing_mode, guess_protocol_from_atr, :leave
60
+ return self
53
61
  end
54
62
 
55
63
  # Windows really doesn't like a receiving IoRequest.
56
64
  if FFI::Platform.windows? || FFI::Platform.mac?
57
65
  @recv_pci = nil
58
66
  end
67
+ self
59
68
  end
60
69
  private :set_protocol
61
70
 
@@ -78,6 +87,7 @@ class Card
78
87
  preferred_protocols, disposition, protocol_ptr
79
88
  raise Smartcard::PCSC::Exception, status unless status == :success
80
89
 
90
+ @sharing_mode = sharing_mode
81
91
  set_protocol FFILib::Protocol[protocol_ptr[:value]]
82
92
  end
83
93
 
@@ -269,6 +279,40 @@ class Card
269
279
  end
270
280
  end
271
281
 
282
+ # Returns the first valid protocol listed in the card's ATR.
283
+ def guess_protocol_from_atr
284
+ atr = info[:atr]
285
+
286
+ # NOTE: inspired from the following sources:
287
+ # http://en.wikipedia.org/wiki/Answer_to_reset
288
+ # http://www.atmel.com/dyn/resources/prod_documents/doc5025.pdf
289
+ # http://pyscard.sourceforge.net/epydoc/smartcard.ATR-pysrc.html#ATR.__initInstance__
290
+ atr_bytes = atr.unpack('C*')
291
+ protocols = []
292
+ i = 1
293
+ loop do
294
+ next_nibble = atr_bytes[i] >> 4
295
+ next_bits = (0...4).map { |j| (next_nibble >> j) & 1 }
296
+ next_bits.each { |bit| i += bit }
297
+ if next_bits[3] == 1 # TD byte was last, i is right on it
298
+ protocols << (atr_bytes[i] & 0x0f)
299
+ else
300
+ break # No TD, no more bytes
301
+ end
302
+ end
303
+
304
+ protocols.sort!
305
+ case protocols[0]
306
+ when 0
307
+ :t0
308
+ when 1
309
+ :t1
310
+ else
311
+ :t0
312
+ end
313
+ end
314
+ private :guess_protocol_from_atr
315
+
272
316
  # The low-level _SCARDHANDLE_ data.
273
317
  #
274
318
  # This should not be used by client code.
@@ -276,6 +320,9 @@ class Card
276
320
 
277
321
  # The communication protocol in use with this smart-card.
278
322
  attr_reader :protocol
323
+
324
+ # The sharing mode for this smart-card session. (:shared or :exclusive)
325
+ attr_reader :sharing_mode
279
326
  end # class Smartcard::PCSC::Card
280
327
 
281
328
  end # namespace Smartcard::PCSC
data/smartcard.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{smartcard}
5
- s.version = "0.5.0"
5
+ s.version = "0.5.1"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Victor Costan"]
9
- s.date = %q{2009-11-27}
9
+ s.date = %q{2010-11-27}
10
10
  s.description = %q{Interface with ISO 7816 smart cards.}
11
11
  s.email = %q{victor@costan.us}
12
12
  s.extra_rdoc_files = ["BUILD", "CHANGELOG", "LICENSE", "README", "lib/smartcard.rb", "lib/smartcard/gp/asn1_ber.rb", "lib/smartcard/gp/cap_loader.rb", "lib/smartcard/gp/des.rb", "lib/smartcard/gp/gp_card_mixin.rb", "lib/smartcard/iso/apdu_error.rb", "lib/smartcard/iso/auto_configurator.rb", "lib/smartcard/iso/iso_card_mixin.rb", "lib/smartcard/iso/jcop_remote_protocol.rb", "lib/smartcard/iso/jcop_remote_server.rb", "lib/smartcard/iso/jcop_remote_transport.rb", "lib/smartcard/iso/pcsc_transport.rb", "lib/smartcard/iso/transport.rb", "lib/smartcard/pcsc/card.rb", "lib/smartcard/pcsc/context.rb", "lib/smartcard/pcsc/ffi_autogen.rb", "lib/smartcard/pcsc/ffi_functions.rb", "lib/smartcard/pcsc/ffi_lib.rb", "lib/smartcard/pcsc/ffi_structs.rb", "lib/smartcard/pcsc/pcsc_exception.rb", "lib/smartcard/pcsc/reader_state_queries.rb", "tasks/ffi_codegen.rb"]
@@ -15,15 +15,15 @@ Gem::Specification.new do |s|
15
15
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Smartcard", "--main", "README"]
16
16
  s.require_paths = ["lib"]
17
17
  s.rubyforge_project = %q{smartcard}
18
- s.rubygems_version = %q{1.3.5}
18
+ s.rubygems_version = %q{1.3.7}
19
19
  s.summary = %q{Interface with ISO 7816 smart cards.}
20
- s.test_files = ["test/iso/iso_card_mixin_test.rb", "test/iso/auto_configurator_test.rb", "test/iso/iso_exception_test.rb", "test/iso/jcop_remote_test.rb", "test/pcsc/card_test.rb", "test/pcsc/context_test.rb", "test/pcsc/reader_state_queries_test.rb", "test/gp/gp_card_mixin_test.rb", "test/gp/gp_card_mixin_compat_test.rb", "test/gp/cap_loader_test.rb", "test/gp/asn1_ber_test.rb", "test/gp/des_test.rb"]
20
+ s.test_files = ["test/gp/asn1_ber_test.rb", "test/gp/cap_loader_test.rb", "test/gp/des_test.rb", "test/gp/gp_card_mixin_compat_test.rb", "test/gp/gp_card_mixin_test.rb", "test/iso/auto_configurator_test.rb", "test/iso/iso_card_mixin_test.rb", "test/iso/iso_exception_test.rb", "test/iso/jcop_remote_test.rb", "test/pcsc/card_test.rb", "test/pcsc/context_test.rb", "test/pcsc/reader_state_queries_test.rb"]
21
21
 
22
22
  if s.respond_to? :specification_version then
23
23
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
24
  s.specification_version = 3
25
25
 
26
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
27
27
  s.add_runtime_dependency(%q<ffi>, [">= 0.5.3"])
28
28
  s.add_runtime_dependency(%q<rubyzip>, [">= 0.9.1"])
29
29
  s.add_runtime_dependency(%q<zerg_support>, [">= 0.1.5"])
@@ -6,6 +6,9 @@ require 'smartcard'
6
6
 
7
7
  require 'test/unit'
8
8
 
9
+ require 'rubygems'
10
+ require 'flexmock/test_unit'
11
+
9
12
 
10
13
  class CardTest < Test::Unit::TestCase
11
14
  def setup
@@ -19,8 +22,13 @@ class CardTest < Test::Unit::TestCase
19
22
  @context.release
20
23
  end
21
24
 
25
+ def test_sharing_mode
26
+ assert_equal :shared, @card.sharing_mode
27
+ end
28
+
22
29
  def test_reconnect
23
30
  @card.reconnect :shared
31
+ assert_equal :shared, @card.sharing_mode
24
32
  end
25
33
 
26
34
  def test_transaction
@@ -65,4 +73,22 @@ class CardTest < Test::Unit::TestCase
65
73
  ctl_response = @card.control 0x42000001, [0x02].pack('C*')
66
74
  end
67
75
  end
76
+
77
+ def test_set_protocol_guesses
78
+ flexmock(@card).should_receive(:guess_protocol_from_atr).and_return(:t0)
79
+ flexmock(@card).should_receive(:reconnect).with(:shared, :t0, :leave)
80
+ @card.send :set_protocol, :unset
81
+ end
82
+
83
+ def test_guess_protocol_t0_from_atr
84
+ flexmock(@card).should_receive(:info).and_return(:atr =>
85
+ ";\026\224q\001\001\005\002\000")
86
+ assert_equal :t0, @card.send(:guess_protocol_from_atr)
87
+ end
88
+
89
+ def test_guess_protocol_t1_from_atr
90
+ flexmock(@card).should_receive(:info).and_return(:atr =>
91
+ ";\212\001JCOP41V221\377")
92
+ assert_equal :t1, @card.send(:guess_protocol_from_atr)
93
+ end
68
94
  end
metadata CHANGED
@@ -1,7 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smartcard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ hash: 9
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 5
9
+ - 1
10
+ version: 0.5.1
5
11
  platform: ruby
6
12
  authors:
7
13
  - Victor Costan
@@ -9,59 +15,88 @@ autorequire:
9
15
  bindir: bin
10
16
  cert_chain: []
11
17
 
12
- date: 2009-11-27 00:00:00 -05:00
18
+ date: 2010-11-27 00:00:00 -05:00
13
19
  default_executable:
14
20
  dependencies:
15
21
  - !ruby/object:Gem::Dependency
16
22
  name: ffi
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
20
26
  requirements:
21
27
  - - ">="
22
28
  - !ruby/object:Gem::Version
29
+ hash: 13
30
+ segments:
31
+ - 0
32
+ - 5
33
+ - 3
23
34
  version: 0.5.3
24
- version:
35
+ type: :runtime
36
+ version_requirements: *id001
25
37
  - !ruby/object:Gem::Dependency
26
38
  name: rubyzip
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
30
42
  requirements:
31
43
  - - ">="
32
44
  - !ruby/object:Gem::Version
45
+ hash: 57
46
+ segments:
47
+ - 0
48
+ - 9
49
+ - 1
33
50
  version: 0.9.1
34
- version:
51
+ type: :runtime
52
+ version_requirements: *id002
35
53
  - !ruby/object:Gem::Dependency
36
54
  name: zerg_support
37
- type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
40
58
  requirements:
41
59
  - - ">="
42
60
  - !ruby/object:Gem::Version
61
+ hash: 17
62
+ segments:
63
+ - 0
64
+ - 1
65
+ - 5
43
66
  version: 0.1.5
44
- version:
67
+ type: :runtime
68
+ version_requirements: *id003
45
69
  - !ruby/object:Gem::Dependency
46
70
  name: echoe
47
- type: :development
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
50
74
  requirements:
51
75
  - - ">="
52
76
  - !ruby/object:Gem::Version
77
+ hash: 3
78
+ segments:
79
+ - 3
80
+ - 2
53
81
  version: "3.2"
54
- version:
82
+ type: :development
83
+ version_requirements: *id004
55
84
  - !ruby/object:Gem::Dependency
56
85
  name: flexmock
57
- type: :development
58
- version_requirement:
59
- version_requirements: !ruby/object:Gem::Requirement
86
+ prerelease: false
87
+ requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
60
89
  requirements:
61
90
  - - ">="
62
91
  - !ruby/object:Gem::Version
92
+ hash: 51
93
+ segments:
94
+ - 0
95
+ - 8
96
+ - 6
63
97
  version: 0.8.6
64
- version:
98
+ type: :development
99
+ version_requirements: *id005
65
100
  description: Interface with ISO 7816 smart cards.
66
101
  email: victor@costan.us
67
102
  executables: []
@@ -154,34 +189,41 @@ rdoc_options:
154
189
  require_paths:
155
190
  - lib
156
191
  required_ruby_version: !ruby/object:Gem::Requirement
192
+ none: false
157
193
  requirements:
158
194
  - - ">="
159
195
  - !ruby/object:Gem::Version
196
+ hash: 3
197
+ segments:
198
+ - 0
160
199
  version: "0"
161
- version:
162
200
  required_rubygems_version: !ruby/object:Gem::Requirement
201
+ none: false
163
202
  requirements:
164
203
  - - ">="
165
204
  - !ruby/object:Gem::Version
205
+ hash: 11
206
+ segments:
207
+ - 1
208
+ - 2
166
209
  version: "1.2"
167
- version:
168
210
  requirements: []
169
211
 
170
212
  rubyforge_project: smartcard
171
- rubygems_version: 1.3.5
213
+ rubygems_version: 1.3.7
172
214
  signing_key:
173
215
  specification_version: 3
174
216
  summary: Interface with ISO 7816 smart cards.
175
217
  test_files:
176
- - test/iso/iso_card_mixin_test.rb
218
+ - test/gp/asn1_ber_test.rb
219
+ - test/gp/cap_loader_test.rb
220
+ - test/gp/des_test.rb
221
+ - test/gp/gp_card_mixin_compat_test.rb
222
+ - test/gp/gp_card_mixin_test.rb
177
223
  - test/iso/auto_configurator_test.rb
224
+ - test/iso/iso_card_mixin_test.rb
178
225
  - test/iso/iso_exception_test.rb
179
226
  - test/iso/jcop_remote_test.rb
180
227
  - test/pcsc/card_test.rb
181
228
  - test/pcsc/context_test.rb
182
229
  - test/pcsc/reader_state_queries_test.rb
183
- - test/gp/gp_card_mixin_test.rb
184
- - test/gp/gp_card_mixin_compat_test.rb
185
- - test/gp/cap_loader_test.rb
186
- - test/gp/asn1_ber_test.rb
187
- - test/gp/des_test.rb