From 8aea82b29603b70d159ba566b74a4c9a7f79d4b2 Mon Sep 17 00:00:00 2001 From: Didactic Drunk <1479616+didactic-drunk@users.noreply.github.com> Date: Sat, 14 Sep 2019 06:05:13 -0700 Subject: [PATCH] Add Sodium::CryptoBox::SecretKey#decrypt_string Add Sodium::SecretBox#decrypt_string Add Documentation. --- spec/sodium/secret_box_spec.cr | 14 +++++++------- src/sodium/crypto_box/secret_key.cr | 27 ++++++++++++++++++++++++--- src/sodium/secret_box.cr | 24 +++++++++++++++--------- 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/spec/sodium/secret_box_spec.cr b/spec/sodium/secret_box_spec.cr index 0f662ee..19c2914 100644 --- a/spec/sodium/secret_box_spec.cr +++ b/spec/sodium/secret_box_spec.cr @@ -32,11 +32,11 @@ describe Sodium::SecretBox do message = "foobar" encrypted, nonce = box.encrypt message - decrypted = box.decrypt encrypted, nonce: nonce - message.should eq String.new(decrypted) + decrypted = box.decrypt_string encrypted, nonce: nonce + decrypted.should eq message expect_raises(Sodium::Error::DecryptionFailed) do - box.decrypt "badmsgbadmsgbadmsgbadmsgbadmsg".to_slice, nonce + box.decrypt "badmsgbadmsgbadmsgbadmsgbadmsg".to_slice, nonce: nonce end end @@ -59,7 +59,7 @@ describe Sodium::SecretBox do encrypted.should eq ciphertext decrypted = box.decrypt encrypted, nonce: nonce - plaintext.should eq decrypted + decrypted.should eq plaintext end end @@ -67,11 +67,11 @@ describe Sodium::SecretBox do detached_test_vectors.each do |vec| box, nonce, plaintext, ciphertext = box_from_test_vector vec - encrypted = box.encrypt_detached plaintext, nonce + encrypted = box.encrypt_detached plaintext, nonce: nonce encrypted.should eq ciphertext - decrypted = box.decrypt_detached encrypted, nonce - plaintext.should eq decrypted + decrypted = box.decrypt_detached encrypted, nonce: nonce + decrypted.should eq plaintext end end end diff --git a/src/sodium/crypto_box/secret_key.cr b/src/sodium/crypto_box/secret_key.cr index 91993de..3c32a27 100644 --- a/src/sodium/crypto_box/secret_key.cr +++ b/src/sodium/crypto_box/secret_key.cr @@ -10,6 +10,8 @@ class Sodium::CryptoBox # # # Authenticated encryption # [https://libsodium.gitbook.io/doc/public-key_cryptography/authenticated_encryption](https://libsodium.gitbook.io/doc/public-key_cryptography/authenticated_encryption#purpose) + # + # Usage: # ``` # bob = Sodium::CryptoBox::SecretKey.new # alice = Sodium::CryptoBox::SecretKey.new @@ -23,6 +25,8 @@ class Sodium::CryptoBox # # # Sealed Boxes # [https://libsodium.gitbook.io/doc/public-key_cryptography/sealed_boxes](https://libsodium.gitbook.io/doc/public-key_cryptography/sealed_boxes#purpose) + # + # Usage: # ``` # secret_key = Sodium::CryptoBox::SecretKey.new # public_key = secret_key.public_key @@ -117,11 +121,28 @@ class Sodium::CryptoBox # Anonymously receive messages without a signature. # # For authenticated messages use `secret_key.box(recipient_public_key).decrypt`. - def decrypt(src) - encrypt src.to_slice + # + # Optionally supply a destination buffer. + def decrypt(src, dst : Bytes? = nil) : Bytes + decrypt src.to_slice, dst end - def decrypt(src : Bytes, dst : Bytes = Bytes.new(src.bytesize - SEAL_SIZE)) : Bytes + # Anonymously receive messages without a signature. + # + # For authenticated messages use `secret_key.box(recipient_public_key).decrypt`. + # + # Optionally supply a destination buffer. + def decrypt_string(src, dst : Bytes? = nil) : String + msg = decrypt src.to_slice, dst + String.new msg + end + + # :nodoc: + def decrypt(src : Bytes, dst : Bytes? = nil) : Bytes + dst_size = src.bytesize - SEAL_SIZE + dst ||= Bytes.new dst_size + raise ArgumentError.new("dst.bytesize must be src.bytesize - SEAL_SIZE, got #{dst.bytesize}") unless dst.bytesize == dst_size + if LibSodium.crypto_box_seal_open(dst, src, src.bytesize, @public_key.to_slice, self.to_slice) != 0 raise Sodium::Error.new("crypto_box_seal_open") end diff --git a/src/sodium/secret_box.cr b/src/sodium/secret_box.cr index d0ffea0..820cd8f 100644 --- a/src/sodium/secret_box.cr +++ b/src/sodium/secret_box.cr @@ -66,20 +66,26 @@ module Sodium end # Returns decrypted message. - def decrypt(src : Bytes, nonce : Nonce) : Bytes - dst_size = src.bytesize - MAC_SIZE - raise Sodium::Error::DecryptionFailed.new("encrypted data too small #{src.bytesize}") if dst_size <= 0 - dst = Bytes.new dst_size - decrypt(src, dst, nonce) + # + # Optionally supply a destination buffer. + def decrypt(src, dst : Bytes? = nil, *, nonce : Nonce) : Bytes + decrypt src.to_slice, dst, nonce: nonce end # Returns decrypted message. # # Optionally supply a destination buffer. - def decrypt(src : Bytes, dst : Bytes, nonce : Nonce) : Bytes - if dst.bytesize != (src.bytesize - MAC_SIZE) - raise ArgumentError.new("dst.bytesize must be src.bytesize - MAC_SIZE, got #{dst.bytesize}") - end + def decrypt_string(src, dst : Bytes? = nil, *, nonce : Nonce) : String + msg = decrypt src.to_slice, dst, nonce: nonce + String.new msg + end + + # :nodoc: + def decrypt(src : Bytes, dst : Bytes? = nil, *, nonce : Nonce) : Bytes + dst_size = src.bytesize - MAC_SIZE + dst ||= Bytes.new dst_size + raise ArgumentError.new("dst.bytesize must be src.bytesize - MAC_SIZE, got #{dst.bytesize}") if dst.bytesize != (src.bytesize - MAC_SIZE) + r = @key.readonly do LibSodium.crypto_secretbox_open_easy(dst, src, src.bytesize, nonce.to_slice, @key) end