rubythemis 0.9.1
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 +7 -0
- data/lib/rubythemis.rb +308 -0
- metadata +69 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c533507748e3b83574754d815e8876013636b55b
|
4
|
+
data.tar.gz: c8b9067cbefeeab4d80a4ca4380affda98d21b79
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 78a31344f698b9798b403d9c2cbdbf92601f90c20d62e8e97cf69c9dffc9cffbfe9c97c38ee8d4650829bb2d5056d824e855f64a9848e4d81e3f4bf5e99a4964
|
7
|
+
data.tar.gz: 13c1baf7117e3af8ed2496222ca6182e75ee0c709395bfb92042504de8046eb09fba1e45cf86c32636380d74dad9261649074d1833bd18c310ce25516a9ebee7
|
data/lib/rubythemis.rb
ADDED
@@ -0,0 +1,308 @@
|
|
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(:char, string.force_encoding("BINARY").size)
|
22
|
+
string_buf.put_bytes(0, string.force_encoding("BINARY"), 0, string.force_encoding("BINARY").size)
|
23
|
+
return string_buf, string.force_encoding("BINARY").size
|
24
|
+
end
|
25
|
+
module_function :string_to_pointer_size
|
26
|
+
end
|
27
|
+
|
28
|
+
module ThemisImport
|
29
|
+
extend FFI::Library
|
30
|
+
ffi_lib 'themis'
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
callback :get_pub_key_by_id_type, [:pointer, :int, :pointer, :int, :uint], :int
|
35
|
+
callback :send_callback_type, [:pointer, :int, :uint], :int
|
36
|
+
callback :receive_callback_type, [:pointer, :int, :uint], :int
|
37
|
+
|
38
|
+
class Callbacks_struct < FFI::Struct
|
39
|
+
layout :send_data, :send_callback_type,
|
40
|
+
:receive_data, :receive_callback_type,
|
41
|
+
:state_changed, :pointer,
|
42
|
+
:get_pub_key_for_id, :get_pub_key_by_id_type,
|
43
|
+
:user_data, :uint
|
44
|
+
end
|
45
|
+
|
46
|
+
attach_function :secure_session_create, [ :pointer, :uint, :pointer, :uint, :pointer], :pointer
|
47
|
+
attach_function :secure_session_destroy, [ :pointer], :int
|
48
|
+
attach_function :secure_session_generate_connect_request, [ :pointer, :pointer, :pointer], :int
|
49
|
+
attach_function :secure_session_wrap, [ :pointer, :pointer, :int, :pointer, :pointer], :int
|
50
|
+
attach_function :secure_session_unwrap, [ :pointer, :pointer, :int, :pointer, :pointer], :int
|
51
|
+
attach_function :secure_session_is_established, [ :pointer], :bool
|
52
|
+
|
53
|
+
attach_function :themis_secure_message_wrap, [:pointer, :int, :pointer, :int, :pointer, :int, :pointer, :pointer], :int
|
54
|
+
attach_function :themis_secure_message_unwrap, [:pointer, :int, :pointer, :int, :pointer, :int, :pointer, :pointer], :int
|
55
|
+
|
56
|
+
attach_function :themis_gen_rsa_key_pair, [:pointer, :pointer, :pointer, :pointer], :int
|
57
|
+
attach_function :themis_gen_ec_key_pair, [:pointer, :pointer, :pointer, :pointer], :int
|
58
|
+
attach_function :themis_version, [], :string
|
59
|
+
|
60
|
+
attach_function :themis_secure_cell_encrypt_full, [:pointer, :int, :pointer, :int, :pointer, :int, :pointer, :pointer], :int
|
61
|
+
attach_function :themis_secure_cell_decrypt_full, [:pointer, :int, :pointer, :int, :pointer, :int, :pointer, :pointer], :int
|
62
|
+
|
63
|
+
attach_function :themis_secure_cell_encrypt_auto_split, [:pointer, :int, :pointer, :int, :pointer, :int, :pointer, :pointer, :pointer, :pointer], :int
|
64
|
+
attach_function :themis_secure_cell_decrypt_auto_split, [:pointer, :int, :pointer, :int, :pointer, :int, :pointer, :int, :pointer, :pointer], :int
|
65
|
+
|
66
|
+
attach_function :themis_secure_cell_encrypt_user_split, [:pointer, :int, :pointer, :int, :pointer, :int, :pointer, :pointer], :int
|
67
|
+
attach_function :themis_secure_cell_decrypt_user_split, [:pointer, :int, :pointer, :int, :pointer, :int, :pointer, :pointer], :int
|
68
|
+
end
|
69
|
+
|
70
|
+
module Themis
|
71
|
+
|
72
|
+
BUFFER_TOO_SMALL = -4
|
73
|
+
SUCCESS = 0
|
74
|
+
FAIL = -1
|
75
|
+
SEND_AS_IS = 1
|
76
|
+
|
77
|
+
|
78
|
+
class ThemisError < StandardError
|
79
|
+
end
|
80
|
+
|
81
|
+
class Callbacks
|
82
|
+
def get_pub_key_by_id(id)
|
83
|
+
raise ThemisError, "Callbacks not implemented: get_pub_key_by_id"
|
84
|
+
end
|
85
|
+
|
86
|
+
def send(message)
|
87
|
+
raise ThemisError, "Callbacks not implemented: send"
|
88
|
+
end
|
89
|
+
|
90
|
+
def receive()
|
91
|
+
raise ThemisError, "Callbacks not implemented: receive"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
class SKeyPairGen
|
96
|
+
include ThemisCommon
|
97
|
+
include ThemisImport
|
98
|
+
|
99
|
+
def ec()
|
100
|
+
private_key_length=FFI::MemoryPointer.new(:uint)
|
101
|
+
public_key_length= FFI::MemoryPointer.new(:uint)
|
102
|
+
res=themis_gen_ec_key_pair(nil, private_key_length, nil, public_key_length)
|
103
|
+
raise ThemisError, "themis_gen_ec_key_pair (length determination) error: #{res}" unless res == BUFFER_TOO_SMALL
|
104
|
+
private_key = FFI::MemoryPointer.new(:char, private_key_length.read_uint)
|
105
|
+
public_key = FFI::MemoryPointer.new(:char, public_key_length.read_uint)
|
106
|
+
res=themis_gen_ec_key_pair(private_key, private_key_length, public_key, public_key_length)
|
107
|
+
raise ThemisError, "themis_gen_ec_key_pair error: #{res}" unless res == SUCCESS
|
108
|
+
return private_key.get_bytes(0, private_key_length.read_uint), public_key.get_bytes(0, public_key_length.read_uint)
|
109
|
+
end
|
110
|
+
|
111
|
+
def rsa()
|
112
|
+
private_key_length=FFI::MemoryPointer.new(:uint)
|
113
|
+
public_key_length= FFI::MemoryPointer.new(:uint)
|
114
|
+
res=themis_gen_rsa_key_pair(nil, private_key_length, nil, public_key_length)
|
115
|
+
raise ThemisError, "themis_gen_ec_key_pair (length determination) error: #{res}" unless res == BUFFER_TOO_SMALL
|
116
|
+
private_key = FFI::MemoryPointer.new(:char, private_key_length.read_uint)
|
117
|
+
public_key = FFI::MemoryPointer.new(:char, public_key_length.read_uint)
|
118
|
+
res=themis_gen_rsa_key_pair(private_key, private_key_length, public_key, public_key_length)
|
119
|
+
raise ThemisError, "themis_gen_ec_key_pair error: #{res}" unless res == SUCCESS
|
120
|
+
return private_key.get_bytes(0, private_key_length.read_uint), public_key.get_bytes(0, public_key_length.read_uint)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
class Ssession
|
124
|
+
include ThemisCommon
|
125
|
+
include ThemisImport
|
126
|
+
|
127
|
+
MAPPING = {}
|
128
|
+
|
129
|
+
Get_pub_key_by_id_callback = FFI::Function.new(:int, [:pointer, :int, :pointer, :int, :uint]) do |id_buf, id_length, pubkey_buf, pubkey_length, obj|
|
130
|
+
pub_key=MAPPING[obj].get_pub_key_by_id(id_buf.get_bytes(0,id_length))
|
131
|
+
if !pub_key
|
132
|
+
-1
|
133
|
+
end
|
134
|
+
pubkey_buf.put_bytes(0, pub_key)
|
135
|
+
0
|
136
|
+
end
|
137
|
+
|
138
|
+
def initialize(id, private_key, transport)
|
139
|
+
id_buf, id_length = string_to_pointer_size(id)
|
140
|
+
private_key_buf, private_key_length = string_to_pointer_size(private_key)
|
141
|
+
@callbacks = Callbacks_struct.new
|
142
|
+
@callbacks[:get_pub_key_for_id] = Get_pub_key_by_id_callback
|
143
|
+
MAPPING[transport.object_id]=transport
|
144
|
+
@callbacks[:user_data] =transport.object_id
|
145
|
+
@session=secure_session_create(id_buf, id_length, private_key_buf, private_key_length, @callbacks);
|
146
|
+
raise ThemisError, "secure_session_create error" unless @session
|
147
|
+
end
|
148
|
+
|
149
|
+
def is_established()
|
150
|
+
return secure_session_is_established(@session)
|
151
|
+
end
|
152
|
+
|
153
|
+
def connect_request()
|
154
|
+
connect_request_length = FFI::MemoryPointer.new(:uint)
|
155
|
+
res=secure_session_generate_connect_request(@session, nil, connect_request_length)
|
156
|
+
raise ThemisError, "secure_session_generate_connect_request (length determination) error: #{res}" unless res == BUFFER_TOO_SMALL
|
157
|
+
connect_request = FFI::MemoryPointer.new(:char, connect_request_length.read_uint)
|
158
|
+
res=secure_session_generate_connect_request(@session, connect_request, connect_request_length)
|
159
|
+
raise ThemisError, "secure_session_generate_connect_request error: #{res}" unless res == SUCCESS
|
160
|
+
return connect_request.get_bytes(0, connect_request_length.read_uint);
|
161
|
+
end
|
162
|
+
|
163
|
+
def unwrap(message)
|
164
|
+
message_, message_length_=string_to_pointer_size(message)
|
165
|
+
unwrapped_message_length = FFI::MemoryPointer.new(:uint)
|
166
|
+
res=secure_session_unwrap(@session, message_, message_length_, nil, unwrapped_message_length)
|
167
|
+
raise ThemisError, "secure_session_unwrap (length determination) error: #{res}" unless res == BUFFER_TOO_SMALL || res == SUCCESS
|
168
|
+
if res == SUCCESS
|
169
|
+
return SUCCESS, ""
|
170
|
+
end
|
171
|
+
unwrapped_message = FFI::MemoryPointer.new(:char, unwrapped_message_length.read_uint)
|
172
|
+
res=secure_session_unwrap(@session, message_, message_length_, unwrapped_message, unwrapped_message_length)
|
173
|
+
raise ThemisError, "secure_session_unwrap error: #{res}" unless res == SUCCESS || res == SEND_AS_IS
|
174
|
+
return res, unwrapped_message.get_bytes(0, unwrapped_message_length.read_uint);
|
175
|
+
end
|
176
|
+
|
177
|
+
def wrap(message)
|
178
|
+
message_, message_length_=string_to_pointer_size(message)
|
179
|
+
wrapped_message_length = FFI::MemoryPointer.new(:uint)
|
180
|
+
res=secure_session_wrap(@session, message_, message_length_, nil, wrapped_message_length)
|
181
|
+
raise ThemisError, "secure_session_wrap (length determination) error: #{res}" unless res == BUFFER_TOO_SMALL
|
182
|
+
wrapped_message = FFI::MemoryPointer.new(:char, wrapped_message_length.read_uint)
|
183
|
+
res=secure_session_wrap(@session, message_, message_length_, wrapped_message, wrapped_message_length)
|
184
|
+
raise ThemisError, "secure_session_wrap error: #{res}" unless res == SUCCESS || res == SEND_AS_IS
|
185
|
+
return wrapped_message.get_bytes(0, wrapped_message_length.read_uint);
|
186
|
+
end
|
187
|
+
|
188
|
+
def finalize
|
189
|
+
res=secure_session_destroy(@session)
|
190
|
+
raise ThemisError, "secure_session_destroy error" unless res == SUCCESS
|
191
|
+
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
class Smessage
|
196
|
+
include ThemisCommon
|
197
|
+
include ThemisImport
|
198
|
+
def initialize(private_key, peer_public_key)
|
199
|
+
@private_key, @private_key_length = string_to_pointer_size(private_key)
|
200
|
+
@peer_public_key, @peer_public_key_length = string_to_pointer_size(peer_public_key)
|
201
|
+
end
|
202
|
+
|
203
|
+
def wrap(message)
|
204
|
+
message_, message_length_=string_to_pointer_size(message)
|
205
|
+
wrapped_message_length = FFI::MemoryPointer.new(:uint)
|
206
|
+
res=themis_secure_message_wrap(@private_key, @private_key_length, @peer_public_key, @peer_public_key_length, message_, message_length_, nil, wrapped_message_length)
|
207
|
+
raise ThemisError, "themis_secure_message_wrap (length determination) error: #{res}" unless res == BUFFER_TOO_SMALL
|
208
|
+
wrapped_message = FFI::MemoryPointer.new(:char, wrapped_message_length.read_uint)
|
209
|
+
res=themis_secure_message_wrap(@private_key, @private_key_length, @peer_public_key, @peer_public_key_length, message_, message_length_, wrapped_message, wrapped_message_length)
|
210
|
+
raise ThemisError, "themis_secure_message_wrap error: #{res}" unless res == SUCCESS
|
211
|
+
return wrapped_message.get_bytes(0, wrapped_message_length.read_uint);
|
212
|
+
end
|
213
|
+
|
214
|
+
def unwrap(message)
|
215
|
+
message_, message_length_=string_to_pointer_size(message)
|
216
|
+
unwrapped_message_length = FFI::MemoryPointer.new(:uint)
|
217
|
+
res=themis_secure_message_unwrap(@private_key, @private_key_length, @peer_public_key, @peer_public_key_length, message_, message_length_, nil, unwrapped_message_length)
|
218
|
+
raise ThemisError, "themis_secure_message_unwrap (length determination) error: #{res}" unless res == BUFFER_TOO_SMALL
|
219
|
+
unwrapped_message = FFI::MemoryPointer.new(:char, unwrapped_message_length.read_uint)
|
220
|
+
res=themis_secure_message_unwrap(@private_key, @private_key_length, @peer_public_key, @peer_public_key_length, message_, message_length_, unwrapped_message, unwrapped_message_length)
|
221
|
+
raise ThemisError, "themis_secure_message_unwrap error: #{res}" unless res == SUCCESS
|
222
|
+
return unwrapped_message.get_bytes(0, unwrapped_message_length.read_uint);
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
class Scell
|
227
|
+
include ThemisCommon
|
228
|
+
include ThemisImport
|
229
|
+
|
230
|
+
FULL_MODE = 0
|
231
|
+
AUTO_SPLIT_MODE = 1
|
232
|
+
USER_SPLIT_MODE = 2
|
233
|
+
|
234
|
+
def initialize(key, mode)
|
235
|
+
@key, @key_length = string_to_pointer_size(key)
|
236
|
+
@mode = mode
|
237
|
+
end
|
238
|
+
|
239
|
+
def encrypt(message, context=nil)
|
240
|
+
message_, message_length_ = string_to_pointer_size(message)
|
241
|
+
context_, context_length_ = context.nil? ? [nil,0] : string_to_pointer_size(context)
|
242
|
+
encrypted_message_length=FFI::MemoryPointer.new(:uint)
|
243
|
+
enccontext_length=FFI::MemoryPointer.new(:uint)
|
244
|
+
case @mode
|
245
|
+
when FULL_MODE
|
246
|
+
res=themis_secure_cell_encrypt_full(@key, @key_length, context_, context_length_, message_, message_length_, nil, encrypted_message_length)
|
247
|
+
raise ThemisError, "themis_secure_cell_encrypt_... (length determination) error: #{res}" unless res == BUFFER_TOO_SMALL
|
248
|
+
encrypted_message = FFI::MemoryPointer.new(:char, encrypted_message_length.read_uint)
|
249
|
+
res=themis_secure_cell_encrypt_full(@key, @key_length, context_, context_length_, message_, message_length_, encrypted_message, encrypted_message_length)
|
250
|
+
raise ThemisError, "themis_secure_cell_encrypt_full (length determination) error: #{res}" unless res == SUCCESS
|
251
|
+
return encrypted_message.get_bytes(0, encrypted_message_length.read_uint)
|
252
|
+
when AUTO_SPLIT_MODE
|
253
|
+
res=themis_secure_cell_encrypt_auto_split(@key, @key_length, context_, context_length_, message_, message_length_, nil, enccontext_length, nil, encrypted_message_length)
|
254
|
+
raise ThemisError, "themis_secure_cell_encrypt_... (length determination) error: #{res}" unless res == BUFFER_TOO_SMALL
|
255
|
+
encrypted_message = FFI::MemoryPointer.new(:char, encrypted_message_length.read_uint)
|
256
|
+
enccontext = FFI::MemoryPointer.new(:char, enccontext_length.read_uint)
|
257
|
+
res=themis_secure_cell_encrypt_auto_split(@key, @key_length, context_, context_length_, message_, message_length_, enccontext, enccontext_length, encrypted_message, encrypted_message_length)
|
258
|
+
raise ThemisError, "themis_secure_cell_encrypt_auto_split (length determination) error: #{res}" unless res == SUCCESS
|
259
|
+
return enccontext.get_bytes(0, enccontext_length.read_uint), encrypted_message.get_bytes(0, encrypted_message_length.read_uint)
|
260
|
+
when USER_SPLIT_MODE
|
261
|
+
res=themis_secure_cell_encrypt_user_split(@key, @key_length, message_, message_length_, context_, context_length_, nil, encrypted_message_length)
|
262
|
+
raise ThemisError, "themis_secure_cell_encrypt_... (length determination) error: #{res}" unless res == BUFFER_TOO_SMALL
|
263
|
+
encrypted_message = FFI::MemoryPointer.new(:char, encrypted_message_length.read_uint)
|
264
|
+
res=themis_secure_cell_encrypt_user_split(@key, @key_length, message_, message_length_, context_, context_length_, encrypted_message, encrypted_message_length)
|
265
|
+
raise ThemisError, "themis_secure_cell_encrypt_user_split (length determination) error: #{res}" unless res == SUCCESS
|
266
|
+
return encrypted_message.get_bytes(0, encrypted_message_length.read_uint)
|
267
|
+
else
|
268
|
+
raise ThemisError, "themis_secure_cell not supported mode"
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
def decrypt(message, context=nil)
|
273
|
+
context_, context_length_ = context.nil? ? [nil,0] : string_to_pointer_size(context)
|
274
|
+
decrypted_message_length=FFI::MemoryPointer.new(:uint)
|
275
|
+
case @mode
|
276
|
+
when FULL_MODE
|
277
|
+
message_, message_length_ = string_to_pointer_size(message)
|
278
|
+
res=themis_secure_cell_decrypt_full(@key, @key_length, context_, context_length_, message_, message_length_, nil, decrypted_message_length)
|
279
|
+
raise ThemisError, "themis_secure_cell_decrypt_full (length determination) error: #{res}" unless res == BUFFER_TOO_SMALL
|
280
|
+
decrypted_message = FFI::MemoryPointer.new(:char, decrypted_message_length.read_uint)
|
281
|
+
res=themis_secure_cell_decrypt_full(@key, @key_length, context_, context_length_, message_, message_length_, decrypted_message, decrypted_message_length)
|
282
|
+
raise ThemisError, "themis_secure_cell_decrypt_full (length determination) error: #{res}" unless res == SUCCESS
|
283
|
+
return decrypted_message.get_bytes(0, decrypted_message_length.read_uint)
|
284
|
+
when AUTO_SPLIT_MODE
|
285
|
+
enccontext, message_ = message
|
286
|
+
message__, message_length__ = string_to_pointer_size(message_)
|
287
|
+
enccontext_, enccontext_length = string_to_pointer_size(enccontext)
|
288
|
+
res=themis_secure_cell_decrypt_auto_split(@key, @key_length, context_, context_length_, message__, message_length__, enccontext_, enccontext_length, nil, decrypted_message_length)
|
289
|
+
raise ThemisError, "themis_secure_cell_encrypt_auto_split (length determination) error: #{res}" unless res == BUFFER_TOO_SMALL
|
290
|
+
decrypted_message = FFI::MemoryPointer.new(:char, decrypted_message_length.read_uint)
|
291
|
+
res=themis_secure_cell_decrypt_auto_split(@key, @key_length, context_, context_length_, message__, message_length__, enccontext_, enccontext_length, decrypted_message, decrypted_message_length)
|
292
|
+
raise ThemisError, "themis_secure_cell_encrypt_auto_split (length determination) error: #{res}" unless res == SUCCESS
|
293
|
+
return decrypted_message.get_bytes(0, decrypted_message_length.read_uint)
|
294
|
+
when USER_SPLIT_MODE
|
295
|
+
message_, message_length_ = string_to_pointer_size(message)
|
296
|
+
res=themis_secure_cell_decrypt_user_split(@key, @key_length, message_, message_length_, context_, context_length_, nil, decrypted_message_length)
|
297
|
+
raise ThemisError, "themis_secure_cell_decrypt_user_split (length determination) error: #{res}" unless res == BUFFER_TOO_SMALL
|
298
|
+
decrypted_message = FFI::MemoryPointer.new(:char, decrypted_message_length.read_uint)
|
299
|
+
res=themis_secure_cell_decrypt_user_split(@key, @key_length, message_, message_length_, context_, context_length_, decrypted_message, decrypted_message_length)
|
300
|
+
raise ThemisError, "themis_secure_cell_decrypt_user_split (length determination) error: #{res}" unless res == SUCCESS
|
301
|
+
return decrypted_message.get_bytes(0, decrypted_message_length.read_uint)
|
302
|
+
else
|
303
|
+
raise ThemisError, "themis_secure_cell not supported mode"
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
end
|
308
|
+
end
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubythemis
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- CossackLabs
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-05-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.9'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 1.9.8
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.9'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.9.8
|
33
|
+
description: Themis is a data security library, providing users with high-quality
|
34
|
+
security services for secure messaging of any kinds and flexible data storage. Themis
|
35
|
+
is aimed at modern developers, with high level OOP wrappers for Ruby, Python, PHP,
|
36
|
+
Java / Android and iOS / OSX. It is designed with ease of use in mind, high security
|
37
|
+
and cross-platform availability.
|
38
|
+
email: dev@cossacklabs.com
|
39
|
+
executables: []
|
40
|
+
extensions: []
|
41
|
+
extra_rdoc_files: []
|
42
|
+
files:
|
43
|
+
- lib/rubythemis.rb
|
44
|
+
homepage: http://cossacklabs.com/
|
45
|
+
licenses:
|
46
|
+
- Apache 2.0
|
47
|
+
metadata: {}
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirements:
|
63
|
+
- libthemis, v0.9
|
64
|
+
rubyforge_project:
|
65
|
+
rubygems_version: 2.4.5
|
66
|
+
signing_key:
|
67
|
+
specification_version: 4
|
68
|
+
summary: Data security library for network communication and data storage for Ruby
|
69
|
+
test_files: []
|