Project 13: HTTPS Client with OpenSSL

Extend your HTTP client (Project 5) to support HTTPS using OpenSSL. Properly validate server certificates, handle the TLS handshake, and send encrypted requests.

Quick Reference

Attribute Value
Primary Language C++
Alternative Languages Rust (rustls), Go
Difficulty Level 3: Advanced
Time Estimate 1-2 weeks
Knowledge Area TLS/SSL, Certificate Validation, OpenSSL API
Tooling Secure HTTP client
Prerequisites Project 5, basic understanding of certificates

What You Will Build

Extend your HTTP client (Project 5) to support HTTPS using OpenSSL. Properly validate server certificates, handle the TLS handshake, and send encrypted requests.

Why It Matters

This project builds core skills that appear repeatedly in real-world systems and tooling.

Core Challenges

  • OpenSSL context setup → maps to SSL_CTX_new, loading CA certificates
  • TLS handshake → maps to SSL_connect, error handling
  • Certificate validation → maps to hostname verification, chain building
  • Reading/writing through SSL → maps to SSL_read, SSL_write vs raw sockets

Key Concepts

  • OpenSSL API: “Network Security with OpenSSL” - Viega, Messier, Chandra
  • TLS Handshake: “Bulletproof SSL and TLS” Chapter 2 - Ristić
  • Certificate Validation: “Bulletproof SSL and TLS” Chapter 6 - Ristić
  • SNI (Server Name Indication): Required for most HTTPS servers

Real-World Outcome

$ ./https_client https://www.google.com/
TLS Handshake:
  Protocol: TLSv1.3
  Cipher: TLS_AES_256_GCM_SHA384
  Certificate: CN=www.google.com
  Issuer: CN=GTS CA 1C3
  Valid: 2024-01-01 to 2024-03-25

HTTP/1.1 200 OK
Content-Type: text/html
...

$ ./https_client https://expired.badssl.com/
Error: certificate verify failed
  Reason: certificate has expired

$ ./https_client https://wrong.host.badssl.com/
Error: certificate verify failed
  Reason: hostname mismatch

$ ./https_client https://self-signed.badssl.com/
Error: certificate verify failed
  Reason: self signed certificate

Implementation Guide

  1. Reproduce the simplest happy-path scenario.
  2. Build the smallest working version of the core feature.
  3. Add input validation and error handling.
  4. Add instrumentation/logging to confirm behavior.
  5. Refactor into clean modules with tests.

Milestones

  • Milestone 1: Minimal working program that runs end-to-end.
  • Milestone 2: Correct outputs for typical inputs.
  • Milestone 3: Robust handling of edge cases.
  • Milestone 4: Clean structure and documented usage.

Validation Checklist

  • Output matches the real-world outcome example
  • Handles invalid inputs safely
  • Provides clear errors and exit codes
  • Repeatable results across runs

References

  • Main guide: LEARN_CPP_NETWORK_PROGRAMMING.md
  • “Bulletproof SSL and TLS” by Ivan Ristić