diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/openssl/test_cipher.rb | 141 |
1 files changed, 137 insertions, 4 deletions
diff --git a/test/openssl/test_cipher.rb b/test/openssl/test_cipher.rb index ab131b8b1f..64c89be8b1 100644 --- a/test/openssl/test_cipher.rb +++ b/test/openssl/test_cipher.rb @@ -3,6 +3,25 @@ require_relative 'utils' if defined?(OpenSSL) class OpenSSL::TestCipher < Test::Unit::TestCase + + class << self + + def has_cipher?(name) + ciphers = OpenSSL::Cipher.ciphers + # redefine method so we can use the cached ciphers value from the closure + # and need not recompute the list each time + define_singleton_method :has_cipher? do |name| + ciphers.include?(name) + end + has_cipher?(name) + end + + def has_ciphers?(list) + list.all? { |name| has_cipher?(name) } + end + + end + def setup @c1 = OpenSSL::Cipher::Cipher.new("DES-EDE3-CBC") @c2 = OpenSSL::Cipher::DES.new(:EDE3, "CBC") @@ -78,11 +97,8 @@ class OpenSSL::TestCipher < Test::Unit::TestCase cipher.decrypt cipher.pkcs5_keyivgen('password') assert_equal('hello,world', cipher.update(c) + cipher.final) - rescue RuntimeError => e - # CTR is from OpenSSL 1.0.1, and for an environment that disables CTR; No idea it exists. - assert_match(/unsupported cipher algorithm/, e.message) end - end + end if has_cipher?('aes-128-ctr') if OpenSSL::OPENSSL_VERSION_NUMBER > 0x00907000 def test_ciphers @@ -116,6 +132,123 @@ class OpenSSL::TestCipher < Test::Unit::TestCase end end end + + if has_ciphers?(['aes-128-gcm', 'aes-192-gcm', 'aes-128-gcm']) + + def test_authenticated + cipher = OpenSSL::Cipher.new('aes-128-gcm') + assert(cipher.authenticated?) + cipher = OpenSSL::Cipher.new('aes-128-cbc') + refute(cipher.authenticated?) + end + + def test_aes_gcm + ['aes-128-gcm', 'aes-192-gcm', 'aes-128-gcm'].each do |algo| + pt = "You should all use Authenticated Encryption!" + cipher, key, iv = new_encryptor(algo) + + cipher.auth_data = "aad" + ct = cipher.update(pt) + cipher.final + tag = cipher.auth_tag + assert_equal(16, tag.size) + + decipher = new_decryptor(algo, key, iv) + decipher.auth_tag = tag + decipher.auth_data = "aad" + + assert_equal(pt, decipher.update(ct) + decipher.final) + end + end + + def test_aes_gcm_short_tag + ['aes-128-gcm', 'aes-192-gcm', 'aes-128-gcm'].each do |algo| + pt = "You should all use Authenticated Encryption!" + cipher, key, iv = new_encryptor(algo) + + cipher.auth_data = "aad" + ct = cipher.update(pt) + cipher.final + tag = cipher.auth_tag(8) + assert_equal(8, tag.size) + + decipher = new_decryptor(algo, key, iv) + decipher.auth_tag = tag + decipher.auth_data = "aad" + + assert_equal(pt, decipher.update(ct) + decipher.final) + end + end + + def test_aes_gcm_wrong_tag + pt = "You should all use Authenticated Encryption!" + cipher, key, iv = new_encryptor('aes-128-gcm') + + cipher.auth_data = "aad" + ct = cipher.update(pt) + cipher.final + tag = cipher.auth_tag + + decipher = new_decryptor('aes-128-gcm', key, iv) + decipher.auth_tag = tag[0..-2] << tag[-1].succ + decipher.auth_data = "aad" + + assert_raise OpenSSL::Cipher::CipherError do + decipher.update(ct) + decipher.final + end + end + + def test_aes_gcm_wrong_auth_data + pt = "You should all use Authenticated Encryption!" + cipher, key, iv = new_encryptor('aes-128-gcm') + + cipher.auth_data = "aad" + ct = cipher.update(pt) + cipher.final + tag = cipher.auth_tag + + decipher = new_decryptor('aes-128-gcm', key, iv) + decipher.auth_tag = tag + decipher.auth_data = "daa" + + assert_raise OpenSSL::Cipher::CipherError do + decipher.update(ct) + decipher.final + end + end + + def test_aes_gcm_wrong_ciphertext + pt = "You should all use Authenticated Encryption!" + cipher, key, iv = new_encryptor('aes-128-gcm') + + cipher.auth_data = "aad" + ct = cipher.update(pt) + cipher.final + tag = cipher.auth_tag + + decipher = new_decryptor('aes-128-gcm', key, iv) + decipher.auth_tag = tag + decipher.auth_data = "aad" + + assert_raise OpenSSL::Cipher::CipherError do + decipher.update(ct[0..-2] << ct[-1].succ) + decipher.final + end + end + + end + + private + + def new_encryptor(algo) + cipher = OpenSSL::Cipher.new(algo) + cipher.encrypt + key = cipher.random_key + iv = cipher.random_iv + [cipher, key, iv] + end + + def new_decryptor(algo, key, iv) + OpenSSL::Cipher.new(algo).tap do |cipher| + cipher.decrypt + cipher.key = key + cipher.iv = iv + end + end + end end |