Skip to content

Curl CLI should handle both SSL_CERT_FILE and SSL_CERT_DIR (at the same time) #11325

Description

@randomstuff

I did this

When using both SSL_CERT_FILE and SSL_CERT_DIR environment variable, curl honors only the former:

$ strace curl https://www.example.com < /dev/null 2>&1 | grep /ssl/
openat(AT_FDCWD, "/usr/lib/ssl/openssl.cnf", O_RDONLY) = 3
openat(AT_FDCWD, "/etc/ssl/certs/ca-certificates.crt", O_RDONLY) = 6
stat("/etc/ssl/certs/e83d98dd.0", 0x7ffcf70f8310) = -1 ENOENT (No such file or directory)

$ SSL_CERT_FILE=./ssl/empty strace curl https://www.example.com < /dev/null 2>&1 | grep /ssl/
openat(AT_FDCWD, "/usr/lib/ssl/openssl.cnf", O_RDONLY) = 3
openat(AT_FDCWD, "./ssl/empty", O_RDONLY) = -1 ENOENT (No such file or directory)

$ SSL_CERT_DIR=./ssl/certs strace curl https://www.example.com < /dev/null 2>&1 | grep /ssl/
openat(AT_FDCWD, "/usr/lib/ssl/openssl.cnf", O_RDONLY) = 3
openat(AT_FDCWD, "/etc/ssl/certs/ca-certificates.crt", O_RDONLY) = 6
stat("./ssl/certs/e83d98dd.0", 0x7fff4d848d60) = -1 ENOENT (No such file or directory)

$ SSL_CERT_FILE=./ssl/empty SSL_CERT_DIR=./ssl/certs strace curl https://www.example.com < /dev/null 2>&1 | grep /ssl/
openat(AT_FDCWD, "/usr/lib/ssl/openssl.cnf", O_RDONLY) = 3
openat(AT_FDCWD, "/etc/ssl/certs/ca-certificates.crt", O_RDONLY) = 6
stat("./ssl/certs/e83d98dd.0", 0x7fffa9e072f0) = -1 ENOENT (No such file or directory)

I expected the following

I would expect the behavior to be consistent with OpenSSL which handles both at the same time:

$ strace openssl s_client -connect www.example.com:443 < /dev/null 2>&1 | grep /ssl/
openat(AT_FDCWD, "/usr/lib/ssl/openssl.cnf", O_RDONLY) = 3
openat(AT_FDCWD, "/usr/lib/ssl/ct_log_list.cnf", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/ssl/cert.pem", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/ssl/certs/e83d98dd.0", 0x7fff93ef8fb0) = -1 ENOENT (No such file or directory)
stat("/usr/lib/ssl/certs/3513523f.0", {st_mode=S_IFREG|0644, st_size=1338, ...}) = 0
openat(AT_FDCWD, "/usr/lib/ssl/certs/3513523f.0", O_RDONLY) = 4
stat("/usr/lib/ssl/certs/3513523f.1", 0x7fff93ef8fb0) = -1 ENOENT (No such file or directory)

$ SSL_CERT_FILE=./ssl/empty strace openssl s_client -connect www.example.com:443 < /dev/null 2>&1 | grep /ssl/
openat(AT_FDCWD, "/usr/lib/ssl/openssl.cnf", O_RDONLY) = 3
openat(AT_FDCWD, "/usr/lib/ssl/ct_log_list.cnf", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "./ssl/empty", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/ssl/certs/e83d98dd.0", 0x7ffdfa475c70) = -1 ENOENT (No such file or directory)
stat("/usr/lib/ssl/certs/3513523f.0", {st_mode=S_IFREG|0644, st_size=1338, ...}) = 0
openat(AT_FDCWD, "/usr/lib/ssl/certs/3513523f.0", O_RDONLY) = 4
stat("/usr/lib/ssl/certs/3513523f.1", 0x7ffdfa475c70) = -1 ENOENT (No such file or directory)

$ SSL_CERT_DIR=./ssl/certs strace openssl s_client -connect www.example.com:443 < /dev/null 2>&1 | grep /ssl/
openat(AT_FDCWD, "/usr/lib/ssl/openssl.cnf", O_RDONLY) = 3
openat(AT_FDCWD, "/usr/lib/ssl/ct_log_list.cnf", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/usr/lib/ssl/cert.pem", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("./ssl/certs/e83d98dd.0", 0x7ffe31068200) = -1 ENOENT (No such file or directory)
stat("./ssl/certs/3513523f.0", 0x7ffe31068200) = -1 ENOENT (No such file or directory)
stat("./ssl/certs/3513523f.0", 0x7ffe31068200) = -1 ENOENT (No such file or directory)

$ SSL_CERT_FILE=./ssl/empty SSL_CERT_DIR=./ssl/certs strace openssl s_client -connect www.example.com:443 < /dev/null 2>&1 | grep /ssl/
openat(AT_FDCWD, "/usr/lib/ssl/openssl.cnf", O_RDONLY) = 3
openat(AT_FDCWD, "/usr/lib/ssl/ct_log_list.cnf", O_RDONLY) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "./ssl/empty", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("./ssl/certs/e83d98dd.0", 0x7ffd0e5362d0) = -1 ENOENT (No such file or directory)
stat("./ssl/certs/3513523f.0", 0x7ffd0e5362d0) = -1 ENOENT (No such file or directory)
stat("./ssl/certs/3513523f.0", 0x7ffd0e5362d0) = -1 ENOENT (No such file or directory)

The difference in behavior could have generate bugs (possibly security impact) for users who are not aware of this subtlety.

curl/libcurl version

curl 7.74.0 (x86_64-pc-linux-gnu) libcurl/7.74.0 OpenSSL/1.1.1n zlib/1.2.11 brotli/1.0.9 libidn2/2.3.0 libpsl/0.21.0 (+libidn2/2.3.0) libssh2/1.9.0 nghttp2/1.43.0 librtmp/2.3
Release-Date: 2020-12-09
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets

operating system

Linux skagos 5.10.0-23-amd64 #1 SMP Debian 5.10.179-1 (2023-05-12) x86_64 GNU/Linux

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions