Skip to content

Do not call openssl_probe::init_ssl_cert_env_vars() on FreeBSD (#1129) #1130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

michael-o
Copy link

The heuristics in openssl-probe leave the process environment with an invalid value breaking the certificate validation on FreeBSD. FreeBSD has a system truststore managed by certctl(8). Leave it to OpenSSL to do the right thing.

Upstream issue: alexcrichton/openssl-probe#37

This fixes #1129

…lang#1129)

The heuristics in openssl-probe leave the process environment with an invalid
value breaking the certificate validation on FreeBSD. FreeBSD has a system
truststore managed by certctl(8). Leave it to OpenSSL to do the right thing.

Upstream issue: alexcrichton/openssl-probe#37

This fixes rust-lang#1129
@rustbot rustbot added the S-waiting-on-review Status: Waiting on review label Feb 24, 2025
michael-o added a commit to michael-o/freebsd-ports that referenced this pull request Feb 24, 2025
Cargo uses curl-rust and git2-rs (which uses curl-rest as well).
Unfortunately, git2-rs calls openssl_probe::init_ssl_cert_env_vars()
unconditionally which breaks the process environment by setting an invalid
value for SSL_CERT_DIR and then the system default truststore is circumvented,
resulting in certificate validation errors even if certlctl(8) manages
everything nicely.

Upstream issues:
* alexcrichton/openssl-probe#37
* rust-lang/git2-rs#1130

Reviewed by:	jrm (mentor), otis (mentor), ...
MFH:		2025Q1
@michael-o
Copy link
Author

@emaste FYI

freebsd-git pushed a commit to freebsd/freebsd-ports that referenced this pull request Mar 7, 2025
Cargo uses curl-rust and git2-rs (which uses curl-rest as well).
Unfortunately, git2-rs calls openssl_probe::init_ssl_cert_env_vars()
unconditionally which breaks the process environment by setting an invalid
value for SSL_CERT_DIR and then the system default truststore is circumvented,
resulting in certificate validation errors even if certctl(8) manages
everything nicely.

Upstream issues:
* alexcrichton/openssl-probe#37
* rust-lang/git2-rs#1130

Reviewed by:	jrm (mentor), mikael (rust)
MFH:		2025Q1
Differential Revision:	https://reviews.freebsd.org/D49120
freebsd-git pushed a commit to freebsd/freebsd-ports that referenced this pull request Mar 7, 2025
Cargo uses curl-rust and git2-rs (which uses curl-rest as well).
Unfortunately, git2-rs calls openssl_probe::init_ssl_cert_env_vars()
unconditionally which breaks the process environment by setting an invalid
value for SSL_CERT_DIR and then the system default truststore is circumvented,
resulting in certificate validation errors even if certctl(8) manages
everything nicely.

Upstream issues:
* alexcrichton/openssl-probe#37
* rust-lang/git2-rs#1130

Reviewed by:	jrm (mentor), mikael (rust)
MFH:		2025Q1
Differential Revision:	https://reviews.freebsd.org/D49120

(cherry picked from commit 0780826)
@ehuss
Copy link
Contributor

ehuss commented Mar 17, 2025

Sorry, I don't know much about FreeBSD in this regard. @asomers do you perhaps have any knowledge here?

Can you say why this wouldn't be a fix in openssl-probe instead?

@michael-o
Copy link
Author

michael-o commented Mar 17, 2025

Sorry, I don't know much about FreeBSD in this regard. @asomers do you perhaps have any knowledge here?

Can you say why this wouldn't be a fix in openssl-probe instead?

Fro two reasons:

  • OpenSSL knows best which store to use by its default verify paths
  • You will never be able to have a complete list of possible locations of truststores without any false positives across 10+ OSes.

Don't set anything explicit if it works works flawless implicit: SSL_CTX_set_default_verify_paths

I have already committed the patch downstream in FreeBSD's Rust port to fix Cargo, but this doesn't fix standalone use of this library: freebsd/freebsd-ports@0780826

@kevans

@asomers
Copy link

asomers commented Mar 18, 2025

Sorry @ehuss ; I'm not knowledgeable about this issue.

@michael-o
Copy link
Author

@ehuss Do you have any objections/pain to merge this?

@michael-o
Copy link
Author

Folks, is there anything I can do to get this upstream or provide your further information how truststore works on FreeBSD?

@ehuss
Copy link
Contributor

ehuss commented Apr 28, 2025

OpenSSL knows best which store to use by its default verify paths

Is this true with OpenSSL is built from source (like when vendored-openssl is set)?

@michael-o
Copy link
Author

OpenSSL knows best which store to use by its default verify paths

Is this true with OpenSSL is built from source (like when vendored-openssl is set)?

Yes, I am building OpenSSL on HP-UX for quite some time and this is how it looks like:

osipovmi@deblndw024v:~
$ openssl version -a
OpenSSL 3.0.15 3 Sep 2024 (Library: OpenSSL 3.0.15 3 Sep 2024)
built on: Thu Sep 12 10:16:00 2024 UTC
platform: hpux-ia64-cc
options:  bn(64,64)
compiler: /opt/aCC/bin/aCC +Z -Ae +DD32 +Olit=all -z +We901 -DB_ENDIAN -DOPENSSL_PIC -D_REENTRANT -DOPENSSL_BUILDING_OPENSSL -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED -D_HPUX_ALT_XOPEN_SOCKET_API -DNDEBUG -I/opt/ports/include
OPENSSLDIR: "/etc/opt/ports/ssl"
ENGINESDIR: "/opt/ports/lib/hpux32/engines-3"
MODULESDIR: "/opt/ports/lib/hpux32/ossl-modules"
Seeding source: os-specific
CPUINFO: N/A
osipovmi@deblndw024v:~
$ ls -1 "/etc/opt/ports/ssl/certs"
002c0b4f.0@
0179095f.0@
02265526.0@
062cdee6.0@
064e0aa9.0@
06dc52d5.0@
09789157.0@
0a775a30.0@
0b1b94ef.0@
0b9bc432.0@
0bf05006.0@
0c6840e5.0@
0e436b80.0@
0e91b229.0@
0f5dc4f3.0@
0f6fa695.0@
1001acf7.0@
106f3e4d.0@
14bc7599.0@
17c10339.0@
18bd5750.0@
1a6b61c8.0@
1c683ff3.0@
1cef98f5.0@
1d3472b9.0@
1e08bfd1.0@
1e09d511.0@
228f89db.0@
244b5494.0@
2923b3f9.0@
2ae6433e.0@
2b349938.0@
2c3a2e0f.0@
31e09dd6.0@
3210d285.0@
32888f65.0@
3513523f.0@
36971e57.0@
3afae52b.0@
3bde41ac.0@
3e1ec334.0@
3e359ba6.0@
3fb36b73.0@
40193066.0@
4042bcee.0@
40547a79.0@
406c9bb1.0@
4158715d.0@
48bec511.0@
4b718d9b.0@
4bfab552.0@
4ca5f54b.0@
4f316efb.0@
4fd49c6c.0@
5443e9e3.0@
54657681.0@
55683be0.0@
580d22f3.0@
5860aaa6.0@
5931b5bc.0@
5ad8a5d6.0@
5cd81ad7.0@
5eeeed34.0@
5f15c80c.0@
5f618aec.0@
607986c7.0@
616816f6.0@
626dceaf.0@
653b494a.0@
67c4d95c.0@
68dd7389.0@
6a9bdba3.0@
6b99d060.0@
6b9a4307.0@
6d41d539.0@
6fa5da56.0@
706f604c.0@
749e9e03.0@
75d1b2ed.0@
76faf6c0.0@
7719f463.0@
773e07ad.0@
7a3adc42.0@
7a780d93.0@
7b1c186e.0@
7f3d5d1d.0@
7fa05551.0@
8160b96c.0@
81841955.0@
81f2d2b1.0@
8312c4c1.0@
8508e720.0@
865fbdf9.0@
878d9bca.0@
8aac0ad6.0@
8af2d467.0@
8af2d467.1@
8cb5ee0f.0@
8d86cdd1.0@
8d89cda1.0@
8f103249.0@
9046744a.0@
90c5a3c8.0@
9245e478.0@
930ac5d2.0@
93bc0acc.0@
940ae196.0@
9482e63a.0@
96f028d4.0@
9846683b.0@
988a38cb.0@
9b46e03d.0@
9b5697b0.0@
9bf03295.0@
9c8dfbd4.0@
9d04f354.0@
9ef4a08a.0@
9f4c149e.0@
9f727ac7.0@
a09a51ae.0@
a3418fda.0@
a89d74c2.0@
a94d09e5.0@
aee5f10d.0@
b0e59380.0@
b1159c4c.0@
b433981b.0@
b5d79467.0@
b66938e9.0@
b727005e.0@
b7a5b843.0@
b81b93f0.0@
b8d25de6.0@
ba8887ce.0@
bc2924b7.0@
bd411d1f.0@
be133774.0@
bf53fb88.0@
c01eb047.0@
c28a8a30.0@
c2cf79c6.0@
ca6e4ad9.0@
cbf06781.0@
cc450945.0@
cd58d51e.0@
cd8c0d63.0@
ce5e74ef.0@
d4dae3dd.0@
d52c538d.0@
d6325660.0@
d7e8dc79.0@
d887a5bb.0@
d9d79a66.0@
da0cfd1d.0@
dc4d6a89.0@
dd8e9d41.0@
ddcda989.0@
de6d66f3.0@
e113c810.0@
e18bfb83.0@
e35234b1.0@
e36a6752.0@
e4f4967e.0@
e73d606e.0@
e8599211.0@
e868b802.0@
e8de2f56.0@
ecccd8db.0@
ed858448.0@
ee64a828.0@
eed8c118.0@
ef954a4e.0@
f081611a.0@
f0c70a8d.0@
f103366b.0@
f249de83.0@
f30dd6ad.0@
f387163d.0@
f39fc864.0@
f51bb24c.0@
fa5da96b.0@
fb717492.0@
fc5a8f99.0@
fd64f3fc.0@
fe8a2cd8.0@
feffd413.0@
ff34af3f.0@
ffdd40f9.0@

Works as designed.

@ehuss
Copy link
Contributor

ehuss commented Apr 29, 2025

Sorry, I don't quite understand the output that you are showing (or how HP-UX is related to FreeBSD). Vendored-openssl wouldn't provide a CLI openssl command, so what gets compiled by that option wouldn't have a direct way to expose how that openssl resolves certificates.

I suppose what I'm asking is, does the openssl built by openssl-src, which is pretty much just building the unmodified OpenSSL from https://github.com/openssl/openssl have special support for FreeBSD to support certctl, or otherwise know the default certificate directories for FreeBSD? Or does that require patches? Or is that fetched through some configuration somewhere?

@michael-o
Copy link
Author

Sorry, I don't quite understand the output that you are showing (or how HP-UX is related to FreeBSD). Vendored-openssl wouldn't provide a CLI openssl command, so what gets compiled by that option wouldn't have a direct way to expose how that openssl resolves certificates.

I suppose what I'm asking is, does the openssl built by openssl-src, which is pretty much just building the unmodified OpenSSL from https://github.com/openssl/openssl have special support for FreeBSD to support certctl, or otherwise know the default certificate directories for FreeBSD? Or does that require patches? Or is that fetched through some configuration somewhere?

I totally misunderstood your question since I know very little about Rust and its ecosytem around Cargo. I will re-evaluate your question and get back to you. The HP-UX was simply to show you that a trust store can be made available at any place and OpenSSL will always pick it if you have configured it properly at compile time and call the right C functions.

@michael-o
Copy link
Author

I suppose what I'm asking is, does the openssl built by openssl-src, which is pretty much just building the unmodified OpenSSL from https://github.com/openssl/openssl have special support for FreeBSD to support certctl, or otherwise know the default certificate directories for FreeBSD? Or does that require patches? Or is that fetched through some configuration somewhere?

I understand your question now. Processing, please hold on.

@michael-o
Copy link
Author

Sorry, I don't quite understand the output that you are showing (or how HP-UX is related to FreeBSD). Vendored-openssl wouldn't provide a CLI openssl command, so what gets compiled by that option wouldn't have a direct way to expose how that openssl resolves certificates.

I suppose what I'm asking is, does the openssl built by openssl-src, which is pretty much just building the unmodified OpenSSL from https://github.com/openssl/openssl have special support for FreeBSD to support certctl, or otherwise know the default certificate directories for FreeBSD? Or does that require patches? Or is that fetched through some configuration somewhere?

OK, this is how it works with the vendored (integrated) version OpenSSL on any platform Rust supports, not just FreeBSD:
I have cloned and ran:

cafe-custom-uis@deblndw013x3j:/usr/home/cafe-custom-uis/rust-openssl (master =)
$ cargo b --features vendored,openssl-src  -v
cafe-custom-uis@deblndw013x3j:/usr/home/cafe-custom-uis/rust-openssl (master =)
$ find . -name \*.a
./target/debug/build/openssl-sys-e607942730c0551f/out/openssl-build/install/lib/libcrypto.a
./target/debug/build/openssl-sys-e607942730c0551f/out/openssl-build/install/lib/libssl.a
./target/debug/build/systest-b6cd7ca4b5241362/out/liball.a

The vendored build is configured here: https://github.com/alexcrichton/openssl-src-rs/blob/7d112379fbbc6a4c343cd2d746b8e257bc75eff5/src/lib.rs#L39. AS you can see OPENSSLDIR is statically set to /usr/local/ssl. I can see this also when you peek with htop:

 0.0  0.0  0:00.98 │        └─ bash
 0.7  0.1  0:00.28 │           └─ cargo b --features vendored,openssl-src -v
32.3  1.0  0:03.92 │              ├─ rustc --crate-name syn --edition=2021 /home/cafe-custom-uis/.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.101/src/lib.rs --error-format=json ...
 2.8  0.0  0:00.36 │              └─ /usr/home/cafe-custom-uis/rust-openssl/target/debug/build/openssl-sys-91f6adc8a7faa160/build-script-main
24.5  0.1  0:02.26 │                 └─ perl ./Configure --prefix=/usr/home/cafe-custom-uis/rust-openssl/target/debug/build/openssl-sys-e607942730c0551f/out/openssl-build/install --openssldir=/usr/local/ssl ...

So this is embedded in the archive:

cafe-custom-uis@deblndw013x3j:/usr/home/cafe-custom-uis/rust-openssl (master =)
$ strings ./target/debug/build/openssl-sys-e607942730c0551f/out/openssl-build/install/lib/libcrypto.a | grep -e OPENSSLDIR -e /usr/local/ssl
/usr/local/ssl/ct_log_list.cnf
OPENSSLDIR: "/usr/local/ssl"
/usr/local/ssl
/usr/local/ssl/private
/usr/local/ssl
/usr/local/ssl/certs
/usr/local/ssl/cert.pem

which come from https://github.com/openssl/openssl/blob/29464b4c15db4c4063633743254986a91b91dd33/include/internal/common.h#L84-L86.
FTR:

cafe-custom-uis@deblndw013x3j:/usr/home/cafe-custom-uis/.cargo
$ ll /usr/local/ssl
ls: /usr/local/ssl: No such file or directory

This compilation unit of OpenSSL will query /usr/local/ssl (more specifically /usr/local/ssl/certs and /usr/local/ssl/cert.pem) for certificates and nothing else unless you tell to. OpenSSL does not require any special treatment for FreeBSD in this regard because the version compiled on FreeBSD in the base system sets OPENSSLDIR to etc/ssl AND OpenSSL does not require to know anything about certlctl because it is a convenience implementation of the original openssl-rehash command which does the cert subject hashing to create a CApath. The link between those two is that certctl knows the target CApath to be /etc/ssl/certs and the base version of OpenSSL has /etc/ssl/certs set as CApath So the vendored OpenSSL compile unit will never see /etc/ssl/certs because it has another OPENSSLDIR. If we get back to the initial problem is that the default approach taken by Cargo and uv is that the system OpenSSL is used which uses a well-known and populated trust store and by explicitly setting the env var SSL_CERT_DIR you are completely defeating this default logic. In other words, as soon as you use an OpenSSL version outside of your system it is your obligation to tell it where to find a truststore, but git2-rs does not know what type of OpenSSL is used.

I hope this helps to understand the complexity of the issue.

FWIW, I have fixed the same issue in PHP composer some time ago: composer/ca-bundle#98

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Waiting on review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Calling openssl_env_init() on FreeBSD breaks certificate validation with the system default trutstore
4 participants