# Ssl Checker

> Use when the user has SSL/TLS certificate issues, needs to verify certificate expiration, debug HTTPS errors, or check certificate chain validity.

- Skill: `skyvanguard/ssl-checker` (Agent Skill)
- Install (CLI): `npx skillmds@latest add skyvanguard/ssl-checker`
- Raw SKILL.md: https://api.skillmd.com/api/skills/skyvanguard/ssl-checker/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: skyvanguard (https://skillmd.com/u/skyvanguard)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/skyvanguard/ssl-checker

---


# SSL/TLS Certificate Checker

## Overview

Diagnose SSL/TLS certificate issues including expiration, chain problems, misconfiguration, and protocol/cipher weaknesses. Supports both remote endpoints and local certificate files.

## Process

### Step 1: Identify the Target

Determine what to check:
- Remote endpoint: `host:port` (default port 443)
- Local certificate file: `.pem`, `.crt`, `.cer`, `.pfx`
- Certificate store: system trust store

### Step 2: Check Remote Certificate

**Basic certificate info:**
```bash
# Full certificate details
echo | openssl s_client -connect [host]:443 -servername [host] 2>/dev/null | openssl x509 -noout -text

# Quick summary (subject, issuer, dates)
echo | openssl s_client -connect [host]:443 -servername [host] 2>/dev/null | openssl x509 -noout -subject -issuer -dates -fingerprint

# Check expiration specifically
echo | openssl s_client -connect [host]:443 -servername [host] 2>/dev/null | openssl x509 -noout -enddate
```

**Windows alternative:**
```powershell
# Check remote certificate
$req = [Net.HttpWebRequest]::Create("https://[host]")
$req.AllowAutoRedirect = $false
$req.Timeout = 10000
try { $req.GetResponse() | Out-Null } catch {}
$cert = $req.ServicePoint.Certificate
[PSCustomObject]@{
    Subject = $cert.Subject
    Issuer = $cert.Issuer
    NotAfter = $cert.GetExpirationDateString()
    NotBefore = $cert.GetEffectiveDateString()
}
```

### Step 3: Certificate Chain Verification

```bash
# Show full chain
echo | openssl s_client -connect [host]:443 -servername [host] -showcerts 2>/dev/null

# Verify chain
echo | openssl s_client -connect [host]:443 -servername [host] -verify_return_error 2>&1 | grep -E "verify|depth|error"

# Check specific CA bundle
echo | openssl s_client -connect [host]:443 -servername [host] -CAfile [ca-bundle.crt] 2>&1 | grep "Verify return code"
```

**Chain issues to check:**
| Issue | Indicator | Fix |
|-------|-----------|-----|
| Incomplete chain | "unable to get local issuer certificate" | Add intermediate certs |
| Self-signed | "self signed certificate" | Install CA or add exception |
| Expired intermediate | Intermediate cert past notAfter | Update intermediate |
| Wrong order | Certs not in order leaf→intermediate→root | Reorder chain |

### Step 4: Expiration Analysis

```bash
# Days until expiration
echo | openssl s_client -connect [host]:443 -servername [host] 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2 | xargs -I{} date -d {} +%s | xargs -I{} echo $(( ({} - $(date +%s)) / 86400 )) days remaining
```

**Expiration thresholds:**
| Days Remaining | Severity | Action |
|---------------|----------|--------|
| > 30 | OK | No action needed |
| 15-30 | WARNING | Plan renewal |
| 7-14 | HIGH | Renew immediately |
| 1-7 | CRITICAL | Emergency renewal |
| 0 or expired | EXPIRED | Service likely broken |

### Step 5: Protocol and Cipher Check

**Supported TLS versions:**
```bash
# Check TLS 1.0 (should be disabled)
echo | openssl s_client -connect [host]:443 -tls1 2>&1 | grep -i "protocol\|error\|alert"

# Check TLS 1.1 (should be disabled)
echo | openssl s_client -connect [host]:443 -tls1_1 2>&1 | grep -i "protocol\|error\|alert"

# Check TLS 1.2
echo | openssl s_client -connect [host]:443 -tls1_2 2>&1 | grep "Protocol\|Cipher"

# Check TLS 1.3
echo | openssl s_client -connect [host]:443 -tls1_3 2>&1 | grep "Protocol\|Cipher"
```

**Cipher strength:**
```bash
# Currently negotiated cipher
echo | openssl s_client -connect [host]:443 -servername [host] 2>/dev/null | grep "Cipher\|Protocol"
```

**Weak configurations to flag:**
| Issue | Risk | Recommendation |
|-------|------|----------------|
| TLS 1.0 enabled | HIGH | Disable |
| TLS 1.1 enabled | MEDIUM | Disable |
| RC4 cipher | HIGH | Remove from config |
| DES/3DES cipher | HIGH | Remove from config |
| No TLS 1.3 | LOW | Enable if possible |
| SHA-1 signature | MEDIUM | Reissue with SHA-256 |
| Key < 2048 bits | HIGH | Reissue with 2048+ |

### Step 6: Local Certificate Inspection

**Read local cert file:**
```bash
# PEM format
openssl x509 -in [file.pem] -noout -text

# DER format
openssl x509 -in [file.der] -inform DER -noout -text

# PKCS12 / PFX
openssl pkcs12 -in [file.pfx] -nokeys -info 2>/dev/null
```

**Windows cert store:**
```powershell
# List certificates expiring within 30 days
Get-ChildItem Cert:\LocalMachine\My | Where-Object {$_.NotAfter -lt (Get-Date).AddDays(30)} | Select Subject, NotAfter, Thumbprint

# All certs in store
Get-ChildItem Cert:\LocalMachine\My | Select Subject, NotAfter, Issuer | Sort NotAfter
```

### Step 7: Common Issues Diagnosis

| Symptom | Likely Cause | Verification |
|---------|-------------|-------------|
| "NET::ERR_CERT_DATE_INVALID" | Expired cert | Check enddate |
| "NET::ERR_CERT_AUTHORITY_INVALID" | Unknown CA or self-signed | Check issuer chain |
| "NET::ERR_CERT_COMMON_NAME_INVALID" | Wrong domain in cert | Check SAN/CN |
| "SSL_ERROR_NO_CYPHER_OVERLAP" | No shared ciphers | Check cipher list |
| "ERR_SSL_VERSION_OR_CIPHER_MISMATCH" | Protocol mismatch | Check TLS versions |
| Mixed content warnings | HTTP resources on HTTPS page | Check page resources |
| HSTS error | Cached strict policy | Check HSTS header |

**Subject Alternative Names check:**
```bash
echo | openssl s_client -connect [host]:443 -servername [host] 2>/dev/null | openssl x509 -noout -ext subjectAltName
```

### Step 8: Present Report

```
## SSL/TLS Certificate Report
**Target:** [host]:443 | **Checked:** [timestamp]

### Certificate Details
| Field | Value |
|-------|-------|
| Subject | [CN] |
| Issuer | [issuer] |
| Valid From | [date] |
| Valid Until | [date] (**[N] days remaining**) |
| Serial | [serial] |
| Signature Alg | [alg] |
| Key Size | [bits] |
| SANs | [domain list] |

### Chain Status
| # | Subject | Issuer | Expires | Status |
|---|---------|--------|---------|--------|
| 0 | [leaf] | [issuer] | [date] | [OK/WARN] |
| 1 | [intermediate] | [issuer] | [date] | [OK/WARN] |
| 2 | [root] | [self] | [date] | [OK/WARN] |

### Protocol & Cipher
| Protocol | Status | Rating |
|----------|--------|--------|
| TLS 1.0 | [enabled/disabled] | [OK/FAIL] |
| TLS 1.1 | [enabled/disabled] | [OK/FAIL] |
| TLS 1.2 | [enabled/disabled] | [OK] |
| TLS 1.3 | [enabled/disabled] | [OK/WARN] |

### Issues Found
- [Issue 1 with severity]
- [Issue 2 with severity]

### Recommendations
1. [Priority actions]
```

## Rules

- NEVER attempt to decrypt or extract private keys
- NEVER modify certificate stores without explicit permission
- ALWAYS use -servername (SNI) for accurate results on shared hosting
- Use timeouts on all network operations
- If openssl is not available, inform user and suggest installation
- Report exact error messages from OpenSSL for debugging
- Check SAN (Subject Alternative Names) not just CN for domain validation

