smartcard 0.4.11 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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