Browse Source

Move patches to specific folder

master
aeris 1 month ago
parent
commit
85ac04a3ab

+ 62
- 26
Makefile View File

@@ -16,7 +16,7 @@ export LD_LIBRARY_PATH = $(PWD)/lib

.SECONDARY:

all: libs ext
all: libs

clean: clean-libs clean-ext
clean-libs:
@@ -42,8 +42,28 @@ build/$(OPENSSL_NAME).tar.gz: | build/
wget https://www.openssl.org/source/$(OPENSSL_NAME).tar.gz -O $@

$(OPENSSL_DIR)/: build/$(OPENSSL_NAME).tar.gz build/chacha-poly.patch
tar -C build -xf build/$(OPENSSL_NAME).tar.gz
#patch -d $(OPENSSL_DIR) -p1 < build/chacha-poly.patch
tar -C build -xf "build/$(OPENSSL_NAME).tar.gz"
patch -d "$(OPENSSL_DIR)" -p1 < build/chacha-poly.patch
patch -d "$(OPENSSL_DIR)" -p1 < patches/openssl/00_disable_digest_check.patch

build/openssl/Makefile: | build/openssl/
#cd $(OPENSSL_DIR) && ./Configure enable-ssl2 enable-ssl3 enable-weak-ssl-ciphers enable-zlib enable-rc5 enable-rc2 enable-gost enable-md2 enable-mdc2 enable-shared linux-x86_64
#cd $(OPENSSL_DIR) && ./config enable-ssl2 enable-ssl3 enable-md2 enable-rc5 enable-weak-ssl-ciphers shared
cd build/openssl/ && ./config enable-ssl2 enable-ssl3 enable-ssl3-method enable-md2 enable-rc5 enable-weak-ssl-ciphers enable-shared

build/openssl/libssl.so \
build/openssl/libcrypto.so: build/openssl/Makefile
$(MAKE) -C build/openssl/

install-openssl: build/openssl/Makefile
$(MAKE) -C build/openssl/ install

LIBS = lib/libssl.so lib/libcrypto.so lib/libssl.so.$(OPENSSL_LIB_VERSION) lib/libcrypto.so.$(OPENSSL_LIB_VERSION)
lib/%.so: build/openssl/%.so
cp "$<" "$@"
lib/%.so.$(OPENSSL_LIB_VERSION): lib/%.so
ln -fs "$(notdir $(subst .$(OPENSSL_LIB_VERSION),,$@))" "$@"
libs: $(LIBS)

$(OPENSSL_DIR)/Makefile: | $(OPENSSL_DIR)/
#cd $(OPENSSL_DIR) && ./Configure enable-ssl2 enable-ssl3 enable-weak-ssl-ciphers enable-zlib enable-rc5 enable-rc2 enable-gost enable-md2 enable-mdc2 enable-shared linux-x86_64
@@ -54,44 +74,60 @@ $(OPENSSL_DIR)/libssl.so \
$(OPENSSL_DIR)/libcrypto.so: $(OPENSSL_DIR)/Makefile
$(MAKE) -C $(OPENSSL_DIR) depend build_libs

LIBS = lib/libssl.so lib/libcrypto.so lib/libssl.so.$(OPENSSL_LIB_VERSION) lib/libcrypto.so.$(OPENSSL_LIB_VERSION)
lib/%.so: $(OPENSSL_DIR)/%.so
cp $< $@
lib/%.so.$(OPENSSL_LIB_VERSION): lib/%.so
ln -fs $(notdir $(subst .$(OPENSSL_LIB_VERSION),,$@)) $@
libs: $(LIBS)
$(RBENV_ROOT)/plugins/ruby-build/share/ruby-build/$(RUBY_VERSION): | $(RBENV_ROOT)/plugins/ruby-build/

build/$(RUBY_VERSION)-cryptcheck: $(RBENV_ROOT)/plugins/ruby-build/share/ruby-build/$(RUBY_VERSION)
cp $< $@
install-ruby: build/$(RUBY_VERSION)-cryptcheck $(LIBS) | $(OPENSSL_DIR)/
cat tmp_key.patch set_ecdh_curves.patch fallback_scsv.patch | \
RUBY_BUILD_CACHE_PATH=$(PWD)/build \
RUBY_BUILD_DEFINITIONS=$(PWD)/build \
rbenv install -fp $(RUBY_VERSION)-cryptcheck
rbenv sequester $(RUBY_VERSION)-cryptcheck
rbenv local $(RUBY_VERSION)-cryptcheck
cp "$<" "$@"

install-rbenv: build/$(RUBY_VERSION)-cryptcheck

install-rbenv-cryptcheck: build/$(RUBY_VERSION)-cryptcheck $(LIBS) | build/openssl/
cat patches/ruby/*.patch | \
RUBY_BUILD_CACHE_PATH="$(PWD)/build" \
RUBY_BUILD_DEFINITIONS="$(PWD)/build" \
rbenv install -fp "$(RUBY_VERSION)-cryptcheck"
rbenv local "$(RUBY_VERSION)-cryptcheck"
gem update --system
gem install bundler
bundle
# bundle install --without test development

$(RUBY_LIB_DIR)/openssl/ssl.rb: $(RUBY_OPENSSL_EXT_DIR)/lib/openssl/ssl.rb
cp $< $@
cp "$<" "$@"

$(RUBY_LIB_DIR)/x86_64-linux/openssl.so: $(RUBY_OPENSSL_EXT_DIR)/openssl.so
cp $< $@
cp "$<" "$@"

sync-ruby: $(RUBY_LIB_DIR)/openssl/ssl.rb $(RUBY_LIB_DIR)/x86_64-linux/openssl.so

build/$(RUBY_NAME).tar.xz: | build/
wget http://cache.ruby-lang.org/pub/ruby/$(RUBY_MAJOR_VERSION)/$(RUBY_NAME).tar.xz -O $@
wget "http://cache.ruby-lang.org/pub/ruby/$(RUBY_MAJOR_VERSION)/$(RUBY_NAME).tar.xz" -O "$@"

$(RUBY_DIR)/: build/$(RUBY_NAME).tar.xz
tar -C build -xf $<
tar -C build -xf "$<"
for p in patches/ruby/*.patch; do patch -d "$@" -p1 < $i; done

$(RUBY_OPENSSL_EXT_DIR)/Makefile: libs | $(RUBY_DIR)/
patch -d $(RUBY_DIR)/ -p1 < tmp_key.patch
cd $(RUBY_OPENSSL_EXT_DIR) && ruby extconf.rb
cd "$(RUBY_OPENSSL_EXT_DIR)" && ruby extconf.rb

$(RUBY_OPENSSL_EXT_DIR)/openssl.so: $(LIBS) $(RUBY_OPENSSL_EXT_DIR)/Makefile
top_srcdir=../.. $(MAKE) -C $(RUBY_OPENSSL_EXT_DIR)
top_srcdir=../.. $(MAKE) -C "$(RUBY_OPENSSL_EXT_DIR)"

lib/openssl.so: $(RUBY_OPENSSL_EXT_DIR)/openssl.so
cp $< $@
cp "$<" "$@"

ext: lib/openssl.so

install-ruby: $(RUBY_DIR)/
cd "$(RUBY_DIR)/" && ./configure --enable-shared --disable-install-rdoc && make install

spec/faketime/libfaketime.so: spec/faketime/faketime.c spec/faketime/faketime.h
$(CC) "$^" -o "$@" -shared -fPIC -ldl -std=c99 -Werror -Wall
lib/libfaketime.so: spec/faketime/libfaketime.so
ln -fs "../$<" "$@"
faketime: lib/libfaketime.so

test-material:
bin/generate-test-material.rb

test: spec/faketime/libfaketime.so
bin/rspec

+ 76
- 0
patches/openssl/00_disable_digest_check.patch View File

@@ -0,0 +1,76 @@
diff --git a/crypto/dsa/dsa_pmeth.c b/crypto/dsa/dsa_pmeth.c
index 42b8bb0..baaa76f 100644
--- a/crypto/dsa/dsa_pmeth.c
+++ b/crypto/dsa/dsa_pmeth.c
@@ -174,26 +174,26 @@ static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
return 1;
case EVP_PKEY_CTRL_DSA_PARAMGEN_MD:
- if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha256) {
- DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
- return 0;
- }
+ // if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
+ // EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
+ // EVP_MD_type((const EVP_MD *)p2) != NID_sha256) {
+ // DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
+ // return 0;
+ // }
dctx->md = p2;
return 1;
case EVP_PKEY_CTRL_MD:
- if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_dsa &&
- EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
- DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
- return 0;
- }
+ // if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
+ // EVP_MD_type((const EVP_MD *)p2) != NID_dsa &&
+ // EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA &&
+ // EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
+ // EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
+ // EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
+ // EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
+ // DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
+ // return 0;
+ // }
dctx->md = p2;
return 1;
diff --git a/crypto/ec/ec_pmeth.c b/crypto/ec/ec_pmeth.c
index b767490..70eea17 100644
--- a/crypto/ec/ec_pmeth.c
+++ b/crypto/ec/ec_pmeth.c
@@ -379,15 +379,15 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
return dctx->kdf_ukmlen;
case EVP_PKEY_CTRL_MD:
- if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
- EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
- ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
- return 0;
- }
+ // if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 &&
+ // EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 &&
+ // EVP_MD_type((const EVP_MD *)p2) != NID_sha224 &&
+ // EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
+ // EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
+ // EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
+ // ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE);
+ // return 0;
+ // }
dctx->md = p2;
return 1;

tmp_key.patch → patches/ruby/01_tmp_key.patch View File


+ 418
- 0
patches/ruby/02_set_ecdh_curves.patch View File

@@ -0,0 +1,418 @@
diff --git a/ext/openssl/extconf.rb b/ext/openssl/extconf.rb
index 0b7fa2a..7c45d7a 100644
--- a/ext/openssl/extconf.rb
+++ b/ext/openssl/extconf.rb
@@ -93,6 +93,7 @@
have_func("X509_NAME_hash_old")
have_func("X509_STORE_get_ex_data")
have_func("X509_STORE_set_ex_data")
+OpenSSL.check_func_or_macro("SSL_CTX_set_tmp_ecdh_callback", "openssl/ssl.h") # removed
have_func("OBJ_NAME_do_all_sorted")
have_func("SSL_SESSION_get_id")
have_func("SSL_SESSION_cmp")
@@ -109,7 +110,10 @@
have_func("TLSv1_2_method")
have_func("TLSv1_2_server_method")
have_func("TLSv1_2_client_method")
+have_func("EC_curve_nist2nid")
have_func("SSL_CTX_set_alpn_select_cb")
+OpenSSL.check_func_or_macro("SSL_CTX_set1_curves_list", "openssl/ssl.h")
+OpenSSL.check_func_or_macro("SSL_CTX_set_ecdh_auto", "openssl/ssl.h")
have_func("SSL_CTX_set_next_proto_select_cb")
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")
diff --git a/ext/openssl/openssl_missing.c b/ext/openssl/openssl_missing.c
index 31f2d0a..bc61a96 100644
--- a/ext/openssl/openssl_missing.c
+++ b/ext/openssl/openssl_missing.c
@@ -34,6 +34,43 @@ HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in)
#endif /* HAVE_HMAC_CTX_COPY */
#endif /* NO_HMAC */
+/* added in 1.0.2 */
+#if !defined(OPENSSL_NO_EC)
+#if !defined(HAVE_EC_CURVE_NIST2NID)
+static struct {
+ const char *name;
+ int nid;
+} nist_curves[] = {
+ {"B-163", NID_sect163r2},
+ {"B-233", NID_sect233r1},
+ {"B-283", NID_sect283r1},
+ {"B-409", NID_sect409r1},
+ {"B-571", NID_sect571r1},
+ {"K-163", NID_sect163k1},
+ {"K-233", NID_sect233k1},
+ {"K-283", NID_sect283k1},
+ {"K-409", NID_sect409k1},
+ {"K-571", NID_sect571k1},
+ {"P-192", NID_X9_62_prime192v1},
+ {"P-224", NID_secp224r1},
+ {"P-256", NID_X9_62_prime256v1},
+ {"P-384", NID_secp384r1},
+ {"P-521", NID_secp521r1}
+};
+
+int
+EC_curve_nist2nid(const char *name)
+{
+ size_t i;
+ for (i = 0; i < (sizeof(nist_curves) / sizeof(nist_curves[0])); i++) {
+ if (!strcmp(nist_curves[i].name, name))
+ return nist_curves[i].nid;
+ }
+ return NID_undef;
+}
+#endif
+#endif
+
#if !defined(HAVE_EVP_MD_CTX_CREATE)
EVP_MD_CTX *
EVP_MD_CTX_create(void)
diff --git a/ext/openssl/openssl_missing.h b/ext/openssl/openssl_missing.h
index 955579c..6e2f5b5 100644
--- a/ext/openssl/openssl_missing.h
+++ b/ext/openssl/openssl_missing.h
@@ -70,6 +70,12 @@ void HMAC_CTX_init(HMAC_CTX *ctx);
void HMAC_CTX_copy(HMAC_CTX *out, HMAC_CTX *in);
#endif
+#if !defined(OPENSSL_NO_EC)
+#if !defined(HAVE_EC_CURVE_NIST2NID)
+int EC_curve_nist2nid(const char *);
+#endif
+#endif
+
#if !defined(HAVE_HMAC_CTX_CLEANUP)
void HMAC_CTX_cleanup(HMAC_CTX *ctx);
#endif
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index cd35ee3..975616f 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -161,6 +161,18 @@ ossl_sslctx_s_alloc(VALUE klass)
RTYPEDDATA_DATA(obj) = ctx;
SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_ptr_idx, (void*)obj);
+#if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
+ /* We use SSL_CTX_set1_curves_list() to specify the curve used in ECDH. It
+ * allows to specify multiple curve names and OpenSSL will select
+ * automatically from them. In OpenSSL 1.0.2, the automatic selection has to
+ * be enabled explicitly. But OpenSSL 1.1.0 removed the knob and it is
+ * always enabled. To uniform the behavior, we enable the automatic
+ * selection also in 1.0.2. Users can still disable ECDH by removing ECDH
+ * cipher suites by SSLContext#ciphers=. */
+ if (!SSL_CTX_set_ecdh_auto(ctx, 1))
+ ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
+#endif
+
return obj;
}
@@ -718,19 +730,33 @@ ossl_sslctx_setup(VALUE self)
#endif
#if !defined(OPENSSL_NO_EC)
- if (RTEST(ossl_sslctx_get_tmp_ecdh_cb(self))){
- SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
- }
-#endif
+ /* We added SSLContext#tmp_ecdh_callback= in Ruby 2.3.0,
+ * but SSL_CTX_set_tmp_ecdh_callback() was removed in OpenSSL 1.1.0. */
+ if (RTEST(ossl_sslctx_get_tmp_ecdh_cb(self))) {
+# if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
+ rb_warn("#tmp_ecdh_callback= is deprecated; use #ecdh_curves= instead");
+ SSL_CTX_set_tmp_ecdh_callback(ctx, ossl_tmp_ecdh_callback);
+# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
+ /* tmp_ecdh_callback and ecdh_auto conflict; OpenSSL ignores
+ * tmp_ecdh_callback. So disable ecdh_auto. */
+ if (!SSL_CTX_set_ecdh_auto(ctx, 0))
+ ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
+# endif
+# else
+ ossl_raise(eSSLError, "OpenSSL does not support tmp_ecdh_callback; "
+ "use #ecdh_curves= instead");
+# endif
+ }
+#endif /* OPENSSL_NO_EC */
val = ossl_sslctx_get_cert_store(self);
if(!NIL_P(val)){
- /*
- * WORKAROUND:
- * X509_STORE can count references, but
- * X509_STORE_free() doesn't care it.
- * So we won't increment it but mark it by ex_data.
- */
+ /*
+ * WORKAROUND:
+ * X509_STORE can count references, but
+ * X509_STORE_free() doesn't care it.
+ * So we won't increment it but mark it by ex_data.
+ */
store = GetX509StorePtr(val); /* NO NEED TO DUP */
SSL_CTX_set_cert_store(ctx, store);
SSL_CTX_set_ex_data(ctx, ossl_ssl_ex_store_p, (void*)1);
@@ -738,7 +764,7 @@ ossl_sslctx_setup(VALUE self)
val = ossl_sslctx_get_extra_cert(self);
if(!NIL_P(val)){
- rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);
+ rb_block_call(val, rb_intern("each"), 0, 0, ossl_sslctx_add_extra_chain_cert_i, self);
}
/* private key may be bundled in certificate file. */
@@ -762,22 +788,21 @@ ossl_sslctx_setup(VALUE self)
val = ossl_sslctx_get_client_ca(self);
if(!NIL_P(val)){
- if (RB_TYPE_P(val, T_ARRAY)) {
- for(i = 0; i < RARRAY_LEN(val); i++){
- client_ca = GetX509CertPtr(RARRAY_AREF(val, i));
- if (!SSL_CTX_add_client_CA(ctx, client_ca)){
- /* Copies X509_NAME => FREE it. */
- ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
- }
- }
- }
- else{
- client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */
+ if (RB_TYPE_P(val, T_ARRAY)) {
+ for(i = 0; i < RARRAY_LEN(val); i++){
+ client_ca = GetX509CertPtr(RARRAY_AREF(val, i));
+ if (!SSL_CTX_add_client_CA(ctx, client_ca)){
+ /* Copies X509_NAME => FREE it. */
+ ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
+ }
+ }
+ } else {
+ client_ca = GetX509CertPtr(val); /* NO DUP NEEDED. */
if (!SSL_CTX_add_client_CA(ctx, client_ca)){
- /* Copies X509_NAME => FREE it. */
- ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
+ /* Copies X509_NAME => FREE it. */
+ ossl_raise(eSSLError, "SSL_CTX_add_client_CA");
}
- }
+ }
}
val = ossl_sslctx_get_ca_file(self);
@@ -785,15 +810,15 @@ ossl_sslctx_setup(VALUE self)
val = ossl_sslctx_get_ca_path(self);
ca_path = NIL_P(val) ? NULL : StringValuePtr(val);
if(ca_file || ca_path){
- if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
- rb_warning("can't set verify locations");
+ if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_path))
+ rb_warning("can't set verify locations");
}
val = ossl_sslctx_get_verify_mode(self);
verify_mode = NIL_P(val) ? SSL_VERIFY_NONE : NUM2INT(val);
SSL_CTX_set_verify(ctx, verify_mode, ossl_ssl_verify_callback);
if (RTEST(ossl_sslctx_get_client_cert_cb(self)))
- SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);
+ SSL_CTX_set_client_cert_cb(ctx, ossl_client_cert_cb);
val = ossl_sslctx_get_timeout(self);
if(!NIL_P(val)) SSL_CTX_set_timeout(ctx, NUM2LONG(val));
@@ -804,26 +829,26 @@ ossl_sslctx_setup(VALUE self)
#ifdef HAVE_SSL_CTX_SET_NEXT_PROTO_SELECT_CB
val = rb_iv_get(self, "@npn_protocols");
if (!NIL_P(val)) {
- rb_iv_set(self, "@_protocols", ssl_encode_npn_protocols(val));
- SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *) self);
- OSSL_Debug("SSL NPN advertise callback added");
+ rb_iv_set(self, "@_protocols", ssl_encode_npn_protocols(val));
+ SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_advertise_cb, (void *) self);
+ OSSL_Debug("SSL NPN advertise callback added");
}
if (RTEST(rb_iv_get(self, "@npn_select_cb"))) {
- SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self);
- OSSL_Debug("SSL NPN select callback added");
+ SSL_CTX_set_next_proto_select_cb(ctx, ssl_npn_select_cb, (void *) self);
+ OSSL_Debug("SSL NPN select callback added");
}
#endif
#ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
val = rb_iv_get(self, "@alpn_protocols");
if (!NIL_P(val)) {
- VALUE rprotos = ssl_encode_npn_protocols(val);
- SSL_CTX_set_alpn_protos(ctx, (const unsigned char *)StringValueCStr(rprotos), RSTRING_LENINT(rprotos));
- OSSL_Debug("SSL ALPN values added");
+ VALUE rprotos = ssl_encode_npn_protocols(val);
+ SSL_CTX_set_alpn_protos(ctx, (const unsigned char *)StringValueCStr(rprotos), RSTRING_LENINT(rprotos));
+ OSSL_Debug("SSL ALPN values added");
}
if (RTEST(rb_iv_get(self, "@alpn_select_cb"))) {
- SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
- OSSL_Debug("SSL ALPN select callback added");
+ SSL_CTX_set_alpn_select_cb(ctx, ssl_alpn_select_cb, (void *) self);
+ OSSL_Debug("SSL ALPN select callback added");
}
#endif
@@ -831,31 +856,31 @@ ossl_sslctx_setup(VALUE self)
val = ossl_sslctx_get_sess_id_ctx(self);
if (!NIL_P(val)){
- StringValue(val);
- if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
- RSTRING_LENINT(val))){
- ossl_raise(eSSLError, "SSL_CTX_set_session_id_context");
- }
+ StringValue(val);
+ if (!SSL_CTX_set_session_id_context(ctx, (unsigned char *)RSTRING_PTR(val),
+ RSTRING_LENINT(val))){
+ ossl_raise(eSSLError, "SSL_CTX_set_session_id_context");
+ }
}
if (RTEST(rb_iv_get(self, "@session_get_cb"))) {
- SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
- OSSL_Debug("SSL SESSION get callback added");
+ SSL_CTX_sess_set_get_cb(ctx, ossl_sslctx_session_get_cb);
+ OSSL_Debug("SSL SESSION get callback added");
}
if (RTEST(rb_iv_get(self, "@session_new_cb"))) {
- SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
- OSSL_Debug("SSL SESSION new callback added");
+ SSL_CTX_sess_set_new_cb(ctx, ossl_sslctx_session_new_cb);
+ OSSL_Debug("SSL SESSION new callback added");
}
if (RTEST(rb_iv_get(self, "@session_remove_cb"))) {
- SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
- OSSL_Debug("SSL SESSION remove callback added");
+ SSL_CTX_sess_set_remove_cb(ctx, ossl_sslctx_session_remove_cb);
+ OSSL_Debug("SSL SESSION remove callback added");
}
#ifdef HAVE_SSL_SET_TLSEXT_HOST_NAME
val = rb_iv_get(self, "@servername_cb");
if (!NIL_P(val)) {
SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
- OSSL_Debug("SSL TLSEXT servername callback added");
+ OSSL_Debug("SSL TLSEXT servername callback added");
}
#endif
@@ -960,6 +985,87 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
return v;
}
+#if !defined(OPENSSL_NO_EC)
+/*
+ * call-seq:
+ * ctx.ecdh_curves = curve_list -> curve_list
+ *
+ * Sets the list of "supported elliptic curves" for this context.
+ *
+ * For a TLS client, the list is directly used in the Supported Elliptic Curves
+ * Extension. For a server, the list is used by OpenSSL to determine the set of
+ * shared curves. OpenSSL will pick the most appropriate one from it.
+ *
+ * Note that this works differently with old OpenSSL (<= 1.0.1). Only one curve
+ * can be set, and this has no effect for TLS clients.
+ *
+ * === Example
+ * ctx1 = OpenSSL::SSL::SSLContext.new
+ * ctx1.ecdh_curves = "X25519:P-256:P-224"
+ * svr = OpenSSL::SSL::SSLServer.new(tcp_svr, ctx1)
+ * Thread.new { svr.accept }
+ *
+ * ctx2 = OpenSSL::SSL::SSLContext.new
+ * ctx2.ecdh_curves = "P-256"
+ * cli = OpenSSL::SSL::SSLSocket.new(tcp_sock, ctx2)
+ * cli.connect
+ *
+ * p cli.tmp_key.group.curve_name
+ * # => "prime256v1" (is an alias for NIST P-256)
+ */
+static VALUE
+ossl_sslctx_set_ecdh_curves(VALUE self, VALUE arg)
+{
+ SSL_CTX *ctx;
+
+ rb_check_frozen(self);
+ GetSSLCTX(self, ctx);
+ StringValueCStr(arg);
+
+#if defined(HAVE_SSL_CTX_SET1_CURVES_LIST)
+ if (!SSL_CTX_set1_curves_list(ctx, RSTRING_PTR(arg)))
+ ossl_raise(eSSLError, NULL);
+#else
+ /* OpenSSL does not have SSL_CTX_set1_curves_list()... Fallback to
+ * SSL_CTX_set_tmp_ecdh(). So only the first curve is used. */
+ {
+ VALUE curve, splitted;
+ EC_KEY *ec;
+ int nid;
+
+ splitted = rb_str_split(arg, ":");
+ if (!RARRAY_LEN(splitted))
+ ossl_raise(eSSLError, "invalid input format");
+ curve = RARRAY_AREF(splitted, 0);
+ StringValueCStr(curve);
+
+ /* SSL_CTX_set1_curves_list() accepts NIST names */
+ nid = EC_curve_nist2nid(RSTRING_PTR(curve));
+ if (nid == NID_undef)
+ nid = OBJ_txt2nid(RSTRING_PTR(curve));
+ if (nid == NID_undef)
+ ossl_raise(eSSLError, "unknown curve name");
+
+ ec = EC_KEY_new_by_curve_name(nid);
+ if (!ec)
+ ossl_raise(eSSLError, NULL);
+ EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
+ SSL_CTX_set_tmp_ecdh(ctx, ec);
+# if defined(HAVE_SSL_CTX_SET_ECDH_AUTO)
+ /* tmp_ecdh and ecdh_auto conflict. tmp_ecdh is ignored when ecdh_auto
+ * is enabled. So disable ecdh_auto. */
+ if (!SSL_CTX_set_ecdh_auto(ctx, 0))
+ ossl_raise(eSSLError, "SSL_CTX_set_ecdh_auto");
+# endif
+ }
+#endif
+
+ return arg;
+}
+#else
+#define ossl_sslctx_set_ecdh_curves rb_f_notimplement
+#endif
+
/*
* call-seq:
* ctx.session_add(session) -> true | false
@@ -2065,6 +2171,7 @@ Init_ossl_ssl(void)
*/
rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse);
+#if defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK)
/*
* A callback invoked when ECDH parameters are required.
*
@@ -2072,10 +2179,11 @@ Init_ossl_ssl(void)
* flag indicating the use of an export cipher and the keylength
* required.
*
- * The callback must return an OpenSSL::PKey::EC instance of the correct
- * key length.
+ * The callback is deprecated. This does not work with recent versions of
+ * OpenSSL. Use OpenSSL::SSL::SSLContext#ecdh_curves= instead.
*/
rb_attr(cSSLContext, rb_intern("tmp_ecdh_callback"), 1, 1, Qfalse);
+#endif
/*
* Sets the context in which a session can be reused. This allows
@@ -2211,6 +2319,7 @@ Init_ossl_ssl(void)
rb_define_method(cSSLContext, "ssl_version=", ossl_sslctx_set_ssl_version, 1);
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
+ rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);

+ 76
- 0
patches/ruby/03_fallback_scsv.patch View File

@@ -0,0 +1,76 @@
diff --git a/ext/openssl/deprecation.rb b/ext/openssl/deprecation.rb
index d773536..f4a6c4b 100644
--- a/ext/openssl/deprecation.rb
+++ b/ext/openssl/deprecation.rb
@@ -19,4 +19,9 @@ def self.check_func(func, header)
have_func(func, header, deprecated_warning_flag) and
have_header(header, nil, deprecated_warning_flag)
end
+
+ def self.check_func_or_macro(func, header)
+ check_func(func, header) or
+ have_macro(func, header) && $defs.push("-DHAVE_#{func.upcase}")
+ end
end
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb
index 9893757..bcb167e 100644
--- a/ext/openssl/lib/openssl/ssl.rb
+++ b/ext/openssl/lib/openssl/ssl.rb
@@ -105,11 +105,12 @@ class SSLContext
# SSLContext.new("SSLv23_client") => ctx
#
# You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS
- def initialize(version = nil)
+ def initialize(version = nil, fallback_scsv: false)
INIT_VARS.each { |v| instance_variable_set v, nil }
self.options = self.options | OpenSSL::SSL::OP_ALL
return unless version
self.ssl_version = version
+ self.enable_fallback_scsv if fallback_scsv
end
##
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 8bd198a..184c864 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -985,6 +985,31 @@ ossl_sslctx_set_ciphers(VALUE self, VALUE v)
return v;
}
+/*
+ * call-seq:
+ * ctx.enable_fallback_scsv() => nil
+ *
+ * Activate TLS_FALLBACK_SCSV for this context.
+ * See RFC 7507.
+ */
+static VALUE
+ossl_sslctx_enable_fallback_scsv(VALUE self)
+{
+ SSL_CTX *ctx;
+
+ GetSSLCTX(self, ctx);
+ if(!ctx){
+ rb_warning("SSL_CTX is not initialized.");
+ return Qnil;
+ }
+
+ long modes = SSL_CTX_get_mode(ctx);
+ modes |= SSL_MODE_SEND_FALLBACK_SCSV;
+ SSL_CTX_set_mode(ctx, modes);
+
+ return Qnil;
+}
+
#if !defined(OPENSSL_NO_EC)
/*
* call-seq:
@@ -2339,6 +2364,7 @@ Init_ossl_ssl(void)
rb_define_method(cSSLContext, "ciphers", ossl_sslctx_get_ciphers, 0);
rb_define_method(cSSLContext, "ciphers=", ossl_sslctx_set_ciphers, 1);
rb_define_method(cSSLContext, "ecdh_curves=", ossl_sslctx_set_ecdh_curves, 1);
+ rb_define_method(cSSLContext, "enable_fallback_scsv", ossl_sslctx_enable_fallback_scsv, 0);
rb_define_method(cSSLContext, "setup", ossl_sslctx_setup, 0);

+ 151
- 0
patches/ruby/04_multiple_certs.patch View File

@@ -0,0 +1,151 @@
diff --git a/ext/openssl/lib/openssl/ssl.rb b/ext/openssl/lib/openssl/ssl.rb
index bcb167e..cd82e6d 100644
--- a/ext/openssl/lib/openssl/ssl.rb
+++ b/ext/openssl/lib/openssl/ssl.rb
@@ -70,7 +70,7 @@ class SSLContext
DEFAULT_CERT_STORE.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL
end
- INIT_VARS = ["cert", "key", "client_ca", "ca_file", "ca_path",
+ INIT_VARS = ["client_ca", "ca_file", "ca_path",
"timeout", "verify_mode", "verify_depth", "renegotiation_cb",
"verify_callback", "cert_store", "extra_chain_cert",
"client_cert_cb", "session_id_context", "tmp_dh_callback",
@@ -106,6 +106,8 @@ class SSLContext
#
# You can get a list of valid methods with OpenSSL::SSL::SSLContext::METHODS
def initialize(version = nil, fallback_scsv: false)
+ @certs = []
+ @keys = []
INIT_VARS.each { |v| instance_variable_set v, nil }
self.options = self.options | OpenSSL::SSL::OP_ALL
return unless version
@@ -131,6 +133,22 @@ def set_params(params={})
end
return params
end
+
+ # Compatibility with previous version supporting a single certificate
+ def cert=(cert)
+ self.certs = [cert]
+ end
+ def cert
+
+ self.certs.first
+ end
+
+ def key=(key)
+ self.keys = [key]
+ end
+ def key
+ self.keys.first
+ end
end
module SocketForwarder
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c
index 184c864..8f08918 100644
--- a/ext/openssl/ossl_ssl.c
+++ b/ext/openssl/ossl_ssl.c
@@ -36,8 +36,8 @@ VALUE cSSLSocket;
static VALUE eSSLErrorWaitReadable;
static VALUE eSSLErrorWaitWritable;
-#define ossl_sslctx_set_cert(o,v) rb_iv_set((o),"@cert",(v))
-#define ossl_sslctx_set_key(o,v) rb_iv_set((o),"@key",(v))
+#define ossl_sslctx_set_certs(o,v) rb_iv_set((o),"@certs",(v))
+#define ossl_sslctx_set_keys(o,v) rb_iv_set((o),"@keys",(v))
#define ossl_sslctx_set_client_ca(o,v) rb_iv_set((o),"@client_ca",(v))
#define ossl_sslctx_set_ca_file(o,v) rb_iv_set((o),"@ca_file",(v))
#define ossl_sslctx_set_ca_path(o,v) rb_iv_set((o),"@ca_path",(v))
@@ -50,8 +50,8 @@ static VALUE eSSLErrorWaitWritable;
#define ossl_sslctx_set_client_cert_cb(o,v) rb_iv_set((o),"@client_cert_cb",(v))
#define ossl_sslctx_set_sess_id_ctx(o, v) rb_iv_set((o),"@session_id_context",(v))
-#define ossl_sslctx_get_cert(o) rb_iv_get((o),"@cert")
-#define ossl_sslctx_get_key(o) rb_iv_get((o),"@key")
+#define ossl_sslctx_get_certs(o) rb_iv_get((o),"@certs")
+#define ossl_sslctx_get_keys(o) rb_iv_get((o),"@keys")
#define ossl_sslctx_get_client_ca(o) rb_iv_get((o),"@client_ca")
#define ossl_sslctx_get_ca_file(o) rb_iv_get((o),"@ca_file")
#define ossl_sslctx_get_ca_path(o) rb_iv_get((o),"@ca_path")
@@ -720,7 +720,8 @@ ossl_sslctx_setup(VALUE self)
char *ca_path = NULL, *ca_file = NULL;
int verify_mode;
long i;
- VALUE val;
+ VALUE val, val2;
+ int cert_defined = 0, key_defined = 0;
if(OBJ_FROZEN(self)) return Qnil;
GetSSLCTX(self, ctx);
@@ -768,19 +769,39 @@ ossl_sslctx_setup(VALUE self)
}
/* private key may be bundled in certificate file. */
- val = ossl_sslctx_get_cert(self);
- cert = NIL_P(val) ? NULL : GetX509CertPtr(val); /* NO DUP NEEDED */
- val = ossl_sslctx_get_key(self);
- key = NIL_P(val) ? NULL : GetPKeyPtr(val); /* NO DUP NEEDED */
- if (cert && key) {
- if (!SSL_CTX_use_certificate(ctx, cert)) {
- /* Adds a ref => Safe to FREE */
- ossl_raise(eSSLError, "SSL_CTX_use_certificate");
+ val = ossl_sslctx_get_certs(self);
+ if (!NIL_P(val)) {
+ Check_Type(val, T_ARRAY);
+ for (i = 0; i < RARRAY_LEN(val); i++) {
+ val2 = rb_ary_entry(val, i);
+ cert = NIL_P(val2) ? NULL : GetX509CertPtr(val2); /* NO DUP NEEDED */
+ if (cert) {
+ cert_defined = 1;
+ if (!SSL_CTX_use_certificate(ctx, cert)) {
+ /* Adds a ref => Safe to FREE */
+ ossl_raise(eSSLError, "SSL_CTX_use_certificate");
+ }
+ }
}
- if (!SSL_CTX_use_PrivateKey(ctx, key)) {
- /* Adds a ref => Safe to FREE */
- ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey");
+ }
+
+ val = ossl_sslctx_get_keys(self);
+ if (!NIL_P(val)) {
+ Check_Type(val, T_ARRAY);
+ for (i = 0; i < RARRAY_LEN(val); i++) {
+ val2 = rb_ary_entry(val, i);
+ key = NIL_P(val2) ? NULL : GetPKeyPtr(val2); /* NO DUP NEEDED */
+ if (cert) {
+ key_defined = 1;
+ if (!SSL_CTX_use_PrivateKey(ctx, key)) {
+ /* Adds a ref => Safe to FREE */
+ ossl_raise(eSSLError, "SSL_CTX_use_certificate");
+ }
+ }
}
+ }
+
+ if (cert_defined && key_defined) {
if (!SSL_CTX_check_private_key(ctx)) {
ossl_raise(eSSLError, "SSL_CTX_check_private_key");
}
@@ -2137,14 +2158,14 @@ Init_ossl_ssl(void)
rb_define_alloc_func(cSSLContext, ossl_sslctx_s_alloc);
/*
- * Context certificate
+ * Context certificates
*/
- rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern("certs"), 1, 1, Qfalse);
/*
- * Context private key
+ * Context private keys
*/
- rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse);
+ rb_attr(cSSLContext, rb_intern("keys"), 1, 1, Qfalse);
/*
* A certificate or Array of certificates that will be sent to the client.

+ 137
- 0
patches/ruby/05_resolv_rr_length.patch.disabled View File

@@ -0,0 +1,137 @@
--- a/lib/resolv.rb 2017-10-29 13:02:49.280729153 +0100
+++ b/lib/resolv.rb 2017-10-29 13:02:37.340717366 +0100
@@ -1644,7 +1641,7 @@
name = self.get_name
type, klass, ttl = self.get_unpack('nnN')
typeclass = Resource.get_class(type, klass)
- res = self.get_length16 { typeclass.decode_rdata self }
+ res = self.get_length16 { |l| typeclass.decode_rdata self, l }
res.instance_variable_set :@ttl, ttl
return name, ttl, res
end
@@ -1659,7 +1656,7 @@
raise EncodeError.new("#{self.class} is query.")
end

- def self.decode_rdata(msg) # :nodoc:
+ def self.decode_rdata(msg, len) # :nodoc:
raise DecodeError.new("#{self.class} is query.")
end
end
@@ -1680,7 +1677,7 @@
raise NotImplementedError.new
end

- def self.decode_rdata(msg) # :nodoc:
+ def self.decode_rdata(msg, len) # :nodoc:
raise NotImplementedError.new
end

@@ -1737,7 +1734,7 @@
msg.put_bytes(data)
end

- def self.decode_rdata(msg) # :nodoc:
+ def self.decode_rdata(msg, _) # :nodoc:
return self.new(msg.get_bytes)
end

@@ -1772,7 +1769,7 @@
msg.put_name(@name)
end

- def self.decode_rdata(msg) # :nodoc:
+ def self.decode_rdata(msg, _) # :nodoc:
return self.new(msg.get_name)
end
end
@@ -1860,7 +1857,7 @@
msg.put_pack('NNNNN', @serial, @refresh, @retry, @expire, @minimum)
end

- def self.decode_rdata(msg) # :nodoc:
+ def self.decode_rdata(msg, _) # :nodoc:
mname = msg.get_name
rname = msg.get_name
serial, refresh, retry_, expire, minimum = msg.get_unpack('NNNNN')
@@ -1906,7 +1903,7 @@
msg.put_string(@os)
end

- def self.decode_rdata(msg) # :nodoc:
+ def self.decode_rdata(msg, _) # :nodoc:
cpu = msg.get_string
os = msg.get_string
return self.new(cpu, os)
@@ -1940,7 +1937,7 @@
msg.put_name(@emailbx)
end

- def self.decode_rdata(msg) # :nodoc:
+ def self.decode_rdata(msg, _) # :nodoc:
rmailbx = msg.get_string
emailbx = msg.get_string
return self.new(rmailbx, emailbx)
@@ -1978,7 +1975,7 @@
msg.put_name(@exchange)
end

- def self.decode_rdata(msg) # :nodoc:
+ def self.decode_rdata(msg, _) # :nodoc:
preference, = msg.get_unpack('n')
exchange = msg.get_name
return self.new(preference, exchange)
@@ -2012,7 +2009,7 @@
msg.put_string_list(@strings)
end

- def self.decode_rdata(msg) # :nodoc:
+ def self.decode_rdata(msg, _) # :nodoc:
strings = msg.get_string_list
return self.new(*strings)
end
@@ -2089,7 +2086,7 @@
msg.put_bytes(@altitude.altitude)
end

- def self.decode_rdata(msg) # :nodoc:
+ def self.decode_rdata(msg, _) # :nodoc:
version = msg.get_bytes(1)
ssize = msg.get_bytes(1)
hprecision = msg.get_bytes(1)
@@ -2159,7 +2156,7 @@
msg.put_bytes(@address.address)
end

- def self.decode_rdata(msg) # :nodoc:
+ def self.decode_rdata(msg, _) # :nodoc:
return self.new(IPv4.new(msg.get_bytes(4)))
end
end
@@ -2204,7 +2201,7 @@
msg.put_bytes(@bitmap)
end

- def self.decode_rdata(msg) # :nodoc:
+ def self.decode_rdata(msg, _) # :nodoc:
address = IPv4.new(msg.get_bytes(4))
protocol, = msg.get_unpack("n")
bitmap = msg.get_bytes
@@ -2236,7 +2233,7 @@
msg.put_bytes(@address.address)
end

- def self.decode_rdata(msg) # :nodoc:
+ def self.decode_rdata(msg, _) # :nodoc:
return self.new(IPv6.new(msg.get_bytes(16)))
end
end
@@ -2306,7 +2303,7 @@
msg.put_name(@target)
end

- def self.decode_rdata(msg) # :nodoc:
+ def self.decode_rdata(msg, _) # :nodoc:
priority, = msg.get_unpack("n")
weight, = msg.get_unpack("n")
port, = msg.get_unpack("n")

Loading…
Cancel
Save