|
| 1 | +# Add OpenSSL package + Asio SSL support |
| 2 | + |
| 3 | +> Created: 2026-07-26 · Status: design |
| 4 | +> Repo: `mcpplibs/mcpp-index` · Branch: `feat/add-openssl-asio-tls` |
| 5 | +
|
| 6 | +## 1. Motivation |
| 7 | + |
| 8 | +The mcpp ecosystem needs TLS support. `chriskohlhoff.asio@1.38.1` (C++23 |
| 9 | +module wrapper) already ships Asio's full source tree but explicitly excludes |
| 10 | +`asio/ssl/*.hpp` because SSL requires an external crypto library. This design |
| 11 | +adds `compat.openssl` as a new static library package and extends |
| 12 | +`chriskohlhoff.asio` with an opt-in `ssl` feature. |
| 13 | + |
| 14 | +mbedTLS (`compat.mbedtls@3.6.1`) already exists in the index but **cannot** |
| 15 | +serve as asio's SSL dependency: asio::ssl is hard-coded against the OpenSSL C |
| 16 | +API (~95 distinct identifiers across SSL_CTX, SSL, BIO, ERR, X509, EVP, PEM, |
| 17 | +DH, RSA, CRYPTO), and mbedTLS provides no OpenSSL compatibility layer |
| 18 | +(its native API is entirely different: `mbedtls_ssl_*`, `mbedtls_x509_*`, etc.). |
| 19 | + |
| 20 | +## 2. Scope |
| 21 | + |
| 22 | +### In scope |
| 23 | +- New package `compat.openssl@3.5.1` (latest LTS, supported to 2030-04-08) |
| 24 | +- Opt-in `ssl` feature on `chriskohlhoff.asio@1.38.1` |
| 25 | +- Consumer test for asio SSL (TCP echo over TLS) |
| 26 | + |
| 27 | +### Out of scope |
| 28 | +- TLS as an abstract capability (like `blas`) — deferred until a second TLS |
| 29 | + provider exists |
| 30 | +- wolfSSL, BoringSSL, LibreSSL packages |
| 31 | +- QUIC or TLS 1.3-only API exposure in the module wrapper |
| 32 | +- Changes to `index.toml` or `min_mcpp` version |
| 33 | +- Windows support (requires prebuilt MSVC binaries, not yet prepared) |
| 34 | + |
| 35 | +## 3. Package: compat.openssl |
| 36 | + |
| 37 | +### 3.1 Identity |
| 38 | + |
| 39 | +| Field | Value | |
| 40 | +|---|---| |
| 41 | +| namespace | `compat` | |
| 42 | +| name | `compat.openssl` | |
| 43 | +| version | `3.5.1` | |
| 44 | +| license | `Apache-2.0` | |
| 45 | +| repo | `https://github.com/openssl/openssl` | |
| 46 | +| type | Form B (inline, install()-driven build) | |
| 47 | + |
| 48 | +### 3.2 Build strategy |
| 49 | + |
| 50 | +OpenSSL's build system (Perl `Configure` + GNU Make) cannot be expressed as a |
| 51 | +flat source glob. Follow the `compat.openblas` pattern: an `install()` Lua hook |
| 52 | +drives the external build and emits an anchor `.c` TU whose absence triggers |
| 53 | +mcpp to run `install()` before compilation. |
| 54 | + |
| 55 | +``` |
| 56 | +install() flow: |
| 57 | + 1. perl Configure no-shared no-dso no-tests no-apps no-engine |
| 58 | + --prefix=<prefix> --openssldir=<prefix>/ssl |
| 59 | + 2. make -j$(nproc) |
| 60 | + 3. make install_sw |
| 61 | + 4. Emit mcpp_openssl_anchor.c |
| 62 | +``` |
| 63 | + |
| 64 | +### 3.3 Platform strategy |
| 65 | + |
| 66 | +| Platform | Approach | Notes | |
| 67 | +|---|---|---| |
| 68 | +| Linux | Source build via install() | Build dep `xim:make@latest`; system Perl expected at `/usr/bin/perl` | |
| 69 | +| macOS | Source build via install() | Same as Linux; static libs only (`no-shared`) | |
| 70 | +| Windows | Deferred | Prebuilt zip (follow `compat.openblas` precedent) requires preparing MSVC static builds for xlings-res; not in initial scope | |
| 71 | + |
| 72 | +The `./config` convenience wrapper auto-detects the target platform (equivalent |
| 73 | +to `perl Configure <auto-detected-target>`). |
| 74 | + |
| 75 | +### 3.4 Build artifacts |
| 76 | + |
| 77 | +| File | Content | |
| 78 | +|---|---| |
| 79 | +| `lib/libcrypto.a` | EVP, X509, ASN1, BIO, ERR, RSA, EC, SHA, AES, RAND, ... | |
| 80 | +| `lib/libssl.a` | TLS/DTLS protocol (depends on libcrypto) | |
| 81 | +| `include/openssl/*.h` | Public API headers | |
| 82 | + |
| 83 | +### 3.5 Descriptor skeleton |
| 84 | + |
| 85 | +```lua |
| 86 | +package = { |
| 87 | + spec = "1", namespace = "compat", name = "compat.openssl", |
| 88 | + description = "OpenSSL — TLS/crypto library (static, install()-driven build)", |
| 89 | + licenses = {"Apache-2.0"}, |
| 90 | + repo = "https://github.com/openssl/openssl", |
| 91 | + type = "package", |
| 92 | + xpm = { |
| 93 | + linux = { deps = { "xim:make@latest" }, ["3.5.1"] = { url = {...}, sha256 = "529043b15cffa5f36077a4d0af83f3de399807181d607441d734196d889b641f" } }, |
| 94 | + macosx = { deps = { "xim:make@latest" }, ["3.5.1"] = { url = {...}, sha256 = "529043b15cffa5f36077a4d0af83f3de399807181d607441d734196d889b641f" } }, |
| 95 | + -- windows deferred (prebuilt zip not yet prepared) |
| 96 | + }, |
| 97 | + mcpp = { |
| 98 | + language = "c++23", import_std = false, c_standard = "c11", |
| 99 | + sources = { "mcpp_openssl_anchor.c" }, |
| 100 | + targets = { ["openssl"] = { kind = "lib" } }, |
| 101 | + include_dirs = { "include" }, |
| 102 | + deps = {}, |
| 103 | + linux = { ldflags = { "-Llib", "-lssl", "-lcrypto" } }, |
| 104 | + macosx = { ldflags = { "-Llib", "-lssl", "-lcrypto" } }, |
| 105 | + }, |
| 106 | +} |
| 107 | +``` |
| 108 | + |
| 109 | +### 3.6 URL / mirror |
| 110 | + |
| 111 | +Canonical upstream tarball: |
| 112 | +- GLOBAL: `https://github.com/openssl/openssl/releases/download/openssl-3.5.1/openssl-3.5.1.tar.gz` |
| 113 | +- CN: `https://gitcode.com/mcpp-res/openssl/releases/download/3.5.1/openssl-3.5.1.tar.gz` |
| 114 | + |
| 115 | +Windows prebuilt zip — deferred (requires preparing MSVC static builds for xlings-res; not in initial scope). |
| 116 | + |
| 117 | +## 4. Package: chriskohlhoff.asio (modified) |
| 118 | + |
| 119 | +### 4.1 New feature: `ssl` |
| 120 | + |
| 121 | +```lua |
| 122 | +features = { |
| 123 | + ["default"] = { implies = { "separate-compilation" } }, |
| 124 | + ["separate-compilation"] = { ... unchanged ... }, |
| 125 | + ["ssl"] = { |
| 126 | + defines = { "MCPP_FEATURE_SSL" }, |
| 127 | + deps = { ["compat.openssl"] = "3.5.1" }, |
| 128 | + sources = { "*/src/asio_ssl.cpp" }, |
| 129 | + }, |
| 130 | +}, |
| 131 | +``` |
| 132 | + |
| 133 | +`ssl` is NOT in the `default` feature set. Consumers opt in explicitly: |
| 134 | +```toml |
| 135 | +[dependencies.chriskohlhoff] |
| 136 | +asio = { version = "1.38.1", features = ["ssl"] } |
| 137 | +``` |
| 138 | + |
| 139 | +When `ssl` is active: |
| 140 | +- `MCPP_FEATURE_SSL` is defined (propagated to consumer TUs) |
| 141 | +- `compat.openssl@3.5.1` is pulled in as a dependency |
| 142 | +- `#ifdef MCPP_FEATURE_SSL` guards in `asio.cppm` activate SSL includes + exports |
| 143 | + |
| 144 | +### 4.2 Feature-gated .cppm strategy |
| 145 | + |
| 146 | +`generated_files` cannot be placed inside a feature block (xpkg features support |
| 147 | +`sources`, `defines`, `flags`, `implies`, `deps`, `requires`, `provides` — not |
| 148 | +`generated_files`). Instead, the single `.cppm` uses `#ifdef MCPP_FEATURE_SSL` |
| 149 | +guards. When the `ssl` feature is disabled, the preprocessor strips the SSL |
| 150 | +blocks and OpenSSL headers are never included. When enabled, `compat.openssl` |
| 151 | +provides the headers and the guards activate. |
| 152 | + |
| 153 | +### 4.3 Module wrapper additions (guarded by MCPP_FEATURE_SSL) |
| 154 | + |
| 155 | +Added to `asio.cppm` after the existing includes: |
| 156 | +```cpp |
| 157 | +#ifdef MCPP_FEATURE_SSL |
| 158 | +#include <asio/ssl.hpp> |
| 159 | +#include <asio/ssl/context.hpp> |
| 160 | +#include <asio/ssl/stream.hpp> |
| 161 | +#include <asio/ssl/error.hpp> |
| 162 | +#endif |
| 163 | +``` |
| 164 | + |
| 165 | +Added to the export block: |
| 166 | +```cpp |
| 167 | +#ifdef MCPP_FEATURE_SSL |
| 168 | +export namespace asio::ssl { |
| 169 | +using ::asio::ssl::context; |
| 170 | +using ::asio::ssl::context_base; |
| 171 | +using ::asio::ssl::stream; |
| 172 | +using ::asio::ssl::verify_mode; |
| 173 | +using ::asio::ssl::verify_none; |
| 174 | +using ::asio::ssl::verify_peer; |
| 175 | +using ::asio::ssl::verify_fail_if_no_peer_cert; |
| 176 | +using ::asio::ssl::rfc2818_verification; |
| 177 | +using ::asio::ssl::host_name_verification; |
| 178 | +} |
| 179 | +#endif |
| 180 | +``` |
| 181 | + |
| 182 | +## 5. Consumer test |
| 183 | + |
| 184 | +New test file: `tests/examples/asio-module/tests/ssl.cpp` |
| 185 | + |
| 186 | +Pattern: TCP echo over TLS — a `stream<ip::tcp::socket>` wrapped around a |
| 187 | +plain socket. PEM cert+key embedded as C++ string literals, loaded via |
| 188 | +`context::use_certificate(const_buffer, pem)` + `context::use_private_key(const_buffer, pem)`. |
| 189 | + |
| 190 | +The test is feature-gated: only compiled when the `ssl` feature is active. |
| 191 | +The existing `mcpp.toml` in `tests/examples/asio-module/` adds the `ssl` |
| 192 | +feature to its dependency declaration. |
| 193 | + |
| 194 | +## 6. Validation contract |
| 195 | + |
| 196 | +Before PR: |
| 197 | +1. `compat.openssl` descriptor passes local Lua lint |
| 198 | +2. `compat.openssl` builds from source on macOS (GLOBAL mirror) |
| 199 | +3. `chriskohlhoff.asio` with `ssl` feature resolves and builds |
| 200 | +4. `mcpp test -p asio-module` passes all existing tests |
| 201 | +5. New `ssl.cpp` test passes (TLS echo) |
| 202 | +6. `git diff --check` clean |
| 203 | + |
| 204 | +## 7. Implementation order |
| 205 | + |
| 206 | +| Step | Description | |
| 207 | +|---|---| |
| 208 | +| 1 | Create `pkgs/c/compat.openssl.lua` | |
| 209 | +| 2 | Local build test of `compat.openssl` | |
| 210 | +| 3 | Modify `pkgs/c/chriskohlhoff.asio.lua` — add ssl feature | |
| 211 | +| 4 | Add `tests/examples/asio-module/tests/ssl.cpp` | |
| 212 | +| 5 | Update `tests/examples/asio-module/mcpp.toml` | |
| 213 | +| 6 | Full `mcpp test -p asio-module` verification | |
| 214 | + |
| 215 | +## 8. Future: TLS capability |
| 216 | + |
| 217 | +When a second TLS provider exists (e.g., `compat.wolfssl`), extract an abstract |
| 218 | +`tls` capability following the `blas` pattern: |
| 219 | + |
| 220 | +```lua |
| 221 | +-- compat.openssl |
| 222 | +provides = { "tls" } |
| 223 | + |
| 224 | +-- chriskohlhoff.asio ssl feature |
| 225 | +["ssl"] = { requires = { "tls" }, deps = { ... } } |
| 226 | +``` |
| 227 | + |
| 228 | +Consumers select via `[capabilities] tls = "compat.openssl"`. Not in scope now. |
0 commit comments