tem_ruby 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,45 @@
1
+ # raised when executing a SEC
2
+ class Tem::SecExecError < StandardError
3
+ attr_reader :buffer_state, :key_state
4
+ attr_reader :trace
5
+
6
+ def initialize(backtrace, tem_trace, buffer_state, key_state)
7
+ super 'SEC execution failed on the TEM'
8
+ set_backtrace backtrace
9
+ @trace = tem_trace
10
+ @buffer_state = buffer_state
11
+ @key_state = key_state
12
+ end
13
+
14
+ def bstat_str
15
+ if @buffer_state.nil?
16
+ "no buffer state available"
17
+ else
18
+ @buffer_state.inspect
19
+ end
20
+ end
21
+
22
+ def kstat_str
23
+ if @key_state.nil?
24
+ "no key state available"
25
+ else
26
+ @key_state.inspect
27
+ end
28
+ end
29
+
30
+ def trace_str
31
+ if @trace.nil?
32
+ "no trace available"
33
+ else
34
+ "ip=#{'%04x' % @trace[:ip]} sp=#{'%04x' % @trace[:sp]} out=#{'%04x' % @trace[:out]} pscell=#{'%04x' % @trace[:pscell]}"
35
+ end
36
+ end
37
+
38
+ def to_s
39
+ "SECpack execution generated an exception on the TEM\nTEM Trace: " + trace_str + "\nTEM Buffer Status:\n" + bstat_str + "\nTEM Key Status:\n" + kstat_str
40
+ end
41
+
42
+ def inspect
43
+ trace_str + "\n" + bstat_str + "\n" + kstat_str
44
+ end
45
+ end
@@ -0,0 +1,154 @@
1
+ class Tem::SecAssembler
2
+ # 2 ST -> 1 ST
3
+ opcode :add, 0x10
4
+ # 2 ST -> 1 ST
5
+ opcode :sub, 0x11
6
+ # 2 ST -> 1 ST
7
+ opcode :mul, 0x12
8
+ # 2 ST -> 1 ST
9
+ opcode :div, 0x13
10
+ # 2 ST -> 1 ST
11
+ opcode :mod, 0x14
12
+ # 2 ST -> 1 ST
13
+ opcode :rnd, 0x1E
14
+
15
+
16
+ # 2 ST -> 1 ST
17
+ opcode :stbv, 0x3A
18
+ # 2 ST -> 1 ST
19
+ opcode :stwv, 0x3B
20
+
21
+ # 2 ST -> 1 ST
22
+ opcode :stk, 0x5B
23
+
24
+
25
+ # 1 ST, 1 IM -> 1 ST
26
+ opcode :stb , 0x38, {:name => :to, :type => :ushort}
27
+ # 1 ST, 1 IM -> 1 ST
28
+ opcode :stw , 0x39, {:name => :to, :type => :ushort}
29
+
30
+
31
+ # 2 IM -> 1 ST
32
+ opcode(:psupfxb, 0x48, {:name => :key, :type => :ushort}, {:name => :from, :type => :ushort})
33
+ # 2 ST -> 1 ST
34
+ opcode :psupvb, 0x49
35
+ # 2 IM -> 1 ST
36
+ opcode(:pswrfxb, 0x4A, {:name => :key, :type => :ushort}, {:name => :from, :type => :ushort})
37
+ # 2 ST -> 1 ST
38
+ opcode :pswrvb, 0x4B
39
+ # 2 IM -> 1 ST
40
+ opcode(:psrdfxb, 0x4C, {:name => :key, :type => :ushort}, {:name => :to, :type => :ushort})
41
+ # 2 ST -> 1 ST
42
+ opcode :psrdvb, 0x4D
43
+ # 2 IM -> 1 ST
44
+ opcode :pshkfxb, 0x4E, {:name => :key, :type => :ushort}
45
+ # 2 ST -> 1 ST
46
+ opcode :pshkvb, 0x4F
47
+
48
+
49
+ # 3 IM -> 1 ST
50
+ opcode(:mdfxb, 0x18, {:name => :size, :type => :ushort}, {:name => :from, :type => :ushort}, {:name => :to, :type => :ushort})
51
+ # 3 ST -> 1 ST
52
+ opcode :mdvb, 0x19
53
+ # 3 IM -> 1 ST
54
+ opcode(:mcmpfxb,0x1A, {:name => :size, :type => :ushort}, {:name => :op1, :type => :ushort}, {:name => :op2, :type => :ushort})
55
+ # 3 ST -> 1 ST
56
+ opcode :mcmpvb, 0x1B
57
+ # 3 IM -> 1 ST
58
+ opcode(:mcfxb, 0x1C, {:name => :size, :type => :ushort}, {:name => :from, :type => :ushort}, {:name => :to, :type => :ushort})
59
+ # 3 ST -> 1 ST
60
+ opcode :mcvb, 0x1D
61
+
62
+ # 1 ST, 3 IM -> 1 ST
63
+ opcode(:kefxb, 0x50, {:name => :size, :type => :ushort}, {:name => :from, :type => :ushort}, {:name => :to, :type => :ushort})
64
+ # 4 ST -> 1 ST
65
+ opcode :kevb, 0x51
66
+ # 1 ST, 3 IM -> 1 ST
67
+ opcode(:kdfxb, 0x52, {:name => :size, :type => :ushort}, {:name => :from, :type => :ushort}, {:name => :to, :type => :ushort})
68
+ # 4 ST -> 1 ST
69
+ opcode :kdvb, 0x53
70
+ # 1 ST, 3 IM -> 1 ST
71
+ opcode(:ksfxb, 0x54, {:name => :size, :type => :ushort}, {:name => :from, :type => :ushort}, {:name => :to, :type => :ushort})
72
+ # 4 ST -> 1 ST
73
+ opcode :ksvb, 0x55
74
+ # 1 ST, 3 IM -> 1 ST
75
+ opcode(:kvsfxb, 0x56, {:name => :size, :type => :ushort}, {:name => :from, :type => :ushort}, {:name => :signature, :type => :ushort})
76
+ # 4 ST -> 1 ST
77
+ opcode :kvsvb, 0x57
78
+
79
+
80
+ # 0 ST -> 0 ST; IP
81
+ opcode :jmp, 0x27, {:name => :to, :type => :ushort, :reladdr => 2}
82
+ # 1 ST -> 0 ST; IP
83
+ opcode :jz, 0x21, {:name => :to, :type => :ushort, :reladdr => 2}
84
+ opcode :je, 0x21, {:name => :to, :type => :ushort, :reladdr => 2}
85
+ # 1 ST -> 0 ST; IP
86
+ opcode :jnz, 0x26, {:name => :to, :type => :ushort, :reladdr => 2}
87
+ opcode :jne, 0x26, {:name => :to, :type => :ushort, :reladdr => 2}
88
+ # 1 ST -> 0 ST; IP
89
+ opcode :ja, 0x22, {:name => :to, :type => :ushort, :reladdr => 2}
90
+ opcode :jg, 0x22, {:name => :to, :type => :ushort, :reladdr => 2}
91
+ # 1 ST -> 0 ST; IP
92
+ opcode :jae, 0x23, {:name => :to, :type => :ushort, :reladdr => 2}
93
+ opcode :jge, 0x23, {:name => :to, :type => :ushort, :reladdr => 2}
94
+ # 1 ST -> 0 ST; IP
95
+ opcode :jb, 0x24, {:name => :to, :type => :ushort, :reladdr => 2}
96
+ opcode :jl, 0x24, {:name => :to, :type => :ushort, :reladdr => 2}
97
+ # 1 ST -> 0 ST; IP
98
+ opcode :jbe, 0x25, {:name => :to, :type => :ushort, :reladdr => 2}
99
+ opcode :jle, 0x25, {:name => :to, :type => :ushort, :reladdr => 2}
100
+
101
+ # 1 IM_B -> 1 ST
102
+ opcode :ldbc, 0x30, {:name => :const, :type => :byte}
103
+ # 1 IM -> 1 ST
104
+ opcode :ldwc, 0x31, {:name => :const, :type => :short}
105
+ # 1 ST -> 1 ST
106
+ opcode :ldb , 0x32, {:name => :from, :type => :ushort}
107
+ # 1 ST -> 1 ST
108
+ opcode :ldw , 0x33, {:name => :from, :type => :ushort}
109
+ # 1 ST -> 1 ST
110
+ opcode :ldbv, 0x36
111
+ # 1 ST -> 1 ST
112
+ opcode :ldwv, 0x37
113
+
114
+ # 1 ST -> 0 ST
115
+ opcode :outnew, 0x42
116
+ # 1 ST -> 0 ST
117
+ opcode :outb, 0x44
118
+ # 1 ST -> 0 ST
119
+ opcode :outw, 0x45
120
+
121
+ # 1 ST -> 0 ST
122
+ opcode :pop, 0x34
123
+ # 2 ST -> 0 ST
124
+ opcode :pop2, 0x35
125
+
126
+ # 1 IM, x ST -> 2x ST
127
+ opcode :dupn, 0x3C, {:name => :n, :type => :ubyte}
128
+ # 1 IM, x ST -> x ST
129
+ opcode :flipn, 0x3D, {:name => :n, :type => :ubyte}
130
+
131
+ # 2 IM -> 0 ST
132
+ opcode(:outfxb, 0x40, {:name => :size, :type => :ushort}, {:name => :from, :type => :ushort})
133
+ # 2 ST -> 0 ST
134
+ opcode(:outvlb, 0x41, {:name => :from, :type => :ushort})
135
+
136
+
137
+ # 1 IM, 1 ST -> 0 ST
138
+ opcode :outvb, 0x43
139
+ # 0 ST -> 0 ST;;
140
+ opcode :halt, 0x46
141
+ # 1 ST -> 0 ST
142
+ opcode :psrm, 0x47
143
+
144
+ # 1 ST -> 1 ST
145
+ opcode :rdk, 0x5A
146
+ # 1 ST -> 0 ST
147
+ opcode :relk, 0x5C
148
+
149
+ opcode :ldkl, 0x5D
150
+ # 1 IM_B -> 2 ST
151
+ opcode :genkp, 0x5E, {:name => :type, :type => :ubyte }
152
+ # 1 ST, 1 IM -> 1 ST
153
+ opcode :authk, 0x5F, {:name => :auth, :type => :ushort }
154
+ end
@@ -0,0 +1,82 @@
1
+ require 'yaml'
2
+
3
+ module Tem::SeClosures
4
+ module MixedMethods
5
+ def assemble(&proc_block)
6
+ return Tem::SecAssembler.new(self).assemble(&proc_block)
7
+ end
8
+ end
9
+
10
+ include MixedMethods
11
+ def self.included(klass)
12
+ klass.extend MixedMethods
13
+ end
14
+
15
+ def sec_trace
16
+ #begin
17
+ response = issue_apdu [0x00, 0x54, 0x00, 0x00, 0x00].flatten
18
+ trace = reply_data(response)
19
+ if trace.length > 2
20
+ case read_tem_short(trace, 0) # trace version
21
+ when 1
22
+ return {:sp => read_tem_short(trace, 2), :ip => read_tem_short(trace, 4),
23
+ :out => read_tem_short(trace, 6), :pscell => read_tem_short(trace, 8)}
24
+ end
25
+ end
26
+ return nil # unreadable trace
27
+ #rescue
28
+ # return nil
29
+ #end
30
+ end
31
+
32
+ def solve_psfault
33
+ # TODO: better strategy, lol
34
+ next_cell = rand(16)
35
+ response = issue_apdu [0x00, 0x53, to_tem_ushort(next_cell), 0x00].flatten
36
+ tem_error(response) if failure_code(response)
37
+ end
38
+
39
+ def execute(compiled_proc, key_id = 0)
40
+ # load SECpack
41
+ buffer_id = post_buffer(compiled_proc.tem_formatted_body)
42
+ response = issue_apdu [0x00, 0x50, to_tem_byte(buffer_id), to_tem_byte(key_id), 0x00].flatten
43
+ release_buffer(buffer_id)
44
+ tem_error(response) if failure_code(response)
45
+ tem_secpack_error(response) if read_tem_byte(response, 0) != 1
46
+
47
+ # execute SEC
48
+ sec_exception = nil
49
+ loop do
50
+ response = issue_apdu [0x00, 0x52, 0x00, 0x00, 0x00].flatten
51
+ tem_error(response) if failure_code(response)
52
+ sec_status = read_tem_byte(response, 0)
53
+ case sec_status
54
+ when 2 # success
55
+ break
56
+ when 3 # exception
57
+ # there is an exception, try to collect the trace
58
+ b_stat = stat_buffers() rescue nil
59
+ k_stat = stat_keys() rescue nil
60
+ trace = sec_trace()
61
+ backtrace = (trace && trace[:ip]) ? compiled_proc.stack_for_ip(trace[:ip]) : Kernel.caller
62
+ sec_exception = Tem::SecExecError.new backtrace, trace, b_stat, k_stat
63
+ break
64
+ when 4 # persistent store fault
65
+ solve_psfault
66
+ else
67
+ raise "Unrecognized execution engine status #{sec_status}"
68
+ end
69
+ end
70
+
71
+ # TODO: handle response to figure out if we need to do page faults or something
72
+
73
+ # unbind SEC
74
+ response = issue_apdu [0x00, 0x51, 0x00, 0x00, 0x00].flatten
75
+ raise sec_exception if sec_exception
76
+ buffer_id, buffer_length = read_tem_byte(response, 0), read_tem_short(response, 1)
77
+ data_buffer = read_buffer buffer_id
78
+ release_buffer buffer_id
79
+
80
+ return data_buffer[0...buffer_length]
81
+ end
82
+ end
@@ -0,0 +1,86 @@
1
+ require 'yaml'
2
+
3
+ class Tem::SecPack
4
+ @@serialized_members = [:body, :labels, :ep, :sp, :extra_bytes, :signed_bytes, :encrypted_bytes, :sealed, :lines]
5
+
6
+ def self.new_from_array(array)
7
+ arg_hash = { :tem_class => Tem::Session }
8
+ @@serialized_members.each_index { |i| arg_hash[@@serialized_members[i]] = array[i] }
9
+ self.new(arg_hash)
10
+ end
11
+
12
+ def self.new_from_yaml_str(yaml_str)
13
+ array = YAML.load yaml_str
14
+ new_from_array array
15
+ end
16
+
17
+ def to_array
18
+ @@serialized_members.map { |m| self.instance_variable_get('@' + m.to_s) }
19
+ end
20
+
21
+ def to_yaml_str
22
+ self.to_array.to_yaml.to_s
23
+ end
24
+
25
+ attr_reader :body, :sealed
26
+ attr_reader :lines
27
+
28
+ def initialize(args)
29
+ @tem_klass = args[:tem_class]
30
+ @@serialized_members.map { |m| self.instance_variable_set('@' + m.to_s, args[m]) }
31
+ @sealed ||= false
32
+ end
33
+
34
+ def label_address(label_name)
35
+ @labels[label_name.to_sym]
36
+ end
37
+
38
+ def tem_header
39
+ # TODO: use 0x0100 (no tracing) depending on options
40
+ hh = [0x0101, @signed_bytes, @encrypted_bytes, @extra_bytes, @sp, @ep].map { |n| @tem_klass.to_tem_ushort n }.flatten
41
+ hh += Array.new((@tem_klass.hash_for_tem [0]).length - hh.length, 0)
42
+ return hh
43
+ end
44
+
45
+ def seal(public_key, encrypt_from = 0, plaintext_from = 0)
46
+ encrypt_from = @labels[encrypt_from.to_sym] unless encrypt_from.instance_of? Numeric
47
+ plaintext_from = @labels[plaintext_from.to_sym] unless plaintext_from.instance_of? Numeric
48
+
49
+ @signed_bytes = encrypt_from
50
+ @encrypted_bytes = plaintext_from - encrypt_from
51
+
52
+ proc_sig = @tem_klass.hash_for_tem [tem_header, @body[0...plaintext_from]].flatten
53
+ crypt = public_key.encrypt [@body[encrypt_from...plaintext_from], proc_sig].flatten
54
+ @body = [@body[0...encrypt_from], crypt, @body[plaintext_from..-1]].flatten
55
+
56
+ label_delta = crypt.length - @encrypted_bytes
57
+ @labels = Hash[*(@labels.map { |k, v|
58
+ if v < encrypt_from
59
+ [k, v]
60
+ elsif v < plaintext_from
61
+ []
62
+ else
63
+ [k, v + label_delta]
64
+ end
65
+ }.flatten)]
66
+
67
+ @sealed = true
68
+ end
69
+
70
+ def tem_formatted_body()
71
+ return [tem_header, @body].flatten
72
+ end
73
+
74
+ def stack_for_ip(ip)
75
+ return nil unless @lines
76
+
77
+ max_value = -1
78
+ st = nil
79
+ @lines.each do |st_ip, stack|
80
+ # if something breaks, it's likely to happen after the opcode
81
+ # of the offending instruction has been read, so assume offending_ip < ip
82
+ max_value, st = st_ip, stack if st_ip < ip && max_value < st_ip
83
+ end
84
+ return st
85
+ end
86
+ end
data/lib/tem/tag.rb ADDED
@@ -0,0 +1,28 @@
1
+ module Tem::Tag
2
+ def set_tag(tag_data)
3
+ buffer_id = post_buffer(tag_data)
4
+ response = issue_apdu [0x00, 0x30, to_tem_byte(buffer_id), 0x00, 0x00].flatten
5
+ tem_error(response) if failure_code(response)
6
+ release_buffer(buffer_id)
7
+ end
8
+
9
+ def get_tag_length
10
+ response = issue_apdu [0x00, 0x31, 0x00, 0x00, 0x00].flatten
11
+ tem_error(response) if failure_code(response)
12
+ return read_tem_short(response, 0)
13
+ end
14
+
15
+ def get_tag_data(offset, length)
16
+ buffer_id = alloc_buffer(length)
17
+ response = issue_apdu [0x00, 0x32, to_tem_byte(buffer_id), 0x00, 0x04, to_tem_short(offset), to_tem_short(length)].flatten
18
+ tem_error(response) if failure_code(response)
19
+ tag_data = read_buffer(buffer_id)
20
+ release_buffer(buffer_id)
21
+ return tag_data
22
+ end
23
+
24
+ def get_tag
25
+ tag_length = self.get_tag_length
26
+ get_tag_data(0, tag_length)
27
+ end
28
+ end
data/lib/tem/tem.rb ADDED
@@ -0,0 +1,47 @@
1
+ require 'pp'
2
+
3
+ class Tem::Session
4
+ include Tem::Abi
5
+ include Tem::Buffers
6
+ include Tem::CA
7
+ include Tem::CryptoAbi
8
+ include Tem::ECert
9
+ include Tem::Keys
10
+ include Tem::Lifecycle
11
+ include Tem::SeClosures
12
+ include Tem::Tag
13
+ include Tem::Toolkit
14
+
15
+ @@aid = [0x19, 0x83, 0x12, 0x29, 0x10, 0xBA, 0xBE]
16
+
17
+ def initialize(javacard)
18
+ @card = javacard
19
+ @card.select_applet(@@aid)
20
+ end
21
+
22
+ def disconnect
23
+ # TODO: deselect applet, reset card
24
+ @card = nil
25
+ end
26
+
27
+ def issue_apdu(apdu)
28
+ @card.issue_apdu apdu
29
+ end
30
+
31
+ def failure_code(reply_apdu)
32
+ @card.failure_code reply_apdu
33
+ end
34
+
35
+ def reply_data(reply_apdu)
36
+ @card.reply_data reply_apdu
37
+ end
38
+
39
+ def tem_error(response)
40
+ fcode = failure_code response
41
+ raise "TEM returned error 0x#{'%04x' % fcode} while processing the request"
42
+ end
43
+
44
+ def tem_secpack_error(response)
45
+ raise "TEM refused the SECpack"
46
+ end
47
+ end
@@ -0,0 +1,104 @@
1
+ module Tem::Toolkit
2
+ def tk_firmware_ver
3
+ tag = get_tag
4
+ return { :major => read_tem_ubyte(tag, 0), :minor => read_tem_ubyte(tag, 1) }
5
+ end
6
+
7
+ def tk_gen_key(type = :asymmetric, authz = nil)
8
+ gen_sec = assemble do |s|
9
+ s.ldbc authz.nil? ? 24 : 4
10
+ s.outnew
11
+ if authz.nil?
12
+ # no authorization given, must generate one
13
+ s.ldbc 20
14
+ s.ldwc :key_auth
15
+ s.dupn :n => 2
16
+ s.rnd
17
+ s.outvb
18
+ end
19
+ s.genkp :type => (type == :asymmetric) ? 0x00 : 0x80
20
+ s.authk :auth => :key_auth
21
+ s.outw
22
+ s.authk :auth => :key_auth
23
+ s.outw
24
+ s.halt
25
+ s.label :key_auth
26
+ if authz.nil?
27
+ s.filler :ubyte, 20
28
+ else
29
+ s.immed :ubyte, authz
30
+ end
31
+ s.stack
32
+ s.extra 8
33
+ end
34
+
35
+ kp_buffer = execute gen_sec
36
+ keys_offset = authz.nil? ? 20 : 0
37
+ k1id, k2id = read_tem_ushort(kp_buffer, keys_offset), read_tem_ushort(kp_buffer, keys_offset + 2)
38
+ if type == :asymmetric
39
+ return_val = { :pubk_id => k1id, :privk_id => k2id }
40
+ else
41
+ return_val = { :key_id => k1id }
42
+ end
43
+ return { :authz => authz.nil? ? kp_buffer[0...20] : authz }.merge!(return_val)
44
+ end
45
+
46
+ def tk_read_key(key_id, authz)
47
+ read_sec = assemble do |s|
48
+ s.ldbc :const => key_id
49
+ s.authk :auth => :key_auth
50
+ s.ldkl
51
+ s.outnew
52
+ s.ldbc :const => key_id
53
+ s.ldbc(-1)
54
+ s.stk
55
+ s.halt
56
+ s.label :key_auth
57
+ s.immed :ubyte, authz
58
+ s.stack
59
+ s.extra 8
60
+ end
61
+
62
+ key_string = execute read_sec
63
+ return read_tem_key(key_string, 0)
64
+ end
65
+
66
+ def tk_delete_key(key_id, authz)
67
+ del_sec = assemble do |s|
68
+ s.ldbc :const => key_id
69
+ s.authk :auth => :key_auth
70
+ s.relk
71
+ s.ldbc :const => 1
72
+ s.outnew
73
+ s.ldbc :const => key_id
74
+ s.outb
75
+ s.halt
76
+ s.label :key_auth
77
+ s.immed :ubyte, authz
78
+ s.stack
79
+ s.extra 8
80
+ end
81
+
82
+ execute del_sec
83
+ end
84
+
85
+ def tk_post_key(key, authz)
86
+ post_sec = assemble do |s|
87
+ s.ldbc :const => 1
88
+ s.outnew
89
+ s.ldwc :const => :key_data
90
+ s.rdk
91
+ s.authk :auth => :key_auth
92
+ s.outb
93
+ s.halt
94
+ s.label :key_data
95
+ s.immed :ubyte, key.to_tem_key
96
+ s.label :key_auth
97
+ s.immed :ubyte, authz
98
+ s.stack
99
+ s.extra 8
100
+ end
101
+ id_string = execute post_sec
102
+ return read_tem_ubyte(id_string, 0)
103
+ end
104
+ end
data/lib/tem_ruby.rb ADDED
@@ -0,0 +1,29 @@
1
+ # gems
2
+ require 'smartcard'
3
+
4
+ module Tem
5
+ end
6
+
7
+ module Tem::SCard
8
+ end
9
+
10
+ require 'scard/pcsc_terminal.rb'
11
+ require 'scard/jcop_remote_terminal.rb'
12
+ require 'scard/java_card.rb'
13
+
14
+ require 'tem/abi.rb'
15
+ require 'tem/buffers.rb'
16
+ require 'tem/ca.rb'
17
+ require 'tem/crypto_abi.rb'
18
+ require 'tem/ecert.rb'
19
+ require 'tem/hive.rb'
20
+ require 'tem/keys.rb'
21
+ require 'tem/lifecycle.rb'
22
+ require 'tem/sec_assembler.rb'
23
+ require 'tem/sec_opcodes.rb'
24
+ require 'tem/sec_exec_error.rb'
25
+ require 'tem/seclosures.rb'
26
+ require 'tem/secpack.rb'
27
+ require 'tem/tag.rb'
28
+ require 'tem/toolkit.rb'
29
+ require 'tem/tem.rb'
data/tem_ruby.gemspec ADDED
@@ -0,0 +1,53 @@
1
+
2
+ # Gem::Specification for Tem_ruby-0.9.0
3
+ # Originally generated by Echoe
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{tem_ruby}
7
+ s.version = "0.9.0"
8
+
9
+ s.specification_version = 2 if s.respond_to? :specification_version=
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.authors = ["Victor Costan"]
13
+ s.date = %q{2008-06-11}
14
+ s.description = %q{TEM (Trusted Execution Module) driver, written in and for ruby.}
15
+ s.email = %q{victor@costan.us}
16
+ s.executables = ["tem_stat", "tem_ca", "tem_irb", "tem_bench"]
17
+ s.extra_rdoc_files = ["bin/tem_stat", "bin/tem_ca", "bin/tem_irb", "bin/tem_bench", "LICENSE", "lib/scard/java_card.rb", "lib/scard/jcop_remote_terminal.rb", "lib/scard/pcsc_terminal.rb", "lib/tem_ruby.rb", "lib/tem/tag.rb", "lib/tem/keys.rb", "lib/tem/sec_opcodes.rb", "lib/tem/_cert.rb", "lib/tem/buffers.rb", "lib/tem/toolkit.rb", "lib/tem/tem.rb", "lib/tem/abi.rb", "lib/tem/crypto_abi.rb", "lib/tem/ca.rb", "lib/tem/secpack.rb", "lib/tem/sec_exec_error.rb", "lib/tem/sec_assembler.rb", "lib/tem/lifecycle.rb", "lib/tem/ecert.rb", "lib/tem/hive.rb", "lib/tem/seclosures.rb", "README", "CHANGELOG"]
18
+ s.has_rdoc = true
19
+ s.homepage = %q{http://tem.rubyforge.org}
20
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Tem_ruby", "--main", "README"]
21
+ s.require_paths = ["lib"]
22
+ s.rubyforge_project = %q{tem}
23
+ s.rubygems_version = %q{1.1.1}
24
+ s.summary = %q{TEM (Trusted Execution Module) driver, written in and for ruby.}
25
+ s.test_files = ["test/test_driver.rb", "test/test_tem.rb", "test/test_exceptions.rb"]
26
+
27
+ s.add_dependency(%q<smartcard>, [">= 0.2.2"])
28
+ end
29
+
30
+
31
+ # # Original Rakefile source (requires the Echoe gem):
32
+ #
33
+ # require 'rubygems'
34
+ # gem 'echoe'
35
+ # require 'echoe'
36
+ #
37
+ # Echoe.new('tem_ruby') do |p|
38
+ # p.project = 'tem' # rubyforge project
39
+ #
40
+ # p.author = 'Victor Costan'
41
+ # p.email = 'victor@costan.us'
42
+ # p.summary = 'TEM (Trusted Execution Module) driver, written in and for ruby.'
43
+ # p.url = 'http://tem.rubyforge.org'
44
+ # p.dependencies = ['smartcard >=0.2.2']
45
+ #
46
+ # p.need_tar_gz = false
47
+ # p.rdoc_pattern = /^(lib|bin|tasks|ext)|^BUILD|^README|^CHANGELOG|^TODO|^LICENSE|^COPYING$/
48
+ # end
49
+ #
50
+ # if $0 == __FILE__
51
+ # Rake.application = Rake::Application.new
52
+ # Rake.application.run
53
+ # end