smartcard 0.2.1-mswin32 → 0.2.2-mswin32

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,8 @@
1
+ v0.2.2 Fixed APDU exchange bugs on Windows
2
+ Restructured PCSC::IoRequest to allow PCI_ consts
3
+ Added PCI_ consts
4
+ Changed test suite to reflect proper way to do transmits
5
+
1
6
  v0.2.1 Added OSX Tiger support
2
7
  Many workarounds for Tiger's buggy/incomplete PC/SC.
3
8
  Small bugfixes for PC/SC status constants.
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License
2
2
 
3
- Copyright (c) 2007 Victor Costan
3
+ Copyright (c) 2007 Massachusetts Institute of Technology
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README CHANGED
@@ -25,5 +25,8 @@ has the license in legalese.
25
25
 
26
26
  = Acknowledgements
27
27
 
28
- +smartcard+ is developed by Victor Costan while working as a Research Assistant for MIT.
29
- The work is sponsored by a grant from Quanta Computer Inc (www.quanta.com.tw)
28
+ +smartcard+ is developed by Victor Costan while working as a Research Assistant for MIT, under
29
+ {Prof. Srini Devadas}[http://people.csail.mit.edu/devadas/], in the
30
+ {Trusted Computing group}[http://projects.csail.mit.edu/tc/].
31
+ The work is funded by a grant from {Quanta Computer Inc}[http://www.quanta.com.tw], under the
32
+ {T-Party Project}[http://projects.csail.mit.edu/tparty/].
@@ -15,7 +15,7 @@ elsif RUBY_PLATFORM =~ /win/
15
15
  have_library('winscard')
16
16
  else
17
17
  # pcsc is retarded and uses stuff like '#include <wintypes.h>'
18
- $CFLAGS += ' -I /usr/include/PCSC -I /usr/local/include/pcsc'
18
+ $CFLAGS += ' -I /usr/include/PCSC -I /usr/local/include/PCSC'
19
19
  have_library('pcsclite')
20
20
  end
21
21
 
@@ -19,6 +19,7 @@ int _PCSC_ReaderStates_lowlevel_get(VALUE rbReaderStates, SCARD_READERSTATE **re
19
19
  extern VALUE cPcscIoRequest;
20
20
  void Init_PCSC_IoRequest();
21
21
  int _PCSC_IoRequest_lowlevel_get(VALUE rbIoRequest, SCARD_IO_REQUEST **io_request);
22
+ VALUE _PCSC_IoRequest_lowlevel_new(SCARD_IO_REQUEST *io_request);
22
23
 
23
24
  /* Class Smartcard::PCSC::Context */
24
25
  extern VALUE cPcscContext;
@@ -263,7 +263,7 @@ static VALUE PCSC_Card_set_attribute(VALUE self, VALUE rbAttributeId, VALUE rbAt
263
263
  * The bytes in the card's response are returned wrapped in a string. (don't complain, it's a low-level API)
264
264
  *
265
265
  * +send_data+:: the APDU to be send to the card; wrap the bytes in a string-like object (low-level API, remember?)
266
- * +send_io_request+:: Smartcard::PCSC::IoRequest instance indicating the send protocol; you can use one of the Smartcard::PCSC::PCI_ constants
266
+ * +send_io_request+:: Smartcard::PCSC::IoRequest instance indicating the send protocol; you should use one of the Smartcard::PCSC::IOREQUEST_ constants
267
267
  * +recv_io_request+:: Smartcard::PCSC::IoRequest instance receving information about the recv protocol; you can use the result of Smartcard::PCSC::IoRequest#new
268
268
  */
269
269
  static VALUE PCSC_Card_transmit(VALUE self, VALUE rbSendData, VALUE rbSendIoRequest, VALUE rbRecvIoRequest) {
@@ -186,10 +186,10 @@ void Init_PCSC_Consts() {
186
186
  /* SCARD_ATTR_MAXINPUT : Maximum size of an APDU supported by the reader. */
187
187
  rb_define_const(mPcsc, "ATTR_MAXINPUT", INT2NUM(SCARD_ATTR_MAXINPUT));
188
188
 
189
-
190
- /*
191
- #define SCARD_PCI_T0 (&g_rgSCardT0Pci)
192
- #define SCARD_PCI_T1 (&g_rgSCardT1Pci)
193
- #define SCARD_PCI_RAW (&g_rgSCardRawPci)
194
- */
195
- }
189
+ /* SCARD_PCI_T0 : IoRequest for transmitting using the T=0 protocol. */
190
+ rb_define_const(mPcsc, "IOREQUEST_T0", _PCSC_IoRequest_lowlevel_new(SCARD_PCI_T0));
191
+ /* SCARD_PCI_T1 : IoRequest for transmitting using the T=1 protocol. */
192
+ rb_define_const(mPcsc, "IOREQUEST_T1", _PCSC_IoRequest_lowlevel_new(SCARD_PCI_T1));
193
+ /* SCARD_PCI_RAW : IoRequest for transmitting using the RAW protocol. */
194
+ rb_define_const(mPcsc, "IOREQUEST_RAW", _PCSC_IoRequest_lowlevel_new(SCARD_PCI_RAW));
195
+ }
@@ -2,20 +2,48 @@
2
2
 
3
3
  VALUE cPcscIoRequest;
4
4
 
5
+ /* Wraps a SCARD_IO_REQUEST, tracking its allocation etc. */
6
+ struct SCardIoRequestEx {
7
+ SCARD_IO_REQUEST *pcsc_request;
8
+ int mallocd;
9
+ };
10
+
5
11
  /* Custom free for Smartcard::PCSC::IoRequest. */
6
- static void PCSC_IoRequest_free(SCARD_IO_REQUEST *_request) {
7
- if(_request != NULL)
12
+ static void PCSC_IoRequest_free(struct SCardIoRequestEx *_request) {
13
+ if(_request != NULL) {
14
+ if(_request->mallocd)
15
+ xfree(_request->pcsc_request);
8
16
  xfree(_request);
17
+ }
9
18
  }
10
19
 
11
- /* Custom allocation for Smartcard::PCSC::Card. Wraps a SCARD_IO_REQUEST. */
20
+ /* Custom allocation for Smartcard::PCSC::Card. Wraps a SCardIoRequestEx. */
12
21
  static VALUE PCSC_IoRequest_alloc(VALUE klass) {
13
- SCARD_IO_REQUEST *request;
22
+ struct SCardIoRequestEx *request;
14
23
 
15
- VALUE rbIoRequest = Data_Make_Struct(klass, SCARD_IO_REQUEST, NULL, PCSC_IoRequest_free, request);
24
+ VALUE rbIoRequest = Data_Make_Struct(klass, struct SCardIoRequestEx, NULL, PCSC_IoRequest_free, request);
25
+ request->pcsc_request = NULL;
26
+ request->mallocd = 0;
16
27
  return rbIoRequest;
17
28
  }
18
29
 
30
+ /* :Document-method: new
31
+ * call-seq:
32
+ * new() --> io_request
33
+ *
34
+ * Creates an uninitialized IoRequest.
35
+ * The request can be used as a receiving IoRequest in Smartcard::PCSC::Card#transmit.
36
+ */
37
+ static VALUE PCSC_IoRequest_initialize(VALUE self) {
38
+ struct SCardIoRequestEx *request;
39
+
40
+ Data_Get_Struct(self, struct SCardIoRequestEx, request);
41
+ request->pcsc_request = ALLOC(SCARD_IO_REQUEST);
42
+ request->mallocd = 1;
43
+
44
+ return self;
45
+ }
46
+
19
47
  /* :Document-method: protocol
20
48
  * call-seq:
21
49
  * io_request.protocol --> protocol
@@ -25,12 +53,12 @@ static VALUE PCSC_IoRequest_alloc(VALUE klass) {
25
53
  * The returned protocol is a number, and should be checked against one of the Smartcard::PCSC::PROTOCOL_ constants.
26
54
  */
27
55
  static VALUE PCSC_IoRequest_get_protocol(VALUE self) {
28
- SCARD_IO_REQUEST *request;
56
+ struct SCardIoRequestEx *request;
29
57
 
30
- Data_Get_Struct(self, SCARD_IO_REQUEST, request);
58
+ Data_Get_Struct(self, struct SCardIoRequestEx, request);
31
59
  if(request == NULL) return Qnil;
32
60
 
33
- return UINT2NUM(request->dwProtocol);
61
+ return UINT2NUM(request->pcsc_request->dwProtocol);
34
62
  }
35
63
 
36
64
  /* :Document-method: protocol=
@@ -42,12 +70,15 @@ static VALUE PCSC_IoRequest_get_protocol(VALUE self) {
42
70
  * +protocol+:: use one of the Smartcard::PCSC::PROTOCOL_ constants
43
71
  */
44
72
  static VALUE PCSC_IoRequest_set_protocol(VALUE self, VALUE rbProtocol) {
45
- SCARD_IO_REQUEST *request;
73
+ struct SCardIoRequestEx *request;
46
74
 
47
- Data_Get_Struct(self, SCARD_IO_REQUEST, request);
75
+ Data_Get_Struct(self, struct SCardIoRequestEx, request);
48
76
  if(request == NULL) return self;
49
77
 
50
- request->dwProtocol = NUM2UINT(rbProtocol);
78
+ if(request->mallocd == 0)
79
+ rb_raise(rb_eSecurityError, "cannot modify PC/SC-global (read-only) IO_REQUEST");
80
+ else
81
+ request->pcsc_request->dwProtocol = NUM2UINT(rbProtocol);
51
82
  return self;
52
83
  }
53
84
 
@@ -66,13 +97,14 @@ static VALUE PCSC_IoRequest_set_protocol(VALUE self, VALUE rbProtocol) {
66
97
  void Init_PCSC_IoRequest() {
67
98
  cPcscIoRequest = rb_define_class_under(mPcsc, "IoRequest", rb_cObject);
68
99
  rb_define_alloc_func(cPcscIoRequest, PCSC_IoRequest_alloc);
100
+ rb_define_method(cPcscIoRequest, "initialize", PCSC_IoRequest_initialize, 0);
69
101
  rb_define_method(cPcscIoRequest, "protocol", PCSC_IoRequest_get_protocol, 0);
70
102
  rb_define_method(cPcscIoRequest, "protocol=", PCSC_IoRequest_set_protocol, 1);
71
103
  }
72
104
 
73
105
  /* Retrieves the SCARD_IO_REQUEST wrapped into a Smartcard::PCSC::IoRequest instance. */
74
106
  int _PCSC_IoRequest_lowlevel_get(VALUE rbIoRequest, SCARD_IO_REQUEST **io_request) {
75
- SCARD_IO_REQUEST *request;
107
+ struct SCardIoRequestEx *request;
76
108
 
77
109
  if(TYPE(rbIoRequest) == T_NIL || TYPE(rbIoRequest) == T_FALSE) {
78
110
  *io_request = NULL;
@@ -81,7 +113,17 @@ int _PCSC_IoRequest_lowlevel_get(VALUE rbIoRequest, SCARD_IO_REQUEST **io_reques
81
113
  if(TYPE(rbIoRequest) != T_DATA || RDATA(rbIoRequest)->dfree != (void (*)(void *))PCSC_IoRequest_free)
82
114
  return 0;
83
115
 
84
- Data_Get_Struct(rbIoRequest, SCARD_IO_REQUEST, request);
85
- *io_request = request;
116
+ Data_Get_Struct(rbIoRequest, struct SCardIoRequestEx, request);
117
+ *io_request = request->pcsc_request;
86
118
  return 1;
87
119
  }
120
+
121
+ /* Creates a Smartcard::PCSC::IoRequest instance wrapping a given SCARD_IO_REQUEST. */
122
+ VALUE _PCSC_IoRequest_lowlevel_new(SCARD_IO_REQUEST *io_request) {
123
+ struct SCardIoRequestEx *request;
124
+
125
+ VALUE rbIoRequest = Data_Make_Struct(cPcscIoRequest, struct SCardIoRequestEx, NULL, PCSC_IoRequest_free, request);
126
+ request->pcsc_request = io_request;
127
+ request->mallocd = 0;
128
+ return rbIoRequest;
129
+ }
@@ -7,4 +7,4 @@ void Init_pcsc() {
7
7
  Init_PCSC_Context();
8
8
  Init_PCSC_Card();
9
9
  Init_PCSC_Consts();
10
- }
10
+ }
@@ -79,4 +79,4 @@ char *pcsc_stringify_error(DWORD scard_error) {
79
79
  scard_error_buffer, sizeof(scard_error_buffer), NULL );
80
80
  return scard_error_buffer;
81
81
  }
82
- #endif
82
+ #endif
Binary file
data/smartcard.gemspec CHANGED
@@ -1,30 +1,35 @@
1
1
 
2
- # Gem::Specification for Smartcard-0.2.1
2
+ # Gem::Specification for Smartcard-0.2.2
3
3
  # Originally generated by Echoe
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = %q{smartcard}
7
- s.version = "0.2.1"
8
- s.date = %q{2007-11-19}
9
- s.summary = %q{Interface with ISO 7816 smart cards.}
10
- s.require_paths = ["lib", "ext"]
11
- s.email = %q{victor@costan.us}
12
- s.homepage = %q{http://www.costan.us/smartcard}
13
- s.rubyforge_project = %q{smartcard}
14
- s.description = %q{Interface with ISO 7816 smart cards.}
15
- s.has_rdoc = true
7
+ s.version = "0.2.2"
16
8
  s.platform = %q{mswin32}
9
+
10
+ s.specification_version = 2 if s.respond_to? :specification_version=
11
+
12
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
17
13
  s.authors = ["Victor Costan"]
14
+ s.date = %q{2007-12-03}
15
+ s.description = %q{Interface with ISO 7816 smart cards.}
16
+ s.email = %q{victor@costan.us}
18
17
  s.files = ["CHANGELOG", "ext/smartcard_pcsc/extconf.rb", "ext/smartcard_pcsc/pcsc.h", "ext/smartcard_pcsc/pcsc_card.c", "ext/smartcard_pcsc/pcsc_constants.c", "ext/smartcard_pcsc/pcsc_context.c", "ext/smartcard_pcsc/pcsc_io_request.c", "ext/smartcard_pcsc/pcsc_main.c", "ext/smartcard_pcsc/pcsc_multi_strings.c", "ext/smartcard_pcsc/pcsc_namespace.c", "ext/smartcard_pcsc/pcsc_reader_states.c", "ext/smartcard_pcsc/pcsc_surrogate_reader.h", "ext/smartcard_pcsc/pcsc_surrogate_wintypes.h", "lib/smartcard.rb", "LICENSE", "README", "test/test_all.rb", "tests/ts_pcsc_ext.rb", "Manifest", "smartcard.gemspec", "lib/smartcard/pcsc.so"]
18
+ s.has_rdoc = true
19
+ s.homepage = %q{http://www.costan.us/smartcard}
20
+ s.require_paths = ["lib", "ext"]
21
+ s.rubyforge_project = %q{smartcard}
22
+ s.rubygems_version = %q{0.9.5}
23
+ s.summary = %q{Interface with ISO 7816 smart cards.}
19
24
  s.test_files = ["test/test_all.rb"]
20
25
  end
21
26
 
22
27
 
23
28
  # # Original Rakefile source (requires the Echoe gem):
24
29
  #
25
- # # Needs the 'echoe' gem
30
+ # require 'rubygems'
31
+ # gem 'echoe'
26
32
  # require 'echoe'
27
- # require 'pp'
28
33
  #
29
34
  # Echoe.new('smartcard') do |p|
30
35
  # p.project = 'smartcard' # rubyforge project
@@ -52,4 +57,9 @@ end
52
57
  # task :package => [ :clean, :compile, :postcompile_hacks ]
53
58
  # end
54
59
  # end
60
+ # end
61
+ #
62
+ # if $0 == __FILE__
63
+ # Rake.application = Rake::Application.new
64
+ # Rake.application.run
55
65
  # end
data/tests/ts_pcsc_ext.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'rubygems'
2
+ gem 'smartcard', '>= 0.2.1'
1
3
  require 'smartcard'
2
4
  require 'pp'
3
5
 
@@ -57,7 +59,7 @@ def test_io_request
57
59
  io_request = Smartcard::PCSC::IoRequest.new
58
60
  [Smartcard::PCSC::PROTOCOL_T0, Smartcard::PCSC::PROTOCOL_T1, Smartcard::PCSC::PROTOCOL_RAW].each do |t_protocol|
59
61
  io_request.protocol = t_protocol
60
- r_protocol = io_request.protocol
62
+ r_protocol = io_request.protocol
61
63
  if r_protocol != t_protocol
62
64
  puts "FAILED: IoRequest.protocol= / protocol failed for protocol #{t_protocol} (got #{r_protocol} instead)\n"
63
65
  return false
@@ -116,9 +118,10 @@ rescue RuntimeError => e
116
118
  end
117
119
 
118
120
  puts "Selecting applet\n"
119
- aid = [0x19, 0x83, 0x12, 0x29, 0xba, 0xbe]
121
+ aid = [0x19, 0x83, 0x12, 0x29, 0x10, 0xba, 0xbe]
120
122
  select_apdu = [0x00, 0xA4, 0x04, 0x00, aid.length, aid].flatten
121
- send_ioreq = Smartcard::PCSC::IoRequest.new; send_ioreq.protocol = Smartcard::PCSC::PROTOCOL_T1;
123
+ send_ioreq = {Smartcard::PCSC::PROTOCOL_T0 => Smartcard::PCSC::IOREQUEST_T0,
124
+ Smartcard::PCSC::PROTOCOL_T1 => Smartcard::PCSC::IOREQUEST_T1}[card_status[:protocol]]
122
125
  recv_ioreq = Smartcard::PCSC::IoRequest.new
123
126
  select_response = card0.transmit(select_apdu.map {|byte| byte.chr}.join(''), send_ioreq, recv_ioreq)
124
127
  select_response_str = (0...select_response.length).map { |i| ' %02x' % select_response[i].to_i }.join('')
metadata CHANGED
@@ -1,34 +1,26 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.2
3
- specification_version: 1
4
2
  name: smartcard
5
3
  version: !ruby/object:Gem::Version
6
- version: 0.2.1
7
- date: 2007-11-19 00:00:00 -05:00
8
- summary: Interface with ISO 7816 smart cards.
9
- require_paths:
10
- - lib
11
- - ext
12
- email: victor@costan.us
13
- homepage: http://www.costan.us/smartcard
14
- rubyforge_project: smartcard
15
- description: Interface with ISO 7816 smart cards.
16
- autorequire:
17
- default_executable:
18
- bindir: bin
19
- has_rdoc: true
20
- required_ruby_version: !ruby/object:Gem::Version::Requirement
21
- requirements:
22
- - - ">"
23
- - !ruby/object:Gem::Version
24
- version: 0.0.0
25
- version:
4
+ version: 0.2.2
26
5
  platform: mswin32
27
- signing_key:
28
- cert_chain:
29
- post_install_message:
30
6
  authors:
31
7
  - Victor Costan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2007-12-03 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Interface with ISO 7816 smart cards.
17
+ email: victor@costan.us
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
32
24
  files:
33
25
  - CHANGELOG
34
26
  - ext/smartcard_pcsc/extconf.rb
@@ -51,17 +43,32 @@ files:
51
43
  - Manifest
52
44
  - smartcard.gemspec
53
45
  - lib/smartcard/pcsc.so
54
- test_files:
55
- - test/test_all.rb
46
+ has_rdoc: true
47
+ homepage: http://www.costan.us/smartcard
48
+ post_install_message:
56
49
  rdoc_options: []
57
50
 
58
- extra_rdoc_files: []
59
-
60
- executables: []
61
-
62
- extensions: []
63
-
51
+ require_paths:
52
+ - lib
53
+ - ext
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
64
66
  requirements: []
65
67
 
66
- dependencies: []
67
-
68
+ rubyforge_project: smartcard
69
+ rubygems_version: 0.9.5
70
+ signing_key:
71
+ specification_version: 2
72
+ summary: Interface with ISO 7816 smart cards.
73
+ test_files:
74
+ - test/test_all.rb