Tags: jdx/ruby
Tags
fix: auto-detect system SSL certs at C level, remove PORTABLE_RUBY_SS… …L_CERT_* rename (#14) ## Summary - Remove `SSL_CERT_FILE`/`SSL_CERT_DIR` → `PORTABLE_RUBY_SSL_CERT_*` rename from portable-openssl - Patch `X509_get_default_cert_file()` and `X509_get_default_cert_dir()` to auto-detect system certificate paths when the compiled-in default doesn't exist - Only fall back to bundled `cert.pem` when no system certs are found (not unconditionally) ## Problem The previous approach patched Ruby's stdlib `openssl.rb` to bridge `SSL_CERT_FILE` → `PORTABLE_RUBY_SSL_CERT_FILE`. This breaks when the `openssl` gem (v3.3.1+) is installed via Bundler, because the gem replaces stdlib's `openssl.rb` with its own version that doesn't have the bridge code. Without the bridge, `PORTABLE_RUBY_SSL_CERT_FILE` is never set, and the compiled-in default cert path (`/home/linuxbrew/.linuxbrew/Cellar/portable-openssl@.../cert.pem`) doesn't exist at runtime → SSL failures. This affects any Ruby app that uses Bundler with the `openssl` gem in its Gemfile.lock (which includes Rails, Sinatra, and most production Ruby apps). ## Fix **portable-openssl**: Instead of renaming env vars, patch OpenSSL's C code to auto-detect system cert paths at runtime: ```c const char *X509_get_default_cert_file(void) { if (access(X509_CERT_FILE, R_OK) == 0) return X509_CERT_FILE; static const char *system_cert_files[] = { "/etc/ssl/certs/ca-certificates.crt", /* Debian/Ubuntu */ "/etc/pki/tls/certs/ca-bundle.crt", /* RHEL/CentOS/Fedora */ "/etc/ssl/ca-bundle.pem", /* SUSE */ "/etc/ssl/cert.pem", /* macOS/Alpine */ NULL }; for (int i = 0; system_cert_files[i] != NULL; i++) { if (access(system_cert_files[i], R_OK) == 0) return system_cert_files[i]; } return X509_CERT_FILE; } ``` Same pattern for `X509_get_default_cert_dir()` with `/etc/ssl/certs` and `/etc/pki/tls/certs`. **jdx-ruby**: The `openssl.rb` bridge now only sets `SSL_CERT_FILE` to the bundled `cert.pem` when **no system certs exist** (checked against the same well-known paths). On normal systems, the C-level auto-detection runs unimpeded using the system's up-to-date certs. ## Benefits - `SSL_CERT_FILE` and `SSL_CERT_DIR` work as standard OpenSSL env vars (no rename) - Works regardless of whether the `openssl` gem replaces stdlib - C-level auto-detection covers Debian/Ubuntu, RHEL/CentOS, SUSE, macOS, and Alpine - Bundled `cert.pem` still available as last-resort fallback for minimal containers without system certs - System certs are preferred over bundled certs (fresher, org-customizable) - No env var leaking to child processes ## Tested Downloaded the `ubuntu-22.04, yjit: true` CI artifact and tested on a devcontainer (Ubuntu 22.04): | Test | Result | |---|---| | Basic SSL cert detection | PASS - `DEFAULT_CERT_FILE` auto-detects `/etc/ssl/certs/ca-certificates.crt` | | openssl gem 3.3.1 (root cause) | PASS - HTTPS works with gem replacing stdlib | | Custom `SSL_CERT_FILE` + `SSL_CERT_DIR` | PASS - env vars override auto-detection | | Valid custom `SSL_CERT_FILE` | PASS - custom cert path works | | Minimal Docker container (no `ca-certificates`) | PASS - bundled `cert.pem` fallback works | | Custom `SSL_CERT_FILE` in minimal container | PASS - bridge doesn't override explicit env var | ### Before (unpatched Ruby 3.4.7 with openssl gem): ``` DEFAULT_CERT_FILE: /home/linuxbrew/.linuxbrew/Cellar/portable-openssl@3.5.1/3.5.1/libexec/etc/openssl/cert.pem → SSL_connect returned=1 errno=0 state=error: certificate verify failed ``` ### After (patched Ruby 3.4.1 with openssl gem): ``` DEFAULT_CERT_FILE: /etc/ssl/certs/ca-certificates.crt → HTTPS 200 OK ``` ### Minimal container (no ca-certificates): ``` SSL_CERT_FILE env: "/ruby/libexec/cert.pem" (bundled fallback activated) → HTTPS 200 OK ``` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches TLS certificate resolution behavior in `portable-openssl` and all `jdx-ruby` formula variants, which can impact HTTPS connectivity across environments. Logic is straightforward but changes low-level defaults and should be validated on varied distros/containers. > > **Overview** > **Fixes SSL cert resolution for portable Ruby builds (incl. when the `openssl` gem replaces stdlib).** `portable-openssl@3.5.1` stops renaming `SSL_CERT_FILE`/`SSL_CERT_DIR` and instead patches `X509_get_default_cert_file()`/`X509_get_default_cert_dir()` to prefer readable system CA bundle paths/directories when the compiled-in defaults aren’t present. > > Across `Abstract/jdx-ruby.rb` and `jdx-ruby-32/33/34`, the `openssl.rb` patch is simplified to *only* set `SSL_CERT_FILE` to the bundled `libexec/cert.pem` when `SSL_CERT_FILE` is unset **and** no well-known system cert bundle exists, leaving normal system cert usage unchanged. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bc99d55. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
fix: auto-detect system SSL certs at C level, remove PORTABLE_RUBY_SS… …L_CERT_* rename (#14) ## Summary - Remove `SSL_CERT_FILE`/`SSL_CERT_DIR` → `PORTABLE_RUBY_SSL_CERT_*` rename from portable-openssl - Patch `X509_get_default_cert_file()` and `X509_get_default_cert_dir()` to auto-detect system certificate paths when the compiled-in default doesn't exist - Only fall back to bundled `cert.pem` when no system certs are found (not unconditionally) ## Problem The previous approach patched Ruby's stdlib `openssl.rb` to bridge `SSL_CERT_FILE` → `PORTABLE_RUBY_SSL_CERT_FILE`. This breaks when the `openssl` gem (v3.3.1+) is installed via Bundler, because the gem replaces stdlib's `openssl.rb` with its own version that doesn't have the bridge code. Without the bridge, `PORTABLE_RUBY_SSL_CERT_FILE` is never set, and the compiled-in default cert path (`/home/linuxbrew/.linuxbrew/Cellar/portable-openssl@.../cert.pem`) doesn't exist at runtime → SSL failures. This affects any Ruby app that uses Bundler with the `openssl` gem in its Gemfile.lock (which includes Rails, Sinatra, and most production Ruby apps). ## Fix **portable-openssl**: Instead of renaming env vars, patch OpenSSL's C code to auto-detect system cert paths at runtime: ```c const char *X509_get_default_cert_file(void) { if (access(X509_CERT_FILE, R_OK) == 0) return X509_CERT_FILE; static const char *system_cert_files[] = { "/etc/ssl/certs/ca-certificates.crt", /* Debian/Ubuntu */ "/etc/pki/tls/certs/ca-bundle.crt", /* RHEL/CentOS/Fedora */ "/etc/ssl/ca-bundle.pem", /* SUSE */ "/etc/ssl/cert.pem", /* macOS/Alpine */ NULL }; for (int i = 0; system_cert_files[i] != NULL; i++) { if (access(system_cert_files[i], R_OK) == 0) return system_cert_files[i]; } return X509_CERT_FILE; } ``` Same pattern for `X509_get_default_cert_dir()` with `/etc/ssl/certs` and `/etc/pki/tls/certs`. **jdx-ruby**: The `openssl.rb` bridge now only sets `SSL_CERT_FILE` to the bundled `cert.pem` when **no system certs exist** (checked against the same well-known paths). On normal systems, the C-level auto-detection runs unimpeded using the system's up-to-date certs. ## Benefits - `SSL_CERT_FILE` and `SSL_CERT_DIR` work as standard OpenSSL env vars (no rename) - Works regardless of whether the `openssl` gem replaces stdlib - C-level auto-detection covers Debian/Ubuntu, RHEL/CentOS, SUSE, macOS, and Alpine - Bundled `cert.pem` still available as last-resort fallback for minimal containers without system certs - System certs are preferred over bundled certs (fresher, org-customizable) - No env var leaking to child processes ## Tested Downloaded the `ubuntu-22.04, yjit: true` CI artifact and tested on a devcontainer (Ubuntu 22.04): | Test | Result | |---|---| | Basic SSL cert detection | PASS - `DEFAULT_CERT_FILE` auto-detects `/etc/ssl/certs/ca-certificates.crt` | | openssl gem 3.3.1 (root cause) | PASS - HTTPS works with gem replacing stdlib | | Custom `SSL_CERT_FILE` + `SSL_CERT_DIR` | PASS - env vars override auto-detection | | Valid custom `SSL_CERT_FILE` | PASS - custom cert path works | | Minimal Docker container (no `ca-certificates`) | PASS - bundled `cert.pem` fallback works | | Custom `SSL_CERT_FILE` in minimal container | PASS - bridge doesn't override explicit env var | ### Before (unpatched Ruby 3.4.7 with openssl gem): ``` DEFAULT_CERT_FILE: /home/linuxbrew/.linuxbrew/Cellar/portable-openssl@3.5.1/3.5.1/libexec/etc/openssl/cert.pem → SSL_connect returned=1 errno=0 state=error: certificate verify failed ``` ### After (patched Ruby 3.4.1 with openssl gem): ``` DEFAULT_CERT_FILE: /etc/ssl/certs/ca-certificates.crt → HTTPS 200 OK ``` ### Minimal container (no ca-certificates): ``` SSL_CERT_FILE env: "/ruby/libexec/cert.pem" (bundled fallback activated) → HTTPS 200 OK ``` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches TLS certificate resolution behavior in `portable-openssl` and all `jdx-ruby` formula variants, which can impact HTTPS connectivity across environments. Logic is straightforward but changes low-level defaults and should be validated on varied distros/containers. > > **Overview** > **Fixes SSL cert resolution for portable Ruby builds (incl. when the `openssl` gem replaces stdlib).** `portable-openssl@3.5.1` stops renaming `SSL_CERT_FILE`/`SSL_CERT_DIR` and instead patches `X509_get_default_cert_file()`/`X509_get_default_cert_dir()` to prefer readable system CA bundle paths/directories when the compiled-in defaults aren’t present. > > Across `Abstract/jdx-ruby.rb` and `jdx-ruby-32/33/34`, the `openssl.rb` patch is simplified to *only* set `SSL_CERT_FILE` to the bundled `libexec/cert.pem` when `SSL_CERT_FILE` is unset **and** no well-known system cert bundle exists, leaving normal system cert usage unchanged. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bc99d55. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
fix: auto-detect system SSL certs at C level, remove PORTABLE_RUBY_SS… …L_CERT_* rename (#14) ## Summary - Remove `SSL_CERT_FILE`/`SSL_CERT_DIR` → `PORTABLE_RUBY_SSL_CERT_*` rename from portable-openssl - Patch `X509_get_default_cert_file()` and `X509_get_default_cert_dir()` to auto-detect system certificate paths when the compiled-in default doesn't exist - Only fall back to bundled `cert.pem` when no system certs are found (not unconditionally) ## Problem The previous approach patched Ruby's stdlib `openssl.rb` to bridge `SSL_CERT_FILE` → `PORTABLE_RUBY_SSL_CERT_FILE`. This breaks when the `openssl` gem (v3.3.1+) is installed via Bundler, because the gem replaces stdlib's `openssl.rb` with its own version that doesn't have the bridge code. Without the bridge, `PORTABLE_RUBY_SSL_CERT_FILE` is never set, and the compiled-in default cert path (`/home/linuxbrew/.linuxbrew/Cellar/portable-openssl@.../cert.pem`) doesn't exist at runtime → SSL failures. This affects any Ruby app that uses Bundler with the `openssl` gem in its Gemfile.lock (which includes Rails, Sinatra, and most production Ruby apps). ## Fix **portable-openssl**: Instead of renaming env vars, patch OpenSSL's C code to auto-detect system cert paths at runtime: ```c const char *X509_get_default_cert_file(void) { if (access(X509_CERT_FILE, R_OK) == 0) return X509_CERT_FILE; static const char *system_cert_files[] = { "/etc/ssl/certs/ca-certificates.crt", /* Debian/Ubuntu */ "/etc/pki/tls/certs/ca-bundle.crt", /* RHEL/CentOS/Fedora */ "/etc/ssl/ca-bundle.pem", /* SUSE */ "/etc/ssl/cert.pem", /* macOS/Alpine */ NULL }; for (int i = 0; system_cert_files[i] != NULL; i++) { if (access(system_cert_files[i], R_OK) == 0) return system_cert_files[i]; } return X509_CERT_FILE; } ``` Same pattern for `X509_get_default_cert_dir()` with `/etc/ssl/certs` and `/etc/pki/tls/certs`. **jdx-ruby**: The `openssl.rb` bridge now only sets `SSL_CERT_FILE` to the bundled `cert.pem` when **no system certs exist** (checked against the same well-known paths). On normal systems, the C-level auto-detection runs unimpeded using the system's up-to-date certs. ## Benefits - `SSL_CERT_FILE` and `SSL_CERT_DIR` work as standard OpenSSL env vars (no rename) - Works regardless of whether the `openssl` gem replaces stdlib - C-level auto-detection covers Debian/Ubuntu, RHEL/CentOS, SUSE, macOS, and Alpine - Bundled `cert.pem` still available as last-resort fallback for minimal containers without system certs - System certs are preferred over bundled certs (fresher, org-customizable) - No env var leaking to child processes ## Tested Downloaded the `ubuntu-22.04, yjit: true` CI artifact and tested on a devcontainer (Ubuntu 22.04): | Test | Result | |---|---| | Basic SSL cert detection | PASS - `DEFAULT_CERT_FILE` auto-detects `/etc/ssl/certs/ca-certificates.crt` | | openssl gem 3.3.1 (root cause) | PASS - HTTPS works with gem replacing stdlib | | Custom `SSL_CERT_FILE` + `SSL_CERT_DIR` | PASS - env vars override auto-detection | | Valid custom `SSL_CERT_FILE` | PASS - custom cert path works | | Minimal Docker container (no `ca-certificates`) | PASS - bundled `cert.pem` fallback works | | Custom `SSL_CERT_FILE` in minimal container | PASS - bridge doesn't override explicit env var | ### Before (unpatched Ruby 3.4.7 with openssl gem): ``` DEFAULT_CERT_FILE: /home/linuxbrew/.linuxbrew/Cellar/portable-openssl@3.5.1/3.5.1/libexec/etc/openssl/cert.pem → SSL_connect returned=1 errno=0 state=error: certificate verify failed ``` ### After (patched Ruby 3.4.1 with openssl gem): ``` DEFAULT_CERT_FILE: /etc/ssl/certs/ca-certificates.crt → HTTPS 200 OK ``` ### Minimal container (no ca-certificates): ``` SSL_CERT_FILE env: "/ruby/libexec/cert.pem" (bundled fallback activated) → HTTPS 200 OK ``` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches TLS certificate resolution behavior in `portable-openssl` and all `jdx-ruby` formula variants, which can impact HTTPS connectivity across environments. Logic is straightforward but changes low-level defaults and should be validated on varied distros/containers. > > **Overview** > **Fixes SSL cert resolution for portable Ruby builds (incl. when the `openssl` gem replaces stdlib).** `portable-openssl@3.5.1` stops renaming `SSL_CERT_FILE`/`SSL_CERT_DIR` and instead patches `X509_get_default_cert_file()`/`X509_get_default_cert_dir()` to prefer readable system CA bundle paths/directories when the compiled-in defaults aren’t present. > > Across `Abstract/jdx-ruby.rb` and `jdx-ruby-32/33/34`, the `openssl.rb` patch is simplified to *only* set `SSL_CERT_FILE` to the bundled `libexec/cert.pem` when `SSL_CERT_FILE` is unset **and** no well-known system cert bundle exists, leaving normal system cert usage unchanged. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bc99d55. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
fix: auto-detect system SSL certs at C level, remove PORTABLE_RUBY_SS… …L_CERT_* rename (#14) ## Summary - Remove `SSL_CERT_FILE`/`SSL_CERT_DIR` → `PORTABLE_RUBY_SSL_CERT_*` rename from portable-openssl - Patch `X509_get_default_cert_file()` and `X509_get_default_cert_dir()` to auto-detect system certificate paths when the compiled-in default doesn't exist - Only fall back to bundled `cert.pem` when no system certs are found (not unconditionally) ## Problem The previous approach patched Ruby's stdlib `openssl.rb` to bridge `SSL_CERT_FILE` → `PORTABLE_RUBY_SSL_CERT_FILE`. This breaks when the `openssl` gem (v3.3.1+) is installed via Bundler, because the gem replaces stdlib's `openssl.rb` with its own version that doesn't have the bridge code. Without the bridge, `PORTABLE_RUBY_SSL_CERT_FILE` is never set, and the compiled-in default cert path (`/home/linuxbrew/.linuxbrew/Cellar/portable-openssl@.../cert.pem`) doesn't exist at runtime → SSL failures. This affects any Ruby app that uses Bundler with the `openssl` gem in its Gemfile.lock (which includes Rails, Sinatra, and most production Ruby apps). ## Fix **portable-openssl**: Instead of renaming env vars, patch OpenSSL's C code to auto-detect system cert paths at runtime: ```c const char *X509_get_default_cert_file(void) { if (access(X509_CERT_FILE, R_OK) == 0) return X509_CERT_FILE; static const char *system_cert_files[] = { "/etc/ssl/certs/ca-certificates.crt", /* Debian/Ubuntu */ "/etc/pki/tls/certs/ca-bundle.crt", /* RHEL/CentOS/Fedora */ "/etc/ssl/ca-bundle.pem", /* SUSE */ "/etc/ssl/cert.pem", /* macOS/Alpine */ NULL }; for (int i = 0; system_cert_files[i] != NULL; i++) { if (access(system_cert_files[i], R_OK) == 0) return system_cert_files[i]; } return X509_CERT_FILE; } ``` Same pattern for `X509_get_default_cert_dir()` with `/etc/ssl/certs` and `/etc/pki/tls/certs`. **jdx-ruby**: The `openssl.rb` bridge now only sets `SSL_CERT_FILE` to the bundled `cert.pem` when **no system certs exist** (checked against the same well-known paths). On normal systems, the C-level auto-detection runs unimpeded using the system's up-to-date certs. ## Benefits - `SSL_CERT_FILE` and `SSL_CERT_DIR` work as standard OpenSSL env vars (no rename) - Works regardless of whether the `openssl` gem replaces stdlib - C-level auto-detection covers Debian/Ubuntu, RHEL/CentOS, SUSE, macOS, and Alpine - Bundled `cert.pem` still available as last-resort fallback for minimal containers without system certs - System certs are preferred over bundled certs (fresher, org-customizable) - No env var leaking to child processes ## Tested Downloaded the `ubuntu-22.04, yjit: true` CI artifact and tested on a devcontainer (Ubuntu 22.04): | Test | Result | |---|---| | Basic SSL cert detection | PASS - `DEFAULT_CERT_FILE` auto-detects `/etc/ssl/certs/ca-certificates.crt` | | openssl gem 3.3.1 (root cause) | PASS - HTTPS works with gem replacing stdlib | | Custom `SSL_CERT_FILE` + `SSL_CERT_DIR` | PASS - env vars override auto-detection | | Valid custom `SSL_CERT_FILE` | PASS - custom cert path works | | Minimal Docker container (no `ca-certificates`) | PASS - bundled `cert.pem` fallback works | | Custom `SSL_CERT_FILE` in minimal container | PASS - bridge doesn't override explicit env var | ### Before (unpatched Ruby 3.4.7 with openssl gem): ``` DEFAULT_CERT_FILE: /home/linuxbrew/.linuxbrew/Cellar/portable-openssl@3.5.1/3.5.1/libexec/etc/openssl/cert.pem → SSL_connect returned=1 errno=0 state=error: certificate verify failed ``` ### After (patched Ruby 3.4.1 with openssl gem): ``` DEFAULT_CERT_FILE: /etc/ssl/certs/ca-certificates.crt → HTTPS 200 OK ``` ### Minimal container (no ca-certificates): ``` SSL_CERT_FILE env: "/ruby/libexec/cert.pem" (bundled fallback activated) → HTTPS 200 OK ``` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches TLS certificate resolution behavior in `portable-openssl` and all `jdx-ruby` formula variants, which can impact HTTPS connectivity across environments. Logic is straightforward but changes low-level defaults and should be validated on varied distros/containers. > > **Overview** > **Fixes SSL cert resolution for portable Ruby builds (incl. when the `openssl` gem replaces stdlib).** `portable-openssl@3.5.1` stops renaming `SSL_CERT_FILE`/`SSL_CERT_DIR` and instead patches `X509_get_default_cert_file()`/`X509_get_default_cert_dir()` to prefer readable system CA bundle paths/directories when the compiled-in defaults aren’t present. > > Across `Abstract/jdx-ruby.rb` and `jdx-ruby-32/33/34`, the `openssl.rb` patch is simplified to *only* set `SSL_CERT_FILE` to the bundled `libexec/cert.pem` when `SSL_CERT_FILE` is unset **and** no well-known system cert bundle exists, leaving normal system cert usage unchanged. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bc99d55. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
fix: auto-detect system SSL certs at C level, remove PORTABLE_RUBY_SS… …L_CERT_* rename (#14) ## Summary - Remove `SSL_CERT_FILE`/`SSL_CERT_DIR` → `PORTABLE_RUBY_SSL_CERT_*` rename from portable-openssl - Patch `X509_get_default_cert_file()` and `X509_get_default_cert_dir()` to auto-detect system certificate paths when the compiled-in default doesn't exist - Only fall back to bundled `cert.pem` when no system certs are found (not unconditionally) ## Problem The previous approach patched Ruby's stdlib `openssl.rb` to bridge `SSL_CERT_FILE` → `PORTABLE_RUBY_SSL_CERT_FILE`. This breaks when the `openssl` gem (v3.3.1+) is installed via Bundler, because the gem replaces stdlib's `openssl.rb` with its own version that doesn't have the bridge code. Without the bridge, `PORTABLE_RUBY_SSL_CERT_FILE` is never set, and the compiled-in default cert path (`/home/linuxbrew/.linuxbrew/Cellar/portable-openssl@.../cert.pem`) doesn't exist at runtime → SSL failures. This affects any Ruby app that uses Bundler with the `openssl` gem in its Gemfile.lock (which includes Rails, Sinatra, and most production Ruby apps). ## Fix **portable-openssl**: Instead of renaming env vars, patch OpenSSL's C code to auto-detect system cert paths at runtime: ```c const char *X509_get_default_cert_file(void) { if (access(X509_CERT_FILE, R_OK) == 0) return X509_CERT_FILE; static const char *system_cert_files[] = { "/etc/ssl/certs/ca-certificates.crt", /* Debian/Ubuntu */ "/etc/pki/tls/certs/ca-bundle.crt", /* RHEL/CentOS/Fedora */ "/etc/ssl/ca-bundle.pem", /* SUSE */ "/etc/ssl/cert.pem", /* macOS/Alpine */ NULL }; for (int i = 0; system_cert_files[i] != NULL; i++) { if (access(system_cert_files[i], R_OK) == 0) return system_cert_files[i]; } return X509_CERT_FILE; } ``` Same pattern for `X509_get_default_cert_dir()` with `/etc/ssl/certs` and `/etc/pki/tls/certs`. **jdx-ruby**: The `openssl.rb` bridge now only sets `SSL_CERT_FILE` to the bundled `cert.pem` when **no system certs exist** (checked against the same well-known paths). On normal systems, the C-level auto-detection runs unimpeded using the system's up-to-date certs. ## Benefits - `SSL_CERT_FILE` and `SSL_CERT_DIR` work as standard OpenSSL env vars (no rename) - Works regardless of whether the `openssl` gem replaces stdlib - C-level auto-detection covers Debian/Ubuntu, RHEL/CentOS, SUSE, macOS, and Alpine - Bundled `cert.pem` still available as last-resort fallback for minimal containers without system certs - System certs are preferred over bundled certs (fresher, org-customizable) - No env var leaking to child processes ## Tested Downloaded the `ubuntu-22.04, yjit: true` CI artifact and tested on a devcontainer (Ubuntu 22.04): | Test | Result | |---|---| | Basic SSL cert detection | PASS - `DEFAULT_CERT_FILE` auto-detects `/etc/ssl/certs/ca-certificates.crt` | | openssl gem 3.3.1 (root cause) | PASS - HTTPS works with gem replacing stdlib | | Custom `SSL_CERT_FILE` + `SSL_CERT_DIR` | PASS - env vars override auto-detection | | Valid custom `SSL_CERT_FILE` | PASS - custom cert path works | | Minimal Docker container (no `ca-certificates`) | PASS - bundled `cert.pem` fallback works | | Custom `SSL_CERT_FILE` in minimal container | PASS - bridge doesn't override explicit env var | ### Before (unpatched Ruby 3.4.7 with openssl gem): ``` DEFAULT_CERT_FILE: /home/linuxbrew/.linuxbrew/Cellar/portable-openssl@3.5.1/3.5.1/libexec/etc/openssl/cert.pem → SSL_connect returned=1 errno=0 state=error: certificate verify failed ``` ### After (patched Ruby 3.4.1 with openssl gem): ``` DEFAULT_CERT_FILE: /etc/ssl/certs/ca-certificates.crt → HTTPS 200 OK ``` ### Minimal container (no ca-certificates): ``` SSL_CERT_FILE env: "/ruby/libexec/cert.pem" (bundled fallback activated) → HTTPS 200 OK ``` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches TLS certificate resolution behavior in `portable-openssl` and all `jdx-ruby` formula variants, which can impact HTTPS connectivity across environments. Logic is straightforward but changes low-level defaults and should be validated on varied distros/containers. > > **Overview** > **Fixes SSL cert resolution for portable Ruby builds (incl. when the `openssl` gem replaces stdlib).** `portable-openssl@3.5.1` stops renaming `SSL_CERT_FILE`/`SSL_CERT_DIR` and instead patches `X509_get_default_cert_file()`/`X509_get_default_cert_dir()` to prefer readable system CA bundle paths/directories when the compiled-in defaults aren’t present. > > Across `Abstract/jdx-ruby.rb` and `jdx-ruby-32/33/34`, the `openssl.rb` patch is simplified to *only* set `SSL_CERT_FILE` to the bundled `libexec/cert.pem` when `SSL_CERT_FILE` is unset **and** no well-known system cert bundle exists, leaving normal system cert usage unchanged. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bc99d55. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
fix: auto-detect system SSL certs at C level, remove PORTABLE_RUBY_SS… …L_CERT_* rename (#14) ## Summary - Remove `SSL_CERT_FILE`/`SSL_CERT_DIR` → `PORTABLE_RUBY_SSL_CERT_*` rename from portable-openssl - Patch `X509_get_default_cert_file()` and `X509_get_default_cert_dir()` to auto-detect system certificate paths when the compiled-in default doesn't exist - Only fall back to bundled `cert.pem` when no system certs are found (not unconditionally) ## Problem The previous approach patched Ruby's stdlib `openssl.rb` to bridge `SSL_CERT_FILE` → `PORTABLE_RUBY_SSL_CERT_FILE`. This breaks when the `openssl` gem (v3.3.1+) is installed via Bundler, because the gem replaces stdlib's `openssl.rb` with its own version that doesn't have the bridge code. Without the bridge, `PORTABLE_RUBY_SSL_CERT_FILE` is never set, and the compiled-in default cert path (`/home/linuxbrew/.linuxbrew/Cellar/portable-openssl@.../cert.pem`) doesn't exist at runtime → SSL failures. This affects any Ruby app that uses Bundler with the `openssl` gem in its Gemfile.lock (which includes Rails, Sinatra, and most production Ruby apps). ## Fix **portable-openssl**: Instead of renaming env vars, patch OpenSSL's C code to auto-detect system cert paths at runtime: ```c const char *X509_get_default_cert_file(void) { if (access(X509_CERT_FILE, R_OK) == 0) return X509_CERT_FILE; static const char *system_cert_files[] = { "/etc/ssl/certs/ca-certificates.crt", /* Debian/Ubuntu */ "/etc/pki/tls/certs/ca-bundle.crt", /* RHEL/CentOS/Fedora */ "/etc/ssl/ca-bundle.pem", /* SUSE */ "/etc/ssl/cert.pem", /* macOS/Alpine */ NULL }; for (int i = 0; system_cert_files[i] != NULL; i++) { if (access(system_cert_files[i], R_OK) == 0) return system_cert_files[i]; } return X509_CERT_FILE; } ``` Same pattern for `X509_get_default_cert_dir()` with `/etc/ssl/certs` and `/etc/pki/tls/certs`. **jdx-ruby**: The `openssl.rb` bridge now only sets `SSL_CERT_FILE` to the bundled `cert.pem` when **no system certs exist** (checked against the same well-known paths). On normal systems, the C-level auto-detection runs unimpeded using the system's up-to-date certs. ## Benefits - `SSL_CERT_FILE` and `SSL_CERT_DIR` work as standard OpenSSL env vars (no rename) - Works regardless of whether the `openssl` gem replaces stdlib - C-level auto-detection covers Debian/Ubuntu, RHEL/CentOS, SUSE, macOS, and Alpine - Bundled `cert.pem` still available as last-resort fallback for minimal containers without system certs - System certs are preferred over bundled certs (fresher, org-customizable) - No env var leaking to child processes ## Tested Downloaded the `ubuntu-22.04, yjit: true` CI artifact and tested on a devcontainer (Ubuntu 22.04): | Test | Result | |---|---| | Basic SSL cert detection | PASS - `DEFAULT_CERT_FILE` auto-detects `/etc/ssl/certs/ca-certificates.crt` | | openssl gem 3.3.1 (root cause) | PASS - HTTPS works with gem replacing stdlib | | Custom `SSL_CERT_FILE` + `SSL_CERT_DIR` | PASS - env vars override auto-detection | | Valid custom `SSL_CERT_FILE` | PASS - custom cert path works | | Minimal Docker container (no `ca-certificates`) | PASS - bundled `cert.pem` fallback works | | Custom `SSL_CERT_FILE` in minimal container | PASS - bridge doesn't override explicit env var | ### Before (unpatched Ruby 3.4.7 with openssl gem): ``` DEFAULT_CERT_FILE: /home/linuxbrew/.linuxbrew/Cellar/portable-openssl@3.5.1/3.5.1/libexec/etc/openssl/cert.pem → SSL_connect returned=1 errno=0 state=error: certificate verify failed ``` ### After (patched Ruby 3.4.1 with openssl gem): ``` DEFAULT_CERT_FILE: /etc/ssl/certs/ca-certificates.crt → HTTPS 200 OK ``` ### Minimal container (no ca-certificates): ``` SSL_CERT_FILE env: "/ruby/libexec/cert.pem" (bundled fallback activated) → HTTPS 200 OK ``` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches TLS certificate resolution behavior in `portable-openssl` and all `jdx-ruby` formula variants, which can impact HTTPS connectivity across environments. Logic is straightforward but changes low-level defaults and should be validated on varied distros/containers. > > **Overview** > **Fixes SSL cert resolution for portable Ruby builds (incl. when the `openssl` gem replaces stdlib).** `portable-openssl@3.5.1` stops renaming `SSL_CERT_FILE`/`SSL_CERT_DIR` and instead patches `X509_get_default_cert_file()`/`X509_get_default_cert_dir()` to prefer readable system CA bundle paths/directories when the compiled-in defaults aren’t present. > > Across `Abstract/jdx-ruby.rb` and `jdx-ruby-32/33/34`, the `openssl.rb` patch is simplified to *only* set `SSL_CERT_FILE` to the bundled `libexec/cert.pem` when `SSL_CERT_FILE` is unset **and** no well-known system cert bundle exists, leaving normal system cert usage unchanged. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bc99d55. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
fix: use system SSL certificates when available (#12) ## Summary - Auto-detect system SSL cert file paths across distros before falling back to the bundled cert.pem - Auto-detect system SSL cert directory (`/etc/ssl/certs`, `/etc/pki/tls/certs`) when `SSL_CERT_DIR` is not explicitly set - Fix empty `SSL_CERT_DIR=""` bypassing system directory detection (empty string is truthy in Ruby) ## Problem The portable OpenSSL renames `SSL_CERT_FILE`/`SSL_CERT_DIR` to `PORTABLE_RUBY_SSL_CERT_*` to avoid interfering with other OpenSSL instances. Ruby's `openssl.rb` bridges these, but: 1. **`SSL_CERT_DIR`** was only forwarded when explicitly set by the user (rare). Without it, OpenSSL falls back to its compiled-in default — a nonexistent Homebrew prefix path. System certs at `/etc/ssl/certs` were never consulted. 2. **`SSL_CERT_FILE`** always fell back to the bundled `cert.pem` (Mozilla CA bundle frozen at build time), missing system cert updates and custom/corporate CAs. ## Verified Tested with the `jdx-ruby@3.4.1` artifact from this PR's CI build: ``` $ ruby -ropenssl -e 'puts "CERT_FILE: #{ENV["PORTABLE_RUBY_SSL_CERT_FILE"]}"; puts "CERT_DIR: #{ENV["PORTABLE_RUBY_SSL_CERT_DIR"]}"' CERT_FILE: /etc/ssl/certs/ca-certificates.crt CERT_DIR: /etc/ssl/certs $ ruby -ropen-uri -e 'URI.open("https://google.com") { |f| puts f.status.first }' 200 $ SSL_CERT_FILE=/custom/path ruby -ropenssl -e 'puts ENV["PORTABLE_RUBY_SSL_CERT_FILE"]' /custom/path $ SSL_CERT_DIR="" ruby -ropenssl -e 'puts ENV["PORTABLE_RUBY_SSL_CERT_DIR"]' /etc/ssl/certs ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
fix: auto-detect system SSL certs at C level, remove PORTABLE_RUBY_SS… …L_CERT_* rename (#14) ## Summary - Remove `SSL_CERT_FILE`/`SSL_CERT_DIR` → `PORTABLE_RUBY_SSL_CERT_*` rename from portable-openssl - Patch `X509_get_default_cert_file()` and `X509_get_default_cert_dir()` to auto-detect system certificate paths when the compiled-in default doesn't exist - Only fall back to bundled `cert.pem` when no system certs are found (not unconditionally) ## Problem The previous approach patched Ruby's stdlib `openssl.rb` to bridge `SSL_CERT_FILE` → `PORTABLE_RUBY_SSL_CERT_FILE`. This breaks when the `openssl` gem (v3.3.1+) is installed via Bundler, because the gem replaces stdlib's `openssl.rb` with its own version that doesn't have the bridge code. Without the bridge, `PORTABLE_RUBY_SSL_CERT_FILE` is never set, and the compiled-in default cert path (`/home/linuxbrew/.linuxbrew/Cellar/portable-openssl@.../cert.pem`) doesn't exist at runtime → SSL failures. This affects any Ruby app that uses Bundler with the `openssl` gem in its Gemfile.lock (which includes Rails, Sinatra, and most production Ruby apps). ## Fix **portable-openssl**: Instead of renaming env vars, patch OpenSSL's C code to auto-detect system cert paths at runtime: ```c const char *X509_get_default_cert_file(void) { if (access(X509_CERT_FILE, R_OK) == 0) return X509_CERT_FILE; static const char *system_cert_files[] = { "/etc/ssl/certs/ca-certificates.crt", /* Debian/Ubuntu */ "/etc/pki/tls/certs/ca-bundle.crt", /* RHEL/CentOS/Fedora */ "/etc/ssl/ca-bundle.pem", /* SUSE */ "/etc/ssl/cert.pem", /* macOS/Alpine */ NULL }; for (int i = 0; system_cert_files[i] != NULL; i++) { if (access(system_cert_files[i], R_OK) == 0) return system_cert_files[i]; } return X509_CERT_FILE; } ``` Same pattern for `X509_get_default_cert_dir()` with `/etc/ssl/certs` and `/etc/pki/tls/certs`. **jdx-ruby**: The `openssl.rb` bridge now only sets `SSL_CERT_FILE` to the bundled `cert.pem` when **no system certs exist** (checked against the same well-known paths). On normal systems, the C-level auto-detection runs unimpeded using the system's up-to-date certs. ## Benefits - `SSL_CERT_FILE` and `SSL_CERT_DIR` work as standard OpenSSL env vars (no rename) - Works regardless of whether the `openssl` gem replaces stdlib - C-level auto-detection covers Debian/Ubuntu, RHEL/CentOS, SUSE, macOS, and Alpine - Bundled `cert.pem` still available as last-resort fallback for minimal containers without system certs - System certs are preferred over bundled certs (fresher, org-customizable) - No env var leaking to child processes ## Tested Downloaded the `ubuntu-22.04, yjit: true` CI artifact and tested on a devcontainer (Ubuntu 22.04): | Test | Result | |---|---| | Basic SSL cert detection | PASS - `DEFAULT_CERT_FILE` auto-detects `/etc/ssl/certs/ca-certificates.crt` | | openssl gem 3.3.1 (root cause) | PASS - HTTPS works with gem replacing stdlib | | Custom `SSL_CERT_FILE` + `SSL_CERT_DIR` | PASS - env vars override auto-detection | | Valid custom `SSL_CERT_FILE` | PASS - custom cert path works | | Minimal Docker container (no `ca-certificates`) | PASS - bundled `cert.pem` fallback works | | Custom `SSL_CERT_FILE` in minimal container | PASS - bridge doesn't override explicit env var | ### Before (unpatched Ruby 3.4.7 with openssl gem): ``` DEFAULT_CERT_FILE: /home/linuxbrew/.linuxbrew/Cellar/portable-openssl@3.5.1/3.5.1/libexec/etc/openssl/cert.pem → SSL_connect returned=1 errno=0 state=error: certificate verify failed ``` ### After (patched Ruby 3.4.1 with openssl gem): ``` DEFAULT_CERT_FILE: /etc/ssl/certs/ca-certificates.crt → HTTPS 200 OK ``` ### Minimal container (no ca-certificates): ``` SSL_CERT_FILE env: "/ruby/libexec/cert.pem" (bundled fallback activated) → HTTPS 200 OK ``` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches TLS certificate resolution behavior in `portable-openssl` and all `jdx-ruby` formula variants, which can impact HTTPS connectivity across environments. Logic is straightforward but changes low-level defaults and should be validated on varied distros/containers. > > **Overview** > **Fixes SSL cert resolution for portable Ruby builds (incl. when the `openssl` gem replaces stdlib).** `portable-openssl@3.5.1` stops renaming `SSL_CERT_FILE`/`SSL_CERT_DIR` and instead patches `X509_get_default_cert_file()`/`X509_get_default_cert_dir()` to prefer readable system CA bundle paths/directories when the compiled-in defaults aren’t present. > > Across `Abstract/jdx-ruby.rb` and `jdx-ruby-32/33/34`, the `openssl.rb` patch is simplified to *only* set `SSL_CERT_FILE` to the bundled `libexec/cert.pem` when `SSL_CERT_FILE` is unset **and** no well-known system cert bundle exists, leaving normal system cert usage unchanged. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bc99d55. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
fix: auto-detect system SSL certs at C level, remove PORTABLE_RUBY_SS… …L_CERT_* rename (#14) ## Summary - Remove `SSL_CERT_FILE`/`SSL_CERT_DIR` → `PORTABLE_RUBY_SSL_CERT_*` rename from portable-openssl - Patch `X509_get_default_cert_file()` and `X509_get_default_cert_dir()` to auto-detect system certificate paths when the compiled-in default doesn't exist - Only fall back to bundled `cert.pem` when no system certs are found (not unconditionally) ## Problem The previous approach patched Ruby's stdlib `openssl.rb` to bridge `SSL_CERT_FILE` → `PORTABLE_RUBY_SSL_CERT_FILE`. This breaks when the `openssl` gem (v3.3.1+) is installed via Bundler, because the gem replaces stdlib's `openssl.rb` with its own version that doesn't have the bridge code. Without the bridge, `PORTABLE_RUBY_SSL_CERT_FILE` is never set, and the compiled-in default cert path (`/home/linuxbrew/.linuxbrew/Cellar/portable-openssl@.../cert.pem`) doesn't exist at runtime → SSL failures. This affects any Ruby app that uses Bundler with the `openssl` gem in its Gemfile.lock (which includes Rails, Sinatra, and most production Ruby apps). ## Fix **portable-openssl**: Instead of renaming env vars, patch OpenSSL's C code to auto-detect system cert paths at runtime: ```c const char *X509_get_default_cert_file(void) { if (access(X509_CERT_FILE, R_OK) == 0) return X509_CERT_FILE; static const char *system_cert_files[] = { "/etc/ssl/certs/ca-certificates.crt", /* Debian/Ubuntu */ "/etc/pki/tls/certs/ca-bundle.crt", /* RHEL/CentOS/Fedora */ "/etc/ssl/ca-bundle.pem", /* SUSE */ "/etc/ssl/cert.pem", /* macOS/Alpine */ NULL }; for (int i = 0; system_cert_files[i] != NULL; i++) { if (access(system_cert_files[i], R_OK) == 0) return system_cert_files[i]; } return X509_CERT_FILE; } ``` Same pattern for `X509_get_default_cert_dir()` with `/etc/ssl/certs` and `/etc/pki/tls/certs`. **jdx-ruby**: The `openssl.rb` bridge now only sets `SSL_CERT_FILE` to the bundled `cert.pem` when **no system certs exist** (checked against the same well-known paths). On normal systems, the C-level auto-detection runs unimpeded using the system's up-to-date certs. ## Benefits - `SSL_CERT_FILE` and `SSL_CERT_DIR` work as standard OpenSSL env vars (no rename) - Works regardless of whether the `openssl` gem replaces stdlib - C-level auto-detection covers Debian/Ubuntu, RHEL/CentOS, SUSE, macOS, and Alpine - Bundled `cert.pem` still available as last-resort fallback for minimal containers without system certs - System certs are preferred over bundled certs (fresher, org-customizable) - No env var leaking to child processes ## Tested Downloaded the `ubuntu-22.04, yjit: true` CI artifact and tested on a devcontainer (Ubuntu 22.04): | Test | Result | |---|---| | Basic SSL cert detection | PASS - `DEFAULT_CERT_FILE` auto-detects `/etc/ssl/certs/ca-certificates.crt` | | openssl gem 3.3.1 (root cause) | PASS - HTTPS works with gem replacing stdlib | | Custom `SSL_CERT_FILE` + `SSL_CERT_DIR` | PASS - env vars override auto-detection | | Valid custom `SSL_CERT_FILE` | PASS - custom cert path works | | Minimal Docker container (no `ca-certificates`) | PASS - bundled `cert.pem` fallback works | | Custom `SSL_CERT_FILE` in minimal container | PASS - bridge doesn't override explicit env var | ### Before (unpatched Ruby 3.4.7 with openssl gem): ``` DEFAULT_CERT_FILE: /home/linuxbrew/.linuxbrew/Cellar/portable-openssl@3.5.1/3.5.1/libexec/etc/openssl/cert.pem → SSL_connect returned=1 errno=0 state=error: certificate verify failed ``` ### After (patched Ruby 3.4.1 with openssl gem): ``` DEFAULT_CERT_FILE: /etc/ssl/certs/ca-certificates.crt → HTTPS 200 OK ``` ### Minimal container (no ca-certificates): ``` SSL_CERT_FILE env: "/ruby/libexec/cert.pem" (bundled fallback activated) → HTTPS 200 OK ``` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches TLS certificate resolution behavior in `portable-openssl` and all `jdx-ruby` formula variants, which can impact HTTPS connectivity across environments. Logic is straightforward but changes low-level defaults and should be validated on varied distros/containers. > > **Overview** > **Fixes SSL cert resolution for portable Ruby builds (incl. when the `openssl` gem replaces stdlib).** `portable-openssl@3.5.1` stops renaming `SSL_CERT_FILE`/`SSL_CERT_DIR` and instead patches `X509_get_default_cert_file()`/`X509_get_default_cert_dir()` to prefer readable system CA bundle paths/directories when the compiled-in defaults aren’t present. > > Across `Abstract/jdx-ruby.rb` and `jdx-ruby-32/33/34`, the `openssl.rb` patch is simplified to *only* set `SSL_CERT_FILE` to the bundled `libexec/cert.pem` when `SSL_CERT_FILE` is unset **and** no well-known system cert bundle exists, leaving normal system cert usage unchanged. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bc99d55. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
fix: auto-detect system SSL certs at C level, remove PORTABLE_RUBY_SS… …L_CERT_* rename (#14) ## Summary - Remove `SSL_CERT_FILE`/`SSL_CERT_DIR` → `PORTABLE_RUBY_SSL_CERT_*` rename from portable-openssl - Patch `X509_get_default_cert_file()` and `X509_get_default_cert_dir()` to auto-detect system certificate paths when the compiled-in default doesn't exist - Only fall back to bundled `cert.pem` when no system certs are found (not unconditionally) ## Problem The previous approach patched Ruby's stdlib `openssl.rb` to bridge `SSL_CERT_FILE` → `PORTABLE_RUBY_SSL_CERT_FILE`. This breaks when the `openssl` gem (v3.3.1+) is installed via Bundler, because the gem replaces stdlib's `openssl.rb` with its own version that doesn't have the bridge code. Without the bridge, `PORTABLE_RUBY_SSL_CERT_FILE` is never set, and the compiled-in default cert path (`/home/linuxbrew/.linuxbrew/Cellar/portable-openssl@.../cert.pem`) doesn't exist at runtime → SSL failures. This affects any Ruby app that uses Bundler with the `openssl` gem in its Gemfile.lock (which includes Rails, Sinatra, and most production Ruby apps). ## Fix **portable-openssl**: Instead of renaming env vars, patch OpenSSL's C code to auto-detect system cert paths at runtime: ```c const char *X509_get_default_cert_file(void) { if (access(X509_CERT_FILE, R_OK) == 0) return X509_CERT_FILE; static const char *system_cert_files[] = { "/etc/ssl/certs/ca-certificates.crt", /* Debian/Ubuntu */ "/etc/pki/tls/certs/ca-bundle.crt", /* RHEL/CentOS/Fedora */ "/etc/ssl/ca-bundle.pem", /* SUSE */ "/etc/ssl/cert.pem", /* macOS/Alpine */ NULL }; for (int i = 0; system_cert_files[i] != NULL; i++) { if (access(system_cert_files[i], R_OK) == 0) return system_cert_files[i]; } return X509_CERT_FILE; } ``` Same pattern for `X509_get_default_cert_dir()` with `/etc/ssl/certs` and `/etc/pki/tls/certs`. **jdx-ruby**: The `openssl.rb` bridge now only sets `SSL_CERT_FILE` to the bundled `cert.pem` when **no system certs exist** (checked against the same well-known paths). On normal systems, the C-level auto-detection runs unimpeded using the system's up-to-date certs. ## Benefits - `SSL_CERT_FILE` and `SSL_CERT_DIR` work as standard OpenSSL env vars (no rename) - Works regardless of whether the `openssl` gem replaces stdlib - C-level auto-detection covers Debian/Ubuntu, RHEL/CentOS, SUSE, macOS, and Alpine - Bundled `cert.pem` still available as last-resort fallback for minimal containers without system certs - System certs are preferred over bundled certs (fresher, org-customizable) - No env var leaking to child processes ## Tested Downloaded the `ubuntu-22.04, yjit: true` CI artifact and tested on a devcontainer (Ubuntu 22.04): | Test | Result | |---|---| | Basic SSL cert detection | PASS - `DEFAULT_CERT_FILE` auto-detects `/etc/ssl/certs/ca-certificates.crt` | | openssl gem 3.3.1 (root cause) | PASS - HTTPS works with gem replacing stdlib | | Custom `SSL_CERT_FILE` + `SSL_CERT_DIR` | PASS - env vars override auto-detection | | Valid custom `SSL_CERT_FILE` | PASS - custom cert path works | | Minimal Docker container (no `ca-certificates`) | PASS - bundled `cert.pem` fallback works | | Custom `SSL_CERT_FILE` in minimal container | PASS - bridge doesn't override explicit env var | ### Before (unpatched Ruby 3.4.7 with openssl gem): ``` DEFAULT_CERT_FILE: /home/linuxbrew/.linuxbrew/Cellar/portable-openssl@3.5.1/3.5.1/libexec/etc/openssl/cert.pem → SSL_connect returned=1 errno=0 state=error: certificate verify failed ``` ### After (patched Ruby 3.4.1 with openssl gem): ``` DEFAULT_CERT_FILE: /etc/ssl/certs/ca-certificates.crt → HTTPS 200 OK ``` ### Minimal container (no ca-certificates): ``` SSL_CERT_FILE env: "/ruby/libexec/cert.pem" (bundled fallback activated) → HTTPS 200 OK ``` <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Touches TLS certificate resolution behavior in `portable-openssl` and all `jdx-ruby` formula variants, which can impact HTTPS connectivity across environments. Logic is straightforward but changes low-level defaults and should be validated on varied distros/containers. > > **Overview** > **Fixes SSL cert resolution for portable Ruby builds (incl. when the `openssl` gem replaces stdlib).** `portable-openssl@3.5.1` stops renaming `SSL_CERT_FILE`/`SSL_CERT_DIR` and instead patches `X509_get_default_cert_file()`/`X509_get_default_cert_dir()` to prefer readable system CA bundle paths/directories when the compiled-in defaults aren’t present. > > Across `Abstract/jdx-ruby.rb` and `jdx-ruby-32/33/34`, the `openssl.rb` patch is simplified to *only* set `SSL_CERT_FILE` to the bundled `libexec/cert.pem` when `SSL_CERT_FILE` is unset **and** no well-known system cert bundle exists, leaving normal system cert usage unchanged. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit bc99d55. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
PreviousNext