From 5625fdeaae46f80e5673d8863319b2abfdc4ccf7 Mon Sep 17 00:00:00 2001 From: rhe Date: Sun, 5 Jun 2016 15:35:12 +0000 Subject: openssl: adapt to OpenSSL 1.1.0 opaque structs * ext/openssl/extconf.rb: Check existence of accessor functions that don't exist in OpenSSL 0.9.8. OpenSSL 1.1.0 made most of its structures opaque and requires use of these accessor functions. [ruby-core:75225] [Feature #12324] * ext/openssl/openssl_missing.[ch]: Implement them if missing. * ext/openssl/ossl*.c: Use these accessor functions. * test/openssl/test_hmac.rb: Add missing test for HMAC#reset. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55287 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ext/openssl/ossl_cipher.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) (limited to 'ext/openssl/ossl_cipher.c') diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c index d56b3411e7..54e363faa2 100644 --- a/ext/openssl/ossl_cipher.c +++ b/ext/openssl/ossl_cipher.c @@ -11,10 +11,12 @@ #define NewCipher(klass) \ TypedData_Wrap_Struct((klass), &ossl_cipher_type, 0) -#define MakeCipher(obj, klass, ctx) \ - (obj) = TypedData_Make_Struct((klass), EVP_CIPHER_CTX, &ossl_cipher_type, (ctx)) -#define AllocCipher(obj, ctx) \ - (DATA_PTR(obj) = (ctx) = ZALLOC(EVP_CIPHER_CTX)) +#define AllocCipher(obj, ctx) do { \ + (ctx) = EVP_CIPHER_CTX_new(); \ + if (!(ctx)) \ + ossl_raise(rb_eRuntimeError, NULL); \ + RTYPEDDATA_DATA(obj) = (ctx); \ +} while (0) #define GetCipherInit(obj, ctx) do { \ TypedData_Get_Struct((obj), EVP_CIPHER_CTX, &ossl_cipher_type, (ctx)); \ } while (0) @@ -37,13 +39,13 @@ VALUE eCipherError; static VALUE ossl_cipher_alloc(VALUE klass); static void ossl_cipher_free(void *ptr); -static size_t ossl_cipher_memsize(const void *ptr); static const rb_data_type_t ossl_cipher_type = { "OpenSSL/Cipher", - {0, ossl_cipher_free, ossl_cipher_memsize,}, - 0, 0, - RUBY_TYPED_FREE_IMMEDIATELY, + { + 0, ossl_cipher_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, }; /* @@ -67,7 +69,6 @@ ossl_cipher_new(const EVP_CIPHER *cipher) ret = ossl_cipher_alloc(cCipher); AllocCipher(ret, ctx); - EVP_CIPHER_CTX_init(ctx); if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) ossl_raise(eCipherError, NULL); @@ -87,13 +88,6 @@ ossl_cipher_free(void *ptr) } } -static size_t -ossl_cipher_memsize(const void *ptr) -{ - const EVP_CIPHER_CTX *ctx = ptr; - return sizeof(*ctx); -} - static VALUE ossl_cipher_alloc(VALUE klass) { @@ -114,7 +108,7 @@ ossl_cipher_initialize(VALUE self, VALUE str) EVP_CIPHER_CTX *ctx; const EVP_CIPHER *cipher; char *name; - unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char dummy_key[EVP_MAX_KEY_LENGTH] = { 0 }; name = StringValueCStr(str); GetCipherInit(self, ctx); @@ -122,18 +116,19 @@ ossl_cipher_initialize(VALUE self, VALUE str) ossl_raise(rb_eRuntimeError, "Cipher already inititalized!"); } AllocCipher(self, ctx); - EVP_CIPHER_CTX_init(ctx); if (!(cipher = EVP_get_cipherbyname(name))) { ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%"PRIsVALUE")", str); } /* + * EVP_CipherInit_ex() allows to specify NULL to key and IV, however some + * ciphers don't handle well (OpenSSL's bug). [Bug #2768] + * * 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, dummy_key, NULL, -1) != 1) ossl_raise(eCipherError, NULL); return self; -- cgit v1.2.3