Sophie

Sophie

distrib > Mageia > 5 > i586 > media > core-updates-src > by-pkgid > 72359a4accb612af93f2f9dc19bf7a74 > files > 9

ruby-2.0.0.p648-1.6.mga5.src.rpm

--- ruby-2.0.0-p648/ext/openssl/ossl_cipher.c.0022	2015-01-14 07:25:48.000000000 +0000
+++ ruby-2.0.0-p648/ext/openssl/ossl_cipher.c	2016-10-03 21:47:10.496529244 +0100
@@ -35,6 +35,7 @@
  */
 VALUE cCipher;
 VALUE eCipherError;
+static ID id_key_set;
 
 static VALUE ossl_cipher_alloc(VALUE klass);
 
@@ -102,7 +103,6 @@
     EVP_CIPHER_CTX *ctx;
     const EVP_CIPHER *cipher;
     char *name;
-    unsigned char key[EVP_MAX_KEY_LENGTH];
 
     name = StringValuePtr(str);
     GetCipherInit(self, ctx);
@@ -114,14 +114,7 @@
     if (!(cipher = EVP_get_cipherbyname(name))) {
 	ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%s)", name);
     }
-    /*
-     * The EVP which has EVP_CIPH_RAND_KEY flag (such as DES3) allows
-     * uninitialized key, but other EVPs (such as AES) does not allow it.
-     * Calling EVP_CipherUpdate() without initializing key causes SEGV so we
-     * set the data filled with "\0" as the key by default.
-     */
-    memset(key, 0, EVP_MAX_KEY_LENGTH);
-    if (EVP_CipherInit_ex(ctx, cipher, NULL, key, NULL, -1) != 1)
+    if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1)
 	ossl_raise(eCipherError, NULL);
 
     return self;
@@ -239,7 +232,8 @@
     if (EVP_CipherInit_ex(ctx, NULL, NULL, p_key, p_iv, mode) != 1) {
 	ossl_raise(eCipherError, NULL);
     }
-
+    if (p_key)
+	rb_ivar_set(self, id_key_set, Qtrue);
     return self;
 }
 
@@ -326,6 +320,7 @@
     OPENSSL_cleanse(key, sizeof key);
     OPENSSL_cleanse(iv, sizeof iv);
 
+    rb_ivar_set(self, id_key_set, Qtrue);
     return Qnil;
 }
 
@@ -379,6 +374,9 @@
 
     rb_scan_args(argc, argv, "11", &data, &str);
 
+    if (!RTEST(rb_attr_get(self, id_key_set)))
+	ossl_raise(eCipherError, "key not set");
+
     StringValue(data);
     in = (unsigned char *)RSTRING_PTR(data);
     if ((in_len = RSTRING_LEN(data)) == 0)
@@ -478,6 +476,7 @@
     if (EVP_CipherInit_ex(ctx, NULL, NULL, (unsigned char *)RSTRING_PTR(key), NULL, -1) != 1)
         ossl_raise(eCipherError, NULL);
 
+    rb_ivar_set(self, id_key_set, Qtrue);
     return key;
 }
 
@@ -996,5 +995,7 @@
     rb_define_method(cCipher, "iv_len", ossl_cipher_iv_length, 0);
     rb_define_method(cCipher, "block_size", ossl_cipher_block_size, 0);
     rb_define_method(cCipher, "padding=", ossl_cipher_set_padding, 1);
+
+    id_key_set = rb_intern_const("key_set");
 }
 
--- ruby-2.0.0-p648/test/openssl/test_cipher.rb.0022	2015-02-17 08:59:14.000000000 +0000
+++ ruby-2.0.0-p648/test/openssl/test_cipher.rb	2016-10-03 21:44:11.051625297 +0100
@@ -128,12 +128,10 @@
       }
     end
 
-    def test_AES_crush
-      500.times do
-        assert_nothing_raised("[Bug #2768]") do
-          # it caused OpenSSL SEGV by uninitialized key
-          OpenSSL::Cipher::AES128.new("ECB").update "." * 17
-        end
+    def test_update_raise_if_key_not_set
+      assert_raise(OpenSSL::Cipher::CipherError) do
+        # it caused OpenSSL SEGV by uninitialized key [Bug #2768]
+        OpenSSL::Cipher::AES128.new("ECB").update "." * 17
       end
     end
   end
@@ -235,6 +233,23 @@
       end
     end
 
+    def test_aes_gcm_key_iv_order_issue
+      pt = "You should all use Authenticated Encryption!"
+      cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt
+      cipher.key = "x" * 16
+      cipher.iv = "a" * 12
+      ct1 = cipher.update(pt) << cipher.final
+      tag1 = cipher.auth_tag
+
+      cipher = OpenSSL::Cipher.new("aes-128-gcm").encrypt
+      cipher.iv = "a" * 12
+      cipher.key = "x" * 16
+      ct2 = cipher.update(pt) << cipher.final
+      tag2 = cipher.auth_tag
+
+      assert_equal ct1, ct2
+      assert_equal tag1, tag2
+    end if has_cipher?("aes-128-gcm")
   end
 
   private