pkcs11 0.1.0-x86-mswin32 → 0.2.0-x86-mswin32
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/.yardopts +2 -0
- data/History.txt +23 -0
- data/Manifest.txt +6 -0
- data/README.rdoc +28 -15
- data/Rakefile +51 -2
- data/ext/extconf.rb +1 -0
- data/ext/generate_structs.rb +157 -0
- data/ext/generate_thread_funcs.rb +72 -0
- data/ext/pk11.c +482 -252
- data/ext/pk11.h +4 -1
- data/ext/pk11_const.c +25 -476
- data/ext/pk11_const_def.inc +452 -0
- data/ext/pk11_struct_def.inc +304 -0
- data/ext/pk11_struct_impl.inc +304 -0
- data/ext/pk11_thread_funcs.c +411 -0
- data/ext/pk11_thread_funcs.h +482 -0
- data/lib/1.8/pkcs11_ext.so +0 -0
- data/lib/1.9/pkcs11_ext.so +0 -0
- data/lib/pkcs11.rb +5 -8
- data/lib/pkcs11/extensions.rb +17 -109
- data/lib/pkcs11/helper.rb +151 -0
- data/lib/pkcs11/library.rb +44 -13
- data/lib/pkcs11/object.rb +73 -17
- data/lib/pkcs11/session.rb +318 -121
- data/lib/pkcs11/slot.rb +30 -9
- data/test/helper.rb +13 -6
- data/test/test_pkcs11.rb +13 -2
- data/test/test_pkcs11_crypt.rb +38 -3
- data/test/test_pkcs11_object.rb +18 -4
- data/test/test_pkcs11_session.rb +28 -2
- data/test/test_pkcs11_slot.rb +9 -6
- data/test/test_pkcs11_structs.rb +134 -0
- data/test/test_pkcs11_thread.rb +45 -0
- metadata +40 -7
data/lib/pkcs11/session.rb
CHANGED
@@ -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 token
|
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
|
-
|
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
|
-
|
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
|
61
|
-
# 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
|
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,
|
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 application
|
77
|
-
# sessions will enter either the
|
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.
|
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
|
-
#
|
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
|
-
#
|
102
|
-
#
|
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,
|
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
|
-
#
|
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
|
-
#
|
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.
|
152
|
-
#
|
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,
|
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 user
|
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
|
-
#
|
232
|
-
#
|
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,
|
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
|
-
#
|
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
|
-
#
|
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,
|
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
|
-
#
|
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,
|
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
|
-
#
|
330
|
-
#
|
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
|
-
#
|
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,
|
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
|
-
#
|
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
|
503
|
+
# See {Session#verify} for convenience.
|
398
504
|
def C_VerifyInit(mechanism, key)
|
399
|
-
@pk.C_VerifyInit(@sess,
|
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
|
-
#
|
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
|
-
#
|
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,
|
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,
|
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
|
-
#
|
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,
|
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
|
-
#
|
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,
|
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
|
-
#
|
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,
|
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
|
-
#
|
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,
|
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
|
-
#
|
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,
|
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 token
|
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
|
-
#
|
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
|