From fec7a017a12515b420d4e03d723fe75de63f851d Mon Sep 17 00:00:00 2001 From: Kazuki Yamaguchi Date: Sun, 17 Apr 2016 22:49:22 +0900 Subject: work with OpenSSL 1.0.2g --- ext/openssl/extconf.rb | 197 ++++++----- ext/openssl/openssl_missing.c | 736 +++++++++++++++++++---------------------- ext/openssl/openssl_missing.h | 413 +++++++++++++++-------- ext/openssl/ossl.c | 4 +- ext/openssl/ossl_cipher.c | 2 - ext/openssl/ossl_pkcs5.c | 4 - ext/openssl/ossl_ssl.c | 11 +- ext/openssl/ossl_ssl_session.c | 25 +- test/openssl/test_pair.rb | 45 --- test/openssl/test_ssl.rb | 30 ++ 10 files changed, 762 insertions(+), 705 deletions(-) diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb index d042fd210a..b5fb770a36 100644 --- a/ext/openssl/extconf.rb +++ b/ext/openssl/extconf.rb @@ -63,129 +63,122 @@ def have_func_or_macro(name, header) have_macro(name, [header]) && $defs.push("-DHAVE_#{name.upcase}") end +def have_funcish(name) + have_func(name) || + have_macro(name, [header]) && $defs.push("-DHAVE_#{name.upcase}") +end + Logging::message "=== Checking for OpenSSL features... ===\n" +# added in 0.9.6a-0.9.7 +have_func("OPENSSL_cleanse") have_func("ERR_peek_last_error") +have_func("CONF_get1_default_config_file") have_func("ASN1_put_eoc") +have_func("OBJ_NAME_do_all_sorted") +have_func("PEM_def_callback") +have_func("BN_rand_range") +have_func("BN_pseudo_rand_range") +have_func("BN_nnmod") have_func("BN_mod_add") -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("BN_GENCB_new") -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("BN_mod_sqr") +have_func("EVP_MD_CTX_init") +have_func("EVP_MD_CTX_create") +have_func("EVP_MD_CTX_destroy") 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_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("EVP_PKEY_id") -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_reset") +have_func("EVP_DigestFinal_ex") +have_func("EVP_CipherInit_ex") +have_func("EVP_CipherFinal_ex") have_func("HMAC_Init_ex") -have_func("HMAC_CTX_copy") -have_func("PEM_def_callback") -have_func("PKCS5_PBKDF2_HMAC") -have_func("PKCS5_PBKDF2_HMAC_SHA1") -have_func("RAND_egd") -have_func("EC_curve_nist2nid") -have_func("X509V3_set_nconf") -have_func("X509V3_EXT_nconf_nid") +have_func("HMAC_CTX_init") +have_func("HMAC_CTX_cleanup") +have_func("X509_CRL_set_nextUpdate") have_func("X509_CRL_add0_revoked") have_func("X509_CRL_set_issuer_name") have_func("X509_CRL_set_version") have_func("X509_CRL_sort") -have_func("X509_CRL_set_nextUpdate") # for 0.9.6 +have_func("X509_STORE_get_ex_data") +have_func("X509_STORE_set_ex_data") +have_func("X509V3_set_nconf") +have_func("X509V3_EXT_nconf_nid") + +have_header("openssl/engine.h") +have_func("ENGINE_add") +have_func("ENGINE_get_digest") +have_func("ENGINE_get_cipher") +# ENGINE_load_xx is deprecated in OpenSSL 1.1.0 and become a macro +engines = %w{builtin_engines openbsd_dev_crypto dynamic 4758cca aep atalla chil + cswift nuron sureware ubsec padlock capi gmp gost cryptodev aesni} +engines.each { |name| have_func_or_macro("ENGINE_load_#{name}", "openssl/engine.h") } + +have_header("openssl/ocsp.h") + +# added in -0.9.8 +have_func("BN_is_prime_ex") +have_func("BN_is_prime_fasttest_ex") +have_func("BN_generate_prime_ex") +have_func("EVP_CIPHER_CTX_new") +have_func("EVP_CIPHER_CTX_free") +have_func("DH_generate_parameters_ex") +have_func("DSA_generate_parameters_ex") +have_func("RSA_generate_key_ex") +have_func("SSL_SESSION_get_id") +have_func("SSL_CTX_set_tmp_ecdh_callback") # removed in 1.1.0 +have_func("OCSP_SINGLERESP_delete_ext") + +# added in 1.0.0 +have_struct_member("CRYPTO_THREADID", "ptr", "openssl/crypto.h") # check if CRYPTO_THREADID exists +have_func("EVP_CIPHER_CTX_copy") +have_func("EVP_PKEY_id") +have_func("HMAC_CTX_copy") +have_func("PKCS5_PBKDF2_HMAC") +have_func("X509_NAME_hash_old") +have_func_or_macro("SSL_set_tlsext_host_name", 'openssl/ssl.h') + +# added in 1.0.1 +have_func("SSL_CTX_set_next_proto_select_cb") +have_macro("EVP_CTRL_GCM_GET_TAG", ['openssl/evp.h']) && $defs.push("-DHAVE_AUTHENTICATED_ENCRYPTION") + +# added in 1.0.2 +have_func("EC_curve_nist2nid") +have_func("SSL_CTX_set_alpn_select_cb") +have_func_or_macro("SSL_CTX_set1_curves_list", "openssl/ssl.h") +have_func_or_macro("SSL_CTX_set_ecdh_auto", "openssl/ssl.h") # removed in 1.1.0 +have_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("BN_GENCB_new") +have_func("BN_GENCB_free") +have_func("BN_GENCB_get_arg") +have_func("HMAC_CTX_new") +have_func("HMAC_CTX_free") +have_func("HMAC_CTX_reset") +have_func("EVP_MD_CTX_new") +have_func("EVP_MD_CTX_free") +have_func("X509_up_ref") have_func("X509_CRL_get0_signature") have_func("X509_REQ_get0_signature") have_func("X509_get0_tbs_sigalg") have_func("X509_REVOKED_get0_serialNumber") have_func("X509_REVOKED_set_serialNumber") have_func("X509_REVOKED_get0_revocationDate") -have_func("X509_REVOKED_set_nextUpdate") -have_func("X509_NAME_hash_old") -have_func("X509_STORE_get_ex_data") -have_func("X509_STORE_set_ex_data") -have_func("X509_up_ref") -have_func("OBJ_NAME_do_all_sorted") -have_func("SSL_SESSION_get_id") -have_func("SSL_SESSION_cmp") -have_func("OPENSSL_cleanse") -have_func("SSLv2_method") -have_func("SSLv2_server_method") -have_func("SSLv2_client_method") -have_func("SSLv3_method") -have_func("SSLv3_server_method") -have_func("SSLv3_client_method") +have_func("TLS_method") # renamed from SSLv23_method +have_func("SSL_CTX_get_ciphers") +have_func("SSL_CTX_get_security_level") +have_func("OCSP_SINGLERESP_get0_id") +have_struct_member("EVP_PKEY", "type", "openssl/evp.h") # removed + +# depending on OpenSSL configuration have_func("TLSv1_1_method") -have_func("TLSv1_1_server_method") -have_func("TLSv1_1_client_method") have_func("TLSv1_2_method") -have_func("TLSv1_2_server_method") -have_func("TLSv1_2_client_method") -have_func("SSL_CTX_set_alpn_select_cb") -have_func("SSL_CTX_set_next_proto_select_cb") -have_func("SSL_CTX_set_tmp_ecdh_callback") -have_func("SSL_CTX_get_ciphers") -have_func("SSL_CTX_get_security_level") # 1.1.0 -have_func_or_macro("SSL_CTX_set1_curves_list", "openssl/ssl.h") -have_macro("SSL_get_server_tmp_key", ['openssl/ssl.h']) && $defs.push("-DHAVE_SSL_GET_SERVER_TMP_KEY") -unless have_func("SSL_set_tlsext_host_name", ['openssl/ssl.h']) - have_macro("SSL_set_tlsext_host_name", ['openssl/ssl.h']) && $defs.push("-DHAVE_SSL_SET_TLSEXT_HOST_NAME") -end -if have_header("openssl/engine.h") - have_func("ENGINE_add") - have_func("ENGINE_load_builtin_engines") - have_func("ENGINE_load_openbsd_dev_crypto") - have_func("ENGINE_get_digest") - have_func("ENGINE_get_cipher") - have_func_or_macro("ENGINE_load_dynamic", "openssl/engine.h") - have_func_or_macro("ENGINE_load_4758cca", "openssl/engine.h") - have_func_or_macro("ENGINE_load_aep", "openssl/engine.h") - have_func_or_macro("ENGINE_load_atalla", "openssl/engine.h") - have_func_or_macro("ENGINE_load_chil", "openssl/engine.h") - have_func_or_macro("ENGINE_load_cswift", "openssl/engine.h") - have_func_or_macro("ENGINE_load_nuron", "openssl/engine.h") - have_func_or_macro("ENGINE_load_sureware", "openssl/engine.h") - have_func_or_macro("ENGINE_load_ubsec", "openssl/engine.h") - have_func_or_macro("ENGINE_load_padlock", "openssl/engine.h") - have_func_or_macro("ENGINE_load_capi", "openssl/engine.h") - have_func_or_macro("ENGINE_load_gmp", "openssl/engine.h") - have_func_or_macro("ENGINE_load_gost", "openssl/engine.h") - have_func_or_macro("ENGINE_load_cryptodev", "openssl/engine.h") - have_func_or_macro("ENGINE_load_aesni", "openssl/engine.h") -end -have_func("DH_generate_parameters_ex") -have_func("DSA_generate_parameters_ex") -have_func("RSA_generate_key_ex") -if checking_for('OpenSSL version is 0.9.7 or later') { - try_static_assert('OPENSSL_VERSION_NUMBER >= 0x00907000L', 'openssl/opensslv.h') - } - have_header("openssl/ocsp.h") - have_func("OCSP_id_get0_info") - have_func("OCSP_SINGLERESP_delete_ext") - have_func("OCSP_SINGLERESP_get0_id") -end -have_struct_member("CRYPTO_THREADID", "ptr", "openssl/crypto.h") -have_struct_member("EVP_CIPHER_CTX", "flags", "openssl/evp.h") -have_struct_member("EVP_CIPHER_CTX", "engine", "openssl/evp.h") -have_struct_member("EVP_PKEY", "type", "openssl/evp.h") +have_func("SSLv2_method") +have_func("SSLv3_method") 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 + +# LibreSSL support +have_func("RAND_egd") # removed Logging::message "=== Checking done. ===\n" diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c index 71ce15172e..e8c6e87627 100644 --- a/ext/openssl/openssl_missing.c +++ b/ext/openssl/openssl_missing.c @@ -7,164 +7,197 @@ * This program is licensed under the same licence as Ruby. * (See the file 'LICENCE'.) */ +#include + #include RUBY_EXTCONF_H +#include "openssl_missing.h" -#include +/* OPENSSL_NO_EVP is not supported */ +#include +#include +#include -#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_EVP_CIPHER_CTX_ENGINE) -# include +/* added in -0.9.7 */ +#if !defined(HAVE_CONF_GET1_DEFAULT_CONFIG_FILE) +#define OPENSSL_CONF "openssl.cnf" +char * +CONF_get1_default_config_file(void) +{ + char *file; + int len; + + file = getenv("OPENSSL_CONF"); + if (file) return BUF_strdup(file); + len = strlen(X509_get_default_cert_area()); +#ifndef OPENSSL_SYS_VMS + len++; +#endif + len += strlen(OPENSSL_CONF); + file = OPENSSL_malloc(len + 1); + if (!file) return NULL; + strcpy(file,X509_get_default_cert_area()); +#ifndef OPENSSL_SYS_VMS + strcat(file,"/"); #endif -#include + strcat(file,OPENSSL_CONF); -/*** 0.9.6 compatibility ***/ -#if !defined(HAVE_X509_CRL_SET_NEXTUPDATE) -int -X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) -{ - ASN1_TIME *in = M_ASN1_TIME_dup(tm); - if (!in) - return 0; - x->crl->nextUpdate = in; - return 1; + return file; } #endif -/*** 0.9.6 compatibility end ***/ - -/* HMAC */ -#if !defined(OPENSSL_NO_HMAC) -#include /* memcpy() */ -#include - -#include "openssl_missing.h" - -#if !defined(HAVE_HMAC_CTX_COPY) -void -HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in) +#if !defined(HAVE_ASN1_PUT_EOC) +int +ASN1_put_eoc(unsigned char **pp) { - 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); + unsigned char *p = *pp; + *p++ = 0; + *p++ = 0; + *pp = p; + return 2; } -#endif /* HAVE_HMAC_CTX_COPY */ +#endif -#if !defined(HAVE_HMAC_INIT_EX) +#if !defined(HAVE_PEM_DEF_CALLBACK) +#define OSSL_PASS_MIN_LENGTH 4 int -HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, - const EVP_MD *md, void *impl) +PEM_def_callback(char *buf, int num, int w, void *key) { - if (impl) - rb_bug("impl not supported"); - return HMAC_Init(ctx, key, key_len, md); + int i,j; + const char *prompt; + + if (key) { + i = strlen(key); + i = (i > num) ? num : i; + memcpy(buf, key, i); + return i; + } + + prompt = EVP_get_pw_prompt(); + if (prompt == NULL) prompt = "Enter PEM pass phrase:"; + for (;;) { + i = EVP_read_pw_string(buf, num, prompt, w); + if (i != 0) { + memset(buf, 0, (unsigned int)num); + return(-1); + } + j = strlen(buf); + if (j < OSSL_PASS_MIN_LENGTH) { + fprintf(stderr, + "phrase is too short, needs to be at least %d chars\n", + OSSL_PASS_MIN_LENGTH); + } + else break; + } + return j; } #endif -#if !defined(HAVE_HMAC_CTX_RESET) -#if !defined(HAVE_EVP_MD_CTX_INIT) -static void -EVP_MD_CTX_init(EVP_MD_CTX *ctx) +#if !defined(HAVE_BN_RAND_RANGE) || !defined(HAVE_BN_PSEUDO_RAND_RANGE) +static int +bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range) { - memset(ctx, 0, sizeof(EVP_MD_CTX)); + int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand; + int n; + + if (range->neg || BN_is_zero(range)) return 0; + + n = BN_num_bits(range); + + if (n == 1) { + if (!BN_zero(r)) return 0; + } else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) { + do { + if (!bn_rand(r, n + 1, -1, 0)) return 0; + if (BN_cmp(r ,range) >= 0) { + if (!BN_sub(r, r, range)) return 0; + if (BN_cmp(r, range) >= 0) + if (!BN_sub(r, r, range)) return 0; + } + } while (BN_cmp(r, range) >= 0); + } else { + do { + if (!bn_rand(r, n, -1, 0)) return 0; + } while (BN_cmp(r, range) >= 0); + } + + return 1; } #endif +#if !defined(HAVE_BN_RAND_RANGE) int -HMAC_CTX_reset(HMAC_CTX *ctx) +BN_rand_range(BIGNUM *r, const BIGNUM *range) { -#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 0; + return bn_rand_range(0, r, range); } #endif -#if !defined(HAVE_HMAC_CTX_NEW) -/* new in 1.1.0 */ -HMAC_CTX * -HMAC_CTX_new(void) +#if !defined(HAVE_BN_PSEUDO_RAND_RANGE) +int +BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range) { - HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX)); - HMAC_CTX_reset(ctx); - if (!ctx) - return NULL; - return ctx; + return bn_rand_range(1, r, range); } #endif -#if !defined(HAVE_HMAC_CTX_FREE) -void -HMAC_CTX_free(HMAC_CTX *ctx) +#if !defined(HAVE_BN_NNMOD) +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_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); -#endif - OPENSSL_free(ctx); + if (!BN_mod(r,m,d,ctx)) return 0; + if (!r->neg) return 1; + return (d->neg ? BN_sub : BN_add)(r, r, d); } #endif -#endif /* NO_HMAC */ - -/* X509 */ -#if !defined(HAVE_X509_STORE_SET_EX_DATA) -int X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data) +#if !defined(HAVE_BN_MOD_ADD) +int +BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) { - return CRYPTO_set_ex_data(&str->ex_data, idx, data); + if (!BN_add(r, a, b)) return 0; + return BN_nnmod(r, r, m, ctx); } #endif -#if !defined(HAVE_X509_STORE_GET_EX_DATA) -void *X509_STORE_get_ex_data(X509_STORE *str, int idx) +#if !defined(HAVE_BN_MOD_SUB) +int +BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) { - return CRYPTO_get_ex_data(&str->ex_data, idx); + if (!BN_sub(r, a, b)) return 0; + return BN_nnmod(r, r, m, ctx); } #endif -#if !defined(HAVE_X509_CRL_SET_VERSION) +#if !defined(HAVE_BN_MOD_SQR) int -X509_CRL_set_version(X509_CRL *x, long version) +BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) { - if (x == NULL || x->crl == NULL) return 0; - if (x->crl->version == NULL) { - x->crl->version = M_ASN1_INTEGER_new(); - if (x->crl->version == NULL) return 0; - } - return ASN1_INTEGER_set(x->crl->version, version); + if (!BN_sqr(r, (BIGNUM*)a, ctx)) return 0; + return BN_mod(r, r, m, ctx); } #endif -#if !defined(HAVE_X509_CRL_SET_ISSUER_NAME) +#if !defined(OPENSSL_NO_HMAC) +#include +#if !defined(HAVE_HMAC_INIT_EX) int -X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) +HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, + const EVP_MD *md, void *impl) { - if (x == NULL || x->crl == NULL) return 0; - return X509_NAME_set(&x->crl->issuer, name); + if (impl) + rb_bug("impl not supported"); + return HMAC_Init(ctx, key, key_len, md); } #endif +#endif -#if !defined(HAVE_X509_CRL_SORT) +#if !defined(HAVE_X509_CRL_SET_NEXTUPDATE) int -X509_CRL_sort(X509_CRL *c) +X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) { - int i; - X509_REVOKED *r; - /* sort the data so it will be written in serial - * number order */ - sk_X509_REVOKED_sort(c->crl->revoked); - for (i=0; icrl->revoked); i++) { - r=sk_X509_REVOKED_value(c->crl->revoked, i); - r->sequence=i; - } + ASN1_TIME *in = M_ASN1_TIME_dup(tm); + if (!in) + return 0; + x->crl->nextUpdate = in; return 1; } #endif @@ -192,207 +225,47 @@ X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) } #endif -#if !defined(HAVE_X509_CRL_GET0_SIGNATURE) -void -X509_CRL_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_CRL *crl) -{ - if (psig != NULL) - *psig = crl->signature; - if (palg != NULL) - *palg = crl->sig_alg; -} -#endif - -#if !defined(HAVE_X509_REQ_GET0_SIGNATURE) -void -X509_REQ_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_REQ *req) -{ - if (psig != NULL) - *psig = req->signature; - if (palg != NULL) - *palg = req->sig_alg; -} -#endif - -#if !defined(HAVE_X509_REVOKED_SET_SERIALNUMBER) -int -X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial) -{ - ASN1_INTEGER *in = x->serialNumber; - if (in != serial) - return ASN1_STRING_copy(in, serial); - return 1; -} -#endif - - -/* EVP_MD */ -#include -#if !defined(HAVE_EVP_MD_CTX_NEW) -/* new in 1.1.0 */ -EVP_MD_CTX * -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; - memset(ctx, 0, sizeof(EVP_MD_CTX)); - return ctx; -#endif -} -#endif - -#if !defined(HAVE_EVP_MD_CTX_FREE) -/* new in 1.1.0 */ -void -EVP_MD_CTX_free(EVP_MD_CTX *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_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 - -#if !defined(HAVE_EVP_CIPHER_CTX_COPY) -/* - * this function does not exist in OpenSSL yet... or ever?. - * a future version may break this function. - * tested on 0.9.7d. - */ -int -EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, EVP_CIPHER_CTX *in) -{ - memcpy(out, in, sizeof(EVP_CIPHER_CTX)); - -#if defined(HAVE_ENGINE_ADD) && defined(HAVE_EVP_CIPHER_CTX_ENGINE) - if (in->engine) ENGINE_add(out->engine); - if (in->cipher_data) { - out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); - memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); - } -#endif - - return 1; -} -#endif - -/* BIGNUM */ -#if !defined(HAVE_BN_MOD_SQR) -int -BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) -{ - if (!BN_sqr(r, (BIGNUM*)a, ctx)) return 0; - return BN_mod(r, r, m, ctx); -} -#endif - -#if !defined(HAVE_BN_MOD_ADD) || !defined(HAVE_BN_MOD_SUB) -int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) -{ - if (!BN_mod(r,m,d,ctx)) return 0; - if (!r->neg) return 1; - return (d->neg ? BN_sub : BN_add)(r, r, d); -} -#endif - -#if !defined(HAVE_BN_MOD_ADD) -int -BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) -{ - if (!BN_add(r, a, b)) return 0; - return BN_nnmod(r, r, m, ctx); -} -#endif - -#if !defined(HAVE_BN_MOD_SUB) +#if !defined(HAVE_X509_CRL_SET_ISSUER_NAME) int -BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx) -{ - if (!BN_sub(r, a, b)) return 0; - return BN_nnmod(r, r, m, ctx); -} -#endif - -#if !defined(HAVE_BN_RAND_RANGE) || !defined(HAVE_BN_PSEUDO_RAND_RANGE) -static int -bn_rand_range(int pseudo, BIGNUM *r, BIGNUM *range) +X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) { - int (*bn_rand)(BIGNUM *, int, int, int) = pseudo ? BN_pseudo_rand : BN_rand; - int n; - - if (range->neg || BN_is_zero(range)) return 0; - - n = BN_num_bits(range); - - if (n == 1) { - if (!BN_zero(r)) return 0; - } else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) { - do { - if (!bn_rand(r, n + 1, -1, 0)) return 0; - if (BN_cmp(r ,range) >= 0) { - if (!BN_sub(r, r, range)) return 0; - if (BN_cmp(r, range) >= 0) - if (!BN_sub(r, r, range)) return 0; - } - } while (BN_cmp(r, range) >= 0); - } else { - do { - if (!bn_rand(r, n, -1, 0)) return 0; - } while (BN_cmp(r, range) >= 0); - } - - return 1; + if (x == NULL || x->crl == NULL) return 0; + return X509_NAME_set(&x->crl->issuer, name); } #endif -#if !defined(HAVE_BN_RAND_RANGE) +#if !defined(HAVE_X509_CRL_SET_VERSION) int -BN_rand_range(BIGNUM *r, BIGNUM *range) +X509_CRL_set_version(X509_CRL *x, long version) { - return bn_rand_range(0, r, range); + if (x == NULL || x->crl == NULL) return 0; + if (x->crl->version == NULL) { + x->crl->version = M_ASN1_INTEGER_new(); + if (x->crl->version == NULL) return 0; + } + return ASN1_INTEGER_set(x->crl->version, version); } #endif -#if !defined(HAVE_BN_PSEUDO_RAND_RANGE) +#if !defined(HAVE_X509_CRL_SORT) int -BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range) +X509_CRL_sort(X509_CRL *c) { - return bn_rand_range(1, r, range); + int i; + X509_REVOKED *r; + /* sort the data so it will be written in serial + * number order */ + sk_X509_REVOKED_sort(c->crl->revoked); + for (i=0; icrl->revoked); i++) { + r=sk_X509_REVOKED_value(c->crl->revoked, i); + r->sequence=i; + } + return 1; } #endif -#if !defined(HAVE_BN_IS_PRIME_EX) /* for 0.9.6 */ +/*** added in 0.9.8 ***/ +#if !defined(HAVE_BN_IS_PRIME_EX) int BN_is_prime_ex(const BIGNUM *bn, int checks, BN_CTX *ctx, void *cb) { if (cb) @@ -401,7 +274,7 @@ int BN_is_prime_ex(const BIGNUM *bn, int checks, BN_CTX *ctx, void *cb) } #endif -#if !defined(HAVE_BN_IS_PRIME_FASTTEST_EX) /* for 0.9.6 */ +#if !defined(HAVE_BN_IS_PRIME_FASTTEST_EX) int BN_is_prime_fasttestex(const BIGNUM *bn, int checks, BN_CTX *ctx, int do_trial_division, void *cb) { @@ -411,7 +284,7 @@ int BN_is_prime_fasttestex(const BIGNUM *bn, int checks, BN_CTX *ctx, } #endif -#if !defined(HAVE_BN_GENERATE_PRIME_EX) /* for 0.9.6 */ +#if !defined(HAVE_BN_GENERATE_PRIME_EX) int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) { @@ -421,104 +294,27 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, } #endif -#if !defined(HAVE_CONF_GET1_DEFAULT_CONFIG_FILE) -#define OPENSSL_CONF "openssl.cnf" -char * -CONF_get1_default_config_file(void) -{ - char *file; - int len; - - file = getenv("OPENSSL_CONF"); - if (file) return BUF_strdup(file); - len = strlen(X509_get_default_cert_area()); -#ifndef OPENSSL_SYS_VMS - len++; -#endif - len += strlen(OPENSSL_CONF); - file = OPENSSL_malloc(len + 1); - if (!file) return NULL; - strcpy(file,X509_get_default_cert_area()); -#ifndef OPENSSL_SYS_VMS - strcat(file,"/"); -#endif - strcat(file,OPENSSL_CONF); - - return file; -} -#endif - -#if !defined(HAVE_PEM_DEF_CALLBACK) -#define OSSL_PASS_MIN_LENGTH 4 -int -PEM_def_callback(char *buf, int num, int w, void *key) -{ - int i,j; - const char *prompt; - - if (key) { - i = strlen(key); - i = (i > num) ? num : i; - memcpy(buf, key, i); - return i; - } - - prompt = EVP_get_pw_prompt(); - if (prompt == NULL) prompt = "Enter PEM pass phrase:"; - for (;;) { - i = EVP_read_pw_string(buf, num, prompt, w); - if (i != 0) { - memset(buf, 0, (unsigned int)num); - return(-1); - } - j = strlen(buf); - if (j < OSSL_PASS_MIN_LENGTH) { - fprintf(stderr, - "phrase is too short, needs to be at least %d chars\n", - OSSL_PASS_MIN_LENGTH); - } - else break; - } - return j; -} -#endif - - -/* ASN.1 */ -#include -#if !defined(HAVE_ASN1_PUT_EOC) -int -ASN1_put_eoc(unsigned char **pp) +#if !defined(HAVE_EVP_CIPHER_CTX_NEW) +EVP_CIPHER_CTX * +EVP_CIPHER_CTX_new(void) { - unsigned char *p = *pp; - *p++ = 0; - *p++ = 0; - *pp = p; - return 2; + EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX)); + if (!ctx) + return NULL; + EVP_CIPHER_CTX_init(ctx); + return ctx; } #endif -/* OCSP */ -#if defined(HAVE_OPENSSL_OCSP_H) -#include -#if !defined(HAVE_OCSP_ID_GET0_INFO) -int -OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, - ASN1_OCTET_STRING **pikeyHash, - ASN1_INTEGER **pserial, OCSP_CERTID *cid) +#if !defined(HAVE_EVP_CIPHER_CTX_FREE) +void +EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) { - if (piNameHash || pmd || pikeyHash) - rb_bug("not supported"); - if (pserial) - *pserial = cid->serialNumber; - return 1; + EVP_CIPHER_CTX_cleanup(ctx); + OPENSSL_free(ctx); } #endif -#endif /* HAVE_OPENSSL_OCSP_H */ - -/* SSL */ -#include #if !defined(HAVE_SSL_SESSION_GET_ID) const unsigned char * SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len) @@ -529,31 +325,52 @@ SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len) } #endif -#if !defined(HAVE_SSL_SESSION_CMP) /* removed in 1.0.0 */ +/*** added in 1.0.0 ***/ +#if !defined(HAVE_EVP_CIPHER_CTX_COPY) +#if defined(HAVE_ENGINE_ADD) +# include +#endif +/* + * this function does not exist in OpenSSL yet... or ever?. + * a future version may break this function. + * tested on 0.9.7d. + */ int -SSL_SESSION_cmp(const SSL_SESSION *a, const SSL_SESSION *b) +EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { - unsigned int a_len; - const unsigned char *a_sid = SSL_SESSION_get_id(a, &a_len); - unsigned int b_len; - const unsigned char *b_sid = SSL_SESSION_get_id(b, &b_len); + memcpy(out, in, sizeof(EVP_CIPHER_CTX)); -#if !defined(HAVE_SSL_SESSION_GET_ID) /* 1.0.2 or older */ - if (a->ssl_version != b->ssl_version) - return 1; +#if defined(HAVE_ENGINE_ADD) + if (in->engine) ENGINE_add(out->engine); + if (in->cipher_data) { + out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); + memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); + } #endif - if (a_len != b_len) - return 1; -#if defined(_WIN32) - return memcmp(a_sid, b_sid, a_len); -#else - return CRYPTO_memcmp(a_sid, b_sid, a_len); + return 1; +} #endif + +#if !defined(OPENSSL_NO_HMAC) +#include +#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 /* SSL */ +#endif +#endif -#if !defined(HAVE_EC_CURVE_NIST2NID) /* new in 1.0.2 */ +/*** added in 1.0.1 ***/ +/*** added in 1.0.2 ***/ +#if !defined(HAVE_EC_CURVE_NIST2NID) static struct { const char *name; int nid; @@ -586,3 +403,122 @@ EC_curve_nist2nid(const char *name) return NID_undef; } #endif + +/*** added in 1.1.0 ***/ +#if !defined(OPENSSL_NO_HMAC) +#include +#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) +{ +#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); +#endif + OPENSSL_free(ctx); +} +#endif + +#if !defined(HAVE_HMAC_CTX_RESET) +#if !defined(HAVE_EVP_MD_CTX_INIT) +#include /* memcpy() */ +static void +EVP_MD_CTX_init(EVP_MD_CTX *ctx) +{ + memset(ctx, 0, sizeof(EVP_MD_CTX)); +} +#endif + +int +HMAC_CTX_reset(HMAC_CTX *ctx) +{ +#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 0; +} +#endif +#endif + +#if !defined(HAVE_EVP_MD_CTX_NEW) +EVP_MD_CTX * +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; + memset(ctx, 0, sizeof(EVP_MD_CTX)); + return ctx; +#endif +} +#endif + +#if !defined(HAVE_EVP_MD_CTX_FREE) +void +EVP_MD_CTX_free(EVP_MD_CTX *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_X509_CRL_GET0_SIGNATURE) +void +X509_CRL_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_CRL *crl) +{ + if (psig != NULL) + *psig = crl->signature; + if (palg != NULL) + *palg = crl->sig_alg; +} +#endif + +#if !defined(HAVE_X509_REQ_GET0_SIGNATURE) +void +X509_REQ_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_REQ *req) +{ + if (psig != NULL) + *psig = req->signature; + if (palg != NULL) + *palg = req->sig_alg; +} +#endif + +#if !defined(HAVE_X509_REVOKED_SET_SERIALNUMBER) +int +X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial) +{ + ASN1_INTEGER *in = x->serialNumber; + if (in != serial) + return ASN1_STRING_copy(in, serial); + return 1; +} +#endif diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h index 02a50fbd95..b51f8bb057 100644 --- a/ext/openssl/openssl_missing.h +++ b/ext/openssl/openssl_missing.h @@ -10,24 +10,24 @@ #if !defined(_OSSL_OPENSSL_MISSING_H_) #define _OSSL_OPENSSL_MISSING_H_ +#include + #if defined(__cplusplus) extern "C" { #endif +/* added in -0.9.7 */ +/* These functions are not included in headers of OPENSSL <= 0.9.6b */ #ifndef TYPEDEF_D2I_OF -typedef char *d2i_of_void(); +typedef char *d2i_of_void(void **, const unsigned char **, long); #endif #ifndef TYPEDEF_I2D_OF -typedef int i2d_of_void(); +typedef int i2d_of_void(void *, unsigned char **); #endif -/* - * These functions are not included in headers of OPENSSL <= 0.9.6b - */ - #if !defined(PEM_read_bio_DSAPublicKey) # define PEM_read_bio_DSAPublicKey(bp,x,cb,u) (DSA *)PEM_ASN1_read_bio( \ - (d2i_of_void *)d2i_DSAPublicKey,PEM_STRING_DSA_PUBLIC,(bp),(void **)(x),(cb),(u)) + (d2i_of_void *)d2i_DSAPublicKey,PEM_STRING_DSA_PUBLIC,(bp),(void **)(x),(cb),(u)) #endif #if !defined(PEM_write_bio_DSAPublicKey) @@ -62,47 +62,86 @@ typedef int i2d_of_void(); (d2i_of_void *)d2i_PKCS7_RECIP_INFO, (char *)(ri)) #endif -#if !defined(HAVE_X509_CRL_SET_NEXTUPDATE) -int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); + +#if !defined(EVP_CIPHER_name) +# define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) #endif +#if !defined(EVP_MD_name) +# define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_type(e)) +#endif +#if !defined(PKCS7_is_detached) +# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) +#endif -#if !defined(HAVE_HMAC_CTX_NEW) -HMAC_CTX *HMAC_CTX_new(void); +#if !defined(PKCS7_type_is_encrypted) +# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) #endif -#if !defined(HAVE_HMAC_CTX_FREE) -void HMAC_CTX_free(HMAC_CTX *ctx); +/* start: checked by extconf.rb */ +#if !defined(HAVE_OPENSSL_CLEANSE) +#define OPENSSL_cleanse(p, l) memset((p), 0, (l)) #endif -#if !defined(HAVE_HMAC_CTX_COPY) -void HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in); +#if !defined(HAVE_ERR_PEEK_LAST_ERROR) #endif -#if !defined(HAVE_EVP_MD_CTX_NEW) -EVP_MD_CTX *EVP_MD_CTX_new(void); +#if !defined(HAVE_CONF_GET1_DEFAULT_CONFIG_FILE) +char *CONF_get1_default_config_file(void); #endif -#if !defined(HAVE_EVP_MD_CTX_FREE) -void EVP_MD_CTX_free(EVP_MD_CTX *ctx); +#if !defined(HAVE_ASN1_PUT_EOC) +int ASN1_put_eoc(unsigned char **pp); #endif -#if !defined(HAVE_EVP_CIPHER_CTX_NEW) -EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); +#if !defined(HAVE_OBJ_NAME_DO_ALL_SORTED) #endif -#if !defined(HAVE_EVP_CIPHER_CTX_FREE) -void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); +#if !defined(HAVE_PEM_DEF_CALLBACK) +int PEM_def_callback(char *buf, int num, int w, void *key); #endif -#if !defined(HAVE_EVP_CIPHER_CTX_COPY) -int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, EVP_CIPHER_CTX *in); +#if !defined(HAVE_BN_RAND_RANGE) +int BN_rand_range(BIGNUM *r, const BIGNUM *range); +#endif + +#if !defined(HAVE_BN_PSEUDO_RAND_RANGE) +int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range); +#endif + +#if !defined(HAVE_BN_NNMOD) +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); +#endif + +#if !defined(HAVE_BN_MOD_ADD) +int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); +#endif + +#if !defined(HAVE_BN_MOD_SUB) +int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); +#endif + +#if !defined(HAVE_BN_MOD_SQR) +int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +#endif + +#if !defined(HAVE_MD_CTX_INIT) +#endif + +#if !defined(HAVE_MD_CTX_CREATE) +#endif + +#if !defined(HAVE_MD_CTX_DESTROY) +#endif + +#if !defined(HAVE_EVP_CIPHER_CTX_SET_PADDING) #endif #if !defined(HAVE_EVP_DIGESTINIT_EX) # define EVP_DigestInit_ex(ctx, md, engine) EVP_DigestInit((ctx), (md)) #endif + #if !defined(HAVE_EVP_DIGESTFINAL_EX) # define EVP_DigestFinal_ex(ctx, buf, len) EVP_DigestFinal((ctx), (buf), (len)) #endif @@ -110,141 +149,181 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, EVP_CIPHER_CTX *in); #if !defined(HAVE_EVP_CIPHERINIT_EX) # define EVP_CipherInit_ex(ctx, type, impl, key, iv, enc) EVP_CipherInit((ctx), (type), (key), (iv), (enc)) #endif + #if !defined(HAVE_EVP_CIPHERFINAL_EX) # define EVP_CipherFinal_ex(ctx, outm, outl) EVP_CipherFinal((ctx), (outm), (outl)) #endif -#if !defined(EVP_CIPHER_name) -# define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) +#if !defined(OPENSSL_NO_HMAC) +#if !defined(HAVE_HMAC_INIT_EX) +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, void *impl); #endif -#if !defined(EVP_MD_name) -# define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_type(e)) +#if !defined(HAVE_HMAC_CTX_INIT) #endif -#if !defined(PKCS7_is_detached) -# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) +#if !defined(HAVE_HMAC_CTX_CLEANUP) +#endif #endif -#if !defined(PKCS7_type_is_encrypted) -# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) +#if !defined(HAVE_X509_CRL_SET_NEXTUPDATE) +int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); #endif -#if !defined(HAVE_OPENSSL_CLEANSE) -#define OPENSSL_cleanse(p, l) memset((p), 0, (l)) +#if !defined(HAVE_X509_CRL_ADD0_REVOKED) +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +#endif + +#if !defined(HAVE_X509_CRL_SET_ISSUER_NAME) +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); +#endif + +#if !defined(HAVE_X509_CRL_SET_VERSION) +int X509_CRL_set_version(X509_CRL *x, long version); +#endif + +#if !defined(HAVE_X509_CRL_SORT) +int X509_CRL_sort(X509_CRL *c); #endif #if !defined(HAVE_X509_STORE_GET_EX_DATA) -void *X509_STORE_get_ex_data(X509_STORE *str, int idx); +# define X509_STORE_get_ex_data(str, idx) \ + CRYPTO_get_ex_data(&(str)->ex_data, idx) #endif #if !defined(HAVE_X509_STORE_SET_EX_DATA) -int X509_STORE_set_ex_data(X509_STORE *str, int idx, void *data); +# define X509_STORE_set_ex_data(str, idx, data) \ + CRYPTO_set_ex_data(&(str)->ex_data, idx, data) #endif -#if !defined(HAVE_X509_CRL_SET_VERSION) -int X509_CRL_set_version(X509_CRL *x, long version); +#if !defined(HAVE_X509V3_SET_NCONF) #endif -#if !defined(HAVE_X509_CRL_SET_ISSUER_NAME) -int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); +#if !defined(HAVE_X509V3_EXT_NCONF_NID) #endif -#if !defined(HAVE_X509_CRL_SORT) -int X509_CRL_sort(X509_CRL *c); +/* ENGINE related API can't be polyfilled */ + + +/*** added in 0.9.8 ***/ +#if !defined(HAVE_BN_IS_PRIME_EX) +int BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb); #endif -#if !defined(HAVE_X509_CRL_ADD0_REVOKED) -int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +#if !defined(HAVE_BN_IS_PRIME_FASTTEST_EX) +int BN_is_prime_fasttest_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, int do_trial_division, BN_GENCB *cb); #endif -#if !defined(HAVE_BN_MOD_SQR) -int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +#if !defined(HAVE_BN_GENERATE_PRIME_EX) +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb); #endif -#if !defined(HAVE_BN_MOD_ADD) -int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); +#if !defined(HAVE_EVP_CIPHER_CTX_NEW) +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); #endif -#if !defined(HAVE_BN_MOD_SUB) -int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, BN_CTX *ctx); +#if !defined(HAVE_EVP_CIPHER_CTX_FREE) +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); #endif -#if !defined(HAVE_BN_RAND_RANGE) -int BN_rand_range(BIGNUM *r, BIGNUM *range); +#if !defined(HAVE_DH_GENERATE_PARAMETERS_EX) #endif -#if !defined(HAVE_BN_PSEUDO_RAND_RANGE) -int BN_pseudo_rand_range(BIGNUM *r, BIGNUM *range); +#if !defined(HAVE_DSA_GENERATE_PARAMETERS_EX) #endif -#if !defined(HAVE_CONF_GET1_DEFAULT_CONFIG_FILE) -char *CONF_get1_default_config_file(void); +#if !defined(HAVE_RSA_GENERATE_KEY_EX) #endif -#if !defined(HAVE_PEM_DEF_CALLBACK) -int PEM_def_callback(char *buf, int num, int w, void *key); +#if !defined(HAVE_SSL_SESSION_GET_ID) +int SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len); #endif -#if !defined(HAVE_ASN1_PUT_EOC) -int ASN1_put_eoc(unsigned char **pp); +#if !defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK) +#endif + +#if !defined(HAVE_OCSP_SINGLERESP_DELETE_EXT) +# define OCSP_SINGLERESP_delete_ext(s, loc) \ + sk_X509_EXTENSION_delete((s)->singleExtensions, (loc)) +#endif + +/*** added in 1.0.0 ***/ +#if !defined(HAVE_CRYPTO_THREADID_PTR) +#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_EVP_PKEY_id) -int EVP_PKEY_id(const EVP_PKEY *pkey); +# define EVP_PKEY_id(pkey) ((pkey)->type) #endif -#if !defined(X509_CRL_GET0_SIGNATURE) -void X509_CRL_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_CRL *crl); +#if !defined(HAVE_HMAC_CTX_COPY) +void HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in); #endif -#if !defined(X509_REQ_GET0_SIGNATURE) -void X509_REQ_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_REQ *req); +#if !defined(HAVE_PKCS5_PBKDF2_HMAC) #endif -#if !defined(X509_REVOKED_GET0_SERIALNUMBER) -ASN1_INTEGER *X509_REVOKED_get0_serialNumber(X509_REVOKED *x); +#if !defined(HAVE_X509_NAME_HASH_OLD) #endif -#if !defined(X509_REVOKED_SET_SERIALNUMBER) -int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); +#if !defined(HAVE_SSL_SET_TLSEXT_HOST_NAME) #endif -#if !defined(HAVE_EC_CURVE_NIST2NID) /* new in 1.0.2 */ +/*** added in 1.0.1 ***/ +#if !defined(HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB) +#endif + +/*** added in 1.0.2 ***/ +#if !defined(HAVE_EC_CURVE_NIST2NID) int EC_curve_nist2nid(const char *str); #endif -/*** new in 1.1.0 ***/ -/* OCSP */ -#if defined(HAVE_OPENSSL_OCSP_H) -#if !defined(HAVE_OCSP_ID_GET0_INFO) -int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, - ASN1_OCTET_STRING **pikeyHash, - ASN1_INTEGER **pserial, OCSP_CERTID *cid); +#if !defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) #endif -#if !defined(HAVE_OCSP_SINGLERESP_DELETE_EXT) /* for 0.9.6 */ -# define OCSP_SINGLERESP_delete_ext(s, loc) \ - sk_X509_EXTENSION_delete((s)->singleExtensions, (loc)) +#if !defined(HAVE_SSL_CTX_SET1_CURVES_LIST) #endif -#if !defined(HAVE_OCSP_SINGLERESP_GET0_ID) -# define OCSP_SINGLERESP_get0_id(s) (s)->certId +#if !defined(HAVE_SSL_CTX_SET_ECDH_AUTO) #endif -#endif /* HAVE_OPENSSL_OCSP_H */ -/* SSL */ -#include -#if !defined(HAVE_SSL_SESSION_GET_ID) -int SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len); +#if !defined(HAVE_SSL_GET_SERVER_TMP_KEY) #endif -#if !defined(HAVE_SSL_SESSION_CMP) -int SSL_SESSION_cmp(const SSL_SESSION *a,const SSL_SESSION *b); +/*** added in 1.1.0 ***/ +#if !defined(HAVE_BN_GENCB_NEW) +# define BN_GENCB_new() ((BN_GENCB *)OPENSSL_malloc(sizeof(BN_GENCB))) #endif -#if !defined(HAVE_SSL_CTX_GET_CIPHERS) -static inline STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(SSL_CTX *ctx) { return ctx->cipher_list; } +#if !defined(HAVE_BN_GENCB_FREE) +# define BN_GENCB_free(cb) OPENSSL_free(cb) +#endif + +#if !defined(HAVE_BN_GENCB_GET_ARG) +# define BN_GENCB_get_arg(cb) (cb)->arg +#endif + +#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_EVP_MD_CTX_NEW) +EVP_MD_CTX *EVP_MD_CTX_new(void); +#endif + +#if !defined(HAVE_EVP_MD_CTX_FREE) +void EVP_MD_CTX_free(EVP_MD_CTX *ctx); #endif /* reference counter */ @@ -261,82 +340,124 @@ static inline STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(SSL_CTX *ctx) { return c CRYPTO_add(&(x)->references, 1, CRYPTO_LOCK_EVP_PKEY); #endif -/* EVP_PKEY */ -#if !defined(HAVE_EVP_PKEY_ID) -# define EVP_PKEY_id(pkey) (pkey->type) +#if !defined(HAVE_X509_CRL_GET0_SIGNATURE) +void X509_CRL_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_CRL *crl); #endif -#if defined(HAVE_EVP_PKEY_TYPE) /* is not opaque */ -static inline RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) { return pkey->pkey.rsa; } -static inline DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey) { return pkey->pkey.dsa; } -static inline EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) { return pkey->pkey.ec; } -static inline DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey) { return pkey->pkey.dh; } +#if !defined(HAVE_X509_REQ_GET0_SIGNATURE) +void X509_REQ_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, X509_REQ *req); +#endif -static inline void RSA_get0_key(RSA *rsa, BIGNUM **pn, BIGNUM **pe, BIGNUM **pd) { - if (pn) *pn = rsa->n; - if (pe) *pe = rsa->e; - if (pd) *pd = rsa->d; } -static inline void RSA_get0_factors(RSA *rsa, BIGNUM **pp, BIGNUM **pq) { - if (pp) *pp = rsa->p; - if (pq) *pq = rsa->q; } -static inline void RSA_get0_crt_params(RSA *rsa, BIGNUM **pdmp1, BIGNUM **pdmq1, BIGNUM **piqmp) { - if (pdmp1) *pdmp1 = rsa->dmp1; - if (pdmq1) *pdmq1 = rsa->dmq1; - if (piqmp) *piqmp = rsa->iqmp; } - -static inline void DSA_get0_key(DSA *dsa, BIGNUM **ppub_key, BIGNUM **ppriv_key) { - if (ppub_key) *ppub_key = dsa->pub_key; - if (ppriv_key) *ppriv_key = dsa->priv_key; } -static inline void DSA_get0_pqg(DSA *dsa, BIGNUM **pp, BIGNUM **pq, BIGNUM **pg) { - if (pp) *pp = dsa->p; - if (pq) *pq = dsa->q; - if (pg) *pg = dsa->g; } +#if !defined(HAVE_X509_GET0_TBS_SIGALG) +# define X509_get0_tbs_sigalg(x) ((x)->cert_info->signature) +#endif -static inline ENGINE *DH_get0_engine(DH *dh) { return dh->engine; } -static inline void DH_get0_key(DH *dh, BIGNUM **ppub_key, BIGNUM **ppriv_key) { - if (ppub_key) *ppub_key = dh->pub_key; - if (ppriv_key) *ppriv_key = dh->priv_key; } -static inline void DH_get0_pqg(DH *dh, BIGNUM **pp, BIGNUM **pq, BIGNUM **pg) { - if (pp) *pp = dh->p; - if (pq) *pq = dh->q; - if (pg) *pg = dh->g; } +#if !defined(HAVE_X509_REVOKED_GET0_SERIALNUMBER) +# define X509_REVOKED_get0_serialNumber(x) ((x)->serialNumber) #endif -/* HMAC */ -#if !defined(HAVE_HMAC_CTX_RESET) -int HMAC_CTX_reset(HMAC_CTX *ctx); +#if !defined(HAVE_X509_REVOKED_SET_SERIALNUMBER) +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); #endif -#if !defined(HAVE_HMAC_INIT_EX) -int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md, void *impl); +#if !defined(HAVE_X509_REVOKED_GET0_REVOCATIONDATE) +# define X509_REVOKED_get0_revocationDate(x) (x->revocationDate) #endif -#if !defined(HAVE_HMAC_CTX_NEW) -HMAC_CTX *HMAC_CTX_new(void); +#if !defined(HAVE_TLS_METHOD) +# define TLS_method SSLv23_method +# define TLS_server_method SSLv23_server_method +# define TLS_client_method SSLv23_client_method #endif -/* BN_GENCB */ -#if !defined(HAVE_BN_GENCB_NEW) -# define BN_GENCB_new() ((BN_GENCB *)OPENSSL_malloc(sizeof(BN_GENCB))) -# define BN_GENCB_free(cb) OPENSSL_free(cb) -# define BN_GENCB_get_arg(cb) cb->arg +#if !defined(HAVE_SSL_CTX_GET_CIPHERS) +static inline STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx) { return ctx->cipher_list; } #endif -/* X509 */ -#if !defined(HAVE_X509_GET0_TBS_SIGALG) -# define X509_get0_tbs_sigalg(x) (x->cert_info->signature) +#if !defined(HAVE_SSL_CTX_GET_SECURITY_LEVEL) #endif -#if !defined(HAVE_X509_REVOKED_GET0_SERIALNUMBER) -# define X509_REVOKED_get0_serialNumber(x) (x->serialNumber) +#if !defined(HAVE_SSL_CTX_SET_SECURITY_LEVEL) #endif -#if !defined(HAVE_X509_REVOKED_GET0_REVOCATIONDATE) -# define X509_REVOKED_get0_revocationDate(x) (x->revocationDate) +#if !defined(HAVE_OCSP_SINGLERESP_GET0_ID) +# define OCSP_SINGLERESP_get0_id(s) (s)->certId #endif +#if defined(HAVE_EVP_PKEY_TYPE) /* is not opaque */ +static inline RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) { return pkey->pkey.rsa; } +static inline DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey) { return pkey->pkey.dsa; } +static inline EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) { return pkey->pkey.ec; } +static inline DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey) { return pkey->pkey.dh; } +static inline void RSA_get0_key(RSA *rsa, BIGNUM **n, BIGNUM **e, BIGNUM **d) { + if (n) *n = rsa->n; + if (e) *e = rsa->e; + if (d) *d = rsa->d; } +static inline int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) { + if (!n || !e) return 0; + BN_free(rsa->n); rsa->n = n; + BN_free(rsa->e); rsa->e = e; + BN_free(rsa->d); rsa->d = d; + return 1; } +static inline void RSA_get0_factors(RSA *rsa, BIGNUM **p, BIGNUM **q) { + if (p) *p = rsa->p; + if (q) *q = rsa->q; } +static inline int RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q) { + if (!p || !q) return 0; + BN_free(rsa->p); rsa->p = p; + BN_free(rsa->q); rsa->q = q; + return 1; } +static inline void RSA_get0_crt_params(RSA *rsa, BIGNUM **dmp1, BIGNUM **dmq1, BIGNUM **iqmp) { + if (dmp1) *dmp1 = rsa->dmp1; + if (dmq1) *dmq1 = rsa->dmq1; + if (iqmp) *iqmp = rsa->iqmp; } +static inline int RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) { + if (!dmp1 || !dmq1 || !iqmp) return 0; + BN_free(rsa->dmp1); rsa->dmp1 = dmp1; + BN_free(rsa->dmq1); rsa->dmq1 = dmq1; + BN_free(rsa->iqmp); rsa->iqmp = iqmp; + return 1; } + +static inline void DSA_get0_key(DSA *dsa, BIGNUM **pub_key, BIGNUM **priv_key) { + if (pub_key) *pub_key = dsa->pub_key; + if (priv_key) *priv_key = dsa->priv_key; } +static inline int DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *priv_key) { + if (!pub_key) return 0; + BN_free(dsa->pub_key); dsa->pub_key = pub_key; + BN_free(dsa->priv_key); dsa->priv_key = priv_key; + return 1; } +static inline void DSA_get0_pqg(DSA *dsa, BIGNUM **p, BIGNUM **q, BIGNUM **g) { + if (p) *p = dsa->p; + if (q) *q = dsa->q; + if (g) *g = dsa->g; } +static inline int DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g) { + if (!p || !q || !g) return 0; + BN_free(dsa->p); dsa->p = p; + BN_free(dsa->q); dsa->q = q; + BN_free(dsa->g); dsa->g = g; + return 1; } +static inline ENGINE *DH_get0_engine(DH *dh) { return dh->engine; } +static inline void DH_get0_key(DH *dh, BIGNUM **pub_key, BIGNUM **priv_key) { + if (pub_key) *pub_key = dh->pub_key; + if (priv_key) *priv_key = dh->priv_key; } +static inline int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) { + if (!pub_key) return 0; + BN_free(dh->pub_key); dh->pub_key = pub_key; + BN_free(dh->priv_key); dh->priv_key = priv_key; + return 1; } +static inline void DH_get0_pqg(DH *dh, BIGNUM **p, BIGNUM **q, BIGNUM **g) { + if (p) *p = dh->p; + if (q) *q = dh->q; + if (g) *g = dh->g; } +static inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) { + if (!p || !g) return 0; + BN_free(dh->p); dh->p = p; + BN_free(dh->q); dh->q = q; + BN_free(dh->g); dh->g = g; + return 1; } +#endif #if defined(__cplusplus) } diff --git a/ext/openssl/ossl.c b/ext/openssl/ossl.c index b6f85477dd..8c15112dcf 100644 --- a/ext/openssl/ossl.c +++ b/ext/openssl/ossl.c @@ -462,7 +462,7 @@ ossl_fips_mode_set(VALUE self, VALUE enabled) #endif } -#ifdef HAVE_CRYPTO_LOCK /* OpenSSL 1.0.2 or older */ +#ifndef HAVE_OPENSSL_110_THREADING_API /** * Stores locks needed for OpenSSL thread safety */ @@ -1150,7 +1150,7 @@ Init_openssl(void) */ ossl_s_to_der = rb_intern("to_der"); -#ifdef HAVE_CRYPTO_LOCK +#ifndef HAVE_OPENSSL_110_THREADING_API Init_ossl_locks(); #endif diff --git a/ext/openssl/ossl_cipher.c b/ext/openssl/ossl_cipher.c index a812f0ccba..c9fcb6bdbd 100644 --- a/ext/openssl/ossl_cipher.c +++ b/ext/openssl/ossl_cipher.c @@ -161,9 +161,7 @@ add_cipher_name_to_ary(const OBJ_NAME *name, VALUE ary) rb_ary_push(ary, rb_str_new2(name->name)); return NULL; } -#endif -#ifdef HAVE_OBJ_NAME_DO_ALL_SORTED /* * call-seq: * OpenSSL::Cipher.ciphers -> array[string...] diff --git a/ext/openssl/ossl_pkcs5.c b/ext/openssl/ossl_pkcs5.c index 73d989e164..56ed65fb9d 100644 --- a/ext/openssl/ossl_pkcs5.c +++ b/ext/openssl/ossl_pkcs5.c @@ -48,7 +48,6 @@ ossl_pkcs5_pbkdf2_hmac(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALUE key #endif -#ifdef HAVE_PKCS5_PBKDF2_HMAC_SHA1 /* * call-seq: * PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen) => string @@ -81,9 +80,6 @@ ossl_pkcs5_pbkdf2_hmac_sha1(VALUE self, VALUE pass, VALUE salt, VALUE iter, VALU return str; } -#else -#define ossl_pkcs5_pbkdf2_hmac_sha1 rb_f_notimplement -#endif void Init_ossl_pkcs5(void) diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index 0e68bd869b..7cbb2f474f 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -270,7 +270,7 @@ ossl_tmp_dh_callback(SSL *ssl, int is_export, int keylength) } #endif /* OPENSSL_NO_DH */ -#if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK) +#if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK) && !defined(HAVE_SSL_CTX_SET1_CURVES_LIST) static EC_KEY * ossl_tmp_ecdh_callback(SSL *ssl, int is_export, int keylength) { @@ -696,7 +696,7 @@ ossl_sslctx_setup(VALUE self) SSL_CTX_set_tmp_dh_callback(ctx, ossl_tmp_dh_callback); #endif -#if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK) +#if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK) && !defined(HAVE_SSL_CTX_SET1_CURVES_LIST) SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback); #endif @@ -1012,9 +1012,14 @@ ossl_sslctx_set_elliptic_curves(VALUE self, VALUE str) if (!ctx) ossl_raise(eSSLError, "SSL_CTX is not initialized."); -#if defined(HAVE_SSL_CTX_SET1_CURVES_LIST) /* OpenSSL 1.0.2- */ +#if defined(HAVE_SSL_CTX_SET1_CURVES_LIST) if (!SSL_CTX_set1_curves_list(ctx, cstr)) ossl_raise(eSSLError, "SSL_CTX_set1_curves_list"); +#if defined(HAVE_SSL_CTX_SET_ECDH_AUTO) + /* always enabled in 1.1.0, needed only in 1.0.2 */ + if (!SSL_CTX_set_ecdh_auto(ctx, 1)) + ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto"); +#endif #else if (strstr(cstr, ":")) ossl_raise(eSSLError, "only one curve can be specified"); diff --git a/ext/openssl/ossl_ssl_session.c b/ext/openssl/ossl_ssl_session.c index 08a5357c10..4dbe53e32b 100644 --- a/ext/openssl/ossl_ssl_session.c +++ b/ext/openssl/ossl_ssl_session.c @@ -73,6 +73,29 @@ static VALUE ossl_ssl_session_initialize(VALUE self, VALUE arg1) return self; } + +static int +xSSL_SESSION_cmp(const SSL_SESSION *a, const SSL_SESSION *b) +{ + unsigned int a_len; + const unsigned char *a_sid = SSL_SESSION_get_id(a, &a_len); + unsigned int b_len; + const unsigned char *b_sid = SSL_SESSION_get_id(b, &b_len); + +#if !defined(HAVE_SSL_SESSION_GET_ID) /* 1.0.2 or older */ + if (a->ssl_version != b->ssl_version) + return 1; +#endif + if (a_len != b_len) + return 1; + +#if defined(_WIN32) + return memcmp(a_sid, b_sid, a_len); +#else + return CRYPTO_memcmp(a_sid, b_sid, a_len); +#endif +} + /* * call-seq: * session1 == session2 -> boolean @@ -85,7 +108,7 @@ static VALUE ossl_ssl_session_eq(VALUE val1, VALUE val2) GetSSLSession(val1, ctx1); SafeGetSSLSession(val2, ctx2); - switch (SSL_SESSION_cmp(ctx1, ctx2)) { + switch (xSSL_SESSION_cmp(ctx1, ctx2)) { case 0: return Qtrue; default: return Qfalse; } diff --git a/test/openssl/test_pair.rb b/test/openssl/test_pair.rb index 5279f6010f..df0a47828d 100644 --- a/test/openssl/test_pair.rb +++ b/test/openssl/test_pair.rb @@ -380,51 +380,6 @@ module OpenSSL::TestPairM accepted.close if accepted.respond_to?(:close) end - def test_set_elliptic_curves - ctx2 = OpenSSL::SSL::SSLContext.new - ctx2.ciphers = "ECDH:DH" - ctx2.security_level = 0 - ctx2.set_elliptic_curves("P-384") - - sock1, sock2 = tcp_pair - - s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2) - ctx1 = OpenSSL::SSL::SSLContext.new - ctx1.ciphers = "ECDH:DH" - ctx1.security_level = 0 - - s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1) - th = Thread.new do - begin - rv = s1.connect_nonblock(exception: false) - case rv - when :wait_writable - IO.select(nil, [s1], nil, 5) - when :wait_readable - IO.select([s1], nil, nil, 5) - end - end until rv == s1 - end - - accepted = s2.accept - - assert accepted.cipher[0].start_with?("AECDH"), "AECDH should be used" - # TODO: how to detect what curve was used? - rescue OpenSSL::SSL::SSLError => e - if e.message =~ /no cipher match/ - skip "ECDH cipher not supported." - else - raise e - end - ensure - th.join if th - s1.close if s1 - s2.close if s2 - sock1.close if sock1 - sock2.close if sock2 - accepted.close if accepted.respond_to?(:close) - end - def test_connect_accept_nonblock_no_exception ctx2 = OpenSSL::SSL::SSLContext.new ctx2.ciphers = "ADH" diff --git a/test/openssl/test_ssl.rb b/test/openssl/test_ssl.rb index 58a1990dc4..5644d5db08 100644 --- a/test/openssl/test_ssl.rb +++ b/test/openssl/test_ssl.rb @@ -1206,6 +1206,36 @@ end end end + def test_set_elliptic_curves + return unless OpenSSL::SSL::SSLSocket.method_defined?(:tmp_key) and + OpenSSL::SSL::SSLContext.method_defined?(:set_elliptic_curves) + sock1, sock2 = socketpair + + ctx1 = OpenSSL::SSL::SSLContext.new + ctx1.ciphers = "AECDH-AES256-SHA" + ctx1.security_level = 0 + s1 = OpenSSL::SSL::SSLSocket.new(sock1, ctx1) + + ctx2 = OpenSSL::SSL::SSLContext.new + ctx2.ciphers = "AECDH-AES256-SHA" + ctx2.security_level = 0 + ctx2.set_elliptic_curves("P-521") + s2 = OpenSSL::SSL::SSLSocket.new(sock2, ctx2) + + th = Thread.new { s1.connect } + s2.accept + + assert s2.cipher[0].start_with?("AECDH"), "AECDH should be used" + # TODO: how to detect what curve was used? + # test that the curve is secp521r1 + ensure + th.join if th + s1.close if s1 + s2.close if s2 + sock1.close if sock1 + sock2.close if sock2 + end + private def start_server_version(version, ctx_proc=nil, server_proc=nil, &blk) -- cgit v1.2.3