mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-19 11:19:36 +00:00
OpenSSL allowed client-initiated renegotiation, which runs a handshake update_certs_pem() does not wait for, and kept sessions and ticket keys across a change of client CAs, so a client verified under the old ones could resume. wolfSSL added new client CAs to the old instead of replacing them, and a bad certificate or key left Mbed TLS and wolfSSL half updated. Turn renegotiation off, forget the sessions and ticket keys on a client CA change, replace wolfSSL's CAs, and check new material before swapping it in. Note that the update must not be called from a TLS callback.
79 lines
2.6 KiB
Markdown
79 lines
2.6 KiB
Markdown
---
|
|
title: "T03. Start an SSL/TLS Server"
|
|
order: 45
|
|
status: "draft"
|
|
---
|
|
|
|
To stand up an HTTPS server, use `httplib::SSLServer` instead of `httplib::Server`. Pass a certificate and private key to the constructor, and you get back something that works exactly like `Server`.
|
|
|
|
## Basic usage
|
|
|
|
```cpp
|
|
#define CPPHTTPLIB_OPENSSL_SUPPORT
|
|
#include <httplib.h>
|
|
|
|
int main() {
|
|
httplib::SSLServer svr("cert.pem", "key.pem");
|
|
|
|
svr.Get("/", [](const auto &req, auto &res) {
|
|
res.set_content("hello over TLS", "text/plain");
|
|
});
|
|
|
|
svr.listen("0.0.0.0", 443);
|
|
}
|
|
```
|
|
|
|
Pass the server certificate (PEM format) and private key file paths to the constructor. That's all you need for a TLS-enabled server. Registering handlers and calling `listen()` work the same as with `Server`.
|
|
|
|
## Password-protected private keys
|
|
|
|
The fifth argument is the private key password.
|
|
|
|
```cpp
|
|
httplib::SSLServer svr("cert.pem", "key.pem",
|
|
nullptr, nullptr, "password");
|
|
```
|
|
|
|
The third and fourth arguments are for client certificate verification (mTLS, see [T04. Configure mTLS](../t04-mtls)). For now, pass `nullptr`.
|
|
|
|
## Load PEM data from memory
|
|
|
|
When you want to load certs from memory instead of files, use the `PemMemory` struct.
|
|
|
|
```cpp
|
|
httplib::SSLServer::PemMemory pem{};
|
|
pem.cert_pem = cert_data.data();
|
|
pem.cert_pem_len = cert_data.size();
|
|
pem.key_pem = key_data.data();
|
|
pem.key_pem_len = key_data.size();
|
|
|
|
httplib::SSLServer svr(pem);
|
|
```
|
|
|
|
Handy when you pull certificates from environment variables or a secrets manager.
|
|
|
|
## Rotate certificates
|
|
|
|
Before a certificate expires, you may want to swap it out without restarting the server. That's what `update_certs_pem()` is for.
|
|
|
|
```cpp
|
|
svr.update_certs_pem(new_cert_pem, new_key_pem);
|
|
```
|
|
|
|
Existing connections keep using the old cert; new connections use the new one. It waits for handshakes in progress to finish, at most the read timeout, and new connections wait until it returns. So don't call it from a TLS callback that runs during a handshake: it would wait for that handshake.
|
|
|
|
## Generating a test certificate
|
|
|
|
For a throwaway self-signed cert, use the `openssl` CLI.
|
|
|
|
```sh
|
|
openssl req -x509 -newkey rsa:2048 -days 365 -nodes \
|
|
-keyout key.pem -out cert.pem -subj "/CN=localhost"
|
|
```
|
|
|
|
In production, use certificates from Let's Encrypt or your internal CA.
|
|
|
|
> **Warning:** Binding an HTTPS server to port 443 requires root. For a safe way to do that, see the privilege-drop pattern in [S18. Control startup order with `listen_after_bind`](../s18-listen-after-bind).
|
|
|
|
> For mutual TLS (client certificates), see [T04. Configure mTLS](../t04-mtls).
|