Trivial TLS server

David Howells
2023-03-31T16:33:10Z

Here's a trivial TLS server that can be used to test this.

David
---
/*
* TLS-over-TCP sink server
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <linux/tls.h>

#define OSERROR(X, Y) do { if ((long)(X) == -1) { perror(Y); exit(1); } } while(0)

static unsigned char buffer[512 * 1024] __attribute__((aligned(4096)));

static void set_tls(int sock)
{
struct tls12_crypto_info_aes_gcm_128 crypto_info;

crypto_info.info.version = TLS_1_2_VERSION;
crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128;
memset(crypto_info.iv, 0, TLS_CIPHER_AES_GCM_128_IV_SIZE);
memset(crypto_info.rec_seq, 0, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
memset(crypto_info.key, 0, TLS_CIPHER_AES_GCM_128_KEY_SIZE);
memset(crypto_info.salt, 0, TLS_CIPHER_AES_GCM_128_SALT_SIZE);

OSERROR(setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls")),
"TCP_ULP");
OSERROR(setsockopt(sock, SOL_TLS, TLS_TX, &crypto_info, sizeof(crypto_info)),
"TLS_TX");
OSERROR(setsockopt(sock, SOL_TLS, TLS_RX, &crypto_info, sizeof(crypto_info)),
"TLS_RX");
}

int main(int argc, char *argv[])
{
struct sockaddr_in sin = { .sin_family = AF_INET, .sin_port = htons(5556) };
int sfd, afd;

sfd = socket(AF_INET, SOCK_STREAM, 0);
OSERROR(sfd, "socket");
OSERROR(bind(sfd, (struct sockaddr *)&sin, sizeof(sin)), "bind");
OSERROR(listen(sfd, 1), "listen");

for (;;) {
afd = accept(sfd, NULL, NULL);
if (afd != -1) {
set_tls(afd);
while (read(afd, buffer, sizeof(buffer)) > 0) {}
close(afd);
}
}
}