HTTPS APIs and internal services often rely on custom CRT files for certificate-based security. When default trust stores do not include the required issuer or when mutual TLS is enforced, requests must present specific CA certificates and client certificates so that connections are accepted. Correct configuration with cURL avoids confusing TLS errors and maintains strong authentication.
During a TLS handshake, the server presents its certificate, which is validated against a trusted CA certificate. cURL normally relies on the system trust store, but the --cacert option allows explicit selection of a CA CRT for endpoints signed by private or internal authorities. For mutual TLS, cURL also sends a client certificate from --cert together with a matching private key from --key so the server can verify client identity.
Reliable operation depends on a build of cURL with HTTPS support, access to the required CRT and key files, and secure handling of private keys. Incorrect certificate chains or mismatched keys cause handshake failures, while disabling verification with options such as --insecure undermines confidentiality and integrity. Private key files should remain tightly permissioned to prevent disclosure to other local users or processes.
Steps to use CRT, client key, and CA certificate files in curl:
- Confirm that cURL is installed and shows a TLS backend in the version output.
$ curl --version curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11 Release-Date: 2022-01-05 Protocols: dict file ftp ftps http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp Features: AsynchDNS HTTP2 HTTPS-proxy IPv6 Largefile libz NTLM NTLM_WB SSL TLS-SRP UnixSockets ##### snipped #####
Presence of OpenSSL, GnuTLS, or another TLS backend in the version output confirms HTTPS support.
- Identify whether the target endpoint requires only a custom CA certificate, a client CRT, or full mutual TLS with both certificate and private key.
API or service documentation usually specifies the required certificate chain, file formats, and authentication flow.
- Provide the appropriate CA certificate to cURL with --cacert when the default trust store does not contain the issuer.
$ curl --cacert /path/to/ca.crt --verbose https://secure.example.com/ ##### snipped ##### * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * Server certificate: * subject: CN=secure.example.com * start date: Jan 1 00:00:00 2024 GMT * expire date: Dec 31 23:59:59 2024 GMT * issuer: CN=Example-Internal-CA > GET / HTTP/1.1 > Host: secure.example.com ##### snipped #####
Option --cacert overrides the default trust store and restricts server validation to certificates signed by the provided CA file.
- Pass a client certificate with --cert when the server requires mutual TLS authentication.
$ curl --cert /path/to/client.crt --cacert /path/to/ca.crt https://api.example.com/protected {"message":"client certificate presented"}Option --cert loads the X.509 client certificate used to represent the calling client during the TLS handshake.
- Attach the matching private key with --key if the certificate and key are stored in separate files.
$ curl --cert /path/to/client.crt --key /path/to/client.key --cacert /path/to/ca.crt https://api.example.com/protected {"message":"ok","status":"authorized"}The private key specified by --key must correspond exactly to the public key embedded in the client certificate, or the TLS handshake fails.
- Restrict filesystem permissions on the private key so that only the intended user account can read it.
$ chmod 600 /path/to/client.key
Loose permissions on private key files allow other local users or processes to impersonate the client certificate holder.
- Avoid disabling certificate verification with --insecure except for short-lived diagnostics in controlled environments.
$ curl --insecure https://secure.example.com/
Using --insecure skips TLS certificate verification and exposes traffic to man-in-the-middle attacks and spoofed endpoints.
- Verify successful configuration by running a verbose request that returns the expected HTTP status code without certificate errors.
$ curl --cert /path/to/client.crt --key /path/to/client.key --cacert /path/to/ca.crt --verbose https://api.example.com/protected ##### snipped ##### * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 > GET /protected HTTP/1.1 > Host: api.example.com ##### snipped ##### < HTTP/1.1 200 OK < Content-Type: application/json {"message":"ok","status":"authorized"}Success signals include absence of certificate warnings, a completed SSL connection line, and the expected HTTP status and response body.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
Comment anonymously. Login not required.
