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"