<!-- Copyright (c) 2026 defconxt. All rights reserved. -->
<!-- Licensed under AGPL-3.0 — see LICENSE file for details. -->
---
name: analyzing-tls-certificate-chains
description: >-
  Inspect, validate, and troubleshoot TLS certificate chains including root CA
  trust anchors, intermediate certificates, chain ordering, revocation checks
  (OCSP/CRL), and pinning verification. Covers openssl, certtool, and
  programmatic chain-building for incident triage and compliance audits.
domain: cybersecurity
subdomain: cryptography
tags:
  - tls
  - certificates
  - x509
  - certificate-chain
  - ocsp
  - crl
  - trust-anchors
  - pki
version: "1.0"
author: defconxt
license: AGPL-3.0
metadata:
  mitre-attack: ["T1553.004"]
---

# Analyzing TLS Certificate Chains

## Overview

A TLS certificate chain links a server's leaf certificate through zero or more
intermediate CAs back to a trusted root. Broken, misordered, or expired chains
are a leading cause of TLS failures. This skill covers end-to-end chain
analysis from retrieval through trust validation.

## Prerequisites

| Requirement | Install |
|---|---|
| OpenSSL 3.x | `apt install openssl` / `brew install openssl` |
| certtool (GnuTLS) | `apt install gnutls-bin` |
| Python 3.10+ | For agent tooling |
| curl | HTTP-based OCSP/CRL checks |

## Key Concepts

### Certificate Chain Order

```
Root CA (self-signed, in trust store)
  └── Intermediate CA (signed by Root)
        └── Leaf Certificate (signed by Intermediate)
```

Servers must send the leaf **plus all intermediates** — root is optional
(clients have it in their trust store). Missing intermediates cause
`unable to get local issuer certificate` errors.

### Chain Retrieval

```bash
# Retrieve and display the full chain
openssl s_client -connect example.com:443 -showcerts < /dev/null 2>/dev/null

# Extract just the leaf certificate
openssl s_client -connect example.com:443 < /dev/null 2>/dev/null | \
  openssl x509 -text -noout

# Save each certificate in the chain to separate files
openssl s_client -connect example.com:443 -showcerts < /dev/null 2>/dev/null | \
  awk '/BEGIN CERT/,/END CERT/{if(/BEGIN/)n++;print > "cert-"n".pem"}'

# Check chain depth and order
openssl s_client -connect example.com:443 < /dev/null 2>&1 | \
  grep -E "depth=|verify"
```

### Chain Validation

```bash
# Verify chain against system trust store
openssl verify -verbose cert.pem

# Verify with explicit CA bundle and intermediates
openssl verify -CAfile root-ca.pem -untrusted intermediate.pem leaf.pem

# Check complete chain with all intermediates
openssl verify -CAfile root-ca.pem -untrusted chain.pem server.pem

# Verify certificate purpose
openssl verify -purpose sslserver -CAfile ca-bundle.pem server.pem
```

### Revocation Checking

```bash
# Extract OCSP responder URL from certificate
openssl x509 -in cert.pem -noout -ocsp_uri

# Check OCSP status
openssl ocsp -issuer intermediate.pem -cert leaf.pem \
  -url http://ocsp.example.com -resp_text

# Extract CRL distribution points
openssl x509 -in cert.pem -noout -text | grep -A2 "CRL Distribution"

# Download and inspect CRL
curl -sO http://crl.example.com/intermediate.crl
openssl crl -in intermediate.crl -inform DER -text -noout
```

### Common Chain Failures

| Failure | Cause | Fix |
|---|---|---|
| `unable to get local issuer certificate` | Missing intermediate | Add intermediate to server config |
| `certificate has expired` | Expired cert in chain | Renew the expired certificate |
| `self-signed certificate in chain` | Untrusted root sent | Remove root from server chain or add to trust store |
| `certificate signature failure` | Tampered or corrupt cert | Re-download or re-issue certificate |
| `OCSP response: revoked` | Certificate revoked by CA | Re-issue certificate |

## Workflow

1. **Retrieve** — Pull the chain from the target endpoint
2. **Decompose** — Split chain into individual certificates
3. **Inspect** — Check each cert for validity, algorithm, key size, SANs
4. **Validate** — Verify chain of trust from leaf to root
5. **Revocation** — Check OCSP and CRL status for each cert
6. **Report** — Document findings with severity ratings

## Verification

| Check | Method |
|---|---|
| Chain complete | `openssl s_client` shows all intermediates |
| No expired certs | Each cert `notAfter` is in the future |
| Strong algorithms | No SHA-1 or MD5 signatures in chain |
| Key size adequate | RSA ≥ 2048, ECDSA ≥ P-256 |
| Revocation clean | OCSP returns `good` for all certs |
| Correct order | Leaf → Intermediate(s) → (optional Root) |

## References

- [OpenSSL s_client documentation](https://www.openssl.org/docs/man3.0/man1/openssl-s_client.html)
- [RFC 5280 — X.509 PKI Certificate and CRL Profile](https://datatracker.ietf.org/doc/html/rfc5280)
- [RFC 6960 — OCSP](https://datatracker.ietf.org/doc/html/rfc6960)
- [NIST SP 800-52 Rev. 2 — TLS Guidelines](https://csrc.nist.gov/publications/detail/sp/800-52/rev-2/final)
