Add secret key encrypt_easy.

master
Didactic Drunk 2019-05-28 16:15:57 -07:00
parent a26800765e
commit b69f55456b
3 changed files with 70 additions and 0 deletions

View File

@ -0,0 +1,16 @@
require "../spec_helper"
describe Cox::SecretKey do
it "encrypts/decrypts" do
key = Cox::SecretKey.random
message = "foobar"
encrypted, nonce = key.encrypt_easy message
decrypted = key.decrypt_easy encrypted, nonce
message.should eq String.new(decrypted)
expect_raises(Cox::DecryptionFailed) do
key.decrypt_easy "badmsgbadmsgbadmsgbadmsgbadmsg".to_slice, nonce
end
end
end

View File

@ -33,6 +33,22 @@ module Cox
KDF_CONTEXT_BYTES = crypto_kdf_contextbytes() KDF_CONTEXT_BYTES = crypto_kdf_contextbytes()
PWHASH_STR_BYTES = crypto_pwhash_strbytes() PWHASH_STR_BYTES = crypto_pwhash_strbytes()
fun crypto_secretbox_easy(
output : Pointer(LibC::UChar),
data : Pointer(LibC::UChar),
data_size : LibC::ULongLong,
nonce : Pointer(LibC::UChar),
key : Pointer(LibC::UChar),
) : LibC::Int
fun crypto_secretbox_open_easy(
output : Pointer(LibC::UChar),
data : Pointer(LibC::UChar),
data_size : LibC::ULongLong,
nonce : Pointer(LibC::UChar),
key : Pointer(LibC::UChar),
) : LibC::Int
fun crypto_box_keypair( fun crypto_box_keypair(
public_key_output : Pointer(LibC::UChar), public_key_output : Pointer(LibC::UChar),
secret_key_output : Pointer(LibC::UChar) secret_key_output : Pointer(LibC::UChar)

View File

@ -11,5 +11,43 @@ module Cox
raise ArgumentError.new("Secret key must be #{KEY_LENGTH} bytes, got #{bytes.bytesize}") raise ArgumentError.new("Secret key must be #{KEY_LENGTH} bytes, got #{bytes.bytesize}")
end end
end end
def self.random
new Random::Secure.random_bytes(KEY_LENGTH)
end
def encrypt_easy(data)
encrypt_easy data.to_slice
end
def encrypt_easy(data, nonce : Nonce)
encrypt_easy data.to_slice, nonce
end
def encrypt_easy(data : Bytes)
nonce = Nonce.new
output = encrypt_easy data, nonce
{output, nonce}
end
def encrypt_easy(data : Bytes, nonce : Nonce) : Bytes
output = Bytes.new(data.bytesize + LibSodium::MAC_BYTES)
if LibSodium.crypto_secretbox_easy(output, data, data.bytesize, nonce.pointer, @bytes) != 0
raise Cox::Error.new("crypto_secretbox_easy")
end
output
end
def decrypt_easy(data : Bytes, nonce : Nonce) : Bytes
output_size = data.bytesize - LibSodium::MAC_BYTES
raise Cox::DecryptionFailed.new("encrypted data too small #{data.bytesize}") if output_size <= 0
output = Bytes.new output_size
if LibSodium.crypto_secretbox_open_easy(output, data, data.bytesize, nonce.pointer, @bytes) != 0
raise Cox::DecryptionFailed.new("crypto_secretbox_easy")
end
output
end
# TODO: encrypt_detached
end end
end end