libdpf/include/dpf/net/security.hpp
Ryan Henry 0d22946a0e Checkpoint the party/runtime stack before share-program and malicious-mode work.
Ship the TLS mesh, composer, Beaver/Yao/leaf MPC, prep/online paths, apps, and docs so the tree is pushable before elevating share_expr, security_mode, and prep resume.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-28 05:59:19 -06:00

100 lines
3.6 KiB
C++

/// @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 <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#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<public_key> 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<const identity> self;
/// Keys this party checks, by party id (`party_session::k_dealer_id` for
/// the dealer).
std::map<std::uint32_t, public_key> 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<public_key> 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<const identity> 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<const identity> self;
/// Client keys this server checks; a client without a matching key is
/// accepted unauthenticated and logged.
std::vector<public_key> client_pins;
};
} // namespace net
} // namespace dpf
#endif // LIBDPF_INCLUDE_DPF_NET_SECURITY_HPP__