pkcs11 0.2.4-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/.autotest +23 -0
- data/.gemtest +0 -0
- data/.yardopts +1 -0
- data/History.txt +57 -0
- data/MIT-LICENSE +22 -0
- data/Manifest.txt +57 -0
- data/README.rdoc +205 -0
- data/Rakefile +111 -0
- data/ext/extconf.rb +7 -0
- data/ext/generate_constants.rb +57 -0
- data/ext/generate_structs.rb +206 -0
- data/ext/generate_thread_funcs.rb +72 -0
- data/ext/include/cryptoki.h +66 -0
- data/ext/include/ct-kip.h +50 -0
- data/ext/include/otp-pkcs11.h +125 -0
- data/ext/include/pkcs-11v2-20a3.h +124 -0
- data/ext/include/pkcs11.h +299 -0
- data/ext/include/pkcs11f.h +912 -0
- data/ext/include/pkcs11t.h +1885 -0
- data/ext/pk11.c +1675 -0
- data/ext/pk11.h +81 -0
- data/ext/pk11_const.c +205 -0
- data/ext/pk11_const_def.inc +452 -0
- data/ext/pk11_const_macros.h +38 -0
- data/ext/pk11_struct.doc +792 -0
- data/ext/pk11_struct_def.inc +302 -0
- data/ext/pk11_struct_impl.inc +302 -0
- data/ext/pk11_struct_macros.h +435 -0
- data/ext/pk11_thread_funcs.c +411 -0
- data/ext/pk11_thread_funcs.h +482 -0
- data/ext/pk11_version.h +6 -0
- data/lib/2.0/pkcs11_ext.so +0 -0
- data/lib/pkcs11.rb +9 -0
- data/lib/pkcs11/extensions.rb +68 -0
- data/lib/pkcs11/helper.rb +144 -0
- data/lib/pkcs11/library.rb +140 -0
- data/lib/pkcs11/object.rb +171 -0
- data/lib/pkcs11/session.rb +765 -0
- data/lib/pkcs11/slot.rb +102 -0
- data/pkcs11_protect_server/Manifest.txt +14 -0
- data/pkcs11_protect_server/README_PROTECT_SERVER.rdoc +89 -0
- data/test/fixtures/softokn/cert8.db +0 -0
- data/test/fixtures/softokn/key3.db +0 -0
- data/test/fixtures/softokn/secmod.db +0 -0
- data/test/helper.rb +58 -0
- data/test/test_pkcs11.rb +71 -0
- data/test/test_pkcs11_crypt.rb +220 -0
- data/test/test_pkcs11_object.rb +122 -0
- data/test/test_pkcs11_session.rb +123 -0
- data/test/test_pkcs11_slot.rb +78 -0
- data/test/test_pkcs11_structs.rb +166 -0
- data/test/test_pkcs11_thread.rb +44 -0
- metadata +213 -0
- 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
|