/// @file dpf/net/security.hpp /// @brief What each link encrypts and whom it authenticates. /// @details Party links run TLS 1.3 on every socket edge unless `encrypt` is /// off. A party with no `self` key uses a fresh key for this /// process, so peers can encrypt to it but cannot authenticate it. A /// party authenticates exactly the peers whose keys it holds in /// `trusted`; a peer without an entry is accepted unauthenticated and /// the link logs that. Client links: the server always presents a /// certificate and the client verifies it unless `verify` is off, /// against a pinned key, a CA chain plus host name, or, when neither /// is configured, the built-in development certificate (public, and /// logged as providing no security). #ifndef LIBDPF_INCLUDE_DPF_NET_SECURITY_HPP__ #define LIBDPF_INCLUDE_DPF_NET_SECURITY_HPP__ #include #include #include #include #include #include #include "dpf/net/identity.hpp" namespace dpf { namespace net { /// @brief How one link was secured, for logs and callers. struct link_security { bool encrypted = false; std::string protocol; ///< e.g. `TLSv1.3` std::string cipher; ///< e.g. `TLS_AES_128_GCM_SHA256` std::optional peer_key; /// How this side authenticated the peer: `key` (a key it holds), `ca` /// (CA chain and name), `development`, or `none`. std::string peer_auth = "none"; /// Whether the peer reported that it authenticated this side. bool peer_verified_us = false; }; /// @brief The dealer's id in handshakes and trust tables. inline constexpr std::uint32_t dealer_id = 0xfffffffeu; /// @brief Party-to-party (and dealer) links. struct peer_security { /// TLS 1.3 on socket links; off leaves them plaintext. bool encrypt = true; /// This party's key; empty means a fresh key for this process. std::shared_ptr self; /// Keys this party checks, by party id (`party_session::k_dealer_id` for /// the dealer). std::map trusted; const public_key * trusted_key(std::uint32_t party) const { const auto it = trusted.find(party); return it == trusted.end() ? nullptr : &it->second; } }; /// @brief What a client accepts from a server. struct client_security { /// Off accepts any certificate (logged as an error on every connect). bool verify = true; /// Accept a server presenting one of these raw keys. std::vector pins; /// PEM bundle for CA-issued server certificates; `system` uses OpenSSL's /// default trust store. std::string ca_file; /// Name the CA-issued certificate must carry (default: the host dialed). std::string server_name; /// Optional client key, presented to servers that check clients. std::shared_ptr self; bool configured() const noexcept { return !pins.empty() || !ca_file.empty(); } }; /// @brief What a server presents to clients. struct server_security { /// PEM certificate chain and its private key (CA-issued certificates). std::string cert_file; std::string key_file; /// Raw-key identity when no PEM files are set; with neither, the server /// presents the development certificate. std::shared_ptr self; /// Client keys this server checks; a client without a matching key is /// accepted unauthenticated and logged. std::vector client_pins; }; } // namespace net } // namespace dpf #endif // LIBDPF_INCLUDE_DPF_NET_SECURITY_HPP__