smartcard 0.4.11 → 0.5.0

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.
@@ -0,0 +1,68 @@
1
+ # Author:: Victor Costan
2
+ # Copyright:: Copyright (C) 2008 Massachusetts Institute of Technology
3
+ # License:: MIT
4
+
5
+ require 'smartcard'
6
+
7
+ require 'test/unit'
8
+
9
+
10
+ class CardTest < Test::Unit::TestCase
11
+ def setup
12
+ @context = Smartcard::PCSC::Context.new
13
+ @reader = @context.readers.first
14
+ @card = @context.card @reader, :shared
15
+ end
16
+
17
+ def teardown
18
+ @card.disconnect
19
+ @context.release
20
+ end
21
+
22
+ def test_reconnect
23
+ @card.reconnect :shared
24
+ end
25
+
26
+ def test_transaction
27
+ @card.begin_transaction
28
+ @card.end_transaction
29
+
30
+ @card.transaction { }
31
+ end
32
+
33
+ def test_transmit
34
+ response = @card.transmit [0x00, 0xA4, 0x04, 0x00, 0x00].pack('C*')
35
+ assert_equal [0x90, 0x00], response[-2, 2].unpack('C*'),
36
+ 'In transmit: SELECT with no AID should always return OK'
37
+ end
38
+
39
+ def test_info
40
+ info = @card.info
41
+ assert_operator info[:atr], :kind_of?, String,
42
+ "The card's ATR should be a string"
43
+ assert_operator info[:readers], :include?, @reader,
44
+ "The card's readers list should have the canonical reader"
45
+ assert_operator info[:protocol], :kind_of?, Symbol, "The card's protocol"
46
+ assert_operator info[:state], :include?, :present,
47
+ "The card's state should reflect the card's presence"
48
+ end
49
+
50
+ def test_get_attribute
51
+ vendor_name = @card[:vendor_name]
52
+ assert_operator vendor_name, :kind_of?, String,
53
+ 'IFD attributes should be strings'
54
+ end
55
+
56
+ def test_set_attribute
57
+ assert_raise Smartcard::PCSC::Exception do
58
+ @card[:atr_string] = "\0"
59
+ end
60
+ end
61
+
62
+ def test_control
63
+ # This only works with GemPlus readers... any other suggestions?
64
+ assert_raise(Smartcard::PCSC::Exception, 'Control sequence') do
65
+ ctl_response = @card.control 0x42000001, [0x02].pack('C*')
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,64 @@
1
+ # Author:: Victor Costan
2
+ # Copyright:: Copyright (C) 2008 Massachusetts Institute of Technology
3
+ # License:: MIT
4
+
5
+ require 'smartcard'
6
+
7
+ require 'test/unit'
8
+
9
+
10
+ class ContextTest < Test::Unit::TestCase
11
+ def setup
12
+ @context = Smartcard::PCSC::Context.new :system
13
+ end
14
+
15
+ def teardown
16
+ @context.release
17
+ end
18
+
19
+ def test_reader_groups
20
+ groups = @context.reader_groups
21
+ assert_operator groups, :kind_of?, Enumerable,
22
+ 'reader_groups should produce an array'
23
+ assert_operator groups.length, :>=, 1, 'reader_groups should be non-empty'
24
+ end
25
+
26
+ def test_readers_without_groups
27
+ readers = @context.readers
28
+ _check_readers readers
29
+ end
30
+
31
+ def test_readers_with_groups
32
+ readers = @context.readers @context.reader_groups
33
+ _check_readers readers
34
+ end
35
+
36
+ def _check_readers(readers)
37
+ assert_operator readers, :kind_of?, Enumerable,
38
+ 'readers (without argument) should produce an array'
39
+ readers.each do |reader|
40
+ assert_operator reader, :kind_of?, String,
41
+ 'each reader name should be a string'
42
+ end
43
+ end
44
+
45
+ def test_wait_for_status_change
46
+ readers = @context.readers
47
+ queries = Smartcard::PCSC::ReaderStateQueries.new readers.length
48
+ readers.each_with_index do |name, index|
49
+ queries[index].reader_name = name
50
+ queries[index].current_state = :unknown
51
+ end
52
+
53
+ @context.wait_for_status_change queries
54
+
55
+ readers.each_with_index do |name, index|
56
+ query = queries[index]
57
+ assert_equal name, query.reader_name,
58
+ 'Reader name changed during wait_for_status_change'
59
+ assert_operator query.atr, :kind_of?, String, 'ATR should be a string'
60
+ assert_operator query.event_state, :include?, :changed,
61
+ 'event_state must have changed from :unknown'
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,72 @@
1
+ # Author:: Victor Costan
2
+ # Copyright:: Copyright (C) 2008 Massachusetts Institute of Technology
3
+ # License:: MIT
4
+
5
+ require 'smartcard'
6
+
7
+ require 'test/unit'
8
+
9
+
10
+ class ReaderStatesTest < Test::Unit::TestCase
11
+ def setup
12
+ @queries = Smartcard::PCSC::ReaderStateQueries.new 2
13
+
14
+ @queries[1].current_state = :atrmatch
15
+ @queries[0].current_state = [:inuse, :exclusive]
16
+ @queries[0].event_state = :ignore
17
+ @queries[1].event_state = [:present, :unpowered]
18
+ @queries[1].atr = "Ruby\0rocks!"
19
+ @queries[0].atr = 'grreat success'
20
+ @queries[0].reader_name = 'PC/SC Reader 0'
21
+ @queries[1].reader_name = 'CCID Reader 1'
22
+ end
23
+
24
+ def teardown
25
+ end
26
+
27
+ def test_length
28
+ assert_equal 2, @queries.length
29
+ end
30
+
31
+ def test_atr
32
+ assert_equal "Ruby\0rocks!", @queries[1].atr
33
+ assert_equal 'grreat success', @queries[0].atr
34
+ end
35
+
36
+ def test_atr_reassign
37
+ @queries[1].atr = 'even more success'
38
+ assert_equal 'even more success', @queries[1].atr
39
+ end
40
+
41
+ def test_states
42
+ assert_equal Set.new([:atrmatch]), @queries[1].current_state,
43
+ 'current_state'
44
+ assert_equal Set.new([:inuse, :exclusive]), @queries[0].current_state,
45
+ 'current_state'
46
+
47
+ assert_equal Set.new([:ignore]), @queries[0].event_state,
48
+ 'event_state'
49
+ assert_equal Set.new([:present, :unpowered]), @queries[1].event_state,
50
+ 'event_state'
51
+ end
52
+
53
+ def test_reader_names
54
+ assert_equal 'PC/SC Reader 0', @queries[0].reader_name
55
+ assert_equal 'CCID Reader 1', @queries[1].reader_name
56
+ end
57
+
58
+ def test_ack_changes
59
+ @queries.ack_changes
60
+
61
+ assert_equal Set.new([:ignore]), @queries[0].current_state
62
+ assert_equal Set.new([:present, :unpowered]), @queries[1].current_state
63
+ end
64
+
65
+ def test_invalid_indexes
66
+ [[5, IndexError], [2, IndexError], [nil, TypeError]].each do |test_case|
67
+ assert_raise test_case.last, test_case.inspect do
68
+ @queries[test_case.first]
69
+ end
70
+ end
71
+ end
72
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smartcard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.11
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Costan
@@ -9,9 +9,19 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-16 00:00:00 -05:00
12
+ date: 2009-11-27 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: ffi
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.5.3
24
+ version:
15
25
  - !ruby/object:Gem::Dependency
16
26
  name: rubyzip
17
27
  type: :runtime
@@ -56,26 +66,13 @@ description: Interface with ISO 7816 smart cards.
56
66
  email: victor@costan.us
57
67
  executables: []
58
68
 
59
- extensions:
60
- - ext/smartcard_pcsc/extconf.rb
69
+ extensions: []
70
+
61
71
  extra_rdoc_files:
62
72
  - BUILD
63
73
  - CHANGELOG
64
74
  - LICENSE
65
75
  - README
66
- - ext/smartcard_pcsc/extconf.rb
67
- - ext/smartcard_pcsc/pcsc.h
68
- - ext/smartcard_pcsc/pcsc_card.c
69
- - ext/smartcard_pcsc/pcsc_constants.c
70
- - ext/smartcard_pcsc/pcsc_context.c
71
- - ext/smartcard_pcsc/pcsc_exception.c
72
- - ext/smartcard_pcsc/pcsc_io_request.c
73
- - ext/smartcard_pcsc/pcsc_main.c
74
- - ext/smartcard_pcsc/pcsc_multi_strings.c
75
- - ext/smartcard_pcsc/pcsc_namespace.c
76
- - ext/smartcard_pcsc/pcsc_reader_states.c
77
- - ext/smartcard_pcsc/pcsc_surrogate_reader.h
78
- - ext/smartcard_pcsc/pcsc_surrogate_wintypes.h
79
76
  - lib/smartcard.rb
80
77
  - lib/smartcard/gp/asn1_ber.rb
81
78
  - lib/smartcard/gp/cap_loader.rb
@@ -89,7 +86,15 @@ extra_rdoc_files:
89
86
  - lib/smartcard/iso/jcop_remote_transport.rb
90
87
  - lib/smartcard/iso/pcsc_transport.rb
91
88
  - lib/smartcard/iso/transport.rb
89
+ - lib/smartcard/pcsc/card.rb
90
+ - lib/smartcard/pcsc/context.rb
91
+ - lib/smartcard/pcsc/ffi_autogen.rb
92
+ - lib/smartcard/pcsc/ffi_functions.rb
93
+ - lib/smartcard/pcsc/ffi_lib.rb
94
+ - lib/smartcard/pcsc/ffi_structs.rb
92
95
  - lib/smartcard/pcsc/pcsc_exception.rb
96
+ - lib/smartcard/pcsc/reader_state_queries.rb
97
+ - tasks/ffi_codegen.rb
93
98
  files:
94
99
  - BUILD
95
100
  - CHANGELOG
@@ -97,19 +102,6 @@ files:
97
102
  - Manifest
98
103
  - README
99
104
  - Rakefile
100
- - ext/smartcard_pcsc/extconf.rb
101
- - ext/smartcard_pcsc/pcsc.h
102
- - ext/smartcard_pcsc/pcsc_card.c
103
- - ext/smartcard_pcsc/pcsc_constants.c
104
- - ext/smartcard_pcsc/pcsc_context.c
105
- - ext/smartcard_pcsc/pcsc_exception.c
106
- - ext/smartcard_pcsc/pcsc_io_request.c
107
- - ext/smartcard_pcsc/pcsc_main.c
108
- - ext/smartcard_pcsc/pcsc_multi_strings.c
109
- - ext/smartcard_pcsc/pcsc_namespace.c
110
- - ext/smartcard_pcsc/pcsc_reader_states.c
111
- - ext/smartcard_pcsc/pcsc_surrogate_reader.h
112
- - ext/smartcard_pcsc/pcsc_surrogate_wintypes.h
113
105
  - lib/smartcard.rb
114
106
  - lib/smartcard/gp/asn1_ber.rb
115
107
  - lib/smartcard/gp/cap_loader.rb
@@ -123,7 +115,15 @@ files:
123
115
  - lib/smartcard/iso/jcop_remote_transport.rb
124
116
  - lib/smartcard/iso/pcsc_transport.rb
125
117
  - lib/smartcard/iso/transport.rb
118
+ - lib/smartcard/pcsc/card.rb
119
+ - lib/smartcard/pcsc/context.rb
120
+ - lib/smartcard/pcsc/ffi_autogen.rb
121
+ - lib/smartcard/pcsc/ffi_functions.rb
122
+ - lib/smartcard/pcsc/ffi_lib.rb
123
+ - lib/smartcard/pcsc/ffi_structs.rb
126
124
  - lib/smartcard/pcsc/pcsc_exception.rb
125
+ - lib/smartcard/pcsc/reader_state_queries.rb
126
+ - tasks/ffi_codegen.rb
127
127
  - test/gp/asn1_ber_test.rb
128
128
  - test/gp/cap_loader_test.rb
129
129
  - test/gp/des_test.rb
@@ -135,9 +135,9 @@ files:
135
135
  - test/iso/iso_card_mixin_test.rb
136
136
  - test/iso/iso_exception_test.rb
137
137
  - test/iso/jcop_remote_test.rb
138
- - test/pcsc/containers_test.rb
139
- - test/pcsc/smoke_test.rb
140
- - tests/ts_pcsc_ext.rb
138
+ - test/pcsc/card_test.rb
139
+ - test/pcsc/context_test.rb
140
+ - test/pcsc/reader_state_queries_test.rb
141
141
  - smartcard.gemspec
142
142
  has_rdoc: true
143
143
  homepage: http://www.costan.us/smartcard
@@ -153,7 +153,6 @@ rdoc_options:
153
153
  - README
154
154
  require_paths:
155
155
  - lib
156
- - ext
157
156
  required_ruby_version: !ruby/object:Gem::Requirement
158
157
  requirements:
159
158
  - - ">="
@@ -174,14 +173,15 @@ signing_key:
174
173
  specification_version: 3
175
174
  summary: Interface with ISO 7816 smart cards.
176
175
  test_files:
177
- - test/gp/asn1_ber_test.rb
178
- - test/gp/cap_loader_test.rb
179
- - test/gp/des_test.rb
180
- - test/gp/gp_card_mixin_compat_test.rb
181
- - test/gp/gp_card_mixin_test.rb
182
- - test/iso/auto_configurator_test.rb
183
176
  - test/iso/iso_card_mixin_test.rb
177
+ - test/iso/auto_configurator_test.rb
184
178
  - test/iso/iso_exception_test.rb
185
179
  - test/iso/jcop_remote_test.rb
186
- - test/pcsc/containers_test.rb
187
- - test/pcsc/smoke_test.rb
180
+ - test/pcsc/card_test.rb
181
+ - test/pcsc/context_test.rb
182
+ - 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
@@ -1,79 +0,0 @@
1
- require 'mkmf'
2
-
3
- $CFLAGS ||= ''
4
- $LDFLAGS ||= ''
5
-
6
- pcsc_defines = []
7
-
8
- if RUBY_PLATFORM =~ /darwin/
9
- $LDFLAGS += ' -framework PCSC'
10
- darwin_version = `uname -r`
11
- if darwin_version =~ /^8./
12
- pcsc_defines.push 'RB_SMARTCARD_OSX_TIGER_HACK'
13
- end
14
- elsif RUBY_PLATFORM =~ /win/
15
- have_library('winscard')
16
- unless have_library('winscard', 'SCardIsValidContext')
17
- pcsc_defines << 'PCSC_SURROGATE_SCARD_IS_VALID_CONTEXT'
18
- end
19
- else
20
- # pcsclite is retarded and uses stuff like '#include <wintypes.h>'
21
- $CFLAGS += ' -I /usr/include/PCSC -I /usr/local/include/PCSC'
22
- have_library('pcsclite')
23
- end
24
-
25
- pcsc_headers = []
26
- ['wintypes.h', 'reader.h', 'winscard.h', 'pcsclite.h'].each do |header|
27
- ['', 'PCSC/', './pcsc_surrogate_'].each do |path_prefix|
28
- if have_header(path_prefix + header)
29
- pcsc_headers.push((path_prefix[0,1] == '.') ?
30
- "\"#{path_prefix + header}\"" :
31
- "<#{path_prefix + header}>")
32
- break
33
- end
34
- end
35
- end
36
-
37
- File.open('pcsc_autogen.h', 'w') do |f|
38
- pcsc_defines.each { |d| f.write "\#define #{d}\n" }
39
- pcsc_headers.each { |h| f.write "\#include #{h}\n" }
40
- end
41
-
42
- if have_macro('SCARDHANDLE', ['pcsc_autogen.h']) or
43
- have_type('SCARDHANDLE', ['pcsc_autogen.h'])
44
- create_makefile('smartcard/pcsc')
45
- else
46
- STDERR.write "PC/SC libraries missing!\n"
47
- end
48
-
49
-
50
- def win32_hack(mf_name)
51
- # get the version of MSVC
52
- Kernel.system `cl 2> msvc_version.txt`
53
- msvc_logo = File.open('msvc_version.txt') { |f| f.read }
54
- print msvc_logo
55
- File.delete 'msvc_version.txt'
56
- if msvc_logo =~ /Optimizing Compiler Version (\d+)/
57
- msvc_ver = $1.to_i
58
- # for MSVC 6.0, no manifest BS is needed -- straight-up compilation is good
59
- return if msvc_ver == 12
60
- end
61
-
62
- # HACK: monkey-patch the makefile to embed a manifest in the extension dll
63
- make_contents = File.open(mf_name, 'r') { |f| f.read }
64
- make_rules = make_contents.split(/(\n|\r)(\n|\r)+/)
65
- new_make_rules = make_rules.map do |rule|
66
- if rule =~ /^\$\(DLLIB\)\:/
67
- rule + "\n\tmt.exe -manifest $(@).manifest -outputresource:$(@);2"
68
- else
69
- rule
70
- end
71
- end
72
- File.open(mf_name, 'w') { |f| f.write new_make_rules.join("\n\n")}
73
- end
74
-
75
- case RUBY_PLATFORM
76
- when /darwin/
77
- when /win/
78
- win32_hack 'Makefile'
79
- end
@@ -1,52 +0,0 @@
1
- /* Ruby extension API. */
2
- #include <ruby.h>
3
- /* Generated by 'extconf.rb' to point to the PC/SC header. */
4
- #include "pcsc_autogen.h"
5
-
6
- /* Entrypoint into the Ruby extension. */
7
- void Init_pcsc();
8
-
9
- /* Namespace structure. */
10
- extern VALUE mSmartcard; /* Smartcard module / namespace */
11
- extern VALUE mPcsc; /* Smartcard::PCSC module / namespace */
12
-
13
- /* Class Smartcard::PCSC::ReaderStates */
14
- extern VALUE cPcscReaderStates;
15
- void Init_PCSC_ReaderStates();
16
- int _PCSC_ReaderStates_lowlevel_get(VALUE rbReaderStates, SCARD_READERSTATE **reader_states, size_t *reader_states_count);
17
-
18
- /* Class Smartcard::PCSC::IoRequest */
19
- extern VALUE cPcscIoRequest;
20
- void Init_PCSC_IoRequest();
21
- int _PCSC_IoRequest_lowlevel_get(VALUE rbIoRequest, SCARD_IO_REQUEST **io_request);
22
- VALUE _PCSC_IoRequest_lowlevel_new(const SCARD_IO_REQUEST *io_request);
23
-
24
- /* Class Smartcard::PCSC::Context */
25
- extern VALUE cPcscContext;
26
- void Init_PCSC_Context();
27
- int _PCSC_Context_lowlevel_get(VALUE rbContext, SCARDCONTEXT *pcsc_context);
28
-
29
- /* Class Smartcard::PCSC::Card */
30
- extern VALUE cPcscCard;
31
- void Init_PCSC_Card();
32
- int _PCSC_Card_lowlevel_get(VALUE rbCard, SCARDHANDLE *card_handle);
33
-
34
- /* Class Smartcard::PCSC::Exception */
35
- extern VALUE ePcscException;
36
- void Init_PCSC_Exception();
37
- void _PCSC_Exception_raise(DWORD pcsc_error, char *pcsc_function);
38
-
39
- /* Constants in Smartcard::PCSC */
40
- void Init_PCSC_Consts();
41
-
42
- /* Multi-string (win32 abomination) tools. */
43
- VALUE PCSC_Internal_multistring_to_ruby_array(char *mstr, size_t mstr_len);
44
- int PCSC_Internal_ruby_strings_to_multistring(VALUE rbStrings, char **strings);
45
-
46
- /* Messing up with constants that aren't uniformly defined. */
47
- #if !defined(MAX_ATR_SIZE)
48
- #define MAX_ATR_SIZE 32
49
- #endif
50
- #if !defined(SCARD_PROTOCOL_ANY)
51
- #define SCARD_PROTOCOL_ANY (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1)
52
- #endif