smartcard 0.4.5 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,5 @@
1
+ v0.4.6. Automatic detection of package AID from CAP in install_applet.
2
+
1
3
  v0.4.5. More bugfixes in JcopRemoteTransport's ATR forwarding logic.
2
4
 
3
5
  v0.4.4. Bugfixes in JcopRemoteTransport's ATR forwarding logic.
@@ -4,6 +4,7 @@
4
4
  # Copyright:: Copyright (C) 2009 Massachusetts Institute of Technology
5
5
  # License:: MIT
6
6
 
7
+ require 'set'
7
8
  require 'zip/zip'
8
9
 
9
10
  # :nodoc: namespace
@@ -58,8 +59,8 @@ module CapLoader
58
59
  applets = []
59
60
  return applets unless section = components[:applet]
60
61
  offset = 1
61
- section[0].times do
62
- aid_length = section[offset]
62
+ section[0].ord.times do
63
+ aid_length = section[offset].ord
63
64
  install_method = section[offset + 1 + aid_length, 2].unpack('n').first
64
65
  applets << { :aid => section[offset + 1, aid_length].unpack('C*'),
65
66
  :install_method => install_method }
@@ -68,13 +69,46 @@ module CapLoader
68
69
  applets
69
70
  end
70
71
 
72
+ # Parses the Header section in a CAP file, obtaining package AIDs.
73
+ #
74
+ # Returns a hash with the following keys:
75
+ # :magic:: the header magic value
76
+ # :version:: the CAP specification version (has :minor and :major keys)
77
+ # :flags:: Set of package flags (see HEADER_FLAGS)
78
+ # :package:: package information, has the following keys:
79
+ # :version:: package version (has :minor and :major keys)
80
+ # :aid:: the package's AID
81
+ # :name:: the package's name (may be absent)
82
+ def self.parse_header(components)
83
+ component = components[:header]
84
+ header = { :magic => component[0, 4].unpack('N').first,
85
+ :version => { :minor => component[4].ord,
86
+ :major => component[5].ord } }
87
+ header[:flags] = Set.new(HEADER_FLAGS.select { |flag, mask|
88
+ (component[6].ord & mask) == mask }.map { |flag, mask| flag })
89
+ header[:package] = { :version => { :minor => component[7].ord,
90
+ :major => component[8].ord }}
91
+ aid_length = component[9].ord
92
+ header[:package][:aid] = component[10, aid_length].unpack('C*')
93
+ if component.length > 10 + aid_length
94
+ name_length = component[10 + aid_length].ord
95
+ header[:package][:name] = component[11 + aid_length, name_length]
96
+ end
97
+ header
98
+ end
99
+
71
100
  # Loads a CAP file and serializes its components for on-card loading.
72
101
  #
73
- # Returns an array of bytes.
102
+ # Returns a hash with the following keys:
103
+ # :data:: array of bytes containing the executable load file for the CAP
104
+ # :applets:: array of hashes, one for each applet in the CAP
105
+ # (see parse_applets)
106
+ # :header:: information about the CAP's header (see parse_header)
74
107
  def self.cap_load_data(cap_file)
75
108
  components = load_cap cap_file
76
109
  { :data => serialize_components(components),
77
- :applets => parse_applets(components) }
110
+ :applets => parse_applets(components),
111
+ :header => parse_header(components) }
78
112
  end
79
113
 
80
114
  # Maps numeric tags to tag names.
@@ -83,6 +117,8 @@ module CapLoader
83
117
  5 => :constant_pool, 6 => :class, 7 => :method, 8 => :static_field,
84
118
  9 => :reference_location, 10 => :export, 11 => :descriptor, 12 => :debug
85
119
  }
120
+ # Masks for flags in the Header section.
121
+ HEADER_FLAGS = [[:int_support, 1], [:has_exports, 2], [:has_applets, 4]]
86
122
  end # module Smartcard::Gp::CapLoader
87
123
 
88
- end # namespace
124
+ end # namespace
@@ -363,13 +363,16 @@ module GpCardMixin
363
363
  #
364
364
  # Args:
365
365
  # cap_file:: path to the applet's CAP file
366
- # package_aid:: the applet's package AID
366
+ # package_aid:: the applet's package AID; if nil, the AID in the CAP's
367
+ # header is used (should work all the time)
367
368
  # applet_aid:: the AID used to select the applet; if nil, the first AID
368
369
  # in the CAP's Applet section is used (this works pretty well)
369
370
  # install_data:: data to be passed to the applet at installation time
370
- def install_applet(cap_file, package_aid, applet_aid = nil, install_data = [])
371
+ def install_applet(cap_file, applet_aid = nil, package_aid = nil,
372
+ install_data = [])
371
373
  load_data = CapLoader.cap_load_data(cap_file)
372
374
  applet_aid ||= load_data[:applets].first[:aid]
375
+ package_aid ||= load_data[:header][:package][:aid]
373
376
 
374
377
  delete_application applet_aid
375
378
 
data/smartcard.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{smartcard}
5
- s.version = "0.4.5"
5
+ s.version = "0.4.6"
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"]
@@ -20,5 +20,10 @@ class CapLoaderTest < Test::Unit::TestCase
20
20
  load_data[:data].map { |ch| "%02x" % ch }.join(' ')
21
21
  assert_equal [{:aid => [0x19, 0x83, 0x12, 0x29, 0x10, 0xDE, 0xAD],
22
22
  :install_method => 8}], load_data[:applets]
23
+ golden_header = { :version => { :major => 2, :minor => 1 },
24
+ :magic => 0xDECAFFED, :flags => Set.new([:has_applets]),
25
+ :package => { :aid => [0x19, 0x83, 0x12, 0x29, 0x10, 0xDE, 0xAE],
26
+ :version => { :major => 1, :minor => 0 } } }
27
+ assert_equal golden_header, load_data[:header]
23
28
  end
24
29
  end
@@ -209,8 +209,7 @@ class GpCardMixinTest < Test::Unit::TestCase
209
209
  # Install applet.
210
210
  applet_aid = [0x19, 0x83, 0x12, 0x29, 0x10, 0xDE, 0xAD]
211
211
  cap_file = File.join File.dirname(__FILE__), 'hello.cap'
212
- transport.install_applet cap_file,
213
- [0x19, 0x83, 0x12, 0x29, 0x10, 0xDE, 0xAE]
212
+ transport.install_applet cap_file
214
213
 
215
214
  # Ensure applet works.
216
215
  transport.select_application applet_aid
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.5
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Costan