aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazuki Yamaguchi <k@rhe.jp>2016-04-09 20:54:53 +0900
committerKazuki Yamaguchi <k@rhe.jp>2016-04-21 00:46:34 +0900
commiteeede322991bf2e1e8caad4b2933e7e37bd63a77 (patch)
tree251495371e973404b409408d436208570b32d6f8
parent20cd25c86fd28eb1b5068d0db607e6aa33107f65 (diff)
downloadruby-eeede322991bf2e1e8caad4b2933e7e37bd63a77.tar.gz
wip
-rw-r--r--ext/openssl/extconf.rb26
-rw-r--r--ext/openssl/openssl_missing.c115
-rw-r--r--ext/openssl/openssl_missing.h28
-rw-r--r--ext/openssl/ossl.c6
-rw-r--r--ext/openssl/ossl.h2
-rw-r--r--ext/openssl/ossl_bn.c20
-rw-r--r--ext/openssl/ossl_cipher.c44
-rw-r--r--ext/openssl/ossl_digest.c6
-rw-r--r--ext/openssl/ossl_hmac.c15
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;
}