Details
-
New Feature
-
Status: Stalled (View Workflow)
-
Major
-
Resolution: Unresolved
Description
Problem
MariaDB cannot serve both RSA and ECDSA SSL certificates simultaneously. Web servers (httpd, nginx) and proxies (HAProxy, vsftpd) support this, but MariaDB does not. There is no workaround: a TLS-terminating proxy cannot be used because MySQL uses a STARTTLS-like in-protocol SSL upgrade, not raw TLS connections.
Root Cause
MariaDB calls SSL_CTX_use_certificate_chain_file() exactly once, loading a single certificate into the SSL_CTX. OpenSSL natively supports multiple certificates per SSL_CTX (one per key type: RSA, ECDSA, EdDSA) when SSL_CTX_use_certificate_file() / SSL_CTX_use_PrivateKey_file() are called multiple times. This is how httpd and nginx implement dual-cert support.
Design (PR #5178)
Introduce ssl-alt-cert and ssl-alt-key server options to load a second certificate:
[mysqld]
|
ssl-cert = /path/to/server-rsa.crt
|
ssl-key = /path/to/server-rsa.key
|
ssl-alt-cert = /path/to/server-ecdsa.crt
|
ssl-alt-key = /path/to/server-ecdsa.key
|
The alternate cert is loaded into the same SSL_CTX via SSL_CTX_use_certificate_file() + SSL_CTX_use_PrivateKey_file(). OpenSSL then automatically selects the correct certificate based on the cipher suite negotiated with the client:
- Client requests an ECDHE-ECDSA cipher: ECDSA cert served
- Client requests an ECDHE-RSA cipher: RSA cert served
- Client has no preference: OpenSSL chooses based on its internal preference order
Design Justifications
- Why separate ssl-alt-cert / ssl-alt-key rather than multi-value ssl-cert / ssl-key?
MariaDB's config system uses single-valued Sys_var_charptr for option strings. Supporting multiple values for the same option would require either: (a) a semicolon-separated value syntax with custom parsing, or (b) changes to the config parser to handle repeated options. Both are invasive changes. The ssl-alt-* approach adds the feature with minimal config system impact. If the community prefers the multi-value approach, it can be evolved in a follow-up.
- Why not ssl-alt-ca?
ssl-ca already accepts a CA bundle (concatenated PEM file containing multiple CA certificates). A separate alternate CA option is unnecessary.
- Why SSL_CTX_use_certificate_file() instead of SSL_CTX_use_certificate_chain_file()?
SSL_CTX_use_certificate_chain_file() loads the cert and replaces the chain for the entire SSL_CTX, which would overwrite the primary certificate's chain. For the alternate cert, we use SSL_CTX_use_certificate_file() to load only the certificate. If intermediate CA chain support is needed for the alt cert, SSL_CTX_select_current_cert() + SSL_CTX_set0_chain() or manual chain loading via SSL_CTX_add_extra_chain_cert() can be added in a follow-up.
- Only one alternate pair
OpenSSL supports up to three key types (RSA, ECDSA, EdDSA). EdDSA (Ed25519/Ed448) TLS certificates are not yet issued by any public CA and browser/client support is immature (expected ~2028-2030). Supporting one alternate cert pair covers the realistic RSA+ECDSA use case. EdDSA can be added when it becomes viable.
Validation
- Server rejects startup if only one of ssl-alt-cert / ssl-alt-key is specified (both or neither required)
- Mismatch between alt cert and alt key is detected via SSL_CTX_check_private_key()
Observability
Two status variables are added:
| Variable | Scope | Description |
|---|---|---|
| Ssl_server_cert_type | Per-session | Key type of the certificate used for this connection (RSA, ECDSA, or EdDSA) |
| Ssl_server_cert_types | Global | All certificate key types loaded in the server (e.g. "RSA, ECDSA") |
These allow administrators to verify dual-cert is active and monitor which cert type each client negotiated.
Testing
- MTR test ssl_alt_cert: generates ECDSA cert at runtime, verifies system variables, status variables, RSA/ECDSA cipher selection, default connection behavior
- Full SSL + variables test suite (28 tests): all pass, no regressions
Open Items
- Evaluate switching to multi-value ssl-cert / ssl-key per reviewer feedback
- Client/server option parity (libmariadb changes)
- Intermediate CA chain loading for alt cert
- WolfSSL / GnuTLS compatibility (#ifdef guards, have_ssl_multi_cert detection variable)