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 +2 -0
- data/lib/smartcard/pcsc/card.rb +49 -2
- data/smartcard.gemspec +5 -5
- data/test/pcsc/card_test.rb +26 -0
- metadata +73 -31
data/CHANGELOG
CHANGED
data/lib/smartcard/pcsc/card.rb
CHANGED
@@ -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.
|
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{
|
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.
|
18
|
+
s.rubygems_version = %q{1.3.7}
|
19
19
|
s.summary = %q{Interface with ISO 7816 smart cards.}
|
20
|
-
s.test_files = ["test/
|
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::
|
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"])
|
data/test/pcsc/card_test.rb
CHANGED
@@ -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
|
-
|
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:
|
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
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
25
37
|
- !ruby/object:Gem::Dependency
|
26
38
|
name: rubyzip
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
35
53
|
- !ruby/object:Gem::Dependency
|
36
54
|
name: zerg_support
|
37
|
-
|
38
|
-
|
39
|
-
|
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
|
-
|
67
|
+
type: :runtime
|
68
|
+
version_requirements: *id003
|
45
69
|
- !ruby/object:Gem::Dependency
|
46
70
|
name: echoe
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
-
|
82
|
+
type: :development
|
83
|
+
version_requirements: *id004
|
55
84
|
- !ruby/object:Gem::Dependency
|
56
85
|
name: flexmock
|
57
|
-
|
58
|
-
|
59
|
-
|
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
|
-
|
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.
|
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/
|
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
|