rbthemis 0.10.0 → 0.11.0
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.
- checksums.yaml +4 -4
- data/lib/rbthemis.rb +705 -0
- data/lib/rubythemis.rb +89 -25
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8bb951f9da0bc027471c72aea7cd56eabc7991b1
|
|
4
|
+
data.tar.gz: 2f5d37f48f67ced53c083b259e4f0af4cb5253f9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bf76747c0f1fc78e8d4f2a599877008586daaf24ee9bb57d86cfb989b524db3b7917bd9cb82b00c2366519c4499c0338eb112b4a33148bfa57bbf2a3b413ef37
|
|
7
|
+
data.tar.gz: 75686146b8c9f4801de42033fb1be44d1dea86618286f9ac5b93228f74cf66becb45a734acf13f25a8b0f7b7fd0b440405c59f7c366685bf72d08b13a4791ef2
|
data/lib/rbthemis.rb
ADDED
|
@@ -0,0 +1,705 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2015 Cossack Labs Limited
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
require 'ffi'
|
|
18
|
+
|
|
19
|
+
module ThemisCommon
|
|
20
|
+
def string_to_pointer_size(string)
|
|
21
|
+
string_buf = FFI::MemoryPointer.new(
|
|
22
|
+
:char, string.force_encoding('BINARY').size)
|
|
23
|
+
string_buf.put_bytes(0, string.force_encoding('BINARY'),
|
|
24
|
+
0, string.force_encoding('BINARY').size)
|
|
25
|
+
[string_buf, string.force_encoding('BINARY').size]
|
|
26
|
+
end
|
|
27
|
+
module_function :string_to_pointer_size
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
module ThemisImport
|
|
31
|
+
extend FFI::Library
|
|
32
|
+
ffi_lib 'themis'
|
|
33
|
+
|
|
34
|
+
callback :get_pub_key_by_id_type,
|
|
35
|
+
[:pointer, :int, :pointer, :int, :pointer], :int
|
|
36
|
+
callback :send_callback_type, [:pointer, :int, :uint], :int
|
|
37
|
+
callback :receive_callback_type, [:pointer, :int, :uint], :int
|
|
38
|
+
|
|
39
|
+
class CallbacksStruct < FFI::Struct
|
|
40
|
+
layout :send_data, :send_callback_type,
|
|
41
|
+
:receive_data, :receive_callback_type,
|
|
42
|
+
:state_changed, :pointer,
|
|
43
|
+
:get_pub_key_for_id, :get_pub_key_by_id_type,
|
|
44
|
+
:user_data, :pointer
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
attach_function :secure_session_create,
|
|
48
|
+
[:pointer, :uint, :pointer, :uint, :pointer], :pointer
|
|
49
|
+
attach_function :secure_session_destroy, [:pointer], :int
|
|
50
|
+
attach_function :secure_session_generate_connect_request,
|
|
51
|
+
[:pointer, :pointer, :pointer], :int
|
|
52
|
+
|
|
53
|
+
attach_function :secure_session_wrap,
|
|
54
|
+
[:pointer, :pointer, :int, :pointer, :pointer], :int
|
|
55
|
+
attach_function :secure_session_unwrap,
|
|
56
|
+
[:pointer, :pointer, :int, :pointer, :pointer], :int
|
|
57
|
+
attach_function :secure_session_is_established, [:pointer], :bool
|
|
58
|
+
|
|
59
|
+
attach_function :themis_secure_message_encrypt,
|
|
60
|
+
[:pointer, :int, :pointer, :int, :pointer,
|
|
61
|
+
:int, :pointer, :pointer], :int
|
|
62
|
+
attach_function :themis_secure_message_decrypt,
|
|
63
|
+
[:pointer, :int, :pointer, :int, :pointer,
|
|
64
|
+
:int, :pointer, :pointer], :int
|
|
65
|
+
attach_function :themis_secure_message_sign,
|
|
66
|
+
[:pointer, :int, :pointer, :int, :pointer,
|
|
67
|
+
:pointer], :int
|
|
68
|
+
attach_function :themis_secure_message_verify,
|
|
69
|
+
[:pointer, :int, :pointer, :int, :pointer,
|
|
70
|
+
:pointer], :int
|
|
71
|
+
|
|
72
|
+
attach_function :themis_gen_rsa_key_pair,
|
|
73
|
+
[:pointer, :pointer, :pointer, :pointer], :int
|
|
74
|
+
attach_function :themis_gen_ec_key_pair,
|
|
75
|
+
[:pointer, :pointer, :pointer, :pointer], :int
|
|
76
|
+
|
|
77
|
+
THEMIS_KEY_INVALID = 0
|
|
78
|
+
THEMIS_KEY_RSA_PRIVATE = 1
|
|
79
|
+
THEMIS_KEY_RSA_PUBLIC = 2
|
|
80
|
+
THEMIS_KEY_EC_PRIVATE = 3
|
|
81
|
+
THEMIS_KEY_EC_PUBLIC = 4
|
|
82
|
+
|
|
83
|
+
attach_function :themis_is_valid_asym_key, [:pointer, :int], :int
|
|
84
|
+
attach_function :themis_get_asym_key_kind, [:pointer, :int], :int
|
|
85
|
+
|
|
86
|
+
attach_function :themis_secure_cell_encrypt_seal,
|
|
87
|
+
[:pointer, :int, :pointer, :int, :pointer, :int,
|
|
88
|
+
:pointer, :pointer], :int
|
|
89
|
+
attach_function :themis_secure_cell_decrypt_seal,
|
|
90
|
+
[:pointer, :int, :pointer, :int, :pointer, :int,
|
|
91
|
+
:pointer, :pointer], :int
|
|
92
|
+
|
|
93
|
+
attach_function :themis_secure_cell_encrypt_token_protect,
|
|
94
|
+
[:pointer, :int, :pointer, :int, :pointer, :int,
|
|
95
|
+
:pointer, :pointer, :pointer, :pointer], :int
|
|
96
|
+
attach_function :themis_secure_cell_decrypt_token_protect,
|
|
97
|
+
[:pointer, :int, :pointer, :int, :pointer, :int,
|
|
98
|
+
:pointer, :int, :pointer, :pointer], :int
|
|
99
|
+
|
|
100
|
+
attach_function :themis_secure_cell_encrypt_context_imprint,
|
|
101
|
+
[:pointer, :int, :pointer, :int, :pointer, :int,
|
|
102
|
+
:pointer, :pointer], :int
|
|
103
|
+
attach_function :themis_secure_cell_decrypt_context_imprint,
|
|
104
|
+
[:pointer, :int, :pointer, :int, :pointer, :int,
|
|
105
|
+
:pointer, :pointer], :int
|
|
106
|
+
|
|
107
|
+
begin
|
|
108
|
+
attach_function :secure_comparator_create, [], :pointer
|
|
109
|
+
attach_function :secure_comparator_destroy, [:pointer], :int
|
|
110
|
+
attach_function :secure_comparator_append_secret,
|
|
111
|
+
[:pointer, :pointer, :int], :int
|
|
112
|
+
attach_function :secure_comparator_begin_compare,
|
|
113
|
+
[:pointer, :pointer, :pointer], :int
|
|
114
|
+
attach_function :secure_comparator_proceed_compare,
|
|
115
|
+
[:pointer, :pointer, :int, :pointer, :pointer], :int
|
|
116
|
+
attach_function :secure_comparator_get_result, [:pointer], :int
|
|
117
|
+
rescue FFI::NotFoundError
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
module Themis
|
|
122
|
+
extend ThemisCommon
|
|
123
|
+
extend ThemisImport
|
|
124
|
+
|
|
125
|
+
extend Gem::Deprecate
|
|
126
|
+
|
|
127
|
+
BUFFER_TOO_SMALL = 14
|
|
128
|
+
SUCCESS = 0
|
|
129
|
+
FAIL = 11
|
|
130
|
+
SEND_AS_IS = 1
|
|
131
|
+
|
|
132
|
+
ThemisError = Class.new(StandardError)
|
|
133
|
+
|
|
134
|
+
class Callbacks
|
|
135
|
+
def get_pub_key_by_id(id)
|
|
136
|
+
raise ThemisError, 'Callback is not implemented: get_pub_key_by_id'
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def send(message)
|
|
140
|
+
raise ThemisError, 'Callback is not implemented: send'
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def receive
|
|
144
|
+
raise ThemisError, 'Callback is not implemented: receive'
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
class SKeyPairGen
|
|
149
|
+
include ThemisCommon
|
|
150
|
+
include ThemisImport
|
|
151
|
+
|
|
152
|
+
def ec
|
|
153
|
+
private_key_length = FFI::MemoryPointer.new(:uint)
|
|
154
|
+
public_key_length = FFI::MemoryPointer.new(:uint)
|
|
155
|
+
|
|
156
|
+
res = themis_gen_ec_key_pair(
|
|
157
|
+
nil, private_key_length, nil, public_key_length)
|
|
158
|
+
if res != BUFFER_TOO_SMALL
|
|
159
|
+
raise ThemisError, "Themis failed generating EC KeyPair: #{res}"
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
private_key = FFI::MemoryPointer.new(:char, private_key_length.read_uint)
|
|
163
|
+
public_key = FFI::MemoryPointer.new(:char, public_key_length.read_uint)
|
|
164
|
+
|
|
165
|
+
res = themis_gen_ec_key_pair(
|
|
166
|
+
private_key, private_key_length, public_key, public_key_length)
|
|
167
|
+
if res != SUCCESS
|
|
168
|
+
raise ThemisError, "Themis failed generating EC KeyPair: #{res}"
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
[private_key.get_bytes(0, private_key_length.read_uint),
|
|
172
|
+
public_key.get_bytes(0, public_key_length.read_uint)]
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def rsa
|
|
176
|
+
private_key_length = FFI::MemoryPointer.new(:uint)
|
|
177
|
+
public_key_length = FFI::MemoryPointer.new(:uint)
|
|
178
|
+
|
|
179
|
+
res = themis_gen_rsa_key_pair(
|
|
180
|
+
nil, private_key_length, nil, public_key_length)
|
|
181
|
+
if res != BUFFER_TOO_SMALL
|
|
182
|
+
raise ThemisError, "Themis failed generating RSA KeyPair: #{res}"
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
private_key = FFI::MemoryPointer.new(:char, private_key_length.read_uint)
|
|
186
|
+
public_key = FFI::MemoryPointer.new(:char, public_key_length.read_uint)
|
|
187
|
+
|
|
188
|
+
res = themis_gen_rsa_key_pair(
|
|
189
|
+
private_key, private_key_length, public_key, public_key_length)
|
|
190
|
+
if res != SUCCESS
|
|
191
|
+
raise ThemisError, "Themis failed generating RSA KeyPair: #{res}"
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
[private_key.get_bytes(0, private_key_length.read_uint),
|
|
195
|
+
public_key.get_bytes(0, public_key_length.read_uint)]
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def Themis.valid_key(key)
|
|
200
|
+
if key.nil? || key.empty?
|
|
201
|
+
return false
|
|
202
|
+
end
|
|
203
|
+
key_, len_ = string_to_pointer_size(key)
|
|
204
|
+
return themis_is_valid_asym_key(key_, len_) == SUCCESS
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def Themis.private_key(key)
|
|
208
|
+
key_, len_ = string_to_pointer_size(key)
|
|
209
|
+
kind = themis_get_asym_key_kind(key_, len_)
|
|
210
|
+
return kind == ThemisImport::THEMIS_KEY_RSA_PRIVATE \
|
|
211
|
+
|| kind == ThemisImport::THEMIS_KEY_EC_PRIVATE
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def Themis.public_key(key)
|
|
215
|
+
key_, len_ = string_to_pointer_size(key)
|
|
216
|
+
kind = themis_get_asym_key_kind(key_, len_)
|
|
217
|
+
return kind == ThemisImport::THEMIS_KEY_RSA_PUBLIC \
|
|
218
|
+
|| kind == ThemisImport::THEMIS_KEY_EC_PUBLIC
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
class Ssession
|
|
222
|
+
include ThemisCommon
|
|
223
|
+
include ThemisImport
|
|
224
|
+
|
|
225
|
+
extend Gem::Deprecate
|
|
226
|
+
|
|
227
|
+
MAPPING = {}
|
|
228
|
+
|
|
229
|
+
GetPubKeyByIDCallback =
|
|
230
|
+
FFI::Function.new(:int, [:pointer, :int, :pointer, :int, :pointer]) do |id_buf, id_length, pubkey_buf, pubkey_length, obj|
|
|
231
|
+
pub_key = MAPPING[obj.read_uint64].get_pub_key_by_id(
|
|
232
|
+
id_buf.get_bytes(0, id_length))
|
|
233
|
+
return -1 unless pub_key
|
|
234
|
+
pubkey_buf.put_bytes(0, pub_key)
|
|
235
|
+
0
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def initialize(id, private_key, transport)
|
|
239
|
+
id_buf, id_length = string_to_pointer_size(id)
|
|
240
|
+
private_key_buf, private_key_length = string_to_pointer_size(private_key)
|
|
241
|
+
|
|
242
|
+
@callbacks = CallbacksStruct.new
|
|
243
|
+
@callbacks[:get_pub_key_for_id] = GetPubKeyByIDCallback
|
|
244
|
+
|
|
245
|
+
MAPPING[transport.object_id] = transport
|
|
246
|
+
@transport_obj_id = transport.object_id
|
|
247
|
+
|
|
248
|
+
@callbacks[:user_data] = FFI::MemoryPointer.new(:uint64)
|
|
249
|
+
@callbacks[:user_data].write_uint64(@transport_obj_id)
|
|
250
|
+
|
|
251
|
+
@session = secure_session_create(
|
|
252
|
+
id_buf, id_length, private_key_buf, private_key_length, @callbacks)
|
|
253
|
+
|
|
254
|
+
raise ThemisError, 'Secure Session failed creating' unless @session
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def is_established
|
|
258
|
+
established?
|
|
259
|
+
end
|
|
260
|
+
deprecate(:is_established, :established?, 2018, 6)
|
|
261
|
+
|
|
262
|
+
def established?
|
|
263
|
+
secure_session_is_established @session
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def connect_request
|
|
267
|
+
connect_request_length = FFI::MemoryPointer.new(:uint)
|
|
268
|
+
res = secure_session_generate_connect_request(
|
|
269
|
+
@session, nil, connect_request_length)
|
|
270
|
+
if res != BUFFER_TOO_SMALL
|
|
271
|
+
raise(ThemisError,
|
|
272
|
+
"Secure Session failed making connection request: #{res}")
|
|
273
|
+
end
|
|
274
|
+
connect_request = FFI::MemoryPointer.new(
|
|
275
|
+
:char, connect_request_length.read_uint)
|
|
276
|
+
res = secure_session_generate_connect_request(
|
|
277
|
+
@session, connect_request, connect_request_length)
|
|
278
|
+
if res != SUCCESS
|
|
279
|
+
raise(ThemisError,
|
|
280
|
+
"Secure Session failed making connection request: #{res}")
|
|
281
|
+
end
|
|
282
|
+
connect_request.get_bytes(0, connect_request_length.read_uint)
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def unwrap(message)
|
|
286
|
+
message_, message_length_ = string_to_pointer_size message
|
|
287
|
+
unwrapped_message_length = FFI::MemoryPointer.new(:uint)
|
|
288
|
+
|
|
289
|
+
res = secure_session_unwrap(
|
|
290
|
+
@session, message_, message_length_, nil, unwrapped_message_length)
|
|
291
|
+
return SUCCESS, '' if res == SUCCESS
|
|
292
|
+
if res != BUFFER_TOO_SMALL
|
|
293
|
+
raise ThemisError, "Secure Session failed decrypting: #{res}"
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
unwrapped_message = FFI::MemoryPointer.new(
|
|
297
|
+
:char, unwrapped_message_length.read_uint)
|
|
298
|
+
res = secure_session_unwrap(@session, message_, message_length_,
|
|
299
|
+
unwrapped_message, unwrapped_message_length)
|
|
300
|
+
if res != SUCCESS && res != SEND_AS_IS
|
|
301
|
+
raise ThemisError, "Secure Session failed decrypting: #{res}"
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
[res, unwrapped_message.get_bytes(0, unwrapped_message_length.read_uint)]
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def wrap(message)
|
|
308
|
+
message_, message_length_ = string_to_pointer_size(message)
|
|
309
|
+
|
|
310
|
+
wrapped_message_length = FFI::MemoryPointer.new(:uint)
|
|
311
|
+
res = secure_session_wrap(
|
|
312
|
+
@session, message_, message_length_, nil, wrapped_message_length)
|
|
313
|
+
if res != BUFFER_TOO_SMALL
|
|
314
|
+
raise ThemisError, "Secure Session failed encrypting: #{res}"
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
wrapped_message = FFI::MemoryPointer.new(
|
|
318
|
+
:char, wrapped_message_length.read_uint)
|
|
319
|
+
res = secure_session_wrap(@session, message_, message_length_,
|
|
320
|
+
wrapped_message, wrapped_message_length)
|
|
321
|
+
if res != SUCCESS && res != SEND_AS_IS
|
|
322
|
+
raise ThemisError, "Secure Session failed encrypting: #{res}"
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
wrapped_message.get_bytes(0, wrapped_message_length.read_uint)
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
def finalize
|
|
329
|
+
res = secure_session_destroy(@session)
|
|
330
|
+
raise ThemisError, 'Secure Session failed destroying' if res != SUCCESS
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
class Smessage
|
|
335
|
+
include ThemisCommon
|
|
336
|
+
include ThemisImport
|
|
337
|
+
|
|
338
|
+
def initialize(private_key, peer_public_key)
|
|
339
|
+
if not Themis.valid_key(private_key)
|
|
340
|
+
raise ThemisError, "Secure Message: invalid private key"
|
|
341
|
+
end
|
|
342
|
+
if not Themis.valid_key(peer_public_key)
|
|
343
|
+
raise ThemisError, "Secure Message: invalid public key"
|
|
344
|
+
end
|
|
345
|
+
if not Themis.private_key(private_key)
|
|
346
|
+
raise ThemisError, "Secure Message: public key used instead of private"
|
|
347
|
+
end
|
|
348
|
+
if not Themis.public_key(peer_public_key)
|
|
349
|
+
raise ThemisError, "Secure Message: private key used instead of public"
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
@private_key, @private_key_length = string_to_pointer_size(private_key)
|
|
353
|
+
@peer_public_key, @peer_public_key_length =
|
|
354
|
+
string_to_pointer_size(peer_public_key)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
def wrap(message)
|
|
358
|
+
message_, message_length_ = string_to_pointer_size(message)
|
|
359
|
+
|
|
360
|
+
wrapped_message_length = FFI::MemoryPointer.new(:uint)
|
|
361
|
+
res = themis_secure_message_encrypt(
|
|
362
|
+
@private_key, @private_key_length, @peer_public_key,
|
|
363
|
+
@peer_public_key_length, message_, message_length_,
|
|
364
|
+
nil, wrapped_message_length)
|
|
365
|
+
if res != BUFFER_TOO_SMALL
|
|
366
|
+
raise ThemisError, "Secure Message failed to encrypt: #{res}"
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
wrapped_message = FFI::MemoryPointer.new(
|
|
370
|
+
:char, wrapped_message_length.read_uint)
|
|
371
|
+
res = themis_secure_message_encrypt(
|
|
372
|
+
@private_key, @private_key_length, @peer_public_key,
|
|
373
|
+
@peer_public_key_length, message_, message_length_,
|
|
374
|
+
wrapped_message, wrapped_message_length)
|
|
375
|
+
if res != SUCCESS
|
|
376
|
+
raise ThemisError, "Secure Message failed to encrypt: #{res}"
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
wrapped_message.get_bytes(0, wrapped_message_length.read_uint)
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
def unwrap(message)
|
|
383
|
+
message_, message_length_ = string_to_pointer_size(message)
|
|
384
|
+
unwrapped_message_length = FFI::MemoryPointer.new(:uint)
|
|
385
|
+
res = themis_secure_message_decrypt(
|
|
386
|
+
@private_key, @private_key_length, @peer_public_key,
|
|
387
|
+
@peer_public_key_length, message_, message_length_,
|
|
388
|
+
nil, unwrapped_message_length)
|
|
389
|
+
if res != BUFFER_TOO_SMALL
|
|
390
|
+
raise ThemisError, "Secure Message failed to decrypt: #{res}"
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
unwrapped_message = FFI::MemoryPointer.new(
|
|
394
|
+
:char, unwrapped_message_length.read_uint)
|
|
395
|
+
res = themis_secure_message_decrypt(
|
|
396
|
+
@private_key, @private_key_length, @peer_public_key,
|
|
397
|
+
@peer_public_key_length, message_, message_length_,
|
|
398
|
+
unwrapped_message, unwrapped_message_length)
|
|
399
|
+
if res != SUCCESS
|
|
400
|
+
raise ThemisError, "Secure Message failed to decrypt: #{res}"
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
unwrapped_message.get_bytes(0, unwrapped_message_length.read_uint)
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
def Ssign(*args)
|
|
408
|
+
s_sign(*args)
|
|
409
|
+
end
|
|
410
|
+
deprecate :Ssign, :s_sign, 2018, 6
|
|
411
|
+
|
|
412
|
+
def s_sign(private_key, message)
|
|
413
|
+
if not valid_key(private_key)
|
|
414
|
+
raise ThemisError, "Secure Message: invalid private key"
|
|
415
|
+
end
|
|
416
|
+
if not private_key(private_key)
|
|
417
|
+
raise ThemisError, "Secure Message: public key used instead of private"
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
private_key_, private_key_length_ = string_to_pointer_size(private_key)
|
|
421
|
+
message_, message_length_ = string_to_pointer_size(message)
|
|
422
|
+
|
|
423
|
+
wrapped_message_length = FFI::MemoryPointer.new(:uint)
|
|
424
|
+
res = themis_secure_message_sign(
|
|
425
|
+
private_key_, private_key_length_, message_,
|
|
426
|
+
message_length_, nil, wrapped_message_length)
|
|
427
|
+
if res != BUFFER_TOO_SMALL
|
|
428
|
+
raise ThemisError, "Secure Message failed to sign: #{res}"
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
wrapped_message = FFI::MemoryPointer.new(
|
|
432
|
+
:char, wrapped_message_length.read_uint)
|
|
433
|
+
res = themis_secure_message_sign(
|
|
434
|
+
private_key_, private_key_length_, message_,
|
|
435
|
+
message_length_, wrapped_message, wrapped_message_length)
|
|
436
|
+
if res != SUCCESS
|
|
437
|
+
raise ThemisError, "Secure Message failed to sign: #{res}"
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
wrapped_message.get_bytes(0, wrapped_message_length.read_uint)
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
def Sverify(*args)
|
|
444
|
+
s_verify(*args)
|
|
445
|
+
end
|
|
446
|
+
deprecate :Sverify, :s_verify, 2018, 6
|
|
447
|
+
|
|
448
|
+
def s_verify(peer_public_key, message)
|
|
449
|
+
if not valid_key(peer_public_key)
|
|
450
|
+
raise ThemisError, "Secure Message: invalid public key"
|
|
451
|
+
end
|
|
452
|
+
if not public_key(peer_public_key)
|
|
453
|
+
raise ThemisError, "Secure Message: private key used instead of public"
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
public_key_, public_key_length_ = string_to_pointer_size(peer_public_key)
|
|
457
|
+
message_, message_length_ = string_to_pointer_size(message)
|
|
458
|
+
|
|
459
|
+
unwrapped_message_length = FFI::MemoryPointer.new(:uint)
|
|
460
|
+
res = themis_secure_message_verify(
|
|
461
|
+
public_key_, public_key_length_, message_,
|
|
462
|
+
message_length_, nil, unwrapped_message_length)
|
|
463
|
+
if res != BUFFER_TOO_SMALL
|
|
464
|
+
raise ThemisError, "Secure Message failed to verify: #{res}"
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
unwrapped_message = FFI::MemoryPointer.new(
|
|
468
|
+
:char, unwrapped_message_length.read_uint)
|
|
469
|
+
res = themis_secure_message_verify(
|
|
470
|
+
public_key_, public_key_length_, message_,
|
|
471
|
+
message_length_, unwrapped_message, unwrapped_message_length)
|
|
472
|
+
if res != SUCCESS
|
|
473
|
+
raise ThemisError, "Secure Message failed to verify: #{res}"
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
unwrapped_message.get_bytes(0, unwrapped_message_length.read_uint)
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
class Scell
|
|
480
|
+
include ThemisCommon
|
|
481
|
+
include ThemisImport
|
|
482
|
+
|
|
483
|
+
SEAL_MODE = 0
|
|
484
|
+
TOKEN_PROTECT_MODE = 1
|
|
485
|
+
CONTEXT_IMPRINT_MODE = 2
|
|
486
|
+
|
|
487
|
+
def initialize(key, mode)
|
|
488
|
+
@key, @key_length = string_to_pointer_size(key)
|
|
489
|
+
@mode = mode
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
def encrypt(message, context = nil)
|
|
493
|
+
message_, message_length_ = string_to_pointer_size(message)
|
|
494
|
+
context_, context_length_ =
|
|
495
|
+
context.nil? ? [nil, 0] : string_to_pointer_size(context)
|
|
496
|
+
encrypted_message_length = FFI::MemoryPointer.new(:uint)
|
|
497
|
+
enccontext_length = FFI::MemoryPointer.new(:uint)
|
|
498
|
+
case @mode
|
|
499
|
+
when SEAL_MODE
|
|
500
|
+
res = themis_secure_cell_encrypt_seal(
|
|
501
|
+
@key, @key_length, context_, context_length_, message_,
|
|
502
|
+
message_length_, nil, encrypted_message_length)
|
|
503
|
+
if res != BUFFER_TOO_SMALL
|
|
504
|
+
raise ThemisError, "Secure Cell (Seal) failed encrypting: #{res}"
|
|
505
|
+
end
|
|
506
|
+
encrypted_message = FFI::MemoryPointer.new(
|
|
507
|
+
:char, encrypted_message_length.read_uint)
|
|
508
|
+
res = themis_secure_cell_encrypt_seal(
|
|
509
|
+
@key, @key_length, context_, context_length_, message_,
|
|
510
|
+
message_length_, encrypted_message, encrypted_message_length)
|
|
511
|
+
if res != SUCCESS
|
|
512
|
+
raise ThemisError, "Secure Cell (Seal) failed encrypting: #{res}"
|
|
513
|
+
end
|
|
514
|
+
encrypted_message.get_bytes(0, encrypted_message_length.read_uint)
|
|
515
|
+
when TOKEN_PROTECT_MODE
|
|
516
|
+
res = themis_secure_cell_encrypt_token_protect(
|
|
517
|
+
@key, @key_length, context_, context_length_, message_,
|
|
518
|
+
message_length_, nil, enccontext_length, nil,
|
|
519
|
+
encrypted_message_length)
|
|
520
|
+
if res != BUFFER_TOO_SMALL
|
|
521
|
+
raise(ThemisError,
|
|
522
|
+
"Secure Cell (Token protect) failed encrypting: #{res}")
|
|
523
|
+
end
|
|
524
|
+
encrypted_message = FFI::MemoryPointer.new(
|
|
525
|
+
:char, encrypted_message_length.read_uint)
|
|
526
|
+
enccontext = FFI::MemoryPointer.new(:char, enccontext_length.read_uint)
|
|
527
|
+
res = themis_secure_cell_encrypt_token_protect(
|
|
528
|
+
@key, @key_length, context_, context_length_, message_,
|
|
529
|
+
message_length_, enccontext, enccontext_length, encrypted_message,
|
|
530
|
+
encrypted_message_length)
|
|
531
|
+
if res != SUCCESS
|
|
532
|
+
raise(ThemisError,
|
|
533
|
+
"Secure Cell (Token Protect) failed encrypting: #{res}")
|
|
534
|
+
end
|
|
535
|
+
[encrypted_message.get_bytes(0, encrypted_message_length.read_uint),
|
|
536
|
+
enccontext.get_bytes(0, enccontext_length.read_uint),]
|
|
537
|
+
when CONTEXT_IMPRINT_MODE
|
|
538
|
+
res = themis_secure_cell_encrypt_context_imprint(
|
|
539
|
+
@key, @key_length, message_, message_length_, context_,
|
|
540
|
+
context_length_, nil, encrypted_message_length)
|
|
541
|
+
if res != BUFFER_TOO_SMALL
|
|
542
|
+
raise(ThemisError,
|
|
543
|
+
"Secure Cell (Context Imprint) failed encrypting: #{res}")
|
|
544
|
+
end
|
|
545
|
+
encrypted_message = FFI::MemoryPointer.new(
|
|
546
|
+
:char, encrypted_message_length.read_uint)
|
|
547
|
+
res = themis_secure_cell_encrypt_context_imprint(
|
|
548
|
+
@key, @key_length, message_, message_length_, context_,
|
|
549
|
+
context_length_, encrypted_message, encrypted_message_length)
|
|
550
|
+
if res != SUCCESS
|
|
551
|
+
raise(ThemisError,
|
|
552
|
+
"Secure Cell (Context Imprint) failed encrypting: #{res}")
|
|
553
|
+
end
|
|
554
|
+
encrypted_message.get_bytes(0, encrypted_message_length.read_uint)
|
|
555
|
+
else
|
|
556
|
+
raise ThemisError, 'Secure Cell failed encrypting, undefined mode'
|
|
557
|
+
end
|
|
558
|
+
end
|
|
559
|
+
|
|
560
|
+
def decrypt(message, context = nil)
|
|
561
|
+
context_, context_length_ =
|
|
562
|
+
context.nil? ? [nil, 0] : string_to_pointer_size(context)
|
|
563
|
+
decrypted_message_length = FFI::MemoryPointer.new(:uint)
|
|
564
|
+
case @mode
|
|
565
|
+
when SEAL_MODE
|
|
566
|
+
message_, message_length_ = string_to_pointer_size(message)
|
|
567
|
+
res = themis_secure_cell_decrypt_seal(
|
|
568
|
+
@key, @key_length, context_, context_length_, message_,
|
|
569
|
+
message_length_, nil, decrypted_message_length)
|
|
570
|
+
if res != BUFFER_TOO_SMALL
|
|
571
|
+
raise ThemisError, "Secure Cell (Seal) failed decrypting: #{res}"
|
|
572
|
+
end
|
|
573
|
+
decrypted_message = FFI::MemoryPointer.new(
|
|
574
|
+
:char, decrypted_message_length.read_uint)
|
|
575
|
+
res = themis_secure_cell_decrypt_seal(
|
|
576
|
+
@key, @key_length, context_, context_length_, message_,
|
|
577
|
+
message_length_, decrypted_message, decrypted_message_length)
|
|
578
|
+
if res != SUCCESS
|
|
579
|
+
raise ThemisError, "Secure Cell (Seal) failed decrypting: #{res}"
|
|
580
|
+
end
|
|
581
|
+
decrypted_message.get_bytes(0, decrypted_message_length.read_uint)
|
|
582
|
+
when TOKEN_PROTECT_MODE
|
|
583
|
+
message_, enccontext = message
|
|
584
|
+
message__, message_length__ = string_to_pointer_size(message_)
|
|
585
|
+
enccontext_, enccontext_length = string_to_pointer_size(enccontext)
|
|
586
|
+
res = themis_secure_cell_decrypt_token_protect(
|
|
587
|
+
@key, @key_length, context_, context_length_, message__,
|
|
588
|
+
message_length__, enccontext_, enccontext_length, nil,
|
|
589
|
+
decrypted_message_length)
|
|
590
|
+
if res != BUFFER_TOO_SMALL
|
|
591
|
+
raise(ThemisError,
|
|
592
|
+
"Secure Cell (Token Protect) failed decrypting: #{res}")
|
|
593
|
+
end
|
|
594
|
+
decrypted_message = FFI::MemoryPointer.new(
|
|
595
|
+
:char, decrypted_message_length.read_uint)
|
|
596
|
+
res = themis_secure_cell_decrypt_token_protect(
|
|
597
|
+
@key, @key_length, context_, context_length_, message__,
|
|
598
|
+
message_length__, enccontext_, enccontext_length,
|
|
599
|
+
decrypted_message, decrypted_message_length)
|
|
600
|
+
if res != SUCCESS
|
|
601
|
+
raise(ThemisError,
|
|
602
|
+
"Secure Cell (Token Protect) failed decrypting: #{res}")
|
|
603
|
+
end
|
|
604
|
+
decrypted_message.get_bytes(0, decrypted_message_length.read_uint)
|
|
605
|
+
when CONTEXT_IMPRINT_MODE
|
|
606
|
+
message_, message_length_ = string_to_pointer_size(message)
|
|
607
|
+
res = themis_secure_cell_decrypt_context_imprint(
|
|
608
|
+
@key, @key_length, message_, message_length_, context_,
|
|
609
|
+
context_length_, nil, decrypted_message_length)
|
|
610
|
+
if res != BUFFER_TOO_SMALL
|
|
611
|
+
raise(ThemisError,
|
|
612
|
+
"Secure Cell (Context Imprint) failed decrypting: #{res}")
|
|
613
|
+
end
|
|
614
|
+
decrypted_message = FFI::MemoryPointer.new(
|
|
615
|
+
:char, decrypted_message_length.read_uint)
|
|
616
|
+
res = themis_secure_cell_decrypt_context_imprint(@key, @key_length,
|
|
617
|
+
message_, message_length_, context_, context_length_,
|
|
618
|
+
decrypted_message, decrypted_message_length)
|
|
619
|
+
if res != SUCCESS
|
|
620
|
+
raise(ThemisError,
|
|
621
|
+
"Secure Cell (Context Imprint) failed decrypting: #{res}")
|
|
622
|
+
end
|
|
623
|
+
decrypted_message.get_bytes(0, decrypted_message_length.read_uint)
|
|
624
|
+
else
|
|
625
|
+
raise ThemisError, 'Secure Cell failed encrypting, undefined mode'
|
|
626
|
+
end
|
|
627
|
+
end
|
|
628
|
+
end
|
|
629
|
+
|
|
630
|
+
class Scomparator
|
|
631
|
+
include ThemisCommon
|
|
632
|
+
include ThemisImport
|
|
633
|
+
|
|
634
|
+
MATCH = 21
|
|
635
|
+
NOT_MATCH = 22
|
|
636
|
+
NOT_READY = 0
|
|
637
|
+
|
|
638
|
+
def initialize(shared_secret)
|
|
639
|
+
shared_secret_buf, shared_secret_length =
|
|
640
|
+
string_to_pointer_size(shared_secret)
|
|
641
|
+
@comparator = secure_comparator_create
|
|
642
|
+
raise ThemisError, 'Secure Comparator failed creating' unless @comparator
|
|
643
|
+
res = secure_comparator_append_secret(
|
|
644
|
+
@comparator, shared_secret_buf, shared_secret_length)
|
|
645
|
+
if res != SUCCESS
|
|
646
|
+
raise ThemisError, 'Secure Comparator failed appending secret'
|
|
647
|
+
end
|
|
648
|
+
end
|
|
649
|
+
|
|
650
|
+
def finalize
|
|
651
|
+
res = secure_comparator_destroy(@comparator)
|
|
652
|
+
if res != SUCCESS
|
|
653
|
+
raise ThemisError, 'Secure Comparator failed destroying'
|
|
654
|
+
end
|
|
655
|
+
end
|
|
656
|
+
|
|
657
|
+
def begin_compare
|
|
658
|
+
res_length = FFI::MemoryPointer.new(:uint)
|
|
659
|
+
res = secure_comparator_begin_compare(@comparator, nil, res_length)
|
|
660
|
+
if res != BUFFER_TOO_SMALL
|
|
661
|
+
raise(ThemisError,
|
|
662
|
+
'Secure Comparator failed making initialisation message')
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
res_buffer = FFI::MemoryPointer.new(:char, res_length.read_uint)
|
|
666
|
+
res = secure_comparator_begin_compare(@comparator, res_buffer, res_length)
|
|
667
|
+
if res != SUCCESS && res != SEND_AS_IS
|
|
668
|
+
raise(ThemisError,
|
|
669
|
+
'Secure Comparator failed making initialisation message')
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
res_buffer.get_bytes(0, res_length.read_uint)
|
|
673
|
+
end
|
|
674
|
+
|
|
675
|
+
def proceed_compare(control_message)
|
|
676
|
+
message, message_length = string_to_pointer_size(control_message)
|
|
677
|
+
res_length = FFI::MemoryPointer.new(:uint)
|
|
678
|
+
|
|
679
|
+
res = secure_comparator_proceed_compare(
|
|
680
|
+
@comparator, message, message_length, nil, res_length)
|
|
681
|
+
return '' if res == SUCCESS
|
|
682
|
+
if res != BUFFER_TOO_SMALL
|
|
683
|
+
raise ThemisError, 'Secure Comparator failed proceeding message'
|
|
684
|
+
end
|
|
685
|
+
|
|
686
|
+
res_buffer = FFI::MemoryPointer.new(:char, res_length.read_uint)
|
|
687
|
+
res = secure_comparator_proceed_compare(
|
|
688
|
+
@comparator, message, message_length, res_buffer, res_length)
|
|
689
|
+
if res != SUCCESS && res != SEND_AS_IS
|
|
690
|
+
raise ThemisError, 'Secure Comparator failed proceeding message'
|
|
691
|
+
end
|
|
692
|
+
|
|
693
|
+
res_buffer.get_bytes(0, res_length.read_uint)
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
def result
|
|
697
|
+
secure_comparator_get_result(@comparator)
|
|
698
|
+
end
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
module_function :Ssign
|
|
702
|
+
module_function :Sverify
|
|
703
|
+
module_function :s_sign
|
|
704
|
+
module_function :s_verify
|
|
705
|
+
end
|
data/lib/rubythemis.rb
CHANGED
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
# limitations under the License.
|
|
15
15
|
#
|
|
16
16
|
|
|
17
|
+
warn %(DEPRECATION WARNING: The `rubythemis` gem is deprecated. ) +
|
|
18
|
+
%(Please use "require 'rbthemis'" instead of "require 'rubythemis'". ) +
|
|
19
|
+
%(`rubythemis.rb` will be removed in 0.12.0 release.)
|
|
20
|
+
|
|
17
21
|
require 'ffi'
|
|
18
22
|
|
|
19
23
|
module ThemisCommon
|
|
@@ -56,18 +60,32 @@ module ThemisImport
|
|
|
56
60
|
[:pointer, :pointer, :int, :pointer, :pointer], :int
|
|
57
61
|
attach_function :secure_session_is_established, [:pointer], :bool
|
|
58
62
|
|
|
59
|
-
attach_function :
|
|
63
|
+
attach_function :themis_secure_message_encrypt,
|
|
60
64
|
[:pointer, :int, :pointer, :int, :pointer,
|
|
61
65
|
:int, :pointer, :pointer], :int
|
|
62
|
-
attach_function :
|
|
66
|
+
attach_function :themis_secure_message_decrypt,
|
|
63
67
|
[:pointer, :int, :pointer, :int, :pointer,
|
|
64
68
|
:int, :pointer, :pointer], :int
|
|
69
|
+
attach_function :themis_secure_message_sign,
|
|
70
|
+
[:pointer, :int, :pointer, :int, :pointer,
|
|
71
|
+
:pointer], :int
|
|
72
|
+
attach_function :themis_secure_message_verify,
|
|
73
|
+
[:pointer, :int, :pointer, :int, :pointer,
|
|
74
|
+
:pointer], :int
|
|
65
75
|
|
|
66
76
|
attach_function :themis_gen_rsa_key_pair,
|
|
67
77
|
[:pointer, :pointer, :pointer, :pointer], :int
|
|
68
78
|
attach_function :themis_gen_ec_key_pair,
|
|
69
79
|
[:pointer, :pointer, :pointer, :pointer], :int
|
|
70
|
-
|
|
80
|
+
|
|
81
|
+
THEMIS_KEY_INVALID = 0
|
|
82
|
+
THEMIS_KEY_RSA_PRIVATE = 1
|
|
83
|
+
THEMIS_KEY_RSA_PUBLIC = 2
|
|
84
|
+
THEMIS_KEY_EC_PRIVATE = 3
|
|
85
|
+
THEMIS_KEY_EC_PUBLIC = 4
|
|
86
|
+
|
|
87
|
+
attach_function :themis_is_valid_asym_key, [:pointer, :int], :int
|
|
88
|
+
attach_function :themis_get_asym_key_kind, [:pointer, :int], :int
|
|
71
89
|
|
|
72
90
|
attach_function :themis_secure_cell_encrypt_seal,
|
|
73
91
|
[:pointer, :int, :pointer, :int, :pointer, :int,
|
|
@@ -182,6 +200,28 @@ module Themis
|
|
|
182
200
|
end
|
|
183
201
|
end
|
|
184
202
|
|
|
203
|
+
def Themis.valid_key(key)
|
|
204
|
+
if key.nil? || key.empty?
|
|
205
|
+
return false
|
|
206
|
+
end
|
|
207
|
+
key_, len_ = string_to_pointer_size(key)
|
|
208
|
+
return themis_is_valid_asym_key(key_, len_) == SUCCESS
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def Themis.private_key(key)
|
|
212
|
+
key_, len_ = string_to_pointer_size(key)
|
|
213
|
+
kind = themis_get_asym_key_kind(key_, len_)
|
|
214
|
+
return kind == ThemisImport::THEMIS_KEY_RSA_PRIVATE \
|
|
215
|
+
|| kind == ThemisImport::THEMIS_KEY_EC_PRIVATE
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def Themis.public_key(key)
|
|
219
|
+
key_, len_ = string_to_pointer_size(key)
|
|
220
|
+
kind = themis_get_asym_key_kind(key_, len_)
|
|
221
|
+
return kind == ThemisImport::THEMIS_KEY_RSA_PUBLIC \
|
|
222
|
+
|| kind == ThemisImport::THEMIS_KEY_EC_PUBLIC
|
|
223
|
+
end
|
|
224
|
+
|
|
185
225
|
class Ssession
|
|
186
226
|
include ThemisCommon
|
|
187
227
|
include ThemisImport
|
|
@@ -300,6 +340,19 @@ module Themis
|
|
|
300
340
|
include ThemisImport
|
|
301
341
|
|
|
302
342
|
def initialize(private_key, peer_public_key)
|
|
343
|
+
if not Themis.valid_key(private_key)
|
|
344
|
+
raise ThemisError, "Secure Message: invalid private key"
|
|
345
|
+
end
|
|
346
|
+
if not Themis.valid_key(peer_public_key)
|
|
347
|
+
raise ThemisError, "Secure Message: invalid public key"
|
|
348
|
+
end
|
|
349
|
+
if not Themis.private_key(private_key)
|
|
350
|
+
raise ThemisError, "Secure Message: public key used instead of private"
|
|
351
|
+
end
|
|
352
|
+
if not Themis.public_key(peer_public_key)
|
|
353
|
+
raise ThemisError, "Secure Message: private key used instead of public"
|
|
354
|
+
end
|
|
355
|
+
|
|
303
356
|
@private_key, @private_key_length = string_to_pointer_size(private_key)
|
|
304
357
|
@peer_public_key, @peer_public_key_length =
|
|
305
358
|
string_to_pointer_size(peer_public_key)
|
|
@@ -309,22 +362,22 @@ module Themis
|
|
|
309
362
|
message_, message_length_ = string_to_pointer_size(message)
|
|
310
363
|
|
|
311
364
|
wrapped_message_length = FFI::MemoryPointer.new(:uint)
|
|
312
|
-
res =
|
|
365
|
+
res = themis_secure_message_encrypt(
|
|
313
366
|
@private_key, @private_key_length, @peer_public_key,
|
|
314
367
|
@peer_public_key_length, message_, message_length_,
|
|
315
368
|
nil, wrapped_message_length)
|
|
316
369
|
if res != BUFFER_TOO_SMALL
|
|
317
|
-
raise ThemisError, "Secure Message failed
|
|
370
|
+
raise ThemisError, "Secure Message failed to encrypt: #{res}"
|
|
318
371
|
end
|
|
319
372
|
|
|
320
373
|
wrapped_message = FFI::MemoryPointer.new(
|
|
321
374
|
:char, wrapped_message_length.read_uint)
|
|
322
|
-
res =
|
|
375
|
+
res = themis_secure_message_encrypt(
|
|
323
376
|
@private_key, @private_key_length, @peer_public_key,
|
|
324
377
|
@peer_public_key_length, message_, message_length_,
|
|
325
378
|
wrapped_message, wrapped_message_length)
|
|
326
379
|
if res != SUCCESS
|
|
327
|
-
raise ThemisError, "Secure Message failed
|
|
380
|
+
raise ThemisError, "Secure Message failed to encrypt: #{res}"
|
|
328
381
|
end
|
|
329
382
|
|
|
330
383
|
wrapped_message.get_bytes(0, wrapped_message_length.read_uint)
|
|
@@ -333,22 +386,22 @@ module Themis
|
|
|
333
386
|
def unwrap(message)
|
|
334
387
|
message_, message_length_ = string_to_pointer_size(message)
|
|
335
388
|
unwrapped_message_length = FFI::MemoryPointer.new(:uint)
|
|
336
|
-
res =
|
|
389
|
+
res = themis_secure_message_decrypt(
|
|
337
390
|
@private_key, @private_key_length, @peer_public_key,
|
|
338
391
|
@peer_public_key_length, message_, message_length_,
|
|
339
392
|
nil, unwrapped_message_length)
|
|
340
393
|
if res != BUFFER_TOO_SMALL
|
|
341
|
-
raise ThemisError, "Secure Message failed
|
|
394
|
+
raise ThemisError, "Secure Message failed to decrypt: #{res}"
|
|
342
395
|
end
|
|
343
396
|
|
|
344
397
|
unwrapped_message = FFI::MemoryPointer.new(
|
|
345
398
|
:char, unwrapped_message_length.read_uint)
|
|
346
|
-
res =
|
|
399
|
+
res = themis_secure_message_decrypt(
|
|
347
400
|
@private_key, @private_key_length, @peer_public_key,
|
|
348
401
|
@peer_public_key_length, message_, message_length_,
|
|
349
402
|
unwrapped_message, unwrapped_message_length)
|
|
350
403
|
if res != SUCCESS
|
|
351
|
-
raise ThemisError, "Secure Message failed
|
|
404
|
+
raise ThemisError, "Secure Message failed to decrypt: #{res}"
|
|
352
405
|
end
|
|
353
406
|
|
|
354
407
|
unwrapped_message.get_bytes(0, unwrapped_message_length.read_uint)
|
|
@@ -361,24 +414,31 @@ module Themis
|
|
|
361
414
|
deprecate :Ssign, :s_sign, 2018, 6
|
|
362
415
|
|
|
363
416
|
def s_sign(private_key, message)
|
|
417
|
+
if not valid_key(private_key)
|
|
418
|
+
raise ThemisError, "Secure Message: invalid private key"
|
|
419
|
+
end
|
|
420
|
+
if not private_key(private_key)
|
|
421
|
+
raise ThemisError, "Secure Message: public key used instead of private"
|
|
422
|
+
end
|
|
423
|
+
|
|
364
424
|
private_key_, private_key_length_ = string_to_pointer_size(private_key)
|
|
365
425
|
message_, message_length_ = string_to_pointer_size(message)
|
|
366
426
|
|
|
367
427
|
wrapped_message_length = FFI::MemoryPointer.new(:uint)
|
|
368
|
-
res =
|
|
369
|
-
private_key_, private_key_length_,
|
|
428
|
+
res = themis_secure_message_sign(
|
|
429
|
+
private_key_, private_key_length_, message_,
|
|
370
430
|
message_length_, nil, wrapped_message_length)
|
|
371
431
|
if res != BUFFER_TOO_SMALL
|
|
372
|
-
raise ThemisError, "Secure Message failed
|
|
432
|
+
raise ThemisError, "Secure Message failed to sign: #{res}"
|
|
373
433
|
end
|
|
374
434
|
|
|
375
435
|
wrapped_message = FFI::MemoryPointer.new(
|
|
376
436
|
:char, wrapped_message_length.read_uint)
|
|
377
|
-
res =
|
|
378
|
-
private_key_, private_key_length_,
|
|
437
|
+
res = themis_secure_message_sign(
|
|
438
|
+
private_key_, private_key_length_, message_,
|
|
379
439
|
message_length_, wrapped_message, wrapped_message_length)
|
|
380
440
|
if res != SUCCESS
|
|
381
|
-
raise ThemisError, "Secure Message failed
|
|
441
|
+
raise ThemisError, "Secure Message failed to sign: #{res}"
|
|
382
442
|
end
|
|
383
443
|
|
|
384
444
|
wrapped_message.get_bytes(0, wrapped_message_length.read_uint)
|
|
@@ -390,27 +450,31 @@ module Themis
|
|
|
390
450
|
deprecate :Sverify, :s_verify, 2018, 6
|
|
391
451
|
|
|
392
452
|
def s_verify(peer_public_key, message)
|
|
393
|
-
|
|
394
|
-
|
|
453
|
+
if not valid_key(peer_public_key)
|
|
454
|
+
raise ThemisError, "Secure Message: invalid public key"
|
|
455
|
+
end
|
|
456
|
+
if not public_key(peer_public_key)
|
|
457
|
+
raise ThemisError, "Secure Message: private key used instead of public"
|
|
458
|
+
end
|
|
395
459
|
|
|
396
460
|
public_key_, public_key_length_ = string_to_pointer_size(peer_public_key)
|
|
397
461
|
message_, message_length_ = string_to_pointer_size(message)
|
|
398
462
|
|
|
399
463
|
unwrapped_message_length = FFI::MemoryPointer.new(:uint)
|
|
400
|
-
res =
|
|
401
|
-
|
|
464
|
+
res = themis_secure_message_verify(
|
|
465
|
+
public_key_, public_key_length_, message_,
|
|
402
466
|
message_length_, nil, unwrapped_message_length)
|
|
403
467
|
if res != BUFFER_TOO_SMALL
|
|
404
|
-
raise ThemisError, "Secure Message failed
|
|
468
|
+
raise ThemisError, "Secure Message failed to verify: #{res}"
|
|
405
469
|
end
|
|
406
470
|
|
|
407
471
|
unwrapped_message = FFI::MemoryPointer.new(
|
|
408
472
|
:char, unwrapped_message_length.read_uint)
|
|
409
|
-
res =
|
|
410
|
-
|
|
473
|
+
res = themis_secure_message_verify(
|
|
474
|
+
public_key_, public_key_length_, message_,
|
|
411
475
|
message_length_, unwrapped_message, unwrapped_message_length)
|
|
412
476
|
if res != SUCCESS
|
|
413
|
-
raise ThemisError, "Secure Message failed
|
|
477
|
+
raise ThemisError, "Secure Message failed to verify: #{res}"
|
|
414
478
|
end
|
|
415
479
|
|
|
416
480
|
unwrapped_message.get_bytes(0, unwrapped_message_length.read_uint)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rbthemis
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- CossackLabs
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2019-03-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ffi
|
|
@@ -40,6 +40,7 @@ executables: []
|
|
|
40
40
|
extensions: []
|
|
41
41
|
extra_rdoc_files: []
|
|
42
42
|
files:
|
|
43
|
+
- lib/rbthemis.rb
|
|
43
44
|
- lib/rubythemis.rb
|
|
44
45
|
homepage: http://cossacklabs.com/
|
|
45
46
|
licenses:
|
|
@@ -61,9 +62,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
61
62
|
- !ruby/object:Gem::Version
|
|
62
63
|
version: '0'
|
|
63
64
|
requirements:
|
|
64
|
-
- libthemis, v0.
|
|
65
|
+
- libthemis, v0.11.0
|
|
65
66
|
rubyforge_project:
|
|
66
|
-
rubygems_version: 2.
|
|
67
|
+
rubygems_version: 2.5.2.1
|
|
67
68
|
signing_key:
|
|
68
69
|
specification_version: 4
|
|
69
70
|
summary: Data security library for network communication and data storage for Ruby
|