pkcs11 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,93 +1,69 @@
1
+ require 'pkcs11/helper'
2
+
1
3
  module PKCS11
2
4
  # Cryptoki requires that an application open one or more sessions with a token to gain
3
- # access to the tokens objects and functions. A session provides a logical connection
5
+ # access to the token's objects and functions. A session provides a logical connection
4
6
  # between the application and the token. A session can be a read/write (R/W) session or a
5
7
  # read-only (R/O) session (default).
6
8
  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
9
+ include Helper
22
10
 
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
-
11
+ # @private
45
12
  def initialize(pkcs11, session) # :nodoc:
46
13
  @pk, @sess = pkcs11, session
47
14
  end
48
15
 
49
16
  # The session handle.
17
+ # @return [Integer]
50
18
  def to_int
51
19
  @sess
52
20
  end
53
21
  alias to_i to_int
54
22
 
23
+ # @private
55
24
  def inspect # :nodoc:
56
25
  "#<#{self.class} #{@sess.inspect}>"
57
26
  end
58
27
 
59
28
  # Logs a user into a token.
60
- # user_type:: is the user type CKU_*;
61
- # pin:: is the users PIN.
29
+ # @param [Integer, Symbol] user_type is the user type CKU_*;
30
+ # @param [String] pin is the user's PIN.
31
+ # @return [PKCS11::Session]
62
32
  #
63
33
  # When the user type is either CKU_SO or CKU_USER, if the call succeeds, each of the
64
34
  # application's sessions will enter either the "R/W SO Functions" state, the "R/W User
65
35
  # Functions" state, or the "R/O User Functions" state. If the user type is
66
36
  # 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
37
+ # it is called. Improper use of this user type will raise
68
38
  # CKR_OPERATION_NOT_INITIALIZED.
69
39
  def C_Login(user_type, pin)
70
- @pk.C_Login(@sess, Session::string_to_handle('CKU_', user_type), pin)
40
+ @pk.C_Login(@sess, string_to_handle('CKU_', user_type), pin)
41
+ self
71
42
  end
72
43
  alias login C_Login
73
44
 
74
45
  # Logs a user out from a token.
75
46
  #
76
- # Depending on the current user type, if the call succeeds, each of the applications
77
- # sessions will enter either the R/W Public Session state or the R/O Public Session
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"
78
49
  # state.
50
+ # @return [PKCS11::Session]
79
51
  def C_Logout()
80
52
  @pk.C_Logout(@sess)
53
+ self
81
54
  end
82
55
  alias logout C_Logout
83
56
 
84
57
  # Closes the session between an application and a token.
58
+ # @return [PKCS11::Session]
85
59
  def C_CloseSession()
86
60
  @pk.C_CloseSession(@sess)
61
+ self
87
62
  end
88
63
  alias close C_CloseSession
89
64
 
90
- # Obtains information about a session. Returns a CK_SESSION_INFO.
65
+ # Obtains information about a session.
66
+ # @return [CK_SESSION_INFO]
91
67
  def C_GetSessionInfo()
92
68
  @pk.C_GetSessionInfo(@sess)
93
69
  end
@@ -96,35 +72,43 @@ module PKCS11
96
72
  # Initializes a search for token and session objects that match a
97
73
  # template.
98
74
  #
99
- # find_template:: points to a search template that
75
+ # See {Session#find_objects} for convenience.
76
+ # @param [Hash] find_template points to a search template that
100
77
  # 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
-
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]
104
81
  def C_FindObjectsInit(find_template={})
105
- @pk.C_FindObjectsInit(@sess, Session.hash_to_attributes(find_template))
82
+ @pk.C_FindObjectsInit(@sess, to_attributes(find_template))
83
+ self
106
84
  end
107
85
 
108
86
  # Continues a search for token and session objects that match a template,
109
87
  # obtaining additional object handles.
110
88
  #
111
- # Returns an array of Object instances.
89
+ # See {Session#find_objects} for convenience
90
+ # @return [Array<PKCS11::Object>] Returns an array of Object instances.
112
91
  def C_FindObjects(max_count)
113
92
  objs = @pk.C_FindObjects(@sess, max_count)
114
93
  objs.map{|obj| Object.new @pk, @sess, obj }
115
94
  end
116
95
 
117
96
  # Terminates a search for token and session objects.
97
+ #
98
+ # See {Session#find_objects} for convenience
99
+ # @return [PKCS11::Session]
118
100
  def C_FindObjectsFinal
119
101
  @pk.C_FindObjectsFinal(@sess)
102
+ self
120
103
  end
121
104
 
122
- # Convenience method for the C_FindObjectsInit, C_FindObjects, C_FindObjectsFinal cycle.
105
+ # Convenience method for the {Session#C_FindObjectsInit}, {Session#C_FindObjects}, {Session#C_FindObjectsFinal} cycle.
123
106
  #
124
107
  # * If called with block, it iterates over all found objects.
125
108
  # * If called without block, it returns with an array of all found Object instances.
109
+ # @return [Array<PKCS11::Object>]
126
110
  #
127
- # Example (prints subject of all certificates stored in the token):
111
+ # @example prints subject of all certificates stored in the token:
128
112
  # session.find_objects(:CLASS => PKCS11::CKO_CERTIFICATE) do |obj|
129
113
  # p OpenSSL::X509::Name.new(obj[:SUBJECT])
130
114
  # end
@@ -148,39 +132,61 @@ module PKCS11
148
132
  end
149
133
 
150
134
 
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
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
153
138
  # CKA_LOCAL attribute set to false. If that key object is a secret or private key
154
139
  # then the new key will have the CKA_ALWAYS_SENSITIVE attribute set to
155
140
  # false, and the CKA_NEVER_EXTRACTABLE attribute set to false.
156
141
  #
157
142
  # Only session objects can be created during a read-only session. Only public objects can
158
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')
159
152
  def C_CreateObject(template={})
160
- handle = @pk.C_CreateObject(@sess, Session.hash_to_attributes(template))
153
+ handle = @pk.C_CreateObject(@sess, to_attributes(template))
161
154
  Object.new @pk, @sess, handle
162
155
  end
163
156
  alias create_object C_CreateObject
164
157
 
165
- # Initializes the normal users PIN. This standard
158
+ # Initializes the normal user's PIN. This standard
166
159
  # allows PIN values to contain any valid UTF8 character, but the token may impose subset
167
160
  # restrictions.
161
+ #
162
+ # @param [String] pin
163
+ # @return [PKCS11::Session]
168
164
  def C_InitPIN(pin)
169
165
  @pk.C_InitPIN(@sess, pin)
166
+ self
170
167
  end
171
168
  alias init_pin C_InitPIN
172
169
 
173
170
  # Modifies the PIN of the user that is currently logged in, or the CKU_USER
174
171
  # PIN if the session is not logged in.
172
+ #
173
+ # @param [String] old_pin
174
+ # @param [String] new_pin
175
+ # @return [PKCS11::Session]
175
176
  def C_SetPIN(old_pin, new_pin)
176
177
  @pk.C_SetPIN(@sess, old_pin, new_pin)
178
+ self
177
179
  end
178
180
  alias set_pin C_SetPIN
179
181
 
180
182
  class Cipher
183
+ # @private
181
184
  def initialize(update_block) # :nodoc:
182
185
  @update_block = update_block
183
186
  end
187
+ # Process a data part with the encryption operation.
188
+ # @param [String] data data to be processed
189
+ # @return [String] output data
184
190
  def update(data)
185
191
  @update_block.call(data)
186
192
  end
@@ -188,11 +194,16 @@ module PKCS11
188
194
  end
189
195
 
190
196
  class DigestCipher < Cipher
197
+ # @private
191
198
  def initialize(update_block, digest_key_block) # :nodoc:
192
199
  super(update_block)
193
200
  @digest_key_block = digest_key_block
194
201
  end
195
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
196
207
  def digest_key(key)
197
208
  @digest_key_block.call(key)
198
209
  end
@@ -228,53 +239,81 @@ module PKCS11
228
239
 
229
240
  # Initializes an encryption operation.
230
241
  #
231
- # mechanism:: the encryption mechanism, Hash, String or Integer
232
- # key:: the object handle of the encryption key.
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]
233
245
  #
234
- # See Session#encrypt for convenience.
246
+ # See {Session#encrypt} for convenience
235
247
  #
236
248
  # The CKA_ENCRYPT attribute of the encryption key, which indicates whether the key
237
249
  # supports encryption, must be true.
238
250
  #
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
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
243
255
  # final piece of ciphertext. To process additional data (in single or multiple parts), the
244
- # application must call C_EncryptInit again.
256
+ # application must call {Session#C_EncryptInit} again.
245
257
  def C_EncryptInit(mechanism, key)
246
- @pk.C_EncryptInit(@sess, Session.hash_to_mechanism(mechanism), key)
258
+ @pk.C_EncryptInit(@sess, to_mechanism(mechanism), key)
259
+ self
247
260
  end
248
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]
249
267
  def C_Encrypt(data, out_size=nil)
250
268
  @pk.C_Encrypt(@sess, data, out_size)
251
269
  end
252
270
  # Continues a multiple-part encryption operation, processing another
253
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]
254
277
  def C_EncryptUpdate(data, out_size=nil)
255
278
  @pk.C_EncryptUpdate(@sess, data, out_size)
256
279
  end
257
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]
258
286
  def C_EncryptFinal(out_size=nil)
259
287
  @pk.C_EncryptFinal(@sess, out_size)
260
288
  end
261
289
 
262
- # Convenience method for the C_EncryptInit, C_EncryptUpdate, C_EncryptFinal call flow.
290
+ # Convenience method for the {Session#C_EncryptInit}, {Session#C_EncryptUpdate}, {Session#C_EncryptFinal} call flow.
263
291
  #
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)
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})
266
294
  # 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.
295
+ # {Cipher#update} calls within the block, each giving the encryption result of this part as String.
268
296
  #
269
- # Returns the final part of the encryption operation.
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.
270
302
  #
271
- # Example:
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
272
308
  # iv = "12345678"
273
309
  # cryptogram = ''
274
310
  # cryptogram << session.encrypt( {:DES_CBC_PAD=>iv}, key ) do |cipher|
275
311
  # cryptogram << cipher.update("block 1")
276
312
  # cryptogram << cipher.update("block 2")
277
313
  # end
314
+ #
315
+ # @example Calculating a key check value to a secret key
316
+ # key_kcv = session.encrypt( :DES3_ECB, key, "\0"*8)
278
317
  def encrypt(mechanism, key, data=nil, &block)
279
318
  common_crypt(:C_EncryptInit, :C_EncryptUpdate, :C_EncryptFinal, :C_Encrypt,
280
319
  mechanism, key, data, &block)
@@ -282,27 +321,50 @@ module PKCS11
282
321
 
283
322
  # Initializes a decryption operation.
284
323
  #
285
- # See Session#decrypt for convenience.
324
+ # See {Session#decrypt} for convenience and {Session#C_EncryptInit} for description.
286
325
  def C_DecryptInit(mechanism, key)
287
- @pk.C_DecryptInit(@sess, Session.hash_to_mechanism(mechanism), key)
326
+ @pk.C_DecryptInit(@sess, to_mechanism(mechanism), key)
288
327
  end
289
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]
290
334
  def C_Decrypt(data, out_size=nil)
291
335
  @pk.C_Decrypt(@sess, data, out_size)
292
336
  end
293
337
  # Continues a multiple-part decryption operation, processing another
294
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]
295
344
  def C_DecryptUpdate(data, out_size=nil)
296
345
  @pk.C_DecryptUpdate(@sess, data, out_size)
297
346
  end
298
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]
299
353
  def C_DecryptFinal(out_size=nil)
300
354
  @pk.C_DecryptFinal(@sess, out_size)
301
355
  end
302
356
 
303
- # Convenience method for the C_DecryptInit, C_DecryptUpdate, C_DecryptFinal call flow.
357
+ # Convenience method for the {Session#C_DecryptInit}, {Session#C_DecryptUpdate}, {Session#C_DecryptFinal} call flow.
304
358
  #
305
- # See Session#encrypt
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)
306
368
  def decrypt(mechanism, key, data=nil, &block)
307
369
  common_crypt(:C_DecryptInit, :C_DecryptUpdate, :C_DecryptFinal, :C_Decrypt,
308
370
  mechanism, key, data, &block)
@@ -310,42 +372,67 @@ module PKCS11
310
372
 
311
373
  # Initializes a message-digesting operation.
312
374
  #
313
- # See Session#digest for convenience.
375
+ # See {Session#digest} for convenience.
376
+ # @return [PKCS11::Session]
314
377
  def C_DigestInit(mechanism)
315
- @pk.C_DigestInit(@sess, Session.hash_to_mechanism(mechanism))
378
+ @pk.C_DigestInit(@sess, to_mechanism(mechanism))
379
+ self
316
380
  end
317
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]
318
387
  def C_Digest(data, out_size=nil)
319
388
  @pk.C_Digest(@sess, data, out_size)
320
389
  end
321
390
  # Continues a multiple-part message-digesting operation, processing
322
391
  # another data part.
392
+ #
393
+ # See {Session#digest} for convenience.
394
+ # @return [PKCS11::Session]
323
395
  def C_DigestUpdate(data)
324
396
  @pk.C_DigestUpdate(@sess, data)
397
+ self
325
398
  end
326
399
  # Continues a multiple-part message-digesting operation by digesting the
327
400
  # value of a secret key.
328
401
  #
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
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
331
406
  # order.
407
+ # @return [PKCS11::Session]
332
408
  def C_DigestKey(key)
333
409
  @pk.C_DigestKey(@sess, key)
410
+ self
334
411
  end
335
412
  # Finishes a multiple-part message-digesting operation, returning the
336
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]
337
419
  def C_DigestFinal(out_size=nil)
338
420
  @pk.C_DigestFinal(@sess, out_size)
339
421
  end
340
422
 
341
- # Convenience method for the C_DigestInit, C_DigestUpdate, C_DigestKey,
342
- # C_DigestFinal call flow.
423
+ # Convenience method for the {Session#C_DigestInit}, {Session#C_DigestUpdate}, {Session#C_DigestKey},
424
+ # {Session#C_DigestFinal} call flow.
343
425
  #
344
- # Example:
426
+ # @example
345
427
  # digest_string = session.digest( :SHA_1 ) do |cipher|
346
428
  # cipher.update("key prefix")
347
429
  # cipher.digest_key(some_key)
348
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
349
436
  def digest(mechanism, data=nil, &block)
350
437
  C_DigestInit(mechanism)
351
438
  if block_given?
@@ -364,27 +451,46 @@ module PKCS11
364
451
  # Initializes a signature operation, where the signature is an appendix to the
365
452
  # data.
366
453
  #
367
- # See Session#sign for convenience.
454
+ # See {Session#sign} for convenience.
455
+ # @return [PKCS11::Session]
368
456
  def C_SignInit(mechanism, key)
369
- @pk.C_SignInit(@sess, Session.hash_to_mechanism(mechanism), key)
457
+ @pk.C_SignInit(@sess, to_mechanism(mechanism), key)
458
+ self
370
459
  end
371
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
372
464
  def C_Sign(data, out_size=nil)
373
465
  @pk.C_Sign(@sess, data, out_size)
374
466
  end
375
467
  # Continues a multiple-part signature operation, processing another data
376
468
  # part.
469
+ #
470
+ # See {Session#sign} for convenience.
471
+ # @return [PKCS11::Session]
377
472
  def C_SignUpdate(data)
378
473
  @pk.C_SignUpdate(@sess, data)
474
+ self
379
475
  end
380
476
  # Finishes a multiple-part signature operation, returning the signature.
477
+ #
478
+ # See {Session#sign} for convenience.
479
+ # @return [String] message signature
381
480
  def C_SignFinal(out_size=nil)
382
481
  @pk.C_SignFinal(@sess, out_size)
383
482
  end
384
483
 
385
- # Convenience method for the C_SignInit, C_SignUpdate, C_SignFinal call flow.
484
+ # Convenience method for the {Session#C_SignInit}, {Session#C_SignUpdate}, {Session#C_SignFinal} call flow.
386
485
  #
387
- # See Session#encrypt
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")
388
494
  def sign(mechanism, key, data=nil, &block)
389
495
  common_crypt(:C_SignInit, :C_SignUpdate, :C_SignFinal, :C_Sign,
390
496
  mechanism, key, data, &block)
@@ -394,30 +500,43 @@ module PKCS11
394
500
  # Initializes a verification operation, where the signature is an appendix to
395
501
  # the data.
396
502
  #
397
- # See ession#verify for convenience.
503
+ # See {Session#verify} for convenience.
398
504
  def C_VerifyInit(mechanism, key)
399
- @pk.C_VerifyInit(@sess, Session.hash_to_mechanism(mechanism), key)
505
+ @pk.C_VerifyInit(@sess, to_mechanism(mechanism), key)
400
506
  end
401
507
  # Verifies a signature in a single-part operation, where the signature is an
402
508
  # appendix to the data.
509
+ #
510
+ # See {Session#verify} for convenience.
403
511
  def C_Verify(data, out_size=nil)
404
512
  @pk.C_Verify(@sess, data, out_size)
405
513
  end
406
514
  # Continues a multiple-part verification operation, processing another
407
515
  # data part.
516
+ #
517
+ # See {Session#verify} for convenience.
408
518
  def C_VerifyUpdate(data)
409
519
  @pk.C_VerifyUpdate(@sess, data)
410
520
  end
411
521
  # Finishes a multiple-part verification operation, checking the signature.
412
522
  #
413
- # Returns <tt>true</tt> for valid signature.
523
+ # See {Session#verify} for convenience.
524
+ # @return [Boolean] <tt>true</tt> for valid signature.
414
525
  def C_VerifyFinal(out_size=nil)
415
526
  @pk.C_VerifyFinal(@sess, out_size)
416
527
  end
417
528
 
418
- # Convenience method for the C_VerifyInit, C_VerifyUpdate, C_VerifyFinal call flow.
529
+ # Convenience method for the {Session#C_VerifyInit}, {Session#C_VerifyUpdate}, {Session#C_VerifyFinal} call flow.
419
530
  #
420
- # See Session#encrypt
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)
421
540
  def verify(mechanism, key, signature, data=nil, &block)
422
541
  common_verify(:C_VerifyInit, :C_VerifyUpdate, :C_VerifyFinal, :C_Verify,
423
542
  mechanism, key, signature, data, &block)
@@ -425,16 +544,27 @@ module PKCS11
425
544
 
426
545
  # Initializes a signature operation, where the data can be recovered
427
546
  # from the signature
547
+ #
548
+ # See {Session#sign_recover} for convenience.
428
549
  def C_SignRecoverInit(mechanism, key)
429
- @pk.C_SignRecoverInit(@sess, Session.hash_to_mechanism(mechanism), key)
550
+ @pk.C_SignRecoverInit(@sess, to_mechanism(mechanism), key)
551
+ self
430
552
  end
431
553
  # Signs data in a single operation, where the data can be recovered from
432
554
  # the signature.
555
+ #
556
+ # See {Session#sign_recover} for convenience.
433
557
  def C_SignRecover(data, out_size=nil)
434
558
  @pk.C_SignRecover(@sess, data, out_size)
435
559
  end
436
560
 
437
- # Convenience method for the C_SignRecoverInit, C_SignRecover call flow.
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
438
568
  def sign_recover(mechanism, key, data)
439
569
  C_SignRecoverInit(mechanism, key)
440
570
  C_SignRecover(data)
@@ -444,17 +574,24 @@ module PKCS11
444
574
  # Initializes a signature verification operation, where the data can be recovered
445
575
  # from the signature
446
576
  #
447
- # See Session#verify_recover for convenience.
577
+ # See {Session#verify_recover} for convenience.
448
578
  def C_VerifyRecoverInit(mechanism, key)
449
- @pk.C_VerifyRecoverInit(@sess, Session.hash_to_mechanism(mechanism), key)
579
+ @pk.C_VerifyRecoverInit(@sess, to_mechanism(mechanism), key)
450
580
  end
451
581
  # Verifies a signature in a single-part operation, where the data is
452
582
  # recovered from the signature.
583
+ #
584
+ # See {Session#verify_recover} for convenience.
453
585
  def C_VerifyRecover(signature, out_size=nil)
454
586
  @pk.C_VerifyRecover(@sess, signature, out_size=nil)
455
587
  end
456
588
 
457
- # Convenience method for the C_VerifyRecoverInit, C_VerifyRecover call flow.
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
458
595
  def verify_recover(mechanism, key, signature)
459
596
  C_VerifyRecoverInit(mechanism, key)
460
597
  C_VerifyRecover(signature)
@@ -464,9 +601,9 @@ module PKCS11
464
601
  # processing another data part.
465
602
  #
466
603
  # 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.
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.
470
607
  def C_DigestEncryptUpdate(data, out_size=nil)
471
608
  @pk.C_DigestEncryptUpdate(@sess, data, out_size)
472
609
  end
@@ -475,9 +612,9 @@ module PKCS11
475
612
  # operation, processing another data part.
476
613
  #
477
614
  # 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.
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.
481
618
  def C_DecryptDigestUpdate(data, out_size=nil)
482
619
  @pk.C_DecryptDigestUpdate(@sess, data, out_size)
483
620
  end
@@ -486,9 +623,9 @@ module PKCS11
486
623
  # operation, processing another data part.
487
624
  #
488
625
  # 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.
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.
492
629
  def C_SignEncryptUpdate(data, out_size=nil)
493
630
  @pk.C_SignEncryptUpdate(@sess, data, out_size)
494
631
  end
@@ -497,9 +634,9 @@ module PKCS11
497
634
  # verification operation, processing another data part.
498
635
  #
499
636
  # 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.
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.
503
640
  def C_DecryptVerifyUpdate(data, out_size=nil)
504
641
  @pk.C_DecryptVerifyUpdate(@sess, data, out_size)
505
642
  end
@@ -507,62 +644,122 @@ module PKCS11
507
644
  # Generates a secret key Object or set of domain parameters, creating a new
508
645
  # Object.
509
646
  #
510
- # Returns key Object of the new created key.
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})
511
653
  def C_GenerateKey(mechanism, template={})
512
- obj = @pk.C_GenerateKey(@sess, Session.hash_to_mechanism(mechanism), Session.hash_to_attributes(template))
654
+ obj = @pk.C_GenerateKey(@sess, to_mechanism(mechanism), to_attributes(template))
513
655
  Object.new @pk, @sess, obj
514
656
  end
515
657
  alias generate_key C_GenerateKey
516
658
 
517
659
  # Generates a public/private key pair, creating new key Object instances.
518
660
  #
519
- # Returns an two-items array of new created public and private key Object.
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})
520
669
  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))
670
+ objs = @pk.C_GenerateKeyPair(@sess, to_mechanism(mechanism), to_attributes(pubkey_template), to_attributes(privkey_template))
522
671
  objs.map{|obj| Object.new @pk, @sess, obj }
523
672
  end
524
673
  alias generate_key_pair C_GenerateKeyPair
525
674
 
526
675
  # Wraps (i.e., encrypts) a private or secret key.
527
676
  #
528
- # Returns the encrypted binary data.
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)
529
686
  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)
687
+ @pk.C_WrapKey(@sess, to_mechanism(mechanism), wrapping_key, wrapped_key, out_size)
531
688
  end
532
689
  alias wrap_key C_WrapKey
533
690
 
534
691
  # Unwraps (i.e. decrypts) a wrapped key, creating a new private key or
535
692
  # secret key object.
536
693
  #
537
- # Returns key Object of the new created key.
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)
538
702
  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))
703
+ obj = @pk.C_UnwrapKey(@sess, to_mechanism(mechanism), wrapping_key, wrapped_key, to_attributes(template))
540
704
  Object.new @pk, @sess, obj
541
705
  end
542
706
  alias unwrap_key C_UnwrapKey
543
707
 
544
708
  # Derives a key from a base key, creating a new key object.
545
709
  #
546
- # Returns key Object of the new created key.
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 )
547
718
  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))
719
+ obj = @pk.C_DeriveKey(@sess, to_mechanism(mechanism), base_key, to_attributes(template))
549
720
  Object.new @pk, @sess, obj
550
721
  end
551
722
  alias derive_key C_DeriveKey
552
723
 
553
- # Mixes additional seed material into the tokens random number
724
+ # Mixes additional seed material into the token's random number
554
725
  # generator.
726
+ # @param [String] entropy data
727
+ # @return [PKCS11::Session]
555
728
  def C_SeedRandom(data)
556
729
  @pk.C_SeedRandom(@sess, data)
730
+ self
557
731
  end
558
732
  alias seed_random C_SeedRandom
559
733
 
560
734
  # Generates random or pseudo-random data.
561
735
  #
562
- # Returns random or pseudo-random binary data of <tt>out_size</tt> bytes.
736
+ # @param [Integer] out_size
737
+ # @return [String] random or pseudo-random binary data of <tt>out_size</tt> bytes.
563
738
  def C_GenerateRandom(out_size)
564
739
  @pk.C_GenerateRandom(@sess, out_size)
565
740
  end
566
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
567
764
  end
568
765
  end