pkcs11 0.2.4-x64-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|