client.c (3849B)
1 #include "packet.h" 2 #include <pthread.h> 3 4 uint8_t shared_key[SHARED_KEY_SIZE]; 5 int sockfd; 6 7 /* 8 * Connect to socket server 9 */ 10 int socket_init() 11 { 12 int sockfd = socket(AF_INET, SOCK_STREAM, 0); 13 if (sockfd < 0) { 14 error(1, "Error on opening socket"); 15 } 16 17 struct hostent *server = gethostbyname(DOMAIN); 18 if (server == NULL) { 19 error(1, "No such host %s", DOMAIN); 20 } 21 22 struct sockaddr_in sv_addr; 23 memset(&sv_addr, 0, sizeof(sv_addr)); 24 sv_addr.sin_family = AF_INET; 25 sv_addr.sin_port = htons(PORT); 26 memcpy(&sv_addr.sin_addr.s_addr, server->h_addr, server->h_length); 27 28 /* free(server); */ 29 if (connect(sockfd, (struct sockaddr *) &sv_addr, sizeof(sv_addr)) < 0) { 30 error(1, "Error on connect"); 31 close(sockfd); 32 return 0; 33 } 34 printf("Connected to server at %s\n", DOMAIN); 35 return sockfd; 36 } 37 38 /* 39 * Performs key exchange with server 40 */ 41 int key_exchange(int sockfd) 42 { 43 /* Generate the client's key pair */ 44 uint8_t cl_pk[PUBLIC_KEY_SIZE], cl_sk[PRIVATE_KEY_SIZE]; 45 crypto_kx_keypair(cl_pk, cl_sk); 46 47 /* Send our public key */ 48 if (send_public_key(sockfd, cl_pk) < 0) { 49 return -1; 50 } 51 52 /* Get public key from server */ 53 uint8_t *pk; 54 if ((pk = get_public_key(sockfd)) == NULL) { 55 return -1; 56 } 57 58 /* Compute a shared key using the server's public key and our secret key */ 59 if (crypto_kx_client_session_keys(NULL, shared_key, cl_pk, cl_sk, pk) != 0) { 60 error(1, "Server public key is not acceptable"); 61 free(pk); 62 close(sockfd); 63 return -1; 64 } 65 free(pk); 66 return 0; 67 } 68 69 void *sender() 70 { 71 while (1) { 72 printf("Enter message to send to server: "); 73 fflush(stdout); 74 char line[1024]; 75 line[0] = '\0'; 76 size_t length = strlen(line); 77 while (length <= 1) { 78 fgets(line, sizeof(line), stdin); 79 length = strlen(line); 80 } 81 length -= 1; 82 line[length] = '\0'; 83 84 uint8_t nonce[NONCE_SIZE]; 85 uint8_t encrypted[length + ADDITIONAL_SIZE]; 86 unsigned long long encrypted_len; 87 88 randombytes_buf(nonce, sizeof(nonce)); 89 crypto_aead_xchacha20poly1305_ietf_encrypt(encrypted, &encrypted_len, 90 line, length, 91 NULL, 0, NULL, nonce, shared_key); 92 size_t payload_t = NONCE_SIZE + encrypted_len; 93 uint8_t encryptedwithnonce[payload_t]; 94 memcpy(encryptedwithnonce, nonce, NONCE_SIZE); 95 memcpy(encryptedwithnonce + NONCE_SIZE, encrypted, encrypted_len); 96 97 message *msg = create_packet(1, 0x10, payload_t, encryptedwithnonce); 98 if (send_packet(msg, sockfd) != ZSM_STA_SUCCESS) { 99 close(sockfd); 100 } 101 free_packet(msg); 102 } 103 close(sockfd); 104 105 } 106 107 void *receiver() 108 { 109 while (1) { 110 message servermsg; 111 if (recv_packet(&servermsg, sockfd) != ZSM_STA_SUCCESS) { 112 close(sockfd); 113 return 0; 114 } 115 free(servermsg.data); 116 } 117 return NULL; 118 } 119 120 int main() 121 { 122 if (sodium_init() < 0) { 123 error(1, "Error initializing libsodium"); 124 } 125 sockfd = socket_init(); 126 if (key_exchange(sockfd) < 0) { 127 /* Fatal */ 128 error(1, "Error performing key exchange with server"); 129 } 130 pthread_t recv_worker, send_worker; 131 if (pthread_create(&recv_worker, NULL, sender, NULL) != 0) { 132 fprintf(stderr, "Error creating incoming thread\n"); 133 return 1; 134 } 135 136 if (pthread_create(&send_worker, NULL, receiver, NULL) != 0) { 137 fprintf(stderr, "Error creating outgoing thread\n"); 138 return 1; 139 } 140 141 // Join threads 142 pthread_join(recv_worker, NULL); 143 pthread_join(send_worker, NULL); 144 145 return 0; 146 } 147