diff options
author | Kazuki Yamaguchi <k@rhe.jp> | 2016-04-09 20:54:53 +0900 |
---|---|---|
committer | Kazuki Yamaguchi <k@rhe.jp> | 2016-04-21 00:46:34 +0900 |
commit | eeede322991bf2e1e8caad4b2933e7e37bd63a77 (patch) | |
tree | 251495371e973404b409408d436208570b32d6f8 | |
parent | 20cd25c86fd28eb1b5068d0db607e6aa33107f65 (diff) | |
download | ruby-eeede322991bf2e1e8caad4b2933e7e37bd63a77.tar.gz |
wip
-rw-r--r-- | ext/openssl/extconf.rb | 26 | ||||
-rw-r--r-- | ext/openssl/openssl_missing.c | 115 | ||||
-rw-r--r-- | ext/openssl/openssl_missing.h | 28 | ||||
-rw-r--r-- | ext/openssl/ossl.c | 6 | ||||
-rw-r--r-- | ext/openssl/ossl.h | 2 | ||||
-rw-r--r-- | ext/openssl/ossl_bn.c | 20 | ||||
-rw-r--r-- | ext/openssl/ossl_cipher.c | 44 | ||||
-rw-r--r-- | ext/openssl/ossl_digest.c | 6 | ||||
-rw-r--r-- | ext/openssl/ossl_hmac.c | 15 |
9 files changed, 166 insertions, 96 deletions
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index c36a7021e4..cf69b2736e 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -58,6 +58,11 @@ unless OpenSSL.check_func("SSL_library_init()", "openssl/ssl.h") raise "Ignore OpenSSL broken by Apple.\nPlease use another openssl. (e.g. using `configure --with-openssl-dir=/path/to/openssl')" end +def have_func_or_macro(name, header) + have_func(name) || + have_macro(name, [header]) && $defs.push("-DHAVE_#{name.upcase}") +end + Logging::message "=== Checking for OpenSSL features... ===\n" have_func("ERR_peek_last_error") have_func("ASN1_put_eoc") @@ -66,20 +71,28 @@ have_func("BN_mod_sqr") have_func("BN_mod_sub") have_func("BN_pseudo_rand_range") have_func("BN_rand_range") +have_func("BN_is_prime_ex") # for 0.9.6 +have_func("BN_is_prime_fasttest_ex") # for 0.9.6 +have_func("BN_generate_prime_ex") # for 0.9.6 have_func("CONF_get1_default_config_file") +have_func("EVP_CIPHER_CTX_new") +have_func("EVP_CIPHER_CTX_free") have_func("EVP_CIPHER_CTX_copy") have_func("EVP_CIPHER_CTX_set_padding") have_func("EVP_CipherFinal_ex") have_func("EVP_CipherInit_ex") have_func("EVP_DigestFinal_ex") have_func("EVP_DigestInit_ex") -have_func("EVP_MD_CTX_cleanup") -have_func("EVP_MD_CTX_create") -have_func("EVP_MD_CTX_destroy") -have_func("EVP_MD_CTX_init") -have_func("HMAC_CTX_cleanup") +have_func("EVP_MD_CTX_new") +have_func("EVP_MD_CTX_create") # for 0.9.6 +have_func("EVP_MD_CTX_free") +have_func("EVP_MD_CTX_destroy") # for 0.9.6 +have_func("EVP_MD_CTX_init") # for 0.9.6 +have_func("HMAC_CTX_new") +have_func("HMAC_CTX_init") # for 0.9.6 +have_func("HMAC_CTX_free") +have_func("HMAC_CTX_cleanup") # for 0.9.6 have_func("HMAC_CTX_copy") -have_func("HMAC_CTX_init") have_func("PEM_def_callback") have_func("PKCS5_PBKDF2_HMAC") have_func("PKCS5_PBKDF2_HMAC_SHA1") @@ -152,6 +165,7 @@ have_struct_member("EVP_CIPHER_CTX", "engine", "openssl/evp.h") have_struct_member("X509_ATTRIBUTE", "single", "openssl/x509.h") have_macro("OPENSSL_FIPS", ['openssl/opensslconf.h']) && $defs.push("-DHAVE_OPENSSL_FIPS") have_macro("EVP_CTRL_GCM_GET_TAG", ['openssl/evp.h']) && $defs.push("-DHAVE_AUTHENTICATED_ENCRYPTION") +have_func("CRYPTO_lock") # removed in OpenSSL 1.1 Logging::message "=== Checking done. ===\n" diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c index bd8eef5ea9..907276dada 100644 --- a/ext/openssl/openssl_missing.c +++ b/ext/openssl/openssl_missing.c @@ -48,65 +48,101 @@ void *X509_STORE_get_ex_data(X509_STORE *str, int idx) } #endif -#if !defined(HAVE_EVP_MD_CTX_CREATE) +#if !defined(HAVE_EVP_MD_CTX_NEW) +/* new in 1.1.0 */ EVP_MD_CTX * -EVP_MD_CTX_create(void) +EVP_MD_CTX_new(void) { +#if defined(HAVE_EVP_MD_CTX_CREATE) + return EVP_MD_CTX_create(); +#else /* 0.9.6 */ EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(EVP_MD_CTX)); - if (!ctx) return NULL; - + if (!ctx) + return NULL; memset(ctx, 0, sizeof(EVP_MD_CTX)); - return ctx; -} #endif - -#if !defined(HAVE_EVP_MD_CTX_CLEANUP) -int -EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) -{ - /* FIXME!!! */ - memset(ctx, 0, sizeof(EVP_MD_CTX)); - - return 1; } #endif -#if !defined(HAVE_EVP_MD_CTX_DESTROY) +#if !defined(HAVE_EVP_MD_CTX_FREE) +/* new in 1.1.0 */ void -EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) +EVP_MD_CTX_free(EVP_MD_CTX *ctx) { - EVP_MD_CTX_cleanup(ctx); +#if defined(HAVE_EVP_MD_CTX_DESTROY) + EVP_MD_CTX_destroy(ctx); +#else /* 0.9.6 */ + /* EVP_MD_CTX_cleanup(ctx); */ + /* FIXME!!! */ + memset(ctx, 0, sizeof(EVP_MD_CTX)); OPENSSL_free(ctx); +#endif } #endif +#if !defined(HAVE_HMAC_CTX_NEW) #if !defined(HAVE_EVP_MD_CTX_INIT) -void +static void EVP_MD_CTX_init(EVP_MD_CTX *ctx) { memset(ctx, 0, sizeof(EVP_MD_CTX)); } #endif -#if !defined(HAVE_HMAC_CTX_INIT) -void -HMAC_CTX_init(HMAC_CTX *ctx) +/* new in 1.1.0 */ +HMAC_CTX * +HMAC_CTX_new(void) { + HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX)); + if (!ctx) + return NULL; +#if defined(HAVE_HMAC_CTX_INIT) + HMAC_CTX_init(ctx); +#else /* 0.9.6 */ EVP_MD_CTX_init(&ctx->i_ctx); EVP_MD_CTX_init(&ctx->o_ctx); EVP_MD_CTX_init(&ctx->md_ctx); +#endif + return ctx; } #endif -#if !defined(HAVE_HMAC_CTX_CLEANUP) +#if !defined(HAVE_HMAC_CTX_FREE) void -HMAC_CTX_cleanup(HMAC_CTX *ctx) +HMAC_CTX_free(HMAC_CTX *ctx) { +#if defined(HAVE_HMAC_CTX_CLEANUP) + HMAC_CTX_cleanup(ctx); +#else /* 0.9.6 */ EVP_MD_CTX_cleanup(&ctx->i_ctx); EVP_MD_CTX_cleanup(&ctx->o_ctx); EVP_MD_CTX_cleanup(&ctx->md_ctx); - memset(ctx, 0, sizeof(HMAC_CTX)); +#endif + OPENSSL_free(ctx); +} +#endif + +#if !defined(HAVE_EVP_CIPHER_CTX_NEW) +/* new in 1.1.0 */ +EVP_CIPHER_CTX * +EVP_CIPHER_CTX_new(void) +{ + EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX)); + if (!ctx) + return NULL; + EVP_CIPHER_CTX_init(ctx); + return ctx; +} +#endif + +#if !defined(HAVE_EVP_MD_CTX_FREE) +/* new in 1.1.0 */ +void +EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) +{ + EVP_CIPHER_CTX_cleanup(ctx); /* 0.9.6 also has */ + OPENSSL_free(ctx); } #endif @@ -279,6 +315,35 @@ BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range) } #endif +#if !defined(HAVE_BN_IS_PRIME_EX) /* for 0.9.6 */ +int BN_is_prime_ex(const BIGNUM *bn, int checks, BN_CTX *ctx, void *cb) +{ + if (cb) + rb_bug("not supported"); + return BN_is_prime(bn, checks, NULL, ctx, NULL); +} +#endif + +#if !defined(HAVE_BN_IS_PRIME_FASTTEST_EX) /* for 0.9.6 */ +int BN_is_prime_fasttestex(const BIGNUM *bn, int checks, BN_CTX *ctx, + int do_trial_division, void *cb) +{ + if (cb) + rb_bug("not supported"); + return BN_is_prime_fasttest(bn, checks, NULL, ctx, NULL, do_trial_division); +} +#endif + +#if !defined(HAVE_BN_GENERATE_PRIME_EX) /* for 0.9.6 */ +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) +{ + if (cb) + rb_bug("not supported"); + return BN_generate_prime(ret, bits, safe, add, rem, NULL); +} +#endif + #if !defined(HAVE_CONF_GET1_DEFAULT_CONFIG_FILE) #define OPENSSL_CONF "openssl.cnf" char * diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 2dc49d3fd2..c9717ee27b 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -62,32 +62,32 @@ typedef int i2d_of_void(); (d2i_of_void *)d2i_PKCS7_RECIP_INFO, (char *)(ri)) #endif -#if !defined(HAVE_HMAC_CTX_INIT) -void HMAC_CTX_init(HMAC_CTX *ctx); +#if !defined(HAVE_HMAC_CTX_NEW) +HMAC_CTX *HMAC_CTX_new(void); #endif -#if !defined(HAVE_HMAC_CTX_COPY) -void HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in); +#if !defined(HAVE_HMAC_CTX_FREE) +HMAC_CTX *HMAC_CTX_free(void); #endif -#if !defined(HAVE_HMAC_CTX_CLEANUP) -void HMAC_CTX_cleanup(HMAC_CTX *ctx); +#if !defined(HAVE_HMAC_CTX_COPY) +void HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in); #endif -#if !defined(HAVE_EVP_MD_CTX_CREATE) -EVP_MD_CTX *EVP_MD_CTX_create(void); +#if !defined(HAVE_EVP_MD_CTX_NEW) +EVP_MD_CTX *EVP_MD_CTX_new(void); #endif -#if !defined(HAVE_EVP_MD_CTX_INIT) -void EVP_MD_CTX_init(EVP_MD_CTX *ctx); +#if !defined(HAVE_EVP_MD_CTX_FREE) +void EVP_MD_CTX_free(EVP_MD_CTX *ctx); #endif -#if !defined(HAVE_EVP_MD_CTX_CLEANUP) -int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); +#if !defined(HAVE_EVP_CIPHER_CTX_NEW) +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); #endif -#if !defined(HAVE_EVP_MD_CTX_DESTROY) -void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); +#if !defined(HAVE_EVP_CIPHER_CTX_FREE) +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); #endif #if !defined(HAVE_EVP_CIPHER_CTX_COPY) diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index d03dfa7ad0..2337f2b756 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -7,9 +7,9 @@ * This program is licensed under the same licence as Ruby. * (See the file 'LICENCE'.) */ +#define OPENSSL_MIN_API 0x20000000L #include "ossl.h" #include <stdarg.h> /* for ossl_raise */ - /* * String to HEXString conversion */ @@ -463,6 +463,7 @@ ossl_fips_mode_set(VALUE self, VALUE enabled) #endif } +#ifdef HAVE_CRYPTO_LOCK /* OpenSSL 1.0.2 or older */ /** * Stores locks needed for OpenSSL thread safety */ @@ -550,6 +551,7 @@ static void Init_ossl_locks(void) CRYPTO_set_dynlock_lock_callback(ossl_dyn_lock_callback); CRYPTO_set_dynlock_destroy_callback(ossl_dyn_destroy_callback); } +#endif /* * OpenSSL provides SSL, TLS and general purpose cryptography. It wraps the @@ -1148,7 +1150,9 @@ Init_openssl(void) */ ossl_s_to_der = rb_intern("to_der"); +#ifdef HAVE_CRYPTO_LOCK Init_ossl_locks(); +#endif /* * Init components diff --git a/ext/openssl/ossl.h b/ext/openssl/ossl.h index 3be01b0cb6..91d9d035a8 100644 --- a/ext/openssl/ossl.h +++ b/ext/openssl/ossl.h @@ -54,7 +54,7 @@ extern "C" { #endif #include <errno.h> #include <openssl/err.h> -#include <openssl/asn1_mac.h> +#include <openssl/asn1.h> #include <openssl/x509v3.h> #include <openssl/ssl.h> #include <openssl/pkcs12.h> diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c index fba86cdd44..682870b0c1 100644 --- a/ext/openssl/ossl_bn.c +++ b/ext/openssl/ossl_bn.c @@ -37,17 +37,12 @@ ossl_bn_free(void *ptr) BN_clear_free(ptr); } -static size_t -ossl_bn_size(const void *ptr) -{ - return sizeof(BIGNUM); -} - static const rb_data_type_t ossl_bn_type = { "OpenSSL/BN", - {0, ossl_bn_free, ossl_bn_size,}, - 0, 0, - RUBY_TYPED_FREE_IMMEDIATELY, + { + 0, ossl_bn_free, + }, + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY, }; /* @@ -766,7 +761,7 @@ ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass) if (!(result = BN_new())) { ossl_raise(eBNError, NULL); } - if (!BN_generate_prime(result, num, safe, add, rem, NULL, NULL)) { + if (!BN_generate_prime_ex(result, num, safe, add, rem, NULL, NULL)) { BN_free(result); ossl_raise(eBNError, NULL); } @@ -874,7 +869,7 @@ ossl_bn_is_prime(int argc, VALUE *argv, VALUE self) checks = NUM2INT(vchecks); } GetBN(self, bn); - switch (BN_is_prime(bn, checks, NULL, ossl_bn_ctx, NULL)) { + switch (BN_is_prime_ex(bn, checks, ossl_bn_ctx, NULL)) { case 1: return Qtrue; case 0: @@ -913,7 +908,8 @@ ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self) if (vtrivdiv == Qfalse) { do_trial_division = 0; } - switch (BN_is_prime_fasttest(bn, checks, NULL, ossl_bn_ctx, NULL, do_trial_division)) { + switch (BN_is_prime_fasttest_ex(bn, checks, ossl_bn_ctx, do_trial_division, + NULL)) { case 1: return Qtrue; case 0: diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c index 09b021d987..e9808fb996 100644 --- a/ext/openssl/ossl_cipher.c +++ b/ext/openssl/ossl_cipher.c @@ -11,10 +11,6 @@ #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 GetCipherInit(obj, ctx) do { \ TypedData_Get_Struct((obj), EVP_CIPHER_CTX, &ossl_cipher_type, (ctx)); \ } while (0) @@ -37,13 +33,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, }; /* @@ -62,14 +58,16 @@ GetCipherPtr(VALUE obj) VALUE ossl_cipher_new(const EVP_CIPHER *cipher) { - VALUE ret; - EVP_CIPHER_CTX *ctx; + VALUE ret = ossl_cipher_alloc(cCipher); + EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); + if (!ctx) { + ossl_raise(rb_eRuntimeError, "EVP_CIPHER_CTX_new() failed"); + } + RTYPEDDATA_DATA(ret) = ctx; - ret = ossl_cipher_alloc(cCipher); - AllocCipher(ret, ctx); - EVP_CIPHER_CTX_init(ctx); - if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) + if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, -1) != 1) { ossl_raise(eCipherError, NULL); + } return ret; } @@ -82,18 +80,10 @@ ossl_cipher_free(void *ptr) { EVP_CIPHER_CTX *ctx = ptr; if (ctx) { - EVP_CIPHER_CTX_cleanup(ctx); - ruby_xfree(ctx); + EVP_CIPHER_CTX_free(ctx); } } -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) { @@ -121,8 +111,12 @@ ossl_cipher_initialize(VALUE self, VALUE str) if (ctx) { ossl_raise(rb_eRuntimeError, "Cipher already inititalized!"); } - AllocCipher(self, ctx); - EVP_CIPHER_CTX_init(ctx); + + ctx = EVP_CIPHER_CTX_new(); + if (!ctx) { + ossl_raise(rb_eRuntimeError, "EVP_CIPHER_CTX_new() failed"); + } + RTYPEDDATA_DATA(self) = ctx; if (!(cipher = EVP_get_cipherbyname(name))) { ossl_raise(rb_eRuntimeError, "unsupported cipher algorithm (%s)", name); } diff --git a/ext/openssl/ossl_digest.c b/ext/openssl/ossl_digest.c index 44968dd9e5..001f9f2ad4 100644 --- a/ext/openssl/ossl_digest.c +++ b/ext/openssl/ossl_digest.c @@ -31,7 +31,7 @@ static VALUE ossl_digest_alloc(VALUE klass); static void ossl_digest_free(void *ctx) { - EVP_MD_CTX_destroy(ctx); + EVP_MD_CTX_free(ctx); } static const rb_data_type_t ossl_digest_type = { @@ -95,9 +95,9 @@ static VALUE ossl_digest_alloc(VALUE klass) { VALUE obj = TypedData_Wrap_Struct(klass, &ossl_digest_type, 0); - EVP_MD_CTX *ctx = EVP_MD_CTX_create(); + EVP_MD_CTX *ctx = EVP_MD_CTX_new(); if (ctx == NULL) - ossl_raise(rb_eRuntimeError, "EVP_MD_CTX_create() failed"); + ossl_raise(rb_eRuntimeError, "EVP_MD_CTX_new() failed"); RTYPEDDATA_DATA(obj) = ctx; return obj; diff --git a/ext/openssl/ossl_hmac.c b/ext/openssl/ossl_hmac.c index 5513cb20de..db911bb9cd 100644 --- a/ext/openssl/ossl_hmac.c +++ b/ext/openssl/ossl_hmac.c @@ -11,8 +11,6 @@ #include "ossl.h" -#define MakeHMAC(obj, klass, ctx) \ - (obj) = TypedData_Make_Struct((klass), HMAC_CTX, &ossl_hmac_type, (ctx)) #define GetHMAC(obj, ctx) do { \ TypedData_Get_Struct((obj), HMAC_CTX, &ossl_hmac_type, (ctx)); \ if (!(ctx)) { \ @@ -40,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 = { @@ -55,11 +52,11 @@ 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); + VALUE obj = TypedData_Wrap_Struct(klass, &ossl_hmac_type, 0); + HMAC_CTX *ctx = HMAC_CTX_new(); + if (!ctx) + ossl_raise(rb_eRuntimeError, "HMAC_CTX_new() failed"); + RTYPEDDATA_DATA(obj) = ctx; return obj; } |