Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Allow Lock to decrypt arbitrary strings encrypted with the same keypair.

  • Loading branch information...
commit 8236c73d94ac3909dccf0b48d10df13a8519d6eb 1 parent 850bd70
Jason Whittle authored
View
4 lib/strongbox/lock.rb
@@ -60,10 +60,10 @@ def encrypt plaintext
# Given the private key password decrypts the attribute. Will raise
# OpenSSL::PKey::RSAError if the password is wrong.
- def decrypt password = nil
+ def decrypt password = nil, ciphertext = nil
# Given a private key and a nil password OpenSSL::PKey::RSA.new() will
# *prompt* for a password, we default to an empty string to avoid that.
- ciphertext = @instance[@name]
+ ciphertext ||= @instance[@name]
return nil if ciphertext.nil?
return "" if ciphertext.empty?
View
BIN  test/fixtures/encrypted
Binary file not shown
View
66 test/strongbox_test.rb
@@ -15,31 +15,31 @@ class StrongboxTest < Test::Unit::TestCase
end
end
end
-
+
context 'that is valid' do
setup do
@dummy = Dummy.new
@dummy.secret = 'Shhhh'
@dummy.in_the_clear = 'Hey you guys!'
end
-
+
should 'not change unencrypted fields' do
assert_equal 'Hey you guys!', @dummy.in_the_clear
end
-
+
should 'return "*encrypted*" when locked' do
assert_equal '*encrypted*', @dummy.secret.decrypt
end
-
+
should 'return secret when unlocked' do
assert_equal 'Shhhh', @dummy.secret.decrypt(@password)
end
-
+
should 'generate and store symmetric encryption key and IV' do
assert_not_nil @dummy.attributes['secret_key']
assert_not_nil @dummy.attributes['secret_iv']
end
-
+
should 'raise on bad password' do
assert_raises(OpenSSL::PKey::RSAError) do
@dummy.secret.decrypt('letmein')
@@ -51,12 +51,12 @@ class StrongboxTest < Test::Unit::TestCase
@dummy.in_the_clear = 'I see you...'
@dummy.save
end
-
+
should 'not effect the secret' do
assert_equal 'Shhhh', @dummy.secret.decrypt(@password)
end
end
-
+
context 'updating the secret' do
setup do
@dummy.secret = @new_secret = 'Don\'t tell'
@@ -67,7 +67,7 @@ class StrongboxTest < Test::Unit::TestCase
assert_equal @new_secret, @dummy.secret.decrypt(@password)
end
end
-
+
context 'with symmetric encryption disabled' do
setup do
rebuild_class(:key_pair => File.join(FIXTURES_DIR,'keypair.pem'),
@@ -75,22 +75,27 @@ class StrongboxTest < Test::Unit::TestCase
@dummy = Dummy.new
@dummy.secret = 'Shhhh'
end
-
+
should 'return "*encrypted*" when locked' do
assert_equal '*encrypted*', @dummy.secret.decrypt
end
-
+
should 'return secret when unlocked' do
assert_equal 'Shhhh', @dummy.secret.decrypt(@password)
end
-
+
+ should 'allow decryption of other strings encrypted with the same key' do
+ encrypted_text = File.read(File.join(FIXTURES_DIR,'encrypted'))
+ assert_equal 'Setec Astronomy', @dummy.secret.decrypt(@password, encrypted_text)
+ end
+
should 'not generate and store symmetric encryption key and IV' do
assert_nil @dummy.attributes['secret_key']
assert_nil @dummy.attributes['secret_iv']
end
end
-
+
context 'with Base64 encoding enabled' do
setup do
rebuild_class(:key_pair => File.join(FIXTURES_DIR,'keypair.pem'),
@@ -98,7 +103,7 @@ class StrongboxTest < Test::Unit::TestCase
@dummy = Dummy.new
@dummy.secret = 'Shhhh'
end
-
+
should 'Base64 encode the ciphertext' do
# Base64 encoded text is limited to the charaters A–Z, a–z, and 0–9,
# and is padded with 0 to 2 equal-signs
@@ -106,7 +111,7 @@ class StrongboxTest < Test::Unit::TestCase
assert_match /^[0-9A-Za-z+\/]+={0,2}$/, @dummy.attributes['secret_key']
assert_match /^[0-9A-Za-z+\/]+={0,2}$/, @dummy.attributes['secret_iv']
end
-
+
should 'encrypt the data' do
assert_not_equal @dummy.attributes['secret'], 'Shhhh'
assert_equal '*encrypted*', @dummy.secret.decrypt
@@ -114,7 +119,7 @@ class StrongboxTest < Test::Unit::TestCase
end
end
end
-
+
context 'using blowfish cipher instead of AES' do
setup do
rebuild_class(:key_pair => File.join(FIXTURES_DIR,'keypair.pem'),
@@ -122,7 +127,7 @@ class StrongboxTest < Test::Unit::TestCase
@dummy = Dummy.new
@dummy.secret = 'Shhhh'
end
-
+
should 'encrypt the data' do
assert_not_equal @dummy.attributes['secret'], 'Shhhh'
assert_equal '*encrypted*', @dummy.secret.decrypt
@@ -143,20 +148,20 @@ class StrongboxTest < Test::Unit::TestCase
end
end
end
-
+
context 'when a private key is not provided' do
setup do
@password = 'boost facile'
rebuild_class(:public_key => File.join(FIXTURES_DIR,'keypair.pem'))
@dummy = Dummy.new(:secret => 'Shhhh')
end
-
+
should 'raise on decrypt with a password' do
assert_raises(Strongbox::StrongboxError) do
@dummy.secret.decrypt(@password)
end
end
-
+
should 'return "*encrypted*" when still locked' do
assert_equal '*encrypted*', @dummy.secret.decrypt
end
@@ -185,7 +190,7 @@ class StrongboxTest < Test::Unit::TestCase
assert_equal "Shhhh", @dummy.secret.decrypt('')
end
end
-
+
context 'with validations' do
context 'using validates_presence_of' do
setup do
@@ -194,18 +199,18 @@ class StrongboxTest < Test::Unit::TestCase
@valid = Dummy.new(:secret => 'Shhhh')
@invalid = Dummy.new(:secret => nil)
end
-
+
should 'not have an error on the secret when valid' do
assert @valid.valid?
assert_does_not_have_errors_on(@valid,:secret)
end
-
+
should 'have an error on the secret when invalid' do
assert !@invalid.valid?
assert_has_errors_on(@invalid,:secret)
end
end
-
+
context 'using validates_length_of' do
setup do
rebuild_class(:key_pair => File.join(FIXTURES_DIR,'keypair.pem'))
@@ -220,22 +225,22 @@ class StrongboxTest < Test::Unit::TestCase
@valid_blank = Dummy.new(:secret => '')
@invalid = Dummy.new(:secret => '1')
end
-
+
should 'not have an error on the secret when in range' do
assert @valid.valid?
assert_does_not_have_errors_on(@valid,:secret)
end
-
+
should 'not have an error on the secret when nil' do
assert @valid_nil.valid?
assert_does_not_have_errors_on(@valid_nil,:secret)
end
-
+
should 'not have an error on the secret when blank' do
assert @valid_blank.valid?
assert_does_not_have_errors_on(@valid_blank,:secret)
end
-
+
should 'have an error on the secret when invalid' do
assert !@invalid.valid?
assert_has_errors_on(@invalid,:secret)
@@ -260,7 +265,7 @@ class StrongboxTest < Test::Unit::TestCase
@dummy.secret = 'I have a secret...'
@dummy.segreto = 'Ho un segreto...'
end
-
+
should 'return "*encrypted*" when the record is locked' do
assert_equal '*encrypted*', @dummy.secret.decrypt
assert_equal '*encrypted*', @dummy.segreto.decrypt
@@ -290,10 +295,9 @@ class StrongboxTest < Test::Unit::TestCase
should 'return "*encrypted*" when locked' do
assert_equal '*encrypted*', @dummy.secret.decrypt
end
-
+
should 'return secret when unlocked' do
assert_equal 'Shhhh', @dummy.secret.decrypt(@password)
end
end
end
-
Please sign in to comment.
Something went wrong with that request. Please try again.