Skip to content

Commit

Permalink
openssl: make Cipher#key= and #iv= reject too long values
Browse files Browse the repository at this point in the history
* ext/openssl/ossl_cipher.c (ossl_cipher_set_key, ossl_cipher_set_iv):
  Reject too long values as well as too short ones. Currently they
  just truncate the input but this would hide bugs and lead to
  unexpected encryption/decryption results.

* test/openssl/test_cipher.rb: Test that Cipher#key= and #iv= reject
  Strings with invalid length.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55146 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
rhenium committed May 31, 2016
1 parent 5783408 commit f8eec6b
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
14 changes: 9 additions & 5 deletions ext/openssl/ossl_cipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -480,15 +480,17 @@ static VALUE
ossl_cipher_set_key(VALUE self, VALUE key)
{
EVP_CIPHER_CTX *ctx;
int key_len;

StringValue(key);
GetCipher(self, ctx);

if (RSTRING_LEN(key) < EVP_CIPHER_CTX_key_length(ctx))
ossl_raise(eCipherError, "key length too short");
key_len = EVP_CIPHER_CTX_key_length(ctx);
if (RSTRING_LEN(key) != key_len)
ossl_raise(rb_eArgError, "key must be %d bytes", key_len);

if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1)
ossl_raise(eCipherError, NULL);
ossl_raise(eCipherError, NULL);

return key;
}
Expand All @@ -512,12 +514,14 @@ static VALUE
ossl_cipher_set_iv(VALUE self, VALUE iv)
{
EVP_CIPHER_CTX *ctx;
int iv_len;

StringValue(iv);
GetCipher(self, ctx);

if (RSTRING_LEN(iv) < EVP_CIPHER_CTX_iv_length(ctx))
ossl_raise(eCipherError, "iv length too short");
iv_len = EVP_CIPHER_CTX_iv_length(ctx);
if (RSTRING_LEN(iv) != iv_len)
ossl_raise(rb_eArgError, "iv must be %d bytes", iv_len);

if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, (unsigned char *)RSTRING_PTR(iv), -1) != 1)
ossl_raise(eCipherError, NULL);
Expand Down
12 changes: 12 additions & 0 deletions test/test_cipher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,18 @@ def test_reset
assert_equal(s1, s2, "encrypt reset")
end

def test_key_iv_set
# default value for DES-EDE3-CBC
assert_equal(24, @c1.key_len)
assert_equal(8, @c1.iv_len)
assert_raise(ArgumentError) { @c1.key = "\x01" * 23 }
@c1.key = "\x01" * 24
assert_raise(ArgumentError) { @c1.key = "\x01" * 25 }
assert_raise(ArgumentError) { @c1.iv = "\x01" * 7 }
@c1.iv = "\x01" * 8
assert_raise(ArgumentError) { @c1.iv = "\x01" * 9 }
end

def test_empty_data
@c1.encrypt
assert_raise(ArgumentError){ @c1.update("") }
Expand Down

0 comments on commit f8eec6b

Please sign in to comment.