How does wget on macOS handle certificates? - macos

OS: macOS Big Sur
Applications: wget/openssl1.1 both via brew
I want to download some files from a webserver with wget via https, but I get the error message: Unable to locally verify the issuer's authority. However, I can connect to this server with curl which comes with macOS. Of course I could use --no-check-certificate, but I'd like to understand the background and do it the proper way.
As I understand it curl uses macOS' libressl and wget uses openssl as backend. For wget I've tried to export all system root certificates as a pem file from keychain and passed this pem file via --ca-certificate to wget. Still the same error.
Why can curl verify the certificate without doing anything while wget can not?
╰─$ brew info openssl
openssl#1.1: stable 1.1.1i (bottled) [keg-only]
Cryptography and SSL/TLS Toolkit
https://openssl.org/
/usr/local/Cellar/openssl#1.1/1.1.1i (8,067 files, 18.5MB)
Poured from bottle on 2021-01-28 at 07:11:37
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/openssl#1.1.rb
License: OpenSSL
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
/usr/local/etc/openssl#1.1/certs
and run
/usr/local/opt/openssl#1.1/bin/c_rehash
openssl#1.1 is keg-only, which means it was not symlinked into /usr/local,
because macOS provides LibreSSL.
Edit: This is what I've tried so far:
download via system curl -> no problem
installed (and reinstalled) curl and wget via brew (openssl as dependency) -> both can not verify the certificate, although it is a normal root CA certificate and OpenSSL via brew claims to export all these certificates to its own storage.
system curl with verbose option says it uses /etc/ssl/cert.pem for lookup, so I've tried to pass this file via --cacert resp. --ca-certificate to curl/wget -> same error.
I also tried to export the root CA explicitly in pem format and pass it on, still not working
Download the site's certificate manually via openssl: openssl s_client -showcerts -servername domain -connect domain, save the certificate as .pem and use it with wget -> works
I also checked that the certificate key for the root ca 'Digicert Global Root CA' is present in both /etc/ssl/cert.pem as well as in openssl's /usr/local/etc/openssl#1.1/cert.pem
I still don't understand why it won't work when OpenSSL via brew is supposed to export all the Root CAs to its own storage during install.

There is not enough information in your post to nail down the exact issue, but here are some suggestions that may help you forward:
Download the server's certificate bundle and locally analyse its verification using the openssl verify command.
Leverage the openssl s_client command to set up a TLS connection to the server directly and inspect the logged information, or dig deeper using its debug option(s). It has an undocumented debug option -security_debug_verbose that may help. If your OpenSSL is built with the the enable-ssl-trace option (which is not the case for the brew formula), you could use the -trace option for more output.
Run curl with -v or some --trace flags to get more insight in its verification behavior.
You could do all of this with both the OpenSSL and LibreSSL versions of openssl and curl and observe the differences. The openssl version of curl can be installed with brew.
You could also use another (non-OpenSSL) client to set up a connection and see if it fails with more information. For example gnutls-cli, which you can install via brew install gnutls, provides quite a bit of debug information.

Related

Homebrew package installation with homebrew installed keg-only libraries? How to do it?

I'd like to install curl with openssl via homebrew. I did it like this brew install curl --with-openssl Before that I installed the homebrew openssl, which is version 1.0.2 at the moment. Since this openssl is keg-only and Apple provides also an outdated system version of openssl, Homebrew suggests to set the PKG_CONFIG_PATH environment variable like export PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig", which I did. Then if I run pkg-config --list-all |## Heading ##grep openssl it finds openssl. My problem is that when I then run brew install curl --with-openssl and curl -V it still installs without openssl but uses the secure transport instead. What could be the reason?
curl 7.61.0 (x86_64-apple-darwin15.6.0) libcurl/7.61.0 SecureTransport zlib/1.2.5
Release-Date: 2018-07-11
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IPv6 Largefile NTLM NTLM_WB SSL libz UnixSockets
Thanks!
Although you already resolved the issue, I am adding some information here that might have been useful for you to know.
The brew formula for curl is fairly easy to read. You can also find it locally via brew formula curl. With regard to openssl, it shows you the following:
# cURL has a new firm desire to find ssl with PKG_CONFIG_PATH instead of using
# "--with-ssl" any more. "when possible, set the PKG_CONFIG_PATH environment
# variable instead of using this option". Multi-SSL choice breaks w/o using it.
if MacOS.version < :mountain_lion || build.with?("openssl") || build.with?("nghttp2")
ENV.prepend_path "PKG_CONFIG_PATH", "#{Formula["openssl"].opt_lib}/pkgconfig"
args << "--with-ssl=#{Formula["openssl"].opt_prefix}"
args << "--with-ca-bundle=#{etc}/openssl/cert.pem"
args << "--with-ca-path=#{etc}/openssl/certs"
else
args << "--with-darwinssl"
args << "--without-ca-bundle"
args << "--without-ca-path"
end
So no need to adjust PKG_CONFIG_PATH manually yourself, the formula will do it for you by pointing to the brew-installed version of openssl. (It is unclear to me though why both PKG_CONFIG_PATH and --with-ssl are set, since curl seems to prefer the former, as quoted in the comment lines.)
The args mentioned here should show up when you run brew install as follows (removing some uninteresting output and reformatted somewhat for clarity to make the relevant args start on a new line):
$ brew install curl --with-openssl
==> Downloading https://curl.haxx.se/download/curl-7.61.0.tar.bz2
######################################################################## 100.0%
==> ./configure --disable-silent-rules --prefix=/usr/local/Cellar/curl/7.61.0
--with-ssl=/usr/local/opt/openssl --with-ca-bundle=/usr/local/etc/openssl/cert.pem --with-ca-path=/usr/local/etc/open
==> make install
The --with-ssl argument should point to your brew installation of openssl. If this is not what it looks like for you, you can start debugging the formula...
Apparently using brew reinstall did the trick for you.

Revoke certificates by API

I need to revoke x509 client certificates in Ruby. I can do so via the openssl command:
openssl ca -revoke certificate.pem
but there does not appear to be an API to do this, at least not in Ruby's OpenSSL module.
Is there an API in OpenSSL or another tool (that runs on Linux) that can do this?
See this question.
%x( openssl ca -revoke certificate.pem )

How to validate s/mime signature using openssl

How to validate s/mime signature using OpenSSL. Through command line we can verify with:
openssl smime -verify -in detachedsign.pem -content content.txt
What is the equivalent method for openssl smime -verify command on Mac OSX?
what is the equalant method for openssl smime -verify command in mac osx apps
There is none out of the box. Mac OS X provides OpenSSL 0.9.8y. openssl smime was added at OpenSSL 1.0.0. See smime(1) for details.
0.9.8 is also missing cms. And I don't believe you can use pkcs7 - the sub commands look anemic.
You can use OpenSSL if you build and install OpenSSL on OS X. If you build it, configure with Configure darwin64-x86_64-cc. Once installed, the newer OpenSSL will be located at /usr/local/ssl/bin by default.
Out of the box, for verifiying s/mime signatures on OSX, you have
security cms -D -i smime-message-in-der-format.der
I think you need the message to be in DER instead of PEM format. I don't know about -content, could that be the equivalent of -envelope?

SSL certificate error when installing rvm

Hi I'm trying to install RVM onto a Mac OsX v 10.4.11.
Into the terminal I type:
curl -L get.rvm.io | bash -s stable
I receive this message:
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 185 100 185 0 0 387 0 --:--:-- --:--:-- --:--:-- 0
curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). The default
bundle is named curl-ca-bundle.crt; you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
I found similar questions on StackOverflow eg Curl Certificate Error when Using RVM to install Ruby 1.9.2, but a) this is a problem with installing RVM in the first place, not using RVM to install a new version of Ruby and more importantly b)the best answers to similar questions have suggested this is an error generated when referring to RVM's old site ie. rvm.beginrescueend.com. The solution given is to use
curl -L get.rvm.io | bash -s stable
which is what I am using but which is generating, for me, this error message, and hence why I am stuck. Any help would be greatly appreciated, thanks
Phillip
I installed RVM successfully on Mac OS X Server 10.4.11.
You need:
Xcode 2.5, the latest Xcode for Tiger
MacPorts installed, configured, and up-to-date
gcc-4.2 Apple build 5566, instructions later...
curl
We need curl to use newer certs. Download an up-to-date certificate bundle, and configure curl to use it. Note the cacert.pem path must be absolute.
mkdir ~/.certs
curl -o ~/.certs/cacert.pem http://curl.haxx.se/ca/cacert.pem
echo cacert = \"/Users/your-username/.certs/cacert.pem\" >> ~/.curlrc
Upgrade bash
Next, to properly execute RVM's install script, we must upgrade bash. I used the latest release, version 4.2.
mkdir ~/tmp
cd ~/tmp
curl -C - -O ftp://ftp.cwru.edu/pub/bash/bash-4.2.tar.gz # letter O, not a zero
tar zxf bash-4.2.tar.gz
cd bash-4.2
./configure && make && sudo make install
sudo bash -c "echo /usr/local/bin/bash >> /private/etc/shells"
chsh -s /usr/local/bin/bash
cd /bin
sudo mv bash bash-old
sudo ln -s /usr/local/bin/bash bash
Log into a new shell, and you should be running bash 4.2.
bash --version
#=> GNU bash, version 4.2.0(1)-release (powerpc-apple-darwin8.11.1)
#=> ...
Upgrade libtool
Use macports to upgrade the libtool package. This step is necessary to properly configure yaml.
Make sure macports is up-to-date and ready to go.
sudo port install libtool
This will take bloody ages, for there are many dependencies to compile. Grab a sandwich.
Install gcc-4.2
Your rubies will not compile yet because it tries to use gcc-4.2, which Xcode 2.5 doesn't provide. We must install it ourselves. Download it from AT&T Research:
curl -C - -O http://r.research.att.com/tools/gcc-4.2-5566-darwin8-all.tar.gz
Apple packed this tarball relative to the root directory (/), so this one-liner will extract everything into place.
sudo tar fvxz gcc-4.2-5566-darwin8-all.tar.gz -C /
Done.
Install RVM.
curl -L get.rvm.io | bash -s stable --ruby
RVM should install, yaml and ruby should compile, and you should be good to go.
While installing rails and friends, documentation conversion to UTF-8 gave me warnings, which I'm not too concerned about. The important parts installed without a hiccup.
I am running Mac OS X Server 10.4.11 Build 8S2169 on a Mac Server G4 (QS2002) DP 1.0.
Does echo insecure >> ~/.curlrc work for you? I don't actually use a Mac.
Just read the message, it tells you what to do.
David suggestion will work, but remember it brings all your downloads via curl or git into insecure mode - not validating if the certificate is trusted.
As a hint you might get this answers also helpful (more then the error you got):
https://stackoverflow.com/a/7599151/497756
https://stackoverflow.com/a/7901540/497756
https://stackoverflow.com/a/6817139/497756

curl "no start line" LibreSSL errors after update to OSX High Sierra

I am trying to connect to a server using curl; this server requires a .p12 certificate file and a passphrase. This has not been a problem in the few weeks I have been running my program. However, after my update to High Sierra, I now get LibreSSL errors. My colleagues running Windows 7 and 10 don't have this issue, either:
In Terminal:
$ curl -k https://server_metadata_link --cert certificate.p12 --pass “password”
curl: (58) could not load PEM client certificate, LibreSSL error error:0906D06C:PEM routines:PEM_read_bio:no start line, (no key found, wrong pass phrase, or wrong file format?)
In R:
> set_config(config(ssl_verifyhost = 0L, ssl_verifypeer = 0L))
> set_config(config(sslcert = certificate.p12, keypasswd = password))
> GET("https://server_metadata_link")
Error in curl::curl_fetch_memory(url, handle = handle) : could not load PEM client certificate, LibreSSL error error:0906D06C:PEM routines:PEM_read_bio:no start line, (no key found, wrong pass phrase, or wrong file format?)
I would prefer not to backtrack to Sierra, as I have a colleague with a new Mac who is stuck in High Sierra. I don't think there is an error with the certificates, as like I said, this worked fine before the upgrade to High Sierra. After researching this issue, I think it may have something to do with Mac's move from OpenSSL to LibreSSL in High Sierra. I don't know what effect that might have on the back end, but it could explain why only my colleague and I have the error, while another colleague with Sierra does not.
Another issue may be that my version of curl is 7.54.0 (as is my colleague's with High Sierra), while the latest is 7.58.0. I don't know if this could also be causing a problem, but as a separate issue I'm not sure how to force my Mac to use the most recent version of curl; since it's included in the Mac, Homebrew won't let me install the latest version.
The only other note I have is that if I change the R config from "sslcert = certificate.p12" to "sslkey = certificate.p12" or the Terminal command from "--cert certificate.p12" to "--key certificate.p12" I get a normal 403 error saying I couldn't connect to the server.
Any help would be appreciated, and please let me know if there is any other information I should provide. Thanks in advance.
Homebrew will let you install the latest version of homebrew, but it is keg-only since OSX provides an older version of curl:
$ brew install curl
==> Downloading https://homebrew.bintray.com/bottles/curl-7.58.0.high_sierra.bottle.tar.gz
Already downloaded: /Users/kyle.varga/Library/Caches/Homebrew/curl-7.58.0.high_sierra.bottle.tar.gz
==> Pouring curl-7.58.0.high_sierra.bottle.tar.gz
==> Caveats
This formula is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.
If you need to have this software first in your PATH run:
echo 'export PATH="/usr/local/opt/curl/bin:$PATH"' >> ~/.zshrc
You need to run the export command for it to run. After updating $PATH, you should get
$ which -a curl
/usr/local/opt/curl/bin/curl
/usr/bin/curl
After doing this, when running curl with a p12 file, it asks for me to unlock OSX keychain and resolves the could not load PEM client certificate error.

Resources