tem_ruby 0.9.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,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