← Knowledge base

curl

Is PQC enabled? — quick check

macOS / Linux

# 1) No-dependency check — identify this machine first.
uname -a 2>/dev/null || true

# 2) Dependency check — prompt before installing anything.
if ! command -v curl >/dev/null 2>&1; then
  echo 'curl was not found.'
  printf 'Install or enable curl now? [y/N] '
  read answer
  case "$answer" in
    [Yy]*) echo 'Install curl 8.10+ with an OpenSSL 3.5+, BoringSSL, or rustls backend, then rerun this snippet.' ;;
    *) echo 'Skipping curl-based check.'; exit 1 ;;
  esac
fi

curl -V | head -1
if ! curl --help all 2>/dev/null | grep -q -- '--curves'; then
  echo 'This curl does not expose --curves. Install curl 8.10+ with a PQC-capable TLS backend and retry.'
  exit 1
fi
curl --curves X25519MLKEM768:X25519:secp256r1 -v https://example.com/ 2>&1 | grep -E "SSL connection|Server certificate|server accepted"

Expected when PQC is ON

curl 8.10.1 (x86_64-apple-darwin23.0.0) libcurl/8.10.1 OpenSSL/3.5.0 ...
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519MLKEM768 / RSASSA-PSS

What you'll see when PQC is OFF

curl 8.4.0 (x86_64-pc-linux-gnu) libcurl/8.4.0 OpenSSL/3.0.13 ...
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / x25519 / RSASSA-PSS

The TLS backend at the end of `curl -V` is the gate. OpenSSL 3.5+, BoringSSL, or rustls = PQ. Older OpenSSL or LibreSSL = no PQ.

curl negotiates whichever groups its TLS backend offers. To get X25519MLKEM768 on the wire you need a backend that supports it:

Pin the group on the command line

if ! command -v curl >/dev/null 2>&1; then
  echo 'curl was not found.'
  printf 'Install curl now? [y/N] '; read answer
  case "$answer" in [Yy]*) sudo apt-get update && sudo apt-get install -y curl ;; *) exit 1 ;; esac
fi
if ! curl --help all 2>/dev/null | grep -q -- '--curves'; then
  echo 'This curl does not expose --curves. Install curl 8.10+ with a PQC-capable TLS backend and retry.'
  exit 1
fi
curl --curves X25519MLKEM768:X25519:secp256r1 https://example.com/

--curves is supported in curl 8.10+. Older curl ignores it silently — check curl --help all | grep curves.

Confirm what was negotiated

if ! command -v curl >/dev/null 2>&1; then
  echo 'curl was not found.'
  printf 'Install curl now? [y/N] '; read answer
  case "$answer" in [Yy]*) sudo apt-get update && sudo apt-get install -y curl ;; *) exit 1 ;; esac
fi
curl -v --trace-time --curves X25519MLKEM768 https://example.com/ 2>&1 \
  | grep -E "SSL connection|Peer key|server accepted"

Static / reproducible builds

For container images, build curl against openssl-3.5 from source or use the curlimages/curl tag with a TLS backend confirmed via curl -V.

Run the check on a curl-driven service →