Skip to content

Tags: jdx/ruby

Tags

4.0.1

Toggle 4.0.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
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>

4.0.0

Toggle 4.0.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
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>

4.0.0-preview3

Toggle 4.0.0-preview3's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
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>

4.0.0-preview2

Toggle 4.0.0-preview2's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
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>

3.5.0-preview1

Toggle 3.5.0-preview1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
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>

3.4.8

Toggle 3.4.8's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
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>

3.4.7

Toggle 3.4.7's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
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>

3.4.6

Toggle 3.4.6's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
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>

3.4.5

Toggle 3.4.5's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
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>

3.4.4

Toggle 3.4.4's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
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>