pkcs11 0.2.4-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. data.tar.gz.sig +0 -0
  2. data/.autotest +23 -0
  3. data/.gemtest +0 -0
  4. data/.yardopts +1 -0
  5. data/History.txt +57 -0
  6. data/MIT-LICENSE +22 -0
  7. data/Manifest.txt +57 -0
  8. data/README.rdoc +205 -0
  9. data/Rakefile +111 -0
  10. data/ext/extconf.rb +7 -0
  11. data/ext/generate_constants.rb +57 -0
  12. data/ext/generate_structs.rb +206 -0
  13. data/ext/generate_thread_funcs.rb +72 -0
  14. data/ext/include/cryptoki.h +66 -0
  15. data/ext/include/ct-kip.h +50 -0
  16. data/ext/include/otp-pkcs11.h +125 -0
  17. data/ext/include/pkcs-11v2-20a3.h +124 -0
  18. data/ext/include/pkcs11.h +299 -0
  19. data/ext/include/pkcs11f.h +912 -0
  20. data/ext/include/pkcs11t.h +1885 -0
  21. data/ext/pk11.c +1675 -0
  22. data/ext/pk11.h +81 -0
  23. data/ext/pk11_const.c +205 -0
  24. data/ext/pk11_const_def.inc +452 -0
  25. data/ext/pk11_const_macros.h +38 -0
  26. data/ext/pk11_struct.doc +792 -0
  27. data/ext/pk11_struct_def.inc +302 -0
  28. data/ext/pk11_struct_impl.inc +302 -0
  29. data/ext/pk11_struct_macros.h +435 -0
  30. data/ext/pk11_thread_funcs.c +411 -0
  31. data/ext/pk11_thread_funcs.h +482 -0
  32. data/ext/pk11_version.h +6 -0
  33. data/lib/2.0/pkcs11_ext.so +0 -0
  34. data/lib/pkcs11.rb +9 -0
  35. data/lib/pkcs11/extensions.rb +68 -0
  36. data/lib/pkcs11/helper.rb +144 -0
  37. data/lib/pkcs11/library.rb +140 -0
  38. data/lib/pkcs11/object.rb +171 -0
  39. data/lib/pkcs11/session.rb +765 -0
  40. data/lib/pkcs11/slot.rb +102 -0
  41. data/pkcs11_protect_server/Manifest.txt +14 -0
  42. data/pkcs11_protect_server/README_PROTECT_SERVER.rdoc +89 -0
  43. data/test/fixtures/softokn/cert8.db +0 -0
  44. data/test/fixtures/softokn/key3.db +0 -0
  45. data/test/fixtures/softokn/secmod.db +0 -0
  46. data/test/helper.rb +58 -0
  47. data/test/test_pkcs11.rb +71 -0
  48. data/test/test_pkcs11_crypt.rb +220 -0
  49. data/test/test_pkcs11_object.rb +122 -0
  50. data/test/test_pkcs11_session.rb +123 -0
  51. data/test/test_pkcs11_slot.rb +78 -0
  52. data/test/test_pkcs11_structs.rb +166 -0
  53. data/test/test_pkcs11_thread.rb +44 -0
  54. metadata +213 -0
  55. metadata.gz.sig +0 -0
@@ -0,0 +1,765 @@
1
+ require 'pkcs11/helper'
2
+
3
+ module PKCS11
4
+ # Cryptoki requires that an application open one or more sessions with a token to gain
5
+ # access to the token's objects and functions. A session provides a logical connection
6
+ # between the application and the token. A session can be a read/write (R/W) session or a
7
+ # read-only (R/O) session (default).
8
+ class Session
9
+ include Helper
10
+
11
+ # @private
12
+ def initialize(pkcs11, session) # :nodoc:
13
+ @pk, @sess = pkcs11, session
14
+ end
15
+
16
+ # The session handle.
17
+ # @return [Integer]
18
+ def to_int
19
+ @sess
20
+ end
21
+ alias to_i to_int
22
+
23
+ # @private
24
+ def inspect # :nodoc:
25
+ "#<#{self.class} #{@sess.inspect}>"
26
+ end
27
+
28
+ # Logs a user into a token.
29
+ # @param [Integer, Symbol] user_type is the user type CKU_*;
30
+ # @param [String] pin is the user's PIN.
31
+ # @return [PKCS11::Session]
32
+ #
33
+ # When the user type is either CKU_SO or CKU_USER, if the call succeeds, each of the
34
+ # application's sessions will enter either the "R/W SO Functions" state, the "R/W User
35
+ # Functions" state, or the "R/O User Functions" state. If the user type is
36
+ # CKU_CONTEXT_SPECIFIC , the behavior of C_Login depends on the context in which
37
+ # it is called. Improper use of this user type will raise
38
+ # CKR_OPERATION_NOT_INITIALIZED.
39
+ def C_Login(user_type, pin)
40
+ @pk.C_Login(@sess, string_to_handle('CKU_', user_type), pin)
41
+ self
42
+ end
43
+ alias login C_Login
44
+
45
+ # Logs a user out from a token.
46
+ #
47
+ # Depending on the current user type, if the call succeeds, each of the application's
48
+ # sessions will enter either the "R/W Public Session" state or the "R/O Public Session"
49
+ # state.
50
+ # @return [PKCS11::Session]
51
+ def C_Logout()
52
+ @pk.C_Logout(@sess)
53
+ self
54
+ end
55
+ alias logout C_Logout
56
+
57
+ # Closes the session between an application and a token.
58
+ # @return [PKCS11::Session]
59
+ def C_CloseSession()
60
+ @pk.C_CloseSession(@sess)
61
+ self
62
+ end
63
+ alias close C_CloseSession
64
+
65
+ # Obtains information about a session.
66
+ # @return [CK_SESSION_INFO]
67
+ def C_GetSessionInfo()
68
+ @pk.C_GetSessionInfo(@sess)
69
+ end
70
+ alias info C_GetSessionInfo
71
+
72
+ # Initializes a search for token and session objects that match a
73
+ # template.
74
+ #
75
+ # See {Session#find_objects} for convenience.
76
+ # @param [Hash] find_template points to a search template that
77
+ # specifies the attribute values to match
78
+ # The matching criterion is an exact byte-for-byte match with all attributes in the
79
+ # template. Use empty Hash to find all objects.
80
+ # @return [PKCS11::Session]
81
+ def C_FindObjectsInit(find_template={})
82
+ @pk.C_FindObjectsInit(@sess, to_attributes(find_template))
83
+ self
84
+ end
85
+
86
+ # Continues a search for token and session objects that match a template,
87
+ # obtaining additional object handles.
88
+ #
89
+ # See {Session#find_objects} for convenience
90
+ # @return [Array<PKCS11::Object>] Returns an array of Object instances.
91
+ def C_FindObjects(max_count)
92
+ objs = @pk.C_FindObjects(@sess, max_count)
93
+ objs.map{|obj| Object.new @pk, @sess, obj }
94
+ end
95
+
96
+ # Terminates a search for token and session objects.
97
+ #
98
+ # See {Session#find_objects} for convenience
99
+ # @return [PKCS11::Session]
100
+ def C_FindObjectsFinal
101
+ @pk.C_FindObjectsFinal(@sess)
102
+ self
103
+ end
104
+
105
+ # Convenience method for the {Session#C_FindObjectsInit}, {Session#C_FindObjects}, {Session#C_FindObjectsFinal} cycle.
106
+ #
107
+ # * If called with block, it iterates over all found objects.
108
+ # * If called without block, it returns with an array of all found Object instances.
109
+ # @return [Array<PKCS11::Object>]
110
+ #
111
+ # @example prints subject of all certificates stored in the token:
112
+ # session.find_objects(:CLASS => PKCS11::CKO_CERTIFICATE) do |obj|
113
+ # p OpenSSL::X509::Name.new(obj[:SUBJECT])
114
+ # end
115
+ def find_objects(template={})
116
+ all_objs = [] unless block_given?
117
+ C_FindObjectsInit(template)
118
+ begin
119
+ loop do
120
+ objs = C_FindObjects(20)
121
+ break if objs.empty?
122
+ if block_given?
123
+ objs.each{|obj| yield obj }
124
+ else
125
+ all_objs += objs
126
+ end
127
+ end
128
+ ensure
129
+ C_FindObjectsFinal()
130
+ end
131
+ return all_objs
132
+ end
133
+
134
+
135
+ # Creates a new Object based on given template.
136
+ #
137
+ # If {Session#C_CreateObject} is used to create a key object, the key object will have its
138
+ # CKA_LOCAL attribute set to false. If that key object is a secret or private key
139
+ # then the new key will have the CKA_ALWAYS_SENSITIVE attribute set to
140
+ # false, and the CKA_NEVER_EXTRACTABLE attribute set to false.
141
+ #
142
+ # Only session objects can be created during a read-only session. Only public objects can
143
+ # be created unless the normal user is logged in.
144
+ #
145
+ # @param [Hash] template Attributes of the object to create.
146
+ # @return [PKCS11::Object] the newly created object
147
+ # @example Creating a 112 bit DES key from plaintext
148
+ # secret_key = session.create_object(
149
+ # :CLASS=>PKCS11::CKO_SECRET_KEY, :KEY_TYPE=>PKCS11::CKK_DES2,
150
+ # :ENCRYPT=>true, :WRAP=>true, :DECRYPT=>true, :UNWRAP=>true,
151
+ # :VALUE=>'0123456789abcdef', :LABEL=>'test_secret_key')
152
+ def C_CreateObject(template={})
153
+ handle = @pk.C_CreateObject(@sess, to_attributes(template))
154
+ Object.new @pk, @sess, handle
155
+ end
156
+ alias create_object C_CreateObject
157
+
158
+ # Initializes the normal user's PIN. This standard
159
+ # allows PIN values to contain any valid UTF8 character, but the token may impose subset
160
+ # restrictions.
161
+ #
162
+ # @param [String] pin
163
+ # @return [PKCS11::Session]
164
+ def C_InitPIN(pin)
165
+ @pk.C_InitPIN(@sess, pin)
166
+ self
167
+ end
168
+ alias init_pin C_InitPIN
169
+
170
+ # Modifies the PIN of the user that is currently logged in, or the CKU_USER
171
+ # PIN if the session is not logged in.
172
+ #
173
+ # @param [String] old_pin
174
+ # @param [String] new_pin
175
+ # @return [PKCS11::Session]
176
+ def C_SetPIN(old_pin, new_pin)
177
+ @pk.C_SetPIN(@sess, old_pin, new_pin)
178
+ self
179
+ end
180
+ alias set_pin C_SetPIN
181
+
182
+ class Cipher
183
+ # @private
184
+ def initialize(update_block) # :nodoc:
185
+ @update_block = update_block
186
+ end
187
+ # Process a data part with the encryption operation.
188
+ # @param [String] data data to be processed
189
+ # @return [String] output data
190
+ def update(data)
191
+ @update_block.call(data)
192
+ end
193
+ alias << update
194
+ end
195
+
196
+ class DigestCipher < Cipher
197
+ # @private
198
+ def initialize(update_block, digest_key_block) # :nodoc:
199
+ super(update_block)
200
+ @digest_key_block = digest_key_block
201
+ end
202
+ alias digest_update update
203
+ # Continues a multiple-part message-digesting operation by digesting the
204
+ # value of a secret key.
205
+ # @param [PKCS11::Object] key key to be processed
206
+ # @return [String] output data
207
+ def digest_key(key)
208
+ @digest_key_block.call(key)
209
+ end
210
+ end
211
+
212
+ def common_crypt( init, update, final, single, mechanism, key, data=nil) # :nodoc:
213
+ send(init, mechanism, key)
214
+ if block_given?
215
+ raise "data not nil, but block given" if data
216
+ yield Cipher.new(proc{|data_|
217
+ send(update, data_)
218
+ })
219
+ send(final)
220
+ else
221
+ send(single, data)
222
+ end
223
+ end
224
+ private :common_crypt
225
+
226
+ def common_verify( init, update, final, single, mechanism, key, signature, data=nil ) # :nodoc:
227
+ send(init, mechanism, key)
228
+ if block_given?
229
+ raise "data not nil, but block given" if data
230
+ yield Cipher.new(proc{|data_|
231
+ send(update, data_)
232
+ })
233
+ send(final, signature)
234
+ else
235
+ send(single, data, signature)
236
+ end
237
+ end
238
+ private :common_verify
239
+
240
+ # Initializes an encryption operation.
241
+ #
242
+ # @param [Hash, Symbol, Integer, PKCS11::CK_MECHANISM] mechanism the encryption mechanism
243
+ # @param [PKCS11::Object] key the object handle of the encryption key.
244
+ # @return [PKCS11::Session]
245
+ #
246
+ # See {Session#encrypt} for convenience
247
+ #
248
+ # The CKA_ENCRYPT attribute of the encryption key, which indicates whether the key
249
+ # supports encryption, must be true.
250
+ #
251
+ # After calling {Session#C_EncryptInit}, the application can either call {Session#C_Encrypt} to encrypt data
252
+ # in a single part; or call {Session#C_EncryptUpdate} zero or more times, followed by
253
+ # {Session#C_EncryptFinal}, to encrypt data in multiple parts. The encryption operation is active
254
+ # until the application uses a call to {Session#C_Encrypt} or {Session#C_EncryptFinal} to actually obtain the
255
+ # final piece of ciphertext. To process additional data (in single or multiple parts), the
256
+ # application must call {Session#C_EncryptInit} again.
257
+ def C_EncryptInit(mechanism, key)
258
+ @pk.C_EncryptInit(@sess, to_mechanism(mechanism), key)
259
+ self
260
+ end
261
+ # Encrypts single-part data.
262
+ #
263
+ # See {Session#encrypt} for convenience
264
+ # @param [Integer, nil] out_size The buffer size for output data provided to the
265
+ # library. If nil, size is determined automatically.
266
+ # @return [String]
267
+ def C_Encrypt(data, out_size=nil)
268
+ @pk.C_Encrypt(@sess, data, out_size)
269
+ end
270
+ # Continues a multiple-part encryption operation, processing another
271
+ # data part.
272
+ #
273
+ # See {Session#encrypt} for convenience
274
+ # @param [Integer, nil] out_size The buffer size for output data provided to the
275
+ # library. If nil, size is determined automatically.
276
+ # @return [String]
277
+ def C_EncryptUpdate(data, out_size=nil)
278
+ @pk.C_EncryptUpdate(@sess, data, out_size)
279
+ end
280
+ # Finishes a multiple-part encryption operation.
281
+ #
282
+ # See {Session#encrypt} for convenience
283
+ # @param [Integer, nil] out_size The buffer size for output data provided to the
284
+ # library. If nil, size is determined automatically.
285
+ # @return [String]
286
+ def C_EncryptFinal(out_size=nil)
287
+ @pk.C_EncryptFinal(@sess, out_size)
288
+ end
289
+
290
+ # Convenience method for the {Session#C_EncryptInit}, {Session#C_EncryptUpdate}, {Session#C_EncryptFinal} call flow.
291
+ #
292
+ # If no block is given, the single part operation {Session#C_EncryptInit}, {Session#C_Encrypt} is called.
293
+ # If a block is given, the multi part operation ({Session#C_EncryptInit}, {Session#C_EncryptUpdate}, {Session#C_EncryptFinal})
294
+ # is used. The given block is called once with a cipher object. There can be any number of
295
+ # {Cipher#update} calls within the block, each giving the encryption result of this part as String.
296
+ #
297
+ # @param [Hash, Symbol, Integer, PKCS11::CK_MECHANISM] mechanism used mechanism
298
+ # @param [PKCS11::Object] key used key
299
+ # @param [String] data data to encrypt
300
+ # @yield [PKCS11::Session::Cipher] Cipher object for processing data parts
301
+ # @return [String] the final part of the encryption operation.
302
+ #
303
+ # @example for using single part operation
304
+ # iv = "12345678"
305
+ # cryptogram = session.encrypt( {:DES_CBC_PAD=>iv}, key, "block 1block 2" )
306
+ #
307
+ # @example for using multi part operation
308
+ # iv = "12345678"
309
+ # cryptogram = ''
310
+ # cryptogram << session.encrypt( {:DES_CBC_PAD=>iv}, key ) do |cipher|
311
+ # cryptogram << cipher.update("block 1")
312
+ # cryptogram << cipher.update("block 2")
313
+ # end
314
+ #
315
+ # @example Calculating a key check value to a secret key
316
+ # key_kcv = session.encrypt( :DES3_ECB, key, "\0"*8)
317
+ def encrypt(mechanism, key, data=nil, &block)
318
+ common_crypt(:C_EncryptInit, :C_EncryptUpdate, :C_EncryptFinal, :C_Encrypt,
319
+ mechanism, key, data, &block)
320
+ end
321
+
322
+ # Initializes a decryption operation.
323
+ #
324
+ # See {Session#decrypt} for convenience and {Session#C_EncryptInit} for description.
325
+ def C_DecryptInit(mechanism, key)
326
+ @pk.C_DecryptInit(@sess, to_mechanism(mechanism), key)
327
+ end
328
+ # Decrypts encrypted data in a single part.
329
+ #
330
+ # See {Session#decrypt} for convenience.
331
+ # @param [Integer, nil] out_size The buffer size for output data provided to the
332
+ # library. If nil, size is determined automatically.
333
+ # @return [String]
334
+ def C_Decrypt(data, out_size=nil)
335
+ @pk.C_Decrypt(@sess, data, out_size)
336
+ end
337
+ # Continues a multiple-part decryption operation, processing another
338
+ # encrypted data part.
339
+ #
340
+ # See {Session#decrypt} for convenience.
341
+ # @param [Integer, nil] out_size The buffer size for output data provided to the
342
+ # library. If nil, size is determined automatically.
343
+ # @return [String]
344
+ def C_DecryptUpdate(data, out_size=nil)
345
+ @pk.C_DecryptUpdate(@sess, data, out_size)
346
+ end
347
+ # Finishes a multiple-part decryption operation.
348
+ #
349
+ # See {Session#decrypt} for convenience.
350
+ # @param [Integer, nil] out_size The buffer size for output data provided to the
351
+ # library. If nil, size is determined automatically.
352
+ # @return [String]
353
+ def C_DecryptFinal(out_size=nil)
354
+ @pk.C_DecryptFinal(@sess, out_size)
355
+ end
356
+
357
+ # Convenience method for the {Session#C_DecryptInit}, {Session#C_DecryptUpdate}, {Session#C_DecryptFinal} call flow.
358
+ #
359
+ # @see Session#encrypt
360
+ #
361
+ # @param [Hash, Symbol, Integer, PKCS11::CK_MECHANISM] mechanism used mechanism
362
+ # @param [PKCS11::Object] key used key
363
+ # @param [String] data data to decrypt
364
+ # @yield [PKCS11::Session::Cipher] Cipher object for processing data parts
365
+ # @return [String] the final part of the encryption operation.
366
+ # @example Decrypt data previously encrypted with a RSA pulic key
367
+ # plaintext2 = session.decrypt( :RSA_PKCS, rsa_priv_key, cryptogram)
368
+ def decrypt(mechanism, key, data=nil, &block)
369
+ common_crypt(:C_DecryptInit, :C_DecryptUpdate, :C_DecryptFinal, :C_Decrypt,
370
+ mechanism, key, data, &block)
371
+ end
372
+
373
+ # Initializes a message-digesting operation.
374
+ #
375
+ # See {Session#digest} for convenience.
376
+ # @return [PKCS11::Session]
377
+ def C_DigestInit(mechanism)
378
+ @pk.C_DigestInit(@sess, to_mechanism(mechanism))
379
+ self
380
+ end
381
+ # Digests data in a single part.
382
+ #
383
+ # See {Session#digest} for convenience.
384
+ # @param [Integer, nil] out_size The buffer size for output data provided to the
385
+ # library. If nil, size is determined automatically.
386
+ # @return [String]
387
+ def C_Digest(data, out_size=nil)
388
+ @pk.C_Digest(@sess, data, out_size)
389
+ end
390
+ # Continues a multiple-part message-digesting operation, processing
391
+ # another data part.
392
+ #
393
+ # See {Session#digest} for convenience.
394
+ # @return [PKCS11::Session]
395
+ def C_DigestUpdate(data)
396
+ @pk.C_DigestUpdate(@sess, data)
397
+ self
398
+ end
399
+ # Continues a multiple-part message-digesting operation by digesting the
400
+ # value of a secret key.
401
+ #
402
+ # See {Session#digest} for convenience.
403
+ #
404
+ # The message-digesting operation must have been initialized with {Session#C_DigestInit}. Calls to
405
+ # this function and {Session#C_DigestUpdate} may be interspersed any number of times in any
406
+ # order.
407
+ # @return [PKCS11::Session]
408
+ def C_DigestKey(key)
409
+ @pk.C_DigestKey(@sess, key)
410
+ self
411
+ end
412
+ # Finishes a multiple-part message-digesting operation, returning the
413
+ # message digest as String.
414
+ #
415
+ # See {Session#digest} for convenience.
416
+ # @param [Integer, nil] out_size The buffer size for output data provided to the
417
+ # library. If nil, size is determined automatically.
418
+ # @return [String]
419
+ def C_DigestFinal(out_size=nil)
420
+ @pk.C_DigestFinal(@sess, out_size)
421
+ end
422
+
423
+ # Convenience method for the {Session#C_DigestInit}, {Session#C_DigestUpdate}, {Session#C_DigestKey},
424
+ # {Session#C_DigestFinal} call flow.
425
+ #
426
+ # @example
427
+ # digest_string = session.digest( :SHA_1 ) do |cipher|
428
+ # cipher.update("key prefix")
429
+ # cipher.digest_key(some_key)
430
+ # end
431
+ # @param [Hash, Symbol, Integer, PKCS11::CK_MECHANISM] mechanism used mechanism
432
+ # @param [String] data data to digest
433
+ # @yield [PKCS11::Session::DigestCipher] Cipher object for processing data parts
434
+ # @return [String] final message digest
435
+ # @see Session#encrypt
436
+ def digest(mechanism, data=nil, &block)
437
+ C_DigestInit(mechanism)
438
+ if block_given?
439
+ raise "data not nil, but block given" if data
440
+ yield DigestCipher.new(proc{|data_|
441
+ C_DigestUpdate(data_)
442
+ }, proc{|key_|
443
+ C_DigestKey(key_)
444
+ })
445
+ C_DigestFinal()
446
+ else
447
+ C_Digest(data)
448
+ end
449
+ end
450
+
451
+ # Initializes a signature operation, where the signature is an appendix to the
452
+ # data.
453
+ #
454
+ # See {Session#sign} for convenience.
455
+ # @return [PKCS11::Session]
456
+ def C_SignInit(mechanism, key)
457
+ @pk.C_SignInit(@sess, to_mechanism(mechanism), key)
458
+ self
459
+ end
460
+ # Signs data in a single part, where the signature is an appendix to the data.
461
+ #
462
+ # See {Session#sign} for convenience.
463
+ # @return [String] message signature
464
+ def C_Sign(data, out_size=nil)
465
+ @pk.C_Sign(@sess, data, out_size)
466
+ end
467
+ # Continues a multiple-part signature operation, processing another data
468
+ # part.
469
+ #
470
+ # See {Session#sign} for convenience.
471
+ # @return [PKCS11::Session]
472
+ def C_SignUpdate(data)
473
+ @pk.C_SignUpdate(@sess, data)
474
+ self
475
+ end
476
+ # Finishes a multiple-part signature operation, returning the signature.
477
+ #
478
+ # See {Session#sign} for convenience.
479
+ # @return [String] message signature
480
+ def C_SignFinal(out_size=nil)
481
+ @pk.C_SignFinal(@sess, out_size)
482
+ end
483
+
484
+ # Convenience method for the {Session#C_SignInit}, {Session#C_SignUpdate}, {Session#C_SignFinal} call flow.
485
+ #
486
+ # @param [Hash, Symbol, Integer, PKCS11::CK_MECHANISM] mechanism used mechanism
487
+ # @param [PKCS11::Object] key used key
488
+ # @param [String] data data to sign
489
+ # @yield [PKCS11::Session::Cipher] Cipher object for processing data parts
490
+ # @return [String] signature
491
+ # @see Session#encrypt
492
+ # @example Sign a text by a RSA private key
493
+ # signature = session.sign( :SHA1_RSA_PKCS, rsa_priv_key, "important text")
494
+ def sign(mechanism, key, data=nil, &block)
495
+ common_crypt(:C_SignInit, :C_SignUpdate, :C_SignFinal, :C_Sign,
496
+ mechanism, key, data, &block)
497
+ end
498
+
499
+
500
+ # Initializes a verification operation, where the signature is an appendix to
501
+ # the data.
502
+ #
503
+ # See {Session#verify} for convenience.
504
+ def C_VerifyInit(mechanism, key)
505
+ @pk.C_VerifyInit(@sess, to_mechanism(mechanism), key)
506
+ end
507
+ # Verifies a signature in a single-part operation, where the signature is an
508
+ # appendix to the data.
509
+ #
510
+ # See {Session#verify} for convenience.
511
+ def C_Verify(data, out_size=nil)
512
+ @pk.C_Verify(@sess, data, out_size)
513
+ end
514
+ # Continues a multiple-part verification operation, processing another
515
+ # data part.
516
+ #
517
+ # See {Session#verify} for convenience.
518
+ def C_VerifyUpdate(data)
519
+ @pk.C_VerifyUpdate(@sess, data)
520
+ end
521
+ # Finishes a multiple-part verification operation, checking the signature.
522
+ #
523
+ # See {Session#verify} for convenience.
524
+ # @return [Boolean] <tt>true</tt> for valid signature.
525
+ def C_VerifyFinal(out_size=nil)
526
+ @pk.C_VerifyFinal(@sess, out_size)
527
+ end
528
+
529
+ # Convenience method for the {Session#C_VerifyInit}, {Session#C_VerifyUpdate}, {Session#C_VerifyFinal} call flow.
530
+ #
531
+ # @see Session#encrypt
532
+ # @param [Hash, Symbol, Integer, PKCS11::CK_MECHANISM] mechanism used mechanism
533
+ # @param [PKCS11::Object] key used key
534
+ # @param [String] signature signature
535
+ # @param [String] data data to verify against signature
536
+ # @yield [PKCS11::Session::Cipher] Cipher object for processing data parts
537
+ # @return [Boolean] <tt>true</tt> for valid signature.
538
+ # @example
539
+ # raise("wrong signature") unless session.verify(:SHA1_RSA_PKCS, rsa_pub_key, signature, plaintext)
540
+ def verify(mechanism, key, signature, data=nil, &block)
541
+ common_verify(:C_VerifyInit, :C_VerifyUpdate, :C_VerifyFinal, :C_Verify,
542
+ mechanism, key, signature, data, &block)
543
+ end
544
+
545
+ # Initializes a signature operation, where the data can be recovered
546
+ # from the signature
547
+ #
548
+ # See {Session#sign_recover} for convenience.
549
+ def C_SignRecoverInit(mechanism, key)
550
+ @pk.C_SignRecoverInit(@sess, to_mechanism(mechanism), key)
551
+ self
552
+ end
553
+ # Signs data in a single operation, where the data can be recovered from
554
+ # the signature.
555
+ #
556
+ # See {Session#sign_recover} for convenience.
557
+ def C_SignRecover(data, out_size=nil)
558
+ @pk.C_SignRecover(@sess, data, out_size)
559
+ end
560
+
561
+ # Convenience method for the {Session#C_SignRecoverInit}, {Session#C_SignRecover} call flow.
562
+ #
563
+ # @param [Hash, Symbol, Integer, PKCS11::CK_MECHANISM] mechanism used mechanism
564
+ # @param [PKCS11::Object] key signature key
565
+ # @param [String] data data to be recovered
566
+ # @return [String] signature
567
+ # @see Session#verify_recover
568
+ def sign_recover(mechanism, key, data)
569
+ C_SignRecoverInit(mechanism, key)
570
+ C_SignRecover(data)
571
+ end
572
+
573
+
574
+ # Initializes a signature verification operation, where the data can be recovered
575
+ # from the signature
576
+ #
577
+ # See {Session#verify_recover} for convenience.
578
+ def C_VerifyRecoverInit(mechanism, key)
579
+ @pk.C_VerifyRecoverInit(@sess, to_mechanism(mechanism), key)
580
+ end
581
+ # Verifies a signature in a single-part operation, where the data is
582
+ # recovered from the signature.
583
+ #
584
+ # See {Session#verify_recover} for convenience.
585
+ def C_VerifyRecover(signature, out_size=nil)
586
+ @pk.C_VerifyRecover(@sess, signature, out_size=nil)
587
+ end
588
+
589
+ # Convenience method for the {Session#C_VerifyRecoverInit}, {Session#C_VerifyRecover} call flow.
590
+ #
591
+ # @param [Hash, Symbol, Integer, PKCS11::CK_MECHANISM] mechanism used mechanism
592
+ # @param [PKCS11::Object] key verification key
593
+ # @return [String] recovered data
594
+ # @see Session#sign_recover
595
+ def verify_recover(mechanism, key, signature)
596
+ C_VerifyRecoverInit(mechanism, key)
597
+ C_VerifyRecover(signature)
598
+ end
599
+
600
+ # Continues multiple-part digest and encryption operations,
601
+ # processing another data part.
602
+ #
603
+ # Digest and encryption operations must both be active (they must have been initialized
604
+ # with {Session#C_DigestInit} and {Session#C_EncryptInit}, respectively). This function may be called any
605
+ # number of times in succession, and may be interspersed with {Session#C_DigestUpdate},
606
+ # {Session#C_DigestKey}, and {Session#C_EncryptUpdate} calls.
607
+ def C_DigestEncryptUpdate(data, out_size=nil)
608
+ @pk.C_DigestEncryptUpdate(@sess, data, out_size)
609
+ end
610
+
611
+ # Continues a multiple-part combined decryption and digest
612
+ # operation, processing another data part.
613
+ #
614
+ # Decryption and digesting operations must both be active (they must have been initialized
615
+ # with {Session#C_DecryptInit} and {Session#C_DigestInit}, respectively). This function may be called any
616
+ # number of times in succession, and may be interspersed with {Session#C_DecryptUpdate},
617
+ # {Session#C_DigestUpdate}, and {Session#C_DigestKey} calls.
618
+ def C_DecryptDigestUpdate(data, out_size=nil)
619
+ @pk.C_DecryptDigestUpdate(@sess, data, out_size)
620
+ end
621
+
622
+ # Continues a multiple-part combined signature and encryption
623
+ # operation, processing another data part.
624
+ #
625
+ # Signature and encryption operations must both be active (they must have been initialized
626
+ # with {Session#C_SignInit} and {Session#C_EncryptInit}, respectively). This function may be called any
627
+ # number of times in succession, and may be interspersed with {Session#C_SignUpdate} and
628
+ # {Session#C_EncryptUpdate} calls.
629
+ def C_SignEncryptUpdate(data, out_size=nil)
630
+ @pk.C_SignEncryptUpdate(@sess, data, out_size)
631
+ end
632
+
633
+ # Continues a multiple-part combined decryption and
634
+ # verification operation, processing another data part.
635
+ #
636
+ # Decryption and signature operations must both be active (they must have been initialized
637
+ # with {Session#C_DecryptInit} and {Session#C_VerifyInit}, respectively). This function may be called any
638
+ # number of times in succession, and may be interspersed with {Session#C_DecryptUpdate} and
639
+ # {Session#C_VerifyUpdate} calls.
640
+ def C_DecryptVerifyUpdate(data, out_size=nil)
641
+ @pk.C_DecryptVerifyUpdate(@sess, data, out_size)
642
+ end
643
+
644
+ # Generates a secret key Object or set of domain parameters, creating a new
645
+ # Object.
646
+ #
647
+ # @param [Hash, Symbol, Integer, PKCS11::CK_MECHANISM] mechanism used mechanism
648
+ # @param [Hash] template Attributes of the key to create.
649
+ # @return [PKCS11::Object] key Object of the new created key.
650
+ # @example generate 112 bit DES key
651
+ # key = session.generate_key(:DES2_KEY_GEN,
652
+ # {:ENCRYPT=>true, :WRAP=>true, :DECRYPT=>true, :UNWRAP=>true})
653
+ def C_GenerateKey(mechanism, template={})
654
+ obj = @pk.C_GenerateKey(@sess, to_mechanism(mechanism), to_attributes(template))
655
+ Object.new @pk, @sess, obj
656
+ end
657
+ alias generate_key C_GenerateKey
658
+
659
+ # Generates a public/private key pair, creating new key Object instances.
660
+ #
661
+ # @param [Hash, Symbol, Integer, PKCS11::CK_MECHANISM] mechanism used mechanism
662
+ # @param [Hash] pubkey_template Attributes of the public key to create.
663
+ # @param [Hash] privkey_template Attributes of the private key to create.
664
+ # @return [Array<PKCS11::Object>] an two-items array of new created public and private key Object.
665
+ # @example
666
+ # pub_key, priv_key = session.generate_key_pair(:RSA_PKCS_KEY_PAIR_GEN,
667
+ # {:ENCRYPT=>true, :VERIFY=>true, :WRAP=>true, :MODULUS_BITS=>768, :PUBLIC_EXPONENT=>3},
668
+ # {:SUBJECT=>'test', :ID=>"ID", :DECRYPT=>true, :SIGN=>true, :UNWRAP=>true})
669
+ def C_GenerateKeyPair(mechanism, pubkey_template={}, privkey_template={})
670
+ objs = @pk.C_GenerateKeyPair(@sess, to_mechanism(mechanism), to_attributes(pubkey_template), to_attributes(privkey_template))
671
+ objs.map{|obj| Object.new @pk, @sess, obj }
672
+ end
673
+ alias generate_key_pair C_GenerateKeyPair
674
+
675
+ # Wraps (i.e., encrypts) a private or secret key.
676
+ #
677
+ # @param [Hash, Symbol, Integer, PKCS11::CK_MECHANISM] mechanism used mechanism
678
+ # @param [PKCS11::Object] wrapping_key wrapping key
679
+ # @param [PKCS11::Object] wrapped_key key to wrap
680
+ # @return [String] the encrypted binary data.
681
+ # @see Session#C_UnwrapKey
682
+ # @example Wrapping a secret key
683
+ # wrapped_key_value = session.wrap_key(:DES3_ECB, secret_key, secret_key)
684
+ # @example Wrapping a private key
685
+ # wrapped_key_value = session.wrap_key({:DES3_CBC_PAD=>"\0"*8}, secret_key, rsa_priv_key)
686
+ def C_WrapKey(mechanism, wrapping_key, wrapped_key, out_size=nil)
687
+ @pk.C_WrapKey(@sess, to_mechanism(mechanism), wrapping_key, wrapped_key, out_size)
688
+ end
689
+ alias wrap_key C_WrapKey
690
+
691
+ # Unwraps (i.e. decrypts) a wrapped key, creating a new private key or
692
+ # secret key object.
693
+ #
694
+ # @param [Hash, Symbol, Integer, PKCS11::CK_MECHANISM] mechanism used mechanism
695
+ # @param [PKCS11::Object] wrapping_key wrapping key
696
+ # @param [String] wrapped_key key data of the wrapped key
697
+ # @return [PKCS11::Object] key object of the new created key.
698
+ # @see Session#C_WrapKey
699
+ # @example
700
+ # unwrapped_key = session.unwrap_key(:DES3_ECB, secret_key, wrapped_key_value,
701
+ # :CLASS=>CKO_SECRET_KEY, :KEY_TYPE=>CKK_DES2, :ENCRYPT=>true, :DECRYPT=>true)
702
+ def C_UnwrapKey(mechanism, wrapping_key, wrapped_key, template={})
703
+ obj = @pk.C_UnwrapKey(@sess, to_mechanism(mechanism), wrapping_key, wrapped_key, to_attributes(template))
704
+ Object.new @pk, @sess, obj
705
+ end
706
+ alias unwrap_key C_UnwrapKey
707
+
708
+ # Derives a key from a base key, creating a new key object.
709
+ #
710
+ # @param [Hash, Symbol, Integer, PKCS11::CK_MECHANISM] mechanism used mechanism
711
+ # @param [PKCS11::Object] base_key key to derive
712
+ # @param [Hash] template Attributes of the object to create.
713
+ # @return [PKCS11::Object] key object of the new created key.
714
+ # @example Derive a AES key by XORing with some derivation data
715
+ # deriv_data = "\0"*16
716
+ # new_key = session.derive_key( {CKM_XOR_BASE_AND_DATA => {:pData => deriv_data}}, secret_key,
717
+ # :CLASS=>CKO_SECRET_KEY, :KEY_TYPE=>CKK_AES, :VALUE_LEN=>16, :ENCRYPT=>true )
718
+ def C_DeriveKey(mechanism, base_key, template={})
719
+ obj = @pk.C_DeriveKey(@sess, to_mechanism(mechanism), base_key, to_attributes(template))
720
+ Object.new @pk, @sess, obj
721
+ end
722
+ alias derive_key C_DeriveKey
723
+
724
+ # Mixes additional seed material into the token's random number
725
+ # generator.
726
+ # @param [String] entropy data
727
+ # @return [PKCS11::Session]
728
+ def C_SeedRandom(data)
729
+ @pk.C_SeedRandom(@sess, data)
730
+ self
731
+ end
732
+ alias seed_random C_SeedRandom
733
+
734
+ # Generates random or pseudo-random data.
735
+ #
736
+ # @param [Integer] out_size
737
+ # @return [String] random or pseudo-random binary data of <tt>out_size</tt> bytes.
738
+ def C_GenerateRandom(out_size)
739
+ @pk.C_GenerateRandom(@sess, out_size)
740
+ end
741
+ alias generate_random C_GenerateRandom
742
+
743
+ # Obtains a copy of the cryptographic operations state of a session,
744
+ # encoded as a string of bytes.
745
+ # @return [String]
746
+ # @see Session#C_SetOperationState
747
+ def C_GetOperationState
748
+ @pk.C_GetOperationState(@sess)
749
+ end
750
+ alias get_operation_state C_GetOperationState
751
+
752
+ # Restores the cryptographic operations state of a session from a
753
+ # string of bytes obtained with {Session#C_GetOperationState}.
754
+ #
755
+ # @param [String] state previously stored session state
756
+ # @param [PKCS11::Object] encryption key for sessions stored without keys
757
+ # @param [PKCS11::Object] authentication key for sessions stored without keys
758
+ # @return [PKCS11::Session]
759
+ def C_SetOperationState(state, enc_key=nil, auth_key=nil)
760
+ @pk.C_SetOperationState(@sess, state, enc_key||0, auth_key||0)
761
+ self
762
+ end
763
+ alias set_operation_state C_SetOperationState
764
+ end
765
+ end