From 6dee1987bb8d920e3dfe1f6d8a0fcb139443051f Mon Sep 17 00:00:00 2001 From: Valmo Trindade <70849974+valmojr@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:06:49 -0300 Subject: [PATCH] Document TAK authentication flows --- docs/development/authentication-flows.md | 188 +++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 docs/development/authentication-flows.md diff --git a/docs/development/authentication-flows.md b/docs/development/authentication-flows.md new file mode 100644 index 0000000..1630c82 --- /dev/null +++ b/docs/development/authentication-flows.md @@ -0,0 +1,188 @@ +# TAK authentication flows + +This document describes the authentication and transport flows implemented by the ArmaTAK Rust extension. It is development documentation, not end-user documentation. + +## Security model + +ArmaTAK currently exposes three TCP connection modes: + +| Mode | ArmaTAK entry point | Authentication | Transport protection | Intended use | +| --- | --- | --- | --- | --- | +| Plain TCP | `tcp_socket.start` | None | None | Local development or explicitly trusted isolated networks only | +| Manual mTLS | `tcp_socket.start_mtls` | Client X.509 certificate | TLS with server certificate validation | Production-compatible secure connection | +| Credential enrollment followed by mTLS | `tcp_socket.start_enroll_mtls` | HTTP Basic credentials during enrollment, then client X.509 certificate | Enrollment HTTPS currently skips certificate validation; the resulting TAK stream uses validated mTLS | Transitional/bootstrap flow; do not treat the enrollment phase as secure until server verification is enabled | + +The official TAK Server example enables a TLS input on port `8089`. Its plaintext TCP/streaming examples are anonymous and are shown on ports `8087` and `8088`. ArmaTAK must not infer security from a port number; the selected connection mode controls the client-side security properties. + +## Insecure flow: plain TCP + +The plain flow is deliberately simple: + +```text +Arma/SQF + | + | tcp_socket.start("host:port") + v +ConnectionConfig::Plain + | + v +TCP connect + | + | unencrypted CoT bytes + v +TAK Server plaintext/anonymous input +``` + +`ConnectionConfig::Plain` resolves the supplied address and opens a normal `TcpStream`. No TLS handshake occurs, there is no server identity verification, and no client identity is established by ArmaTAK. + +Consequences: + +- CoT payloads can be observed or modified by an on-path attacker. +- ArmaTAK cannot prove that it connected to the intended TAK Server. +- The server cannot authenticate ArmaTAK by certificate. +- Plain TCP must never be the production default. + +The official TAK Server `CoreConfig.example.xml` keeps anonymous TCP inputs commented out and enables the TLS input instead. Use plain TCP only when a developer intentionally configures a corresponding non-TLS server input. + +## Secure flow: manual mTLS + +The manual mTLS flow uses pre-provisioned certificate material: + +```text +Arma/SQF + | + | tcp_socket.start_mtls( + | address, + | server_name, + | ca_cert_path, + | client_cert_path, + | client_key_path + | ) + v +ConnectionConfig::Mtls + | + +--> load trusted CA certificate(s) + +--> load client certificate chain + +--> load client private key + | + v +rustls client configuration + | + +--> validate server certificate chain + +--> validate TLS server name + +--> present client certificate + v +Authenticated mTLS TAK stream +``` + +The CA file is loaded into a dedicated `rustls::RootCertStore`; the client certificate and private key are used for client authentication. When `server_name` is empty, ArmaTAK derives a name from the target address. A non-empty `server_name` should be preferred when DNS and certificate names are known. + +This is the preferred production flow when certificate provisioning is handled outside ArmaTAK. + +## Enrollment flow: credentials to client certificate + +TAK enrollment converts a username/password bootstrap credential into a short- or medium-lived client certificate, then reconnects using mTLS. + +### Protocol contract + +ArmaTAK follows the contract visible in the official TAK Server and ATAK implementations: + +1. `GET https://HOST:ENROLL_PORT/Marti/api/tls/config` +2. Authenticate the request with HTTP Basic credentials. +3. Read `serverPort` and `enrollPath` from the TAK certificate configuration. If the fields are absent, ArmaTAK currently falls back to `8089` and `/Marti/api/tls/signClient/v2`. +4. Generate a local RSA key pair and PKCS#10 CSR. The private key never needs to be sent to the server. +5. `POST https://HOST:ENROLL_PORT{enrollPath}?clientUid=CLIENT_UID` +6. Authenticate the signing request with HTTP Basic credentials, send the CSR as `application/pkcs10`, and request JSON. +7. Parse `signedCert` and `ca0` from the enrollment response. +8. Build an in-memory client identity from the returned certificate plus the locally generated private key. +9. Connect to `HOST:serverPort` with mTLS and validate the TAK streaming server against the returned CA. + +The official TAK Server exposes `/tls/config`, `/tls/signClient`, and `/tls/signClient/v2`. The v2 endpoint can return JSON containing `signedCert` plus `ca0`, `ca1`, and additional CA-chain entries. The current ArmaTAK implementation consumes `signedCert` and `ca0`. + +### Current ArmaTAK enrollment security caveat + +`enrollment_http_client()` currently uses `danger_accept_invalid_certs(true)`. Therefore the HTTPS bootstrap does **not** authenticate the enrollment server certificate. + +That means the current enrollment phase is vulnerable to an active man-in-the-middle attacker who can impersonate the HTTPS enrollment endpoint and receive the submitted Basic credentials. The private key remains local, but the username/password bootstrap secret is still exposed to the impersonating endpoint. + +The connection established *after* enrollment is mTLS and uses the returned CA, but that does not retroactively secure the bootstrap exchange. Consequently: + +- `start_enroll_mtls` is a transitional flow, not the preferred production-secure flow in its current form. +- `start_mtls` with a trusted CA and pre-provisioned client certificate is the secure production path today. +- A future secure enrollment implementation must validate the HTTPS server with a trusted CA, certificate pin, or equivalent authenticated trust bootstrap. +- An explicit insecure/development enrollment switch is preferable to silently disabling verification. + +The official ATAK enrollment manager exposes a `verifyHost` choice and records whether host verification is on or off. ArmaTAK should converge on the same explicit distinction. + +## Target secure enrollment design + +The intended production enrollment flow is: + +```text +username/password + | + v +HTTPS enrollment endpoint +(server certificate MUST validate) + | + +--> GET /Marti/api/tls/config + +--> generate local private key + CSR + +--> POST configured signClient endpoint + v +signed client certificate + trusted CA + | + v +mTLS TAK streaming connection + | + +--> server authenticated by CA/name + +--> client authenticated by certificate + v +CoT traffic +``` + +The development-only insecure variant should be explicit: + +```text +username/password + | + v +HTTPS enrollment endpoint +(certificate verification explicitly disabled) + | + v +WARNING / development-only path +``` + +Do not silently fall back from verified enrollment to unverified enrollment after a certificate validation failure. + +## Secret-handling requirements + +- Never include passwords, private keys, certificate payloads, or Authorization headers in logs. +- `ConnectionConfig::describe()` may include the username and client UID for diagnostics, but it must never include the password. +- Keep generated private keys in memory unless a future feature explicitly requires persistence. +- Do not commit development certificates or credentials to the repository. +- Treat enrollment credentials as bootstrap secrets and rotate/revoke them according to the TAK Server deployment policy. + +## Test contract + +Unit tests should lock down the protocol-level behavior that does not require a live TAK Server: + +- official endpoint paths and default mTLS port; +- trimming and construction of enrollment URLs; +- parsing TAK enrollment configuration with explicit values and fallback defaults; +- PEM normalization; +- absence of passwords from diagnostic descriptions; +- TLS server-name derivation and PEM parsing where deterministic; +- CoT and MAVLink pure serialization logic. + +Live certificate signing, TLS handshake behavior, socket reconnect behavior, mDNS, video processes, and Arma callback behavior belong in integration/E2E tests because they depend on operating-system or external-server state. + +## Upstream references + +The tests and protocol assumptions in this repository are based on these upstream implementations: + +- TAK Server, `CertManagerApi.java`: +- TAK Server, `CoreConfig.example.xml`: +- ATAK/CommonCommo, `enrollmentmanager.cpp`: + +Pinning the source revisions in this document keeps the development contract reproducible. When the upstream protocol changes, update both the implementation/tests and these references together.