-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use new Secure Message API in RubyThemis #402
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -56,18 +56,33 @@ class CallbacksStruct < FFI::Struct | |
[:pointer, :pointer, :int, :pointer, :pointer], :int | ||
attach_function :secure_session_is_established, [:pointer], :bool | ||
|
||
attach_function :themis_secure_message_wrap, | ||
attach_function :themis_secure_message_encrypt, | ||
[:pointer, :int, :pointer, :int, :pointer, | ||
:int, :pointer, :pointer], :int | ||
attach_function :themis_secure_message_unwrap, | ||
attach_function :themis_secure_message_decrypt, | ||
[:pointer, :int, :pointer, :int, :pointer, | ||
:int, :pointer, :pointer], :int | ||
attach_function :themis_secure_message_sign, | ||
[:pointer, :int, :pointer, :int, :pointer, | ||
:pointer], :int | ||
attach_function :themis_secure_message_verify, | ||
[:pointer, :int, :pointer, :int, :pointer, | ||
:pointer], :int | ||
|
||
attach_function :themis_gen_rsa_key_pair, | ||
[:pointer, :pointer, :pointer, :pointer], :int | ||
attach_function :themis_gen_ec_key_pair, | ||
[:pointer, :pointer, :pointer, :pointer], :int | ||
|
||
THEMIS_KEY_INVALID = 0 | ||
THEMIS_KEY_RSA_PRIVATE = 1 | ||
THEMIS_KEY_RSA_PUBLIC = 2 | ||
THEMIS_KEY_EC_PRIVATE = 3 | ||
THEMIS_KEY_EC_PUBLIC = 4 | ||
|
||
attach_function :themis_is_valid_asym_key, [:pointer, :int], :int | ||
attach_function :themis_get_asym_key_kind, [:pointer, :int], :int | ||
|
||
attach_function :themis_secure_cell_encrypt_seal, | ||
[:pointer, :int, :pointer, :int, :pointer, :int, | ||
:pointer, :pointer], :int | ||
|
@@ -181,6 +196,28 @@ def rsa | |
end | ||
end | ||
|
||
def Themis.valid_key(key) | ||
if key.nil? || key.empty? | ||
return false | ||
end | ||
key_, len_ = string_to_pointer_size(key) | ||
return themis_is_valid_asym_key(key_, len_) == SUCCESS | ||
end | ||
|
||
def Themis.private_key(key) | ||
key_, len_ = string_to_pointer_size(key) | ||
kind = themis_get_asym_key_kind(key_, len_) | ||
return kind == ThemisImport::THEMIS_KEY_RSA_PRIVATE \ | ||
|| kind == ThemisImport::THEMIS_KEY_EC_PRIVATE | ||
end | ||
|
||
def Themis.public_key(key) | ||
key_, len_ = string_to_pointer_size(key) | ||
kind = themis_get_asym_key_kind(key_, len_) | ||
return kind == ThemisImport::THEMIS_KEY_RSA_PUBLIC \ | ||
|| kind == ThemisImport::THEMIS_KEY_EC_PUBLIC | ||
end | ||
|
||
class Ssession | ||
include ThemisCommon | ||
include ThemisImport | ||
|
@@ -299,6 +336,19 @@ class Smessage | |
include ThemisImport | ||
|
||
def initialize(private_key, peer_public_key) | ||
if not Themis.valid_key(private_key) | ||
raise ThemisError, "Secure Message: invalid private key" | ||
end | ||
if not Themis.valid_key(peer_public_key) | ||
raise ThemisError, "Secure Message: invalid public key" | ||
end | ||
if not Themis.private_key(private_key) | ||
raise ThemisError, "Secure Message: public key used instead of private" | ||
end | ||
if not Themis.public_key(peer_public_key) | ||
raise ThemisError, "Secure Message: private key used instead of public" | ||
end | ||
|
||
@private_key, @private_key_length = string_to_pointer_size(private_key) | ||
@peer_public_key, @peer_public_key_length = | ||
string_to_pointer_size(peer_public_key) | ||
|
@@ -308,22 +358,22 @@ def wrap(message) | |
message_, message_length_ = string_to_pointer_size(message) | ||
|
||
wrapped_message_length = FFI::MemoryPointer.new(:uint) | ||
res = themis_secure_message_wrap( | ||
res = themis_secure_message_encrypt( | ||
@private_key, @private_key_length, @peer_public_key, | ||
@peer_public_key_length, message_, message_length_, | ||
nil, wrapped_message_length) | ||
if res != BUFFER_TOO_SMALL | ||
raise ThemisError, "Secure Message failed encrypting: #{res}" | ||
raise ThemisError, "Secure Message failed to encrypt: #{res}" | ||
end | ||
|
||
wrapped_message = FFI::MemoryPointer.new( | ||
:char, wrapped_message_length.read_uint) | ||
res = themis_secure_message_wrap( | ||
res = themis_secure_message_encrypt( | ||
@private_key, @private_key_length, @peer_public_key, | ||
@peer_public_key_length, message_, message_length_, | ||
wrapped_message, wrapped_message_length) | ||
if res != SUCCESS | ||
raise ThemisError, "Secure Message failed encrypting: #{res}" | ||
raise ThemisError, "Secure Message failed to encrypt: #{res}" | ||
end | ||
|
||
wrapped_message.get_bytes(0, wrapped_message_length.read_uint) | ||
|
@@ -332,22 +382,22 @@ def wrap(message) | |
def unwrap(message) | ||
message_, message_length_ = string_to_pointer_size(message) | ||
unwrapped_message_length = FFI::MemoryPointer.new(:uint) | ||
res = themis_secure_message_unwrap( | ||
res = themis_secure_message_decrypt( | ||
@private_key, @private_key_length, @peer_public_key, | ||
@peer_public_key_length, message_, message_length_, | ||
nil, unwrapped_message_length) | ||
if res != BUFFER_TOO_SMALL | ||
raise ThemisError, "Secure Message failed decrypting: #{res}" | ||
raise ThemisError, "Secure Message failed to decrypt: #{res}" | ||
end | ||
|
||
unwrapped_message = FFI::MemoryPointer.new( | ||
:char, unwrapped_message_length.read_uint) | ||
res = themis_secure_message_unwrap( | ||
res = themis_secure_message_decrypt( | ||
@private_key, @private_key_length, @peer_public_key, | ||
@peer_public_key_length, message_, message_length_, | ||
unwrapped_message, unwrapped_message_length) | ||
if res != SUCCESS | ||
raise ThemisError, "Secure Message failed decrypting: #{res}" | ||
raise ThemisError, "Secure Message failed to decrypt: #{res}" | ||
end | ||
|
||
unwrapped_message.get_bytes(0, unwrapped_message_length.read_uint) | ||
|
@@ -360,24 +410,31 @@ def Ssign(*args) | |
deprecate :Ssign, :s_sign, 2018, 6 | ||
|
||
def s_sign(private_key, message) | ||
if not valid_key(private_key) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. technically speaking for user both these checks are the same -- wrong / empty / bad key. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would rather prefer to merge these checks in one, or use "Secure Message: private key used instead of public" as second error message There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a difference between "using an incorrect key" and "using a key incorrectly". If we get to the second check we are sure that the key is at least valid so we should not tell the user that their key is garbled or something. I guess I'll reuse the same messages as for the encrypt/decrypt mode. |
||
raise ThemisError, "Secure Message: invalid private key" | ||
end | ||
if not private_key(private_key) | ||
raise ThemisError, "Secure Message: public key used instead of private" | ||
end | ||
|
||
private_key_, private_key_length_ = string_to_pointer_size(private_key) | ||
message_, message_length_ = string_to_pointer_size(message) | ||
|
||
wrapped_message_length = FFI::MemoryPointer.new(:uint) | ||
res = themis_secure_message_wrap( | ||
private_key_, private_key_length_, nil, 0, message_, | ||
res = themis_secure_message_sign( | ||
private_key_, private_key_length_, message_, | ||
message_length_, nil, wrapped_message_length) | ||
if res != BUFFER_TOO_SMALL | ||
raise ThemisError, "Secure Message failed singing: #{res}" | ||
raise ThemisError, "Secure Message failed to sign: #{res}" | ||
end | ||
|
||
wrapped_message = FFI::MemoryPointer.new( | ||
:char, wrapped_message_length.read_uint) | ||
res = themis_secure_message_wrap( | ||
private_key_, private_key_length_, nil, 0, message_, | ||
res = themis_secure_message_sign( | ||
private_key_, private_key_length_, message_, | ||
message_length_, wrapped_message, wrapped_message_length) | ||
if res != SUCCESS | ||
raise ThemisError, "Secure Message failed singing: #{res}" | ||
raise ThemisError, "Secure Message failed to sign: #{res}" | ||
end | ||
|
||
wrapped_message.get_bytes(0, wrapped_message_length.read_uint) | ||
|
@@ -389,27 +446,31 @@ def Sverify(*args) | |
deprecate :Sverify, :s_verify, 2018, 6 | ||
|
||
def s_verify(peer_public_key, message) | ||
include ThemisCommon | ||
include ThemisImport | ||
if not valid_key(peer_public_key) | ||
raise ThemisError, "Secure Message: invalid public key" | ||
end | ||
if not public_key(peer_public_key) | ||
raise ThemisError, "Secure Message: private key used instead of public" | ||
end | ||
|
||
public_key_, public_key_length_ = string_to_pointer_size(peer_public_key) | ||
message_, message_length_ = string_to_pointer_size(message) | ||
|
||
unwrapped_message_length = FFI::MemoryPointer.new(:uint) | ||
res = themis_secure_message_unwrap( | ||
nil, 0, public_key_, public_key_length_, message_, | ||
res = themis_secure_message_verify( | ||
public_key_, public_key_length_, message_, | ||
message_length_, nil, unwrapped_message_length) | ||
if res != BUFFER_TOO_SMALL | ||
raise ThemisError, "Secure Message failed verifying: #{res}" | ||
raise ThemisError, "Secure Message failed to verify: #{res}" | ||
end | ||
|
||
unwrapped_message = FFI::MemoryPointer.new( | ||
:char, unwrapped_message_length.read_uint) | ||
res = themis_secure_message_unwrap( | ||
nil, 0, public_key_, public_key_length_, message_, | ||
res = themis_secure_message_verify( | ||
public_key_, public_key_length_, message_, | ||
message_length_, unwrapped_message, unwrapped_message_length) | ||
if res != SUCCESS | ||
raise ThemisError, "Secure Message failed verifying: #{res}" | ||
raise ThemisError, "Secure Message failed to verify: #{res}" | ||
end | ||
|
||
unwrapped_message.get_bytes(0, unwrapped_message_length.read_uint) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice checks :)