Introduction
This class library may be used for secure, authenticated network communication over TCP. The main three classes are Dwm::Credence::Peer, Dwm::Credence::KeyStash and Dwm::Credence::KnownKeys. Utilizing just these three classes, it is relatively easy to create secure TCP applications.
The library depends on libsodium, boost::asio and libDwm.
Since I'm using libsodium, I'm using XChaCha20Poly1305 for encryption. User and server authentication uses signatures produced and validated with Ed25519 keys.
No passwords are used, only key files (which aren't password protected). This is intentional since my main usage is in applications that are not launched interactively. I may later add password protected keys.
History
This library came about when I needed a replacement for Crypto++ (needed by libDwmAuth). In my own applications, libDwmAuth will be replaced by libDwmCredence. The new name is a hint that it's not the same as libDwmAuth under the hood, and allows me to migrate my applications as I have time.
Platforms
I only maintain support for 4 platforms: FreeBSD, macOS, desktop linux and Raspbian (now Raspberry Pi OS). FreeBSD is my operating system of choice for servers and macOS is my operating system of choice for desktops and laptops. I have several Raspberry Pis I utilize for various tasks, and Ubuntu VMs and Ubuntu workstations.
Examples
Assumptions
The examples assume that you have created your key files by running credence keygen
, and that they are present in the default directory (~/.credence
). They also assume that you have your own public key (from ~/.credence/id_ed25519.pub
) in the default ~/.credence/known_keys
file.
Simple echo
Simple echo client
3int main(
int argc,
char *argv[])
11 cerr <<
"Usage: " << argv[0] <<
" host port\n";
16 if (peer.
Connect(argv[1], std::stoul(argv[2]))) {
22 while (std::getline(cin, msg)) {
23 if (! peer.
Send(msg)) { rc = 1;
break; }
24 if (! peer.
Receive(msg)) { rc = 1;
break; }
26 if (msg ==
"Goodbye") {
break; }
30 cerr <<
"Failed to authenticate to " << argv[1]
31 <<
" port " << argv[2] <<
'\n';
35 cerr <<
"Failed to connect to " << argv[1]
36 <<
" port " << argv[2] <<
'\n';
Dwm::Credence::Peer class declaration.
Encapsulates storage of an Ed25519KeyPair in a filesystem.
Definition: DwmCredenceKeyStash.hh:56
Encapsulates the storage of a set of known public keys.
Definition: DwmCredenceKnownKeys.hh:60
Encapsulate a network peer.
Definition: DwmCredencePeer.hh:67
bool Send(const T &msg)
Sends the given msg to the peer.
Definition: DwmCredencePeer.hh:127
bool Connect(const std::string &host, uint16_t port)
Used by a client to connect to host at the given port.
bool Receive(T &msg)
Receives the given msg from the peer.
Definition: DwmCredencePeer.hh:159
bool Authenticate(const KeyStash &keyStash, const KnownKeys &knownKeys)
Using the given keyStash and knownKeys, authenticate our identity to the peer and verify the peer's i...
Simple echo server
Note that this server only accepts one client, and will exit after communicating with the client. In other words, it's not typical, but instead is a minimal illustration.
4using namespace boost::asio;
7static bool AcceptPeer(io_context & ioContext,
const string & addr,
11 boost::system::error_code ec;
12 ip::tcp::endpoint endPoint(ip::address::from_string(addr),
14 ip::tcp::acceptor acc(ioContext, endPoint);
15 boost::asio::ip::tcp::acceptor::reuse_address option(
true);
16 acc.set_option(option, ec);
18 acc.non_blocking(
false, ec);
20 ip::tcp::socket sock(ioContext);
21 ip::tcp::endpoint client;
22 acc.accept(sock, client, ec);
24 sock.native_non_blocking(
false, ec);
25 rc = peer.
Accept(std::move(sock));
27 else { cerr <<
"accept() failed\n"; }
29 else { cerr <<
"Failed to set socket as blocking\n"; }
31 else { cerr <<
"Failed to set reuse_addr option\n"; }
37int main(
int argc,
char *argv[])
40 cerr <<
"Usage: " << argv[0] <<
" addr port\n";
47 if (AcceptPeer(ioContext, argv[1], argv[2], peer)) {
52 while (msg !=
"Goodbye") {
53 if (! peer.
Receive(msg)) {
break; }
54 if (! peer.
Send(msg)) {
break; }
60 cerr <<
"Authentication failed\n";
64 cerr <<
"AcceptPeer failed\n";
bool Accept(boost::asio::ip::tcp::socket &&s)
Used by a server to accept a new connection.