pkcs11 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/pkcs11.rb ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Load the correct version if it's a Windows binary gem
4
+ if RUBY_PLATFORM =~/(mswin|mingw)/i
5
+ major_minor = RUBY_VERSION[ /^(\d+\.\d+)/ ] or
6
+ raise "Oops, can't extract the major/minor version from #{RUBY_VERSION.dump}"
7
+ require "#{major_minor}/pkcs11_ext"
8
+ else
9
+ require 'pkcs11_ext'
10
+ end
11
+
12
+ require 'pkcs11/extensions'
@@ -0,0 +1,160 @@
1
+ require 'pkcs11/library'
2
+ require 'pkcs11/slot'
3
+ require 'pkcs11/session'
4
+ require 'pkcs11/object'
5
+
6
+ # Ruby connector to PKCS#11 libraries.
7
+ #
8
+ # This library allowes to use PKCS#11 librarys in Ruby MRI.
9
+ #
10
+ # Example usage:
11
+ #
12
+ # pkcs11 = PKCS11.open("/path/to/pkcs11.so")
13
+ # slot = pkcs11.active_slots.first
14
+ # p slot.info
15
+ # session = slot.open(PKCS11::CKF_SERIAL_SESSION|PKCS11::CKF_RW_SESSION)
16
+ # session.login(:USER, "1234")
17
+ # ...
18
+ # session.logout
19
+ # session.close
20
+ #
21
+ # See unit tests in the <tt>test</tt> directory for further examples of the usage.
22
+ module PKCS11
23
+
24
+ class << self
25
+ # Open a PKCS#11 library file.
26
+ alias new open
27
+ end
28
+
29
+ module InspectableStruct
30
+ # Array of the InspectableStruct's attribute names.
31
+ def members
32
+ (self.methods - ::Object.new.methods - InspectableStruct.instance_methods).grep(/[^=]$/).sort
33
+ end
34
+ # Array of the InspectableStruct's attribute values.
35
+ def values
36
+ members.inject([]){|a,v| a << send(v) }
37
+ end
38
+ # Hash with the InspectableStruct's attribute names and values.
39
+ def to_hash
40
+ members.inject({}){|h,v| h[v.intern] = send(v); h }
41
+ end
42
+ def inspect # :nodoc:
43
+ "#<#{self.class} #{to_hash.map{|k,v| "#{k}=#{v.inspect}"}.join(", ") }>"
44
+ end
45
+ end
46
+
47
+ module InspectableAttribute
48
+ # Array of the InspectableStruct's attribute names.
49
+ def members
50
+ ['type', 'value']
51
+ end
52
+ # Array of the InspectableStruct's attribute values.
53
+ def values
54
+ members.inject([]){|a,v| a << send(v) }
55
+ end
56
+ # Hash with the InspectableStruct's attribute names and values.
57
+ def to_hash
58
+ members.inject({}){|h,v| h[v.intern] = send(v); h }
59
+ end
60
+ # Get the constant name as String of the given value.
61
+ # Returns <tt>nil</tt> if value is unknown.
62
+ def to_s
63
+ ATTRIBUTES[type]
64
+ end
65
+ def inspect # :nodoc:
66
+ "#<#{self.class} #{ to_s ? "#{to_s} (#{type})" : type} value=#{value.inspect}>"
67
+ end
68
+ end
69
+
70
+ # See InspectableStruct.
71
+ class CK_INFO
72
+ include InspectableStruct
73
+ end
74
+ # See InspectableStruct.
75
+ class CK_C_INITIALIZE_ARGS
76
+ include InspectableStruct
77
+ end
78
+ # See InspectableStruct.
79
+ class CK_ATTRIBUTE
80
+ include InspectableAttribute
81
+ end
82
+ # See InspectableStruct.
83
+ class CK_TOKEN_INFO
84
+ include InspectableStruct
85
+ end
86
+ # See InspectableStruct.
87
+ class CK_SLOT_INFO
88
+ include InspectableStruct
89
+ end
90
+ # See InspectableStruct.
91
+ class CK_MECHANISM_INFO
92
+ include InspectableStruct
93
+ end
94
+ # See InspectableStruct.
95
+ class CK_SESSION_INFO
96
+ include InspectableStruct
97
+ end
98
+ # See InspectableStruct.
99
+ class CK_MECHANISM
100
+ include InspectableStruct
101
+ end
102
+
103
+ class ConstValue
104
+ def initialize(enum_hash, value) # :nodoc:
105
+ @enum_hash, @value = enum_hash, value
106
+ end
107
+
108
+ # Get the constant name as String of the given value.
109
+ # Returns <tt>nil</tt> if value is unknown.
110
+ def to_s
111
+ @enum_hash[@value]
112
+ end
113
+ def inspect
114
+ # "#<#{self.class} #{ to_s ? "#{to_s} (#{@value})" : @value}>"
115
+ @value.inspect
116
+ end
117
+
118
+ # The value of the constant.
119
+ def to_int
120
+ @value
121
+ end
122
+ alias to_i to_int
123
+ end
124
+
125
+ module ConstValueHash # :nodoc:
126
+ def [](value)
127
+ super(value.to_int)
128
+ end
129
+ end
130
+
131
+ class << self
132
+ def extend_ConstValueHash(hash_symb) # :nodoc:
133
+ # The MECHANISMS, ATTRIBUTES, etc. Hashs are freezed.
134
+ # So, we have make a copy, to extend the class.
135
+ my_HASH = const_get(hash_symb).dup
136
+ my_HASH.extend ConstValueHash
137
+ my_HASH.freeze
138
+ const_set("UNWRAPPED_#{hash_symb}", hash_symb)
139
+ remove_const(hash_symb)
140
+ const_set(hash_symb, my_HASH)
141
+ end
142
+ private :extend_ConstValueHash
143
+ end
144
+
145
+ extend_ConstValueHash(:OBJECT_CLASSES)
146
+ class ObjectClass < ConstValue
147
+ end
148
+
149
+ extend_ConstValueHash(:ATTRIBUTES)
150
+ class Attribute < ConstValue
151
+ end
152
+
153
+ extend_ConstValueHash(:MECHANISMS)
154
+ class Mechanism < ConstValue
155
+ end
156
+
157
+ # extend_ConstValueHash(:RETURN_VALUES)
158
+ # class ReturnValue < ConstValue
159
+ # end
160
+ end
@@ -0,0 +1,63 @@
1
+ module PKCS11
2
+ # A Library instance holds a handle to the opened PKCS#11 - dll or so file.
3
+ class Library
4
+ alias unwrapped_initialize initialize # :nodoc:
5
+
6
+ # Load and initialize a pkcs11 dynamic library.
7
+ #
8
+ # so_path:: Path to the *.so or *.dll file to load.
9
+ # args:: A Hash or CK_C_INITIALIZE_ARGS instance with load params.
10
+ def initialize(so_path, args={})
11
+ case args
12
+ when Hash
13
+ pargs = CK_C_INITIALIZE_ARGS.new
14
+ args.each{|k,v| pargs.send("#{k}=", v) }
15
+ else
16
+ pargs = args
17
+ end
18
+ unwrapped_initialize(so_path, pargs)
19
+ end
20
+
21
+ alias unwrapped_C_GetInfo C_GetInfo
22
+ # Returns general information about Cryptoki.
23
+ def C_GetInfo
24
+ unwrapped_C_GetInfo
25
+ end
26
+ alias info C_GetInfo
27
+
28
+ alias unwrapped_C_GetSlotList C_GetSlotList
29
+
30
+ # Obtain an array of Slot objects in the system. tokenPresent indicates
31
+ # whether the list obtained includes only those slots with a token present (true), or
32
+ # all slots (false);
33
+ def C_GetSlotList(tokenPresent=true)
34
+ slots = unwrapped_C_GetSlotList(tokenPresent)
35
+ slots.map{|slot|
36
+ Slot.new self, slot
37
+ }
38
+ end
39
+ alias slots C_GetSlotList
40
+
41
+ # Obtain an array of Slot objects in the system with a token present.
42
+ def active_slots
43
+ slots(true)
44
+ end
45
+
46
+ # Obtain an array of Slot objects in the system regardless if a token is present.
47
+ def all_slots
48
+ slots(false)
49
+ end
50
+
51
+ alias unwrapped_C_Finalize C_Finalize
52
+ # Close and unload library. If not called, the library is freed by the GC.
53
+ def C_Finalize
54
+ unwrapped_C_Finalize
55
+ end
56
+ alias close C_Finalize
57
+
58
+ private :unwrapped_initialize
59
+ private :unwrapped_C_GetSlotList
60
+ private :unwrapped_C_Finalize
61
+ private :unwrapped_C_GetInfo
62
+ end
63
+ end
@@ -0,0 +1,104 @@
1
+ module PKCS11
2
+ # Cryptoki’s logical view of a token is a device that stores objects and can perform
3
+ # cryptographic functions. Cryptoki defines three classes of object: data, certificates, and
4
+ # keys.
5
+ #
6
+ # Attributes are characteristics that distinguish an instance of an object.
7
+ class Object
8
+ def initialize(pkcs11, session, object) # :nodoc:
9
+ @pk, @sess, @obj = pkcs11, session, object
10
+ end
11
+
12
+ # The object handle.
13
+ def to_int
14
+ @obj
15
+ end
16
+ alias to_i to_int
17
+
18
+ def inspect # :nodoc:
19
+ "#<#{self.class} #{@obj.inspect}>"
20
+ end
21
+
22
+ # Returns the value of one attribute of the object.
23
+ #
24
+ # attribute:: can be String or Symbol of the attribute constant
25
+ # or the attribute number as Integer.
26
+ #
27
+ # Returns the attribute value as String, Integer or true/false
28
+ # depending on the attribute type.
29
+ # Unknown attributes (out of PKCS#11 v2.2) are not converted but returned as String.
30
+ # That is true/false will be returned as "\\001" respectively "\\000".
31
+ def [](attribute)
32
+ attrs = C_GetAttributeValue( [attribute] )
33
+ attrs.first.value unless attrs.empty?
34
+ end
35
+
36
+ # Modifies the value of one attribute the object.
37
+ #
38
+ # attribute:: can be String or Symbol of the attribute constant
39
+ # or the attribute value as Integer.
40
+ # value:: String value the attribute will be set to.
41
+ #
42
+ # Following value conversations are done:
43
+ # true -> 0x01
44
+ # false -> 0x00
45
+ # nil -> NULL pointer
46
+ # Fixnum -> binary encoded unsigned long
47
+ def []=(attribute, value)
48
+ C_SetAttributeValue( attribute => value )
49
+ end
50
+
51
+ # Modifies the value of one or more attributes of the object in a single call.
52
+ #
53
+ # Examples:
54
+ # object.attributes = {:SUBJECT => cert_subject, PKCS11::CKA_VALUE => cert_data}
55
+ def C_SetAttributeValue(template={})
56
+ template = Session.hash_to_attributes template
57
+ @pk.C_SetAttributeValue(@sess, @obj, template)
58
+ end
59
+ alias attributes= C_SetAttributeValue
60
+
61
+ # Obtains the value of one or more attributes of the object in a single call.
62
+ #
63
+ # Without params all known attributes are tried to read from the Object.
64
+ # This is significant slower then naming the needed attributes and should
65
+ # be used for debug purposes only.
66
+ #
67
+ # Returns an Array of PKCS11::CK_ATTRIBUTE's.
68
+ #
69
+ # Example:
70
+ # certificate.attributes :ID, :VALUE
71
+ def C_GetAttributeValue(*template)
72
+ case template.length
73
+ when 0
74
+ return PKCS11::ATTRIBUTES.values.map{|attr|
75
+ begin
76
+ attributes(PKCS11.const_get(attr))
77
+ rescue PKCS11::Error
78
+ end
79
+ }.flatten.compact
80
+ when 1
81
+ template = template[0]
82
+ end
83
+ template = Session.hash_to_attributes template
84
+ @pk.C_GetAttributeValue(@sess, @obj, template)
85
+ end
86
+ alias attributes C_GetAttributeValue
87
+
88
+ # Destroys the object.
89
+ #
90
+ # Only session objects can be destroyed during a read-only session. Only public objects
91
+ # can be destroyed unless the normal user is logged in.
92
+ def C_DestroyObject()
93
+ @pk.C_DestroyObject(@sess, @obj)
94
+ end
95
+ alias destroy C_DestroyObject
96
+
97
+ # Gets the size of an object in bytes.
98
+ def C_GetObjectSize()
99
+ @pk.C_GetObjectSize(@sess, @obj)
100
+ end
101
+ alias size C_GetObjectSize
102
+
103
+ end
104
+ end
@@ -0,0 +1,568 @@
1
+ module PKCS11
2
+ # Cryptoki requires that an application open one or more sessions with a token to gain
3
+ # access to the token’s objects and functions. A session provides a logical connection
4
+ # between the application and the token. A session can be a read/write (R/W) session or a
5
+ # read-only (R/O) session (default).
6
+ class Session
7
+ class << self
8
+ def hash_to_attributes(template) # :nodoc:
9
+ case template
10
+ when Array
11
+ template.map{|v| PKCS11::CK_ATTRIBUTE.new(string_to_handle('CKA_', v), nil) }
12
+ when Hash
13
+ template.map{|k,v| PKCS11::CK_ATTRIBUTE.new(string_to_handle('CKA_', k), v) }
14
+ when String, Symbol
15
+ [PKCS11::CK_ATTRIBUTE.new(string_to_handle('CKA_', template), nil)]
16
+ when Integer
17
+ [PKCS11::CK_ATTRIBUTE.new(template, nil)]
18
+ else
19
+ template
20
+ end
21
+ end
22
+
23
+ def string_to_handle(prefix, attribute) # :nodoc:
24
+ case attribute
25
+ when String, Symbol
26
+ PKCS11.const_get("#{prefix}#{attribute}")
27
+ else
28
+ attribute
29
+ end
30
+ end
31
+
32
+ def hash_to_mechanism(hash) # :nodoc:
33
+ case hash
34
+ when String, Symbol
35
+ PKCS11::CK_MECHANISM.new(string_to_handle('CKM_', hash))
36
+ when Hash
37
+ raise "only one mechanism allowed" unless hash.length==1
38
+ PKCS11::CK_MECHANISM.new(string_to_handle('CKM_', hash.keys.first), hash.values.first)
39
+ else
40
+ hash.to_int
41
+ end
42
+ end
43
+ end
44
+
45
+ def initialize(pkcs11, session) # :nodoc:
46
+ @pk, @sess = pkcs11, session
47
+ end
48
+
49
+ # The session handle.
50
+ def to_int
51
+ @sess
52
+ end
53
+ alias to_i to_int
54
+
55
+ def inspect # :nodoc:
56
+ "#<#{self.class} #{@sess.inspect}>"
57
+ end
58
+
59
+ # Logs a user into a token.
60
+ # user_type:: is the user type CKU_*;
61
+ # pin:: is the user’s PIN.
62
+ #
63
+ # When the user type is either CKU_SO or CKU_USER, if the call succeeds, each of the
64
+ # application's sessions will enter either the "R/W SO Functions" state, the "R/W User
65
+ # Functions" state, or the "R/O User Functions" state. If the user type is
66
+ # CKU_CONTEXT_SPECIFIC , the behavior of C_Login depends on the context in which
67
+ # it is called. Improper use of this user type will result in a return value
68
+ # CKR_OPERATION_NOT_INITIALIZED.
69
+ def C_Login(user_type, pin)
70
+ @pk.C_Login(@sess, Session::string_to_handle('CKU_', user_type), pin)
71
+ end
72
+ alias login C_Login
73
+
74
+ # Logs a user out from a token.
75
+ #
76
+ # Depending on the current user type, if the call succeeds, each of the application’s
77
+ # sessions will enter either the “R/W Public Session” state or the “R/O Public Session”
78
+ # state.
79
+ def C_Logout()
80
+ @pk.C_Logout(@sess)
81
+ end
82
+ alias logout C_Logout
83
+
84
+ # Closes the session between an application and a token.
85
+ def C_CloseSession()
86
+ @pk.C_CloseSession(@sess)
87
+ end
88
+ alias close C_CloseSession
89
+
90
+ # Obtains information about a session. Returns a CK_SESSION_INFO.
91
+ def C_GetSessionInfo()
92
+ @pk.C_GetSessionInfo(@sess)
93
+ end
94
+ alias info C_GetSessionInfo
95
+
96
+ # Initializes a search for token and session objects that match a
97
+ # template.
98
+ #
99
+ # find_template:: points to a search template that
100
+ # specifies the attribute values to match
101
+ # The matching criterion is an exact byte-for-byte match with all attributes in the
102
+ # template. Use empty Hash to find all objects.
103
+
104
+ def C_FindObjectsInit(find_template={})
105
+ @pk.C_FindObjectsInit(@sess, Session.hash_to_attributes(find_template))
106
+ end
107
+
108
+ # Continues a search for token and session objects that match a template,
109
+ # obtaining additional object handles.
110
+ #
111
+ # Returns an array of Object instances.
112
+ def C_FindObjects(max_count)
113
+ objs = @pk.C_FindObjects(@sess, max_count)
114
+ objs.map{|obj| Object.new @pk, @sess, obj }
115
+ end
116
+
117
+ # Terminates a search for token and session objects.
118
+ def C_FindObjectsFinal
119
+ @pk.C_FindObjectsFinal(@sess)
120
+ end
121
+
122
+ # Convenience method for the C_FindObjectsInit, C_FindObjects, C_FindObjectsFinal cycle.
123
+ #
124
+ # * If called with block, it iterates over all found objects.
125
+ # * If called without block, it returns with an array of all found Object instances.
126
+ #
127
+ # Example (prints subject of all certificates stored in the token):
128
+ # session.find_objects(:CLASS => PKCS11::CKO_CERTIFICATE) do |obj|
129
+ # p OpenSSL::X509::Name.new(obj[:SUBJECT])
130
+ # end
131
+ def find_objects(template={})
132
+ all_objs = [] unless block_given?
133
+ C_FindObjectsInit(template)
134
+ begin
135
+ loop do
136
+ objs = C_FindObjects(20)
137
+ break if objs.empty?
138
+ if block_given?
139
+ objs.each{|obj| yield obj }
140
+ else
141
+ all_objs += objs
142
+ end
143
+ end
144
+ ensure
145
+ C_FindObjectsFinal()
146
+ end
147
+ return all_objs
148
+ end
149
+
150
+
151
+ # Creates a new Object based on given template. Returns a new object’s handle.
152
+ # If C_CreateObject is used to create a key object, the key object will have its
153
+ # CKA_LOCAL attribute set to false. If that key object is a secret or private key
154
+ # then the new key will have the CKA_ALWAYS_SENSITIVE attribute set to
155
+ # false, and the CKA_NEVER_EXTRACTABLE attribute set to false.
156
+ #
157
+ # Only session objects can be created during a read-only session. Only public objects can
158
+ # be created unless the normal user is logged in.
159
+ def C_CreateObject(template={})
160
+ handle = @pk.C_CreateObject(@sess, Session.hash_to_attributes(template))
161
+ Object.new @pk, @sess, handle
162
+ end
163
+ alias create_object C_CreateObject
164
+
165
+ # Initializes the normal user’s PIN. This standard
166
+ # allows PIN values to contain any valid UTF8 character, but the token may impose subset
167
+ # restrictions.
168
+ def C_InitPIN(pin)
169
+ @pk.C_InitPIN(@sess, pin)
170
+ end
171
+ alias init_pin C_InitPIN
172
+
173
+ # Modifies the PIN of the user that is currently logged in, or the CKU_USER
174
+ # PIN if the session is not logged in.
175
+ def C_SetPIN(old_pin, new_pin)
176
+ @pk.C_SetPIN(@sess, old_pin, new_pin)
177
+ end
178
+ alias set_pin C_SetPIN
179
+
180
+ class Cipher
181
+ def initialize(update_block) # :nodoc:
182
+ @update_block = update_block
183
+ end
184
+ def update(data)
185
+ @update_block.call(data)
186
+ end
187
+ alias << update
188
+ end
189
+
190
+ class DigestCipher < Cipher
191
+ def initialize(update_block, digest_key_block) # :nodoc:
192
+ super(update_block)
193
+ @digest_key_block = digest_key_block
194
+ end
195
+ alias digest_update update
196
+ def digest_key(key)
197
+ @digest_key_block.call(key)
198
+ end
199
+ end
200
+
201
+ def common_crypt( init, update, final, single, mechanism, key, data=nil) # :nodoc:
202
+ send(init, mechanism, key)
203
+ if block_given?
204
+ raise "data not nil, but block given" if data
205
+ yield Cipher.new(proc{|data_|
206
+ send(update, data_)
207
+ })
208
+ send(final)
209
+ else
210
+ send(single, data)
211
+ end
212
+ end
213
+ private :common_crypt
214
+
215
+ def common_verify( init, update, final, single, mechanism, key, signature, data=nil ) # :nodoc:
216
+ send(init, mechanism, key)
217
+ if block_given?
218
+ raise "data not nil, but block given" if data
219
+ yield Cipher.new(proc{|data_|
220
+ send(update, data_)
221
+ })
222
+ send(final, signature)
223
+ else
224
+ send(single, data, signature)
225
+ end
226
+ end
227
+ private :common_verify
228
+
229
+ # Initializes an encryption operation.
230
+ #
231
+ # mechanism:: the encryption mechanism, Hash, String or Integer
232
+ # key:: the object handle of the encryption key.
233
+ #
234
+ # See Session#encrypt for convenience.
235
+ #
236
+ # The CKA_ENCRYPT attribute of the encryption key, which indicates whether the key
237
+ # supports encryption, must be true.
238
+ #
239
+ # After calling C_EncryptInit, the application can either call C_Encrypt to encrypt data
240
+ # in a single part; or call C_EncryptUpdate zero or more times, followed by
241
+ # C_EncryptFinal, to encrypt data in multiple parts. The encryption operation is active
242
+ # until the application uses a call to C_Encrypt or C_EncryptFinal to actually obtain the
243
+ # final piece of ciphertext. To process additional data (in single or multiple parts), the
244
+ # application must call C_EncryptInit again.
245
+ def C_EncryptInit(mechanism, key)
246
+ @pk.C_EncryptInit(@sess, Session.hash_to_mechanism(mechanism), key)
247
+ end
248
+ # Encrypts single-part data.
249
+ def C_Encrypt(data, out_size=nil)
250
+ @pk.C_Encrypt(@sess, data, out_size)
251
+ end
252
+ # Continues a multiple-part encryption operation, processing another
253
+ # data part.
254
+ def C_EncryptUpdate(data, out_size=nil)
255
+ @pk.C_EncryptUpdate(@sess, data, out_size)
256
+ end
257
+ # Finishes a multiple-part encryption operation.
258
+ def C_EncryptFinal(out_size=nil)
259
+ @pk.C_EncryptFinal(@sess, out_size)
260
+ end
261
+
262
+ # Convenience method for the C_EncryptInit, C_EncryptUpdate, C_EncryptFinal call flow.
263
+ #
264
+ # If no block is given, the single part operation C_EncryptInit, C_Encrypt is called.
265
+ # If a block is given, the multi part operation (C_EncryptInit, C_EncryptUpdate, C_EncryptFinal)
266
+ # is used. The given block is called once with a cipher object. There can be any number of
267
+ # Cipher#update calls within the block, each giving the encryption result of this part as String.
268
+ #
269
+ # Returns the final part of the encryption operation.
270
+ #
271
+ # Example:
272
+ # iv = "12345678"
273
+ # cryptogram = ''
274
+ # cryptogram << session.encrypt( {:DES_CBC_PAD=>iv}, key ) do |cipher|
275
+ # cryptogram << cipher.update("block 1")
276
+ # cryptogram << cipher.update("block 2")
277
+ # end
278
+ def encrypt(mechanism, key, data=nil, &block)
279
+ common_crypt(:C_EncryptInit, :C_EncryptUpdate, :C_EncryptFinal, :C_Encrypt,
280
+ mechanism, key, data, &block)
281
+ end
282
+
283
+ # Initializes a decryption operation.
284
+ #
285
+ # See Session#decrypt for convenience.
286
+ def C_DecryptInit(mechanism, key)
287
+ @pk.C_DecryptInit(@sess, Session.hash_to_mechanism(mechanism), key)
288
+ end
289
+ # Decrypts encrypted data in a single part.
290
+ def C_Decrypt(data, out_size=nil)
291
+ @pk.C_Decrypt(@sess, data, out_size)
292
+ end
293
+ # Continues a multiple-part decryption operation, processing another
294
+ # encrypted data part.
295
+ def C_DecryptUpdate(data, out_size=nil)
296
+ @pk.C_DecryptUpdate(@sess, data, out_size)
297
+ end
298
+ # Finishes a multiple-part decryption operation.
299
+ def C_DecryptFinal(out_size=nil)
300
+ @pk.C_DecryptFinal(@sess, out_size)
301
+ end
302
+
303
+ # Convenience method for the C_DecryptInit, C_DecryptUpdate, C_DecryptFinal call flow.
304
+ #
305
+ # See Session#encrypt
306
+ def decrypt(mechanism, key, data=nil, &block)
307
+ common_crypt(:C_DecryptInit, :C_DecryptUpdate, :C_DecryptFinal, :C_Decrypt,
308
+ mechanism, key, data, &block)
309
+ end
310
+
311
+ # Initializes a message-digesting operation.
312
+ #
313
+ # See Session#digest for convenience.
314
+ def C_DigestInit(mechanism)
315
+ @pk.C_DigestInit(@sess, Session.hash_to_mechanism(mechanism))
316
+ end
317
+ # Digests data in a single part.
318
+ def C_Digest(data, out_size=nil)
319
+ @pk.C_Digest(@sess, data, out_size)
320
+ end
321
+ # Continues a multiple-part message-digesting operation, processing
322
+ # another data part.
323
+ def C_DigestUpdate(data)
324
+ @pk.C_DigestUpdate(@sess, data)
325
+ end
326
+ # Continues a multiple-part message-digesting operation by digesting the
327
+ # value of a secret key.
328
+ #
329
+ # The message-digesting operation must have been initialized with C_DigestInit. Calls to
330
+ # this function and C_DigestUpdate may be interspersed any number of times in any
331
+ # order.
332
+ def C_DigestKey(key)
333
+ @pk.C_DigestKey(@sess, key)
334
+ end
335
+ # Finishes a multiple-part message-digesting operation, returning the
336
+ # message digest as String.
337
+ def C_DigestFinal(out_size=nil)
338
+ @pk.C_DigestFinal(@sess, out_size)
339
+ end
340
+
341
+ # Convenience method for the C_DigestInit, C_DigestUpdate, C_DigestKey,
342
+ # C_DigestFinal call flow.
343
+ #
344
+ # Example:
345
+ # digest_string = session.digest( :SHA_1 ) do |cipher|
346
+ # cipher.update("key prefix")
347
+ # cipher.digest_key(some_key)
348
+ # end
349
+ def digest(mechanism, data=nil, &block)
350
+ C_DigestInit(mechanism)
351
+ if block_given?
352
+ raise "data not nil, but block given" if data
353
+ yield DigestCipher.new(proc{|data_|
354
+ C_DigestUpdate(data_)
355
+ }, proc{|key_|
356
+ C_DigestKey(key_)
357
+ })
358
+ C_DigestFinal()
359
+ else
360
+ C_Digest(data)
361
+ end
362
+ end
363
+
364
+ # Initializes a signature operation, where the signature is an appendix to the
365
+ # data.
366
+ #
367
+ # See Session#sign for convenience.
368
+ def C_SignInit(mechanism, key)
369
+ @pk.C_SignInit(@sess, Session.hash_to_mechanism(mechanism), key)
370
+ end
371
+ # Signs data in a single part, where the signature is an appendix to the data.
372
+ def C_Sign(data, out_size=nil)
373
+ @pk.C_Sign(@sess, data, out_size)
374
+ end
375
+ # Continues a multiple-part signature operation, processing another data
376
+ # part.
377
+ def C_SignUpdate(data)
378
+ @pk.C_SignUpdate(@sess, data)
379
+ end
380
+ # Finishes a multiple-part signature operation, returning the signature.
381
+ def C_SignFinal(out_size=nil)
382
+ @pk.C_SignFinal(@sess, out_size)
383
+ end
384
+
385
+ # Convenience method for the C_SignInit, C_SignUpdate, C_SignFinal call flow.
386
+ #
387
+ # See Session#encrypt
388
+ def sign(mechanism, key, data=nil, &block)
389
+ common_crypt(:C_SignInit, :C_SignUpdate, :C_SignFinal, :C_Sign,
390
+ mechanism, key, data, &block)
391
+ end
392
+
393
+
394
+ # Initializes a verification operation, where the signature is an appendix to
395
+ # the data.
396
+ #
397
+ # See ession#verify for convenience.
398
+ def C_VerifyInit(mechanism, key)
399
+ @pk.C_VerifyInit(@sess, Session.hash_to_mechanism(mechanism), key)
400
+ end
401
+ # Verifies a signature in a single-part operation, where the signature is an
402
+ # appendix to the data.
403
+ def C_Verify(data, out_size=nil)
404
+ @pk.C_Verify(@sess, data, out_size)
405
+ end
406
+ # Continues a multiple-part verification operation, processing another
407
+ # data part.
408
+ def C_VerifyUpdate(data)
409
+ @pk.C_VerifyUpdate(@sess, data)
410
+ end
411
+ # Finishes a multiple-part verification operation, checking the signature.
412
+ #
413
+ # Returns <tt>true</tt> for valid signature.
414
+ def C_VerifyFinal(out_size=nil)
415
+ @pk.C_VerifyFinal(@sess, out_size)
416
+ end
417
+
418
+ # Convenience method for the C_VerifyInit, C_VerifyUpdate, C_VerifyFinal call flow.
419
+ #
420
+ # See Session#encrypt
421
+ def verify(mechanism, key, signature, data=nil, &block)
422
+ common_verify(:C_VerifyInit, :C_VerifyUpdate, :C_VerifyFinal, :C_Verify,
423
+ mechanism, key, signature, data, &block)
424
+ end
425
+
426
+ # Initializes a signature operation, where the data can be recovered
427
+ # from the signature
428
+ def C_SignRecoverInit(mechanism, key)
429
+ @pk.C_SignRecoverInit(@sess, Session.hash_to_mechanism(mechanism), key)
430
+ end
431
+ # Signs data in a single operation, where the data can be recovered from
432
+ # the signature.
433
+ def C_SignRecover(data, out_size=nil)
434
+ @pk.C_SignRecover(@sess, data, out_size)
435
+ end
436
+
437
+ # Convenience method for the C_SignRecoverInit, C_SignRecover call flow.
438
+ def sign_recover(mechanism, key, data)
439
+ C_SignRecoverInit(mechanism, key)
440
+ C_SignRecover(data)
441
+ end
442
+
443
+
444
+ # Initializes a signature verification operation, where the data can be recovered
445
+ # from the signature
446
+ #
447
+ # See Session#verify_recover for convenience.
448
+ def C_VerifyRecoverInit(mechanism, key)
449
+ @pk.C_VerifyRecoverInit(@sess, Session.hash_to_mechanism(mechanism), key)
450
+ end
451
+ # Verifies a signature in a single-part operation, where the data is
452
+ # recovered from the signature.
453
+ def C_VerifyRecover(signature, out_size=nil)
454
+ @pk.C_VerifyRecover(@sess, signature, out_size=nil)
455
+ end
456
+
457
+ # Convenience method for the C_VerifyRecoverInit, C_VerifyRecover call flow.
458
+ def verify_recover(mechanism, key, signature)
459
+ C_VerifyRecoverInit(mechanism, key)
460
+ C_VerifyRecover(signature)
461
+ end
462
+
463
+ # Continues multiple-part digest and encryption operations,
464
+ # processing another data part.
465
+ #
466
+ # Digest and encryption operations must both be active (they must have been initialized
467
+ # with C_DigestInit and C_EncryptInit, respectively). This function may be called any
468
+ # number of times in succession, and may be interspersed with C_DigestUpdate,
469
+ # C_DigestKey, and C_EncryptUpdate calls.
470
+ def C_DigestEncryptUpdate(data, out_size=nil)
471
+ @pk.C_DigestEncryptUpdate(@sess, data, out_size)
472
+ end
473
+
474
+ # Continues a multiple-part combined decryption and digest
475
+ # operation, processing another data part.
476
+ #
477
+ # Decryption and digesting operations must both be active (they must have been initialized
478
+ # with C_DecryptInit and C_DigestInit, respectively). This function may be called any
479
+ # number of times in succession, and may be interspersed with C_DecryptUpdate,
480
+ # C_DigestUpdate, and C_DigestKey calls.
481
+ def C_DecryptDigestUpdate(data, out_size=nil)
482
+ @pk.C_DecryptDigestUpdate(@sess, data, out_size)
483
+ end
484
+
485
+ # Continues a multiple-part combined signature and encryption
486
+ # operation, processing another data part.
487
+ #
488
+ # Signature and encryption operations must both be active (they must have been initialized
489
+ # with C_SignInit and C_EncryptInit, respectively). This function may be called any
490
+ # number of times in succession, and may be interspersed with C_SignUpdate and
491
+ # C_EncryptUpdate calls.
492
+ def C_SignEncryptUpdate(data, out_size=nil)
493
+ @pk.C_SignEncryptUpdate(@sess, data, out_size)
494
+ end
495
+
496
+ # Continues a multiple-part combined decryption and
497
+ # verification operation, processing another data part.
498
+ #
499
+ # Decryption and signature operations must both be active (they must have been initialized
500
+ # with C_DecryptInit and C_VerifyInit, respectively). This function may be called any
501
+ # number of times in succession, and may be interspersed with C_DecryptUpdate and
502
+ # C_VerifyUpdate calls.
503
+ def C_DecryptVerifyUpdate(data, out_size=nil)
504
+ @pk.C_DecryptVerifyUpdate(@sess, data, out_size)
505
+ end
506
+
507
+ # Generates a secret key Object or set of domain parameters, creating a new
508
+ # Object.
509
+ #
510
+ # Returns key Object of the new created key.
511
+ def C_GenerateKey(mechanism, template={})
512
+ obj = @pk.C_GenerateKey(@sess, Session.hash_to_mechanism(mechanism), Session.hash_to_attributes(template))
513
+ Object.new @pk, @sess, obj
514
+ end
515
+ alias generate_key C_GenerateKey
516
+
517
+ # Generates a public/private key pair, creating new key Object instances.
518
+ #
519
+ # Returns an two-items array of new created public and private key Object.
520
+ def C_GenerateKeyPair(mechanism, pubkey_template={}, privkey_template={})
521
+ objs = @pk.C_GenerateKeyPair(@sess, Session.hash_to_mechanism(mechanism), Session.hash_to_attributes(pubkey_template), Session.hash_to_attributes(privkey_template))
522
+ objs.map{|obj| Object.new @pk, @sess, obj }
523
+ end
524
+ alias generate_key_pair C_GenerateKeyPair
525
+
526
+ # Wraps (i.e., encrypts) a private or secret key.
527
+ #
528
+ # Returns the encrypted binary data.
529
+ def C_WrapKey(mechanism, wrapping_key, wrapped_key, out_size=nil)
530
+ @pk.C_WrapKey(@sess, Session.hash_to_mechanism(mechanism), wrapping_key, wrapped_key, out_size)
531
+ end
532
+ alias wrap_key C_WrapKey
533
+
534
+ # Unwraps (i.e. decrypts) a wrapped key, creating a new private key or
535
+ # secret key object.
536
+ #
537
+ # Returns key Object of the new created key.
538
+ def C_UnwrapKey(mechanism, wrapping_key, wrapped_key, template={})
539
+ obj = @pk.C_UnwrapKey(@sess, Session.hash_to_mechanism(mechanism), wrapping_key, wrapped_key, Session.hash_to_attributes(template))
540
+ Object.new @pk, @sess, obj
541
+ end
542
+ alias unwrap_key C_UnwrapKey
543
+
544
+ # Derives a key from a base key, creating a new key object.
545
+ #
546
+ # Returns key Object of the new created key.
547
+ def C_DeriveKey(mechanism, base_key, template={})
548
+ obj = @pk.C_DeriveKey(@sess, Session.hash_to_mechanism(mechanism), base_key, Session.hash_to_attributes(template))
549
+ Object.new @pk, @sess, obj
550
+ end
551
+ alias derive_key C_DeriveKey
552
+
553
+ # Mixes additional seed material into the token’s random number
554
+ # generator.
555
+ def C_SeedRandom(data)
556
+ @pk.C_SeedRandom(@sess, data)
557
+ end
558
+ alias seed_random C_SeedRandom
559
+
560
+ # Generates random or pseudo-random data.
561
+ #
562
+ # Returns random or pseudo-random binary data of <tt>out_size</tt> bytes.
563
+ def C_GenerateRandom(out_size)
564
+ @pk.C_GenerateRandom(@sess, out_size)
565
+ end
566
+ alias generate_random C_GenerateRandom
567
+ end
568
+ end