From 578935718790e8137dd3afd5c5b10c23bbeec51f Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Wed, 20 Apr 2016 13:26:54 +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 | 5 ++- ext/openssl/openssl_missing.c | 78 +++++++++++++++++++++++++++++++------------ ext/openssl/openssl_missing.h | 35 +++++++++++++------ ext/openssl/ossl_hmac.c | 41 ++++++++++++----------- 4 files changed, 107 insertions(+), 52 deletions(-) diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index b9b5ad61fb..acfc09d376 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -78,10 +78,10 @@ engines.each { |name| have_func("EVP_CIPHER_CTX_new") have_func("EVP_CIPHER_CTX_free") have_func("SSL_CTX_clear_options", ["openssl/ssl.h"]) -have_func("HMAC_CTX_copy") # added in 1.0.0 have_func("EVP_CIPHER_CTX_copy") +have_func("HMAC_CTX_copy") have_func("PKCS5_PBKDF2_HMAC") have_func("X509_NAME_hash_old") have_func("SSL_set_tlsext_host_name", ["openssl/ssl.h"]) @@ -98,6 +98,9 @@ have_func("SSL_CTX_set_alpn_select_cb") have_func("SSL_get_server_tmp_key", ["openssl/ssl.h"]) # added in 1.1.0 +have_func("HMAC_CTX_new") +have_func("HMAC_CTX_free") +have_func("HMAC_CTX_reset") have_func("RAND_pseudo_bytes", ["openssl/rand.h"], "-Werror=deprecated-declarations") 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 2e1e534854..7bd4fb7d9b 100644 --- a/ext/openssl/openssl_missing.c +++ b/ext/openssl/openssl_missing.c @@ -41,19 +41,6 @@ EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) #endif /*** added in 1.0.0 ***/ -#if !defined(HAVE_HMAC_CTX_COPY) -void -HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in) -{ - if (!out || !in) return; - 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); -} -#endif /* HAVE_HMAC_CTX_COPY */ - #if !defined(HAVE_EVP_CIPHER_CTX_COPY) /* * this function does not exist in OpenSSL yet... or ever?. @@ -77,20 +64,22 @@ EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) } #endif -#if !defined(HAVE_X509_STORE_SET_EX_DATA) -int X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data) +#if !defined(HAVE_HMAC_CTX_COPY) +void +HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in) { - return CRYPTO_set_ex_data(&str->ex_data, idx, data); -} -#endif + if (!out || !in) return; + memcpy(out, in, sizeof(HMAC_CTX)); -#if !defined(HAVE_X509_STORE_GET_EX_DATA) -void *X509_STORE_get_ex_data(X509_STORE *str, int idx) -{ - return CRYPTO_get_ex_data(&str->ex_data, idx); + 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); } #endif +/*** added in 1.0.1 ***/ + +/*** added in 1.0.2 ***/ #if !defined(HAVE_CRYPTO_MEMCMP) int CRYPTO_memcmp(const volatile void * volatile in_a, @@ -108,3 +97,48 @@ 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 + +#if !defined(HAVE_X509_STORE_SET_EX_DATA) +int X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data) +{ + return CRYPTO_set_ex_data(&str->ex_data, idx, data); +} +#endif + +#if !defined(HAVE_X509_STORE_GET_EX_DATA) +void *X509_STORE_get_ex_data(X509_STORE *str, int idx) +{ + return CRYPTO_get_ex_data(&str->ex_data, idx); +} +#endif diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 3e2c8159e4..7227c4611e 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -29,22 +29,16 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); #endif /*** added in 1.0.0 ***/ -#if !defined(HAVE_HMAC_CTX_COPY) -void HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in); -#endif - #if !defined(HAVE_EVP_CIPHER_CTX_COPY) int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); #endif -#if !defined(HAVE_X509_STORE_GET_EX_DATA) -void *X509_STORE_get_ex_data(X509_STORE *str, int idx); -#endif - -#if !defined(HAVE_X509_STORE_SET_EX_DATA) -int X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data); +#if !defined(HAVE_HMAC_CTX_COPY) +void HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in); #endif +/*** added in 1.0.1 ***/ +/*** added in 1.0.2 ***/ #if !defined(HAVE_CRYPTO_MEMCMP) int CRYPTO_memcmp(const volatile void * volatile in_a, const volatile void * volatile in_b, size_t len); #endif @@ -54,6 +48,27 @@ int CRYPTO_memcmp(const volatile void * volatile in_a, const volatile void * vol (d2i_of_void *)d2i_X509_REVOKED, (char *)(rev)) #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) +void *X509_STORE_get_ex_data(X509_STORE *str, int idx); +#endif + +#if !defined(HAVE_X509_STORE_SET_EX_DATA) +int X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data); +#endif + #if defined(__cplusplus) } #endif 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