Skip to content

Commit e46d992

Browse files
committed
cipher: remove Cipher#encrypt(password, iv) form
OpenSSL::Cipher#encrypt and #decrypt have long supported a hidden feature to derive a key and an IV from the String argument, but in an inappropriate way. This feature is undocumented, untested, and has been deprecated since commit ruby/ruby@0dc4321 on 2004-06-30, which started printing a non-verbose warning. More than 20 years later, it must be safe to remove it entirely. The deprecated usage: # `password` is a String, `iv` is either a String or nil cipher = OpenSSL::Cipher.new("aes-256-cbc") cipher.encrypt(password, iv) p cipher.update("data") << cipher.final was equivalent to: cipher = OpenSSL::Cipher.new("aes-256-cbc") cipher.encrypt iv ||= "OpenSSL for Ruby rulez!" key = ((cipher.key_len + 15) / 16).times.inject([""]) { |ary, _| ary << OpenSSL::Digest.digest("MD5", ary.last + password + iv[0, 8].ljust(8, "\0")) }.join cipher.key = key[...cipher.key_len] cipher.iv = iv[...cipher.iv_len].ljust(cipher.iv_len, "\0") p cipher.update("data") << cipher.final
1 parent 080b21d commit e46d992

File tree

1 file changed

+12
-43
lines changed

1 file changed

+12
-43
lines changed

ext/openssl/ossl_cipher.c

Lines changed: 12 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -198,47 +198,16 @@ ossl_cipher_reset(VALUE self)
198198
}
199199

200200
static VALUE
201-
ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
201+
ossl_cipher_init(VALUE self, int enc)
202202
{
203203
EVP_CIPHER_CTX *ctx;
204-
unsigned char key[EVP_MAX_KEY_LENGTH], *p_key = NULL;
205-
unsigned char iv[EVP_MAX_IV_LENGTH], *p_iv = NULL;
206-
VALUE pass, init_v;
207-
208-
if(rb_scan_args(argc, argv, "02", &pass, &init_v) > 0){
209-
/*
210-
* oops. this code mistakes salt for IV.
211-
* We deprecated the arguments for this method, but we decided
212-
* keeping this behaviour for backward compatibility.
213-
*/
214-
VALUE cname = rb_class_path(rb_obj_class(self));
215-
rb_warn("arguments for %"PRIsVALUE"#encrypt and %"PRIsVALUE"#decrypt were deprecated; "
216-
"use %"PRIsVALUE"#pkcs5_keyivgen to derive key and IV",
217-
cname, cname, cname);
218-
StringValue(pass);
219-
GetCipher(self, ctx);
220-
if (NIL_P(init_v)) memcpy(iv, "OpenSSL for Ruby rulez!", sizeof(iv));
221-
else{
222-
StringValue(init_v);
223-
if (EVP_MAX_IV_LENGTH > RSTRING_LEN(init_v)) {
224-
memset(iv, 0, EVP_MAX_IV_LENGTH);
225-
memcpy(iv, RSTRING_PTR(init_v), RSTRING_LEN(init_v));
226-
}
227-
else memcpy(iv, RSTRING_PTR(init_v), sizeof(iv));
228-
}
229-
EVP_BytesToKey(EVP_CIPHER_CTX_cipher(ctx), EVP_md5(), iv,
230-
(unsigned char *)RSTRING_PTR(pass), RSTRING_LENINT(pass), 1, key, NULL);
231-
p_key = key;
232-
p_iv = iv;
233-
}
234-
else {
235-
GetCipher(self, ctx);
236-
}
237-
if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) {
238-
ossl_raise(eCipherError, NULL);
204+
205+
GetCipher(self, ctx);
206+
if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, enc) != 1) {
207+
ossl_raise(eCipherError, "EVP_CipherInit_ex");
239208
}
240209

241-
rb_ivar_set(self, id_key_set, p_key ? Qtrue : Qfalse);
210+
rb_ivar_set(self, id_key_set, Qfalse);
242211

243212
return self;
244213
}
@@ -256,9 +225,9 @@ ossl_cipher_init(int argc, VALUE *argv, VALUE self, int mode)
256225
* Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 1).
257226
*/
258227
static VALUE
259-
ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self)
228+
ossl_cipher_encrypt(VALUE self)
260229
{
261-
return ossl_cipher_init(argc, argv, self, 1);
230+
return ossl_cipher_init(self, 1);
262231
}
263232

264233
/*
@@ -274,9 +243,9 @@ ossl_cipher_encrypt(int argc, VALUE *argv, VALUE self)
274243
* Internally calls EVP_CipherInit_ex(ctx, NULL, NULL, NULL, NULL, 0).
275244
*/
276245
static VALUE
277-
ossl_cipher_decrypt(int argc, VALUE *argv, VALUE self)
246+
ossl_cipher_decrypt(VALUE self)
278247
{
279-
return ossl_cipher_init(argc, argv, self, 0);
248+
return ossl_cipher_init(self, 0);
280249
}
281250

282251
/*
@@ -1064,8 +1033,8 @@ Init_ossl_cipher(void)
10641033
rb_define_module_function(cCipher, "ciphers", ossl_s_ciphers, 0);
10651034
rb_define_method(cCipher, "initialize", ossl_cipher_initialize, 1);
10661035
rb_define_method(cCipher, "reset", ossl_cipher_reset, 0);
1067-
rb_define_method(cCipher, "encrypt", ossl_cipher_encrypt, -1);
1068-
rb_define_method(cCipher, "decrypt", ossl_cipher_decrypt, -1);
1036+
rb_define_method(cCipher, "encrypt", ossl_cipher_encrypt, 0);
1037+
rb_define_method(cCipher, "decrypt", ossl_cipher_decrypt, 0);
10691038
rb_define_method(cCipher, "pkcs5_keyivgen", ossl_cipher_pkcs5_keyivgen, -1);
10701039
rb_define_method(cCipher, "update", ossl_cipher_update, -1);
10711040
rb_define_method(cCipher, "final", ossl_cipher_final, 0);

0 commit comments

Comments
 (0)