tls

tls.git
git clone git://git.lenczewski.org/tls.git
Log | Files | Refs

test-server.c (2812B)


      1 #define _GNU_SOURCE 1
      2 
      3 #include "tls.h"
      4 
      5 #include "common.h"
      6 
      7 int
      8 main(int argc, char **argv)
      9 {
     10 	if (argc < 3) {
     11 		fprintf(stderr, "Usage: %s <host> <port>\n", argv[0]);
     12 		exit(EXIT_FAILURE);
     13 	}
     14 
     15 	char *host = argv[1], *port = argv[2];
     16 
     17 	int serv = get_server_socket(host, port, SOCK_STREAM, IPPROTO_TCP);
     18 	if (serv < 0) {
     19 		fprintf(stderr, "Failed to listen on %s:%s\n", host, port);
     20 		exit(EXIT_FAILURE);
     21 	}
     22 
     23 	// get client socket
     24 	int sock = accept(serv);
     25 
     26 	// plaintext buffer
     27 	char buf[4096];
     28 	size_t buf_cap = sizeof buf, buf_cur = 0, buf_len = 0;
     29 
     30 	// ciphertext buffer
     31 	char tlsbuf[TLS_RECORD_MAX_SIZE];
     32 	size_t tlsbuf_cap = sizeof tlsbuf, tlsbuf_len = 0;
     33 
     34 	// setup client tls session state
     35 	struct tls_session session;
     36 	tls_session_init(&session, TLS_VERSION_1_3, tlsbuf, sizeof tlsbuf);
     37 
     38 	char server_privkey[32], server_pubkey[32];
     39 	// TODO: generate keys using x25519
     40 
     41 	tls_session_set_keys(&session, TLS_KEX_X25519,
     42 			     server_privkey, sizeof server_privkey,
     43 			     server_pubkey, sizeof server_pubkey);
     44 
     45 	char server_certificate[8192];
     46 	// TODO: generate certificate
     47 	tls_session_set_cert(&session,
     48 			     server_certificate, sizeof server_certificate);
     49 
     50 	// start client tls handshake
     51 	tls_session_server_handshake(&session);
     52 
     53 	int run = 1;
     54 	while (run) {
     55 		enum tls_step step = tls_session_step(&session);
     56 
     57 		switch (step) {
     58 		case TLS_STEP_WANT_RECV: { // need to fetch data from remote
     59 			size_t cap;
     60 			void *tlsbuf = tls_session_recv(&session, &cap);
     61 
     62 			int res;
     63 			if ((res = recv(sock, tlsbuf, cap, 0)) < 0)
     64 				__builtin_trap();
     65 
     66 			tls_session_recv_commit(&session, res);
     67 		} break;
     68 
     69 		case TLS_STEP_WANT_SEND: { // need to flush data to remote
     70 			size_t len;
     71 			void *tlsbuf = tls_session_send(&session, &len);
     72 			if (sendall(sock, tlsbuf, len) < 0)
     73 				__builtin_trap();
     74 
     75 			tls_session_send_commit(&session, &len);
     76 		} break;
     77 
     78 		case TLS_STEP_HANDSHAKE: { // need to progress handshake fsm
     79 			tls_session_client_handshake(&session);
     80 		} break;
     81 
     82 		case TLS_STEP_UPDATE_KEYS: { // reached key limits, need update
     83 			tls_session_update_keys();
     84 		} break;
     85 
     86 		case TLS_STEP_ALERT: { // received alert (warning or error)
     87 			__builtin_trap();
     88 		} break;
     89 
     90 		case TLS_HANDSHAKE_FINISHED: {
     91 			// TODO: how to signal to wait for a read?
     92 		} break;
     93 
     94 		case TLS_STEP_HAVE_RECORD: { // received complete tls record
     95 			tls_session_pull(&session, buf, sizeof buf, &buf_len);
     96 			printf("read msg: %.*s\n", (int) buf_len, buf);
     97 		} break;
     98 
     99 		case TLS_STEP_WANT_RECORD: { // want data to fill tls record
    100 			buf_cur += tls_session_push(&session, buf, buf_len - buf_cur);
    101 			if (buf_cur == buf_cap)
    102 				tls_session_flush(&session);
    103 		} break;
    104 
    105 		case TLS_STEP_END: {
    106 			run = 0;
    107 		} break;
    108 		}
    109 	}
    110 
    111 	shutdown(sock, SHUT_RDWR);
    112 	close(sock);
    113 
    114 	close(serv);
    115 
    116 	exit(EXIT_SUCCESS);
    117 }
    118 
    119 #include "tls.c"