smartcard 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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