← Back to list

Mastering Curl’s SSL/TLS on Embedded Devices and Custom Linux

curl is a powerful and ubiquitous tool for data transfer, making it a common choice for connected embedded systems and devices running…

PI in Neural Engineer · 2026-02-05 15:49 · 1 claps · 7.4 min read paywalled
#ssl #ca-certificates #curl #software
Open on Medium ↗
Wiki topics: ML · Machine Learning 🔓 · Open Source 📊 · Economic Policy 🏃 · Running & Endurance

Mastering Curl’s SSL/TLS on Embedded Devices and Custom Linux

curl is a powerful and ubiquitous tool for data transfer, making it a common choice for connected embedded systems and devices running custom Linux builds. However, unlike a typical desktop or server environment, these platforms present unique challenges for security. They often lack automatic update mechanisms, may not have a pre-installed CA (Certificate Authority) trust store, and require careful manual configuration to ensure secure SSL/TLS communication.

This article provides a deep dive into curl's SSL/TLS settings, specifically for developers working on embedded and custom platforms. We will cover how to manage CA certificates, handle common errors, and implement best practices for secure data transfer in resource-constrained and manually-managed environments.

The Foundation: SSL/TLS Handshake

Before we dive into curl's options, let's briefly revisit the SSL/TLS handshake. When a client connects to a secure server, a handshake process occurs:

  1. Negotiation: The client and server agree on the protocol version (TLS 1.2, 1.3, etc.) and the cipher suite to be used.
  2. Authentication: The server presents its SSL certificate to the client. The client verifies the certificate’s authenticity to ensure it’s talking to the correct server and not a man-in-the-middle.
  3. Key Exchange: The client and server securely exchange a session key, which will be used to encrypt all subsequent communication.

curl's SSL options primarily come into play during the authentication step.

Core SSL Verification Concepts

By default, curl performs strict SSL/TLS certificate verification on all https requests. This verification is composed of two main checks that happen within the underlying libcurl library: verifying the peer and verifying the host.

  • Peer Verification (ssl_verifypeer): This is the process of checking if the server's certificate was issued by a trusted Certificate Authority (CA). curl does this by comparing the certificate's issuer against its list of known, trusted CAs. This ensures the certificate is authentic and not a forgery.
  • Host Verification (ssl_verifyhost): This is the process of checking that the hostname in the URL you are trying to connect to matches the Common Name (CN) or a Subject Alternative Name (SAN) listed in the server's certificate. This prevents man-in-the-middle attacks, where an attacker might use a valid certificate for a different domain to intercept your connection.

On the curl command line, you do not use flags to enable these checks, as they are on by default. Instead, you only have options to disable them.

Disabling Verification: --insecure

The most common, and most dangerous, SSL-related flag is:

  • -k, --insecure: This single option tells curl to bypass both peer and host verification. It makes the connection insecure by allowing curl to connect to any server with any certificate, without validating its authenticity or hostname. This should only be used in controlled, local development environments where you fully trust the network and the server. Using it in production is a major security risk.

While --insecure is the blanket option, there are no direct command-line flags like --no-ssl-verifypeer or --no-ssl-verifyhost to control these checks individually. The control is all-or-nothing via --insecure.

Specifying a Certificate Authority (CA) on Embedded Systems

On a standard desktop or server, curl can rely on a system-wide CA trust store that is kept current by the OS provider. On an embedded device or custom Linux platform, you must assume that a default trust store does not exist or will never be updated. The paths listed for standard Linux distributions may be empty or non-existent.

This places the responsibility of providing and managing a CA bundle directly on you, the developer. Without it, curl cannot verify any TLS peer and all HTTPS requests will fail.

Certificate Expiry and Manual Updates: A Critical Task

On embedded systems, there is often no package manager or automatic update service running in the background. This means that any CA bundle you install will remain static until you manually update it in a future firmware release.

  • The Core Problem: CA certificates have a finite lifespan. If your device is in the field for years, its CA bundle will inevitably become outdated. Certificates for new services won’t be trusted, and certificates from renewed CAs will fail validation, leading to connection failures.
  • Best Practice for Embedded: You must implement a process for periodically updating the CA bundle as part of your device’s firmware or software update strategy. This is a critical maintenance task to ensure long-term connectivity and security.

Acquiring and Using a CA Bundle

Since the device doesn’t manage a CA bundle for you, you must provide one. The most straightforward approach for embedded systems is to use the --cacert option with a single bundle file.

  • Direct Download for Embedded Systems: The curl project itself provides and maintains a cacert.pem file, which is extracted directly from Mozilla’s root program. This is an excellent, reliable source for embedded devices.
  • Source: curl CA Extract
  • Process: Download this cacert.pem file, place it in the filesystem of your embedded device (e.g., in /etc/ssl/), and use the --cacert flag in your curl commands.
# Example on an embedded device
# The cacert.pem file has been placed in /etc/ssl/ during the build process.
curl --cacert /etc/ssl/cacert.pem https://api.example.com/data

Using a single file is generally preferable to --capath on a minimal system, as it avoids the need for the openssl rehash tool and simplifies filesystem management.

Public CA Root Programs

While direct download is often most practical, understanding the source of these bundles is still valuable. The trust stores for all major platforms are publicly documented.

Now, let’s look at the specifics of using these options.

--cacert <file>

This option allows you to specify a file containing one or more CA certificates to be used for peer verification. The certificates must be in PEM format.

# ansel.pem contains the custom CA certificate
curl --cacert ansel.pem https://ansel.internal.dev

--capath <dir>

This option specifies a directory containing CA certificates. curl will use this directory to build its list of trusted CAs. However, the directory must be prepared in a specific way.

Creating a capath Directory with Certificate Hashing

While --cacert is often the best choice for embedded systems, it's worth understanding how --capath works. This option specifies a directory of CA certificates instead of a single file. For curl to use this directory efficiently, it must be "hashed." curl (via OpenSSL) doesn't just read every file; it looks for files named with a hash of the certificate's subject, which allows for very fast lookups.

Here’s how to create a correctly structured capath directory:

  1. Gather Certificates: Place all your trusted CA certificates (in PEM format) into a directory. Let’s call it my_cas.
  2. Run c_rehash: The openssl toolkit includes a utility called c_rehash that creates the necessary symbolic links. This tool may need to be run on a development machine before packaging the directory for your target device.
# 1. Copy your CA certificates into a directory
mkdir -p my_cas
cp /path/to/ca1.crt my_cas/
cp /path/to/ca2.crt my_cas/

# 2. Run the rehashing tool on your build host
openssl rehash my_cas/
# 3. Check the result. These links must be preserved in your firmware image.
ls -l my_cas/

After running rehash, you'll see symbolic links like a1b2c3d4.0 pointing to your original certificate files.

total 16
-rw-r--r--  1 user  staff  1234 Jan 20 10:00 ca1.crt
-rw-r--r--  1 user  staff  1234 Jan 20 10:01 ca2.crt
lrwxr-xr-x  1 user  staff    11 Jan 20 10:02 a1b2c3d4.0 -> ca1.crt
lrwxr-xr-x  1 user  staff    11 Jan 20 10:02 b5e6f7g8.0 -> ca2.crt

Now you can use this directory with curl:

curl --capath my_cas/ https://ansel.internal.dev

Given the requirement for the openssl rehash tool and the more complex file management, the --cacert method with a single bundle file remains the simpler and more robust solution for most embedded use cases.

curl also does a lookup of default cacert and default capath , for example on link

*  CAfile: cert.pem
*  CApath: /etc/ssl/certs

specifiying the cacerton commandline will override the cert.pem but not the capath. Specifying the capath will override only /etc/ssl/certs

Forcing HTTPS

Sometimes, a server might be configured to listen on both HTTP and HTTPS. To ensure you’re always using a secure connection, you can use:

  • --proto-default https: If no protocol is specified in the URL, curl will default to https.
  • --proto -all,+https: This tells curl to only allow HTTPS for its transfers.

Understanding and Handling SSL Errors

When an SSL/TLS connection fails, curl provides specific exit codes that help diagnose the problem.

Common curl SSL Exit Codes

  • **CURLE_SSL_CONNECT_ERROR (35)**: A generic error during the SSL/TLS handshake. This can be caused by various issues, like cipher suite mismatches or protocol version incompatibility.
  • **CURLE_SSL_PEER_CERTIFICATE or SSH remote key was not OK (51)**: The server's certificate is problematic. This could mean it's expired, not yet valid, or the hostname doesn't match.
  • **CURLE_SSL_CACERT (60)**: Peer certificate cannot be authenticated with known CA certificates. This is the classic "untrusted certificate" error. The CA that signed the server's certificate is not in curl's trust store.

Capturing Specific Certificate Errors

Let’s examine how to identify different validation failures.

Host Mismatch

If you try to connect to an IP address, but the certificate is for a hostname, verifyhost will fail.

# Certificate is for "example.com", not the IP address.
curl https://93.184.216.34

curl: (51) SSL: certificate subject name 'www.example.com' does not match target host name '93.184.216.34'

Invalid or Expired Certificate

If the server’s clock and your clock are correct, but the certificate is outside its validity period, verifypeer will fail.

# Connecting to a server with an expired certificate
curl https://expired.badssl.com/

curl: (60) SSL certificate problem: certificate has expired
More details here: https://curl.se/docs/sslcerts.html
...

Server Time Mismatch

This is a subtle but important issue. The client checks the certificate’s “Not Before” and “Not After” dates against its own local clock. If the server’s clock is significantly off, it might serve a certificate that it thinks is valid, but your client will correctly see it as not yet valid or expired. The error will look the same as an expired certificate error, but the root cause is the server’s time drift.

Untrusted Self-Signed Certificate

This is a very common scenario in development.

# Server is using a self-signed certificate
curl https://self-signed.badssl.com/

curl: (60) SSL certificate problem: self signed certificate
...

To manage this, you would add the self-signed certificate to a .pem file and use --cacert:

# 1. Get the server's self-signed cert and save it
openssl s_client -showcerts -connect self-signed.badssl.com:443 </dev/null 2>/dev/null|openssl x509 -outform PEM > self-signed.pem

# 2. Use it with --cacert
curl --cacert self-signed.pem https://self-signed.badssl.com/

If you found this helpful, consider following my profile and signing up for the newsletter. Have thoughts or questions? Share them in the comments below.

Conclusion

curl provides a robust set of tools for secure data transfer over SSL/TLS. Understanding how to use --cacert, --capath, and interpreting verification errors is essential for any developer working with web services. Always prioritize verification, and only bypass it (--insecure) when you are in a trusted, isolated environment and fully understand the risks. By mastering these options, you can ensure your curl-based scripts and applications are both powerful and secure.

References


메타데이터
post_id
f3d077a54d56
slug
mastering-curls-ssl-tls-on-embedded-devices-and-custom-linux-f3d077a54d56
url
https://blog1.neuralengineer.org/mastering-curls-ssl-tls-on-embedded-devices-and-custom-linux-f3d077a54d56
canonical_url
https://blog1.neuralengineer.org/mastering-curls-ssl-tls-on-embedded-devices-and-custom-linux-f3d077a54d56
author_url
https://medium.com/@pi45757
status
ok
fetched_at
2026-06-13 00:25:45