From 0defff925a85f675b17c7c6d6d8c9d2d20f6c56c Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Thu, 5 May 2016 15:53:08 +0900 Subject: ext/openssl: use HMAC_CTX_{new,free,reset} to allocate HMAC_CTX HMAC_CTX is made opaque in OpenSSL 1.1.0 --- ext/openssl/extconf.rb | 3 +++ ext/openssl/openssl_missing.c | 39 +++++++++++++++++++++++++++++++++++++-- ext/openssl/openssl_missing.h | 14 +++++++++++++- ext/openssl/ossl_hmac.c | 41 ++++++++++++++++++++++------------------- 4 files changed, 75 insertions(+), 22 deletions(-) diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index 8af5e50e8a..20681f932f 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -103,6 +103,9 @@ OpenSSL.check_func_or_macro("SSL_get_server_tmp_key", "openssl/ssl.h") # added in 1.1.0 have_func("CRYPTO_lock") || $defs.push("-DHAVE_OPENSSL_110_THREADING_API") +have_func("HMAC_CTX_new") +have_func("HMAC_CTX_free") +have_func("HMAC_CTX_reset") OpenSSL.check_func("RAND_pseudo_bytes", "openssl/rand.h") # deprecated have_func("X509_STORE_get_ex_data") have_func("X509_STORE_set_ex_data") diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c index 4222ce65bf..735ec8cfd5 100644 --- a/ext/openssl/openssl_missing.c +++ b/ext/openssl/openssl_missing.c @@ -65,15 +65,19 @@ EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) #endif #if !defined(HAVE_HMAC_CTX_COPY) -void +int HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in) { - if (!out || !in) return; + if (!out || !in) + return 0; + memcpy(out, in, sizeof(HMAC_CTX)); EVP_MD_CTX_copy(&out->md_ctx, &in->md_ctx); EVP_MD_CTX_copy(&out->i_ctx, &in->i_ctx); EVP_MD_CTX_copy(&out->o_ctx, &in->o_ctx); + + return 1; } #endif /* HAVE_HMAC_CTX_COPY */ @@ -95,3 +99,34 @@ CRYPTO_memcmp(const volatile void * volatile in_a, return x; } #endif + +/*** added in 1.1.0 ***/ +#if !defined(HAVE_HMAC_CTX_NEW) +HMAC_CTX * +HMAC_CTX_new(void) +{ + HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX)); + HMAC_CTX_reset(ctx); + if (!ctx) + return NULL; + return ctx; +} +#endif + +#if !defined(HAVE_HMAC_CTX_FREE) +void +HMAC_CTX_free(HMAC_CTX *ctx) +{ + HMAC_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} +#endif + +#if !defined(HAVE_HMAC_CTX_RESET) +int +HMAC_CTX_reset(HMAC_CTX *ctx) +{ + HMAC_CTX_init(ctx); + return 0; +} +#endif diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 1261d78a79..f9365124c5 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -30,7 +30,7 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); #endif #if !defined(HAVE_HMAC_CTX_COPY) -void HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in); +int HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in); #endif /* added in 1.0.2 */ @@ -48,6 +48,18 @@ int CRYPTO_memcmp(const volatile void * volatile in_a, const volatile void * vol #endif /* added in 1.1.0 */ +#if !defined(HAVE_HMAC_CTX_NEW) +HMAC_CTX *HMAC_CTX_new(void); +#endif + +#if !defined(HAVE_HMAC_CTX_FREE) +void HMAC_CTX_free(HMAC_CTX *ctx); +#endif + +#if !defined(HAVE_HMAC_CTX_RESET) +int HMAC_CTX_reset(HMAC_CTX *ctx); +#endif + #if !defined(HAVE_X509_STORE_GET_EX_DATA) # define X509_STORE_get_ex_data(x, idx) \ CRYPTO_get_ex_data(&(x)->ex_data, idx) diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c index 7c114cfb68..dbe5cb84a4 100644 --- a/ext/openssl/ossl_hmac.c +++ b/ext/openssl/ossl_hmac.c @@ -9,8 +9,8 @@ */ #include "ossl.h" -#define MakeHMAC(obj, klass, ctx) \ - (obj) = TypedData_Make_Struct((klass), HMAC_CTX, &ossl_hmac_type, (ctx)) +#define NewHMAC(klass) \ + TypedData_Wrap_Struct((klass), &ossl_hmac_type, 0) #define GetHMAC(obj, ctx) do { \ TypedData_Get_Struct((obj), HMAC_CTX, &ossl_hmac_type, (ctx)); \ if (!(ctx)) { \ @@ -38,8 +38,7 @@ VALUE eHMACError; static void ossl_hmac_free(void *ctx) { - HMAC_CTX_cleanup(ctx); - ruby_xfree(ctx); + HMAC_CTX_free(ctx); } static const rb_data_type_t ossl_hmac_type = { @@ -53,11 +52,12 @@ static const rb_data_type_t ossl_hmac_type = { static VALUE ossl_hmac_alloc(VALUE klass) { - HMAC_CTX *ctx; VALUE obj; - - MakeHMAC(obj, klass, ctx); - HMAC_CTX_init(ctx); + HMAC_CTX *ctx = HMAC_CTX_new(); + if (!ctx) + ossl_raise(rb_eRuntimeError, "HMAC_CTX_new() failed"); + obj = NewHMAC(klass); + RTYPEDDATA_DATA(obj) = ctx; return obj; } @@ -105,8 +105,9 @@ ossl_hmac_initialize(VALUE self, VALUE key, VALUE digest) StringValue(key); GetHMAC(self, ctx); - HMAC_Init(ctx, RSTRING_PTR(key), RSTRING_LENINT(key), - GetDigestPtr(digest)); + HMAC_CTX_reset(ctx); + HMAC_Init_ex(ctx, RSTRING_PTR(key), RSTRING_LENINT(key), + GetDigestPtr(digest), NULL); return self; } @@ -159,16 +160,18 @@ ossl_hmac_update(VALUE self, VALUE data) static void hmac_final(HMAC_CTX *ctx, unsigned char **buf, unsigned int *buf_len) { - HMAC_CTX final; - - HMAC_CTX_copy(&final, ctx); - if (!(*buf = OPENSSL_malloc(HMAC_size(&final)))) { - HMAC_CTX_cleanup(&final); - OSSL_Debug("Allocating %d mem", HMAC_size(&final)); + HMAC_CTX *final = HMAC_CTX_new(); + if (!final) + ossl_raise(eHMACError, "HMAC_CTX_new() failed"); + + HMAC_CTX_copy(final, ctx); + if (!(*buf = OPENSSL_malloc(HMAC_size(final)))) { + HMAC_CTX_free(final); + OSSL_Debug("Allocating %"PRIuSIZE" mem", (size_t)HMAC_size(final)); ossl_raise(eHMACError, "Cannot allocate memory for hmac"); } - HMAC_Final(&final, *buf, buf_len); - HMAC_CTX_cleanup(&final); + HMAC_Final(final, *buf, buf_len); + HMAC_CTX_free(final); } /* @@ -254,7 +257,7 @@ ossl_hmac_reset(VALUE self) HMAC_CTX *ctx; GetHMAC(self, ctx); - HMAC_Init(ctx, NULL, 0, NULL); + HMAC_CTX_reset(ctx); return self; } -- cgit v1.2.3