postmodern / ruby-install

Installs Ruby, JRuby, TruffleRuby, or mruby
MIT License
1.89k stars 250 forks source link

openssl@3 support - EVP_MD_CTX_get_pkey_ctx - incomplete definition of type struct evp_md_ctx_st - use openssl@1.1 #473

Closed optimizasean closed 8 months ago

optimizasean commented 8 months ago

Description

Steps To Reproduce

Steps to reproduce the bug:

  1. $ ruby-install ...
  2. FAIL

I have the same issue, many others do with openssl@3. Unable to install any version of ruby (ruby, 3.20, 3.1.4, 3.0.0, 2.7.8, ...). Tried multiple and it fails based on this struct.

You can also force it to use openssl@1.1 but it still fails: ruby-install ruby -- --with-openssl-dir=/opt/homebrew/opt/openssl@1.1

It appears it always reads the openssl@3 libraries no matter what if you follow recommended configuration.

Expected Behavior

Should just work.

Actual Behavior

ossl_hmac.c:249:35: error: incomplete definition of type 'struct evp_md_ctx_st'
    pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx));
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
./openssl_missing.h:230:41: note: expanded from macro 'EVP_MD_CTX_get_pkey_ctx'
#  define EVP_MD_CTX_get_pkey_ctx(x) (x)->pctx
                                     ~~~^
/usr/local/opt/openssl@3/include/openssl/types.h:107:16: note: forward declaration of 'struct evp_md_ctx_st'
typedef struct evp_md_ctx_st EVP_MD_CTX;
               ^
1 warning and 1 error generated.
make[2]: *** [ossl_hmac.o] Error 1
make[1]: *** [ext/openssl/all] Error 2
make: *** [build-ext] Error 2
!!! Compiling ruby 3.2.0 failed!

Above is the openssl@3 error message.

Environment

ruby-install version: 0.9.2 macOS version: 12.7.1 Homebrew version: 4.1.22 openssl version: @3 && @1.1

All ruby versions (2.7+)

Solution

Use openssl@1.1 and remove configuration for openssl@3.

Remove from profile/bashrc/... that homebrew openssl recommends adding:

# OpenSSL@3
# To make OpenSSL@3 first
export PATH="/usr/local/opt/openssl@3/bin:$PATH"
# For compilers to find openssl@3 you may need to set:
export LDFLAGS="-L/usr/local/opt/openssl@3/lib"
export CPPFLAGS="-I/usr/local/opt/openssl@3/include"
# For pkg-config to find openssl@3 you may need to set:
export PKG_CONFIG_PATH="/usr/local/opt/openssl@3/lib/pkgconfig"

Then it will fill openssl@1.1 first so use the path prefix again. Force it to use openssl@1.1: ruby-install ruby -- --with-openssl-dir=/opt/homebrew/opt/openssl@1.1

Now it works (ruby 2.7.8 & 3.2.2 installed and tested).

postmodern commented 8 months ago

openssl-1.1 has already reached EoL and is not receiving any further security updates. https://www.openssl.org/blog/blog/2023/03/28/1.1.1-EOL/

Also, ruby-3.0 will reach EoL on March 31st 2024. https://endoflife.date/ruby

We may just have to accept that Ruby < 3.1 is no longer accepted, and thus we should fully switch to openssl-3.x and ruby >= 3.1. See issue #461 about the switch over. I've been debating whether to make the switch immediately or continue waiting until March 2024. Also, we have already merged a fix to also set --with-openssl-dir in 4971a1f934a687c1032e5e17615f791743e8c5d4, and have been procrastinating releasing a patch release due to other work.

postmodern commented 8 months ago

I have recently added some logic to dynamically install the openssl@1.1 or openssl@3 homebrew package depending on the version of Ruby. See a37e332e055da91db5fb053a3d94ebb0f219043d This will be released shortly in ruby-install 0.9.3.

Also, ruby-install 0.9.3 now specifies --with-openssl-dir instead of just --with-opt-dir, which apparently Ruby's configure script treats with more precedence, and should prevent it from using another detected instance of openssl on the system.

However, this comes with a few caveats:

  1. This is risky, because openssl-1.1 has reached End-of-Life. It will not receive anymore security updates. While I understand people have legacy apps they must maintain, running old unmaintained versions of software is risky. I strongly recommend that people upgrade to at least Ruby 3.1, which uses openssl-3.0.
  2. This only works for homebrew users. Linux and other BSD package managers only provide one version of openssl, and that's most likely openssl-3.0, as openssl-1.1 has reached End-of-Life.
  3. I will eventually remove this complex logic after Ruby 3.0 reaches End-of-Life, which was the last Ruby version to use openssl-1.1. After that point, if users still need to install Ruby 2.7 or 3.0, they will have to specify -- --with-openssl-dir=/path/to/openssl@1.1 themselves.

Comment or reopen this issue if you still have issues with ruby-install 0.9.3.

stonefield commented 4 months ago

This problem also occur with Ruby v 3.3.0. I tried with both OpenSSL 3.2.1 and 3.1.3. Same error occur i both cases:

/usr/local/Cellar/openssl@3/3.2.1/include/openssl/ts.h:426:11: note: previous definition is here
#  define TS_VERIFY_CTS_set_certs(ctx, cert) TS_VERIFY_CTX_set_certs(ctx,cert)
          ^
ossl_hmac.c:249:35: error: incomplete definition of type 'struct evp_md_ctx_st'
    pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx));
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
./openssl_missing.h:230:41: note: expanded from macro 'EVP_MD_CTX_get_pkey_ctx'
#  define EVP_MD_CTX_get_pkey_ctx(x) (x)->pctx
                                     ~~~^
/usr/local/Cellar/openssl@3/3.2.1/include/openssl/types.h:107:16: note: forward declaration of 'struct evp_md_ctx_st'
typedef struct evp_md_ctx_st EVP_MD_CTX;
               ^
1 warning and 1 error generated.
make[2]: *** [ossl_hmac.o] Error 1
make[1]: *** [ext/openssl/all] Error 2
make: *** [build-ext] Error 2
!!! Compiling ruby 3.3.0 failed!
/usr/local/Cellar/openssl@3/3.1.3/include/openssl/ts.h:426:11: note: previous definition is here
#  define TS_VERIFY_CTS_set_certs(ctx, cert) TS_VERIFY_CTX_set_certs(ctx,cert)
          ^
ossl_hmac.c:249:35: error: incomplete definition of type 'struct evp_md_ctx_st'
    pkey = EVP_PKEY_CTX_get0_pkey(EVP_MD_CTX_get_pkey_ctx(ctx));
                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
./openssl_missing.h:230:41: note: expanded from macro 'EVP_MD_CTX_get_pkey_ctx'
#  define EVP_MD_CTX_get_pkey_ctx(x) (x)->pctx
                                     ~~~^
/usr/local/Cellar/openssl@3/3.1.3/include/openssl/types.h:107:16: note: forward declaration of 'struct evp_md_ctx_st'
typedef struct evp_md_ctx_st EVP_MD_CTX;
               ^
1 warning and 1 error generated.
make[2]: *** [ossl_hmac.o] Error 1
make[1]: *** [ext/openssl/all] Error 2
make: *** [build-ext] Error 2
!!! Compiling ruby 3.3.0 failed!
postmodern commented 4 months ago

@stonefield what version of ruby-install are you using? In ruby-install 0.9.3, it will switch between openssl@3 and openssl@11 based on the Ruby version, and explicitly pass in the --with-openssl-dir option to ./configure.

stonefield commented 4 months ago

% brew info ruby-install ==> ruby-install: stable 0.9.3 (bottled), HEAD % sw_vers ProductName: macOS ProductVersion: 14.4.1 BuildVersion: 23E224

stonefield commented 4 months ago

Facepalm

# ls -l /usr/local/bin/ruby-install
lrwxr-xr-x  1 kenmark  admin  45 Jul 26  2023 /usr/local/bin/ruby-install -> ../Cellar/ruby-install/0.9.1/bin/ruby-install

Problem solved. >>> Successfully installed ruby 3.3.0