annotate protocol.c @ 0:17cb7cdbb8be draft default tip

Working prototype
author Ivo Smits <Ivo@UCIS.nl>
date Fri, 07 Feb 2014 23:28:39 +0100
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1 /* Copyright 2014 Ivo Smits <Ivo@UCIS.nl>. All rights reserved.
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
2 Redistribution and use in source and binary forms, with or without modification, are
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
3 permitted provided that the following conditions are met:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
4
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
5 1. Redistributions of source code must retain the above copyright notice, this list of
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
6 conditions and the following disclaimer.
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
7
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
8 2. Redistributions in binary form must reproduce the above copyright notice, this list
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
9 of conditions and the following disclaimer in the documentation and/or other materials
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
10 provided with the distribution.
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
11
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
12 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
13 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
15 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
16 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
17 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
18 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
19 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
20 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
21
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
22 The views and conclusions contained in the software and documentation are those of the
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
23 authors and should not be interpreted as representing official policies, either expressed
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
24 or implied, of Ivo Smits.*/
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
25
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
26 #include <stdio.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
27 #include <stdbool.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
28 #include <unistd.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
29 #include <fcntl.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
30 #include <string.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
31 #include <sys/types.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
32 #include <sodium/crypto_box_curve25519xsalsa20poly1305.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
33 #include <sodium/crypto_scalarmult_curve25519.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
34 #include <sodium/crypto_hash_sha512.h>
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
35 #include "include.h"
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
36
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
37 static unsigned char workbuffer[2000];
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
38
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
39 static int devurandomfd = -1;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
40 static bool randombytes(unsigned char* buffer, int len) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
41 if (devurandomfd == -1) devurandomfd = open("/dev/urandom", O_RDONLY);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
42 if (devurandomfd == -1) return errorexit("could not open /dev/urandom");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
43 while (len > 0) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
44 int got = read(devurandomfd, buffer, len);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
45 if (got < 0) return errorexitp("could not read from /dev/urandom");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
46 buffer += got;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
47 len -= got;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
48 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
49 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
50 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
51
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
52 static void dumphex(char* lbl, unsigned char* buffer, int len) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
53 fprintf(stderr, "%s: ", lbl);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
54 for (; len > 0; len--, buffer++) fprintf(stderr, "%02x", *buffer);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
55 fprintf(stderr, "\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
56 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
57
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
58 static void nonceinc(unsigned char* nonce) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
59 int i;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
60 for (i = 23; i >= 0 && (++nonce[i] == 0); i--);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
61 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
62
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
63 static bool send_all(int socket, unsigned char* buffer, int length) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
64 while (length) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
65 int sent = write(socket, buffer, length);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
66 if (sent <= 0) return errorexitp("socket write failed");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
67 buffer += sent;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
68 length -= sent;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
69 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
70 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
71 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
72 static bool send_packet(connection_context* context, unsigned char* buffer, int length, bool controlflag) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
73 fprintf(stderr, "Send packet (size=%d type=%d control=%d encrypt=%d)\n", length, buffer[0], controlflag, context->send_encrypted);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
74 if (context->send_encrypted) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
75 if (length + 32 > sizeof(workbuffer)) return errorexit("packet too big for encryption buffer");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
76 memmove(workbuffer + 32, buffer, length);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
77 memset(workbuffer, 0, 32);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
78 crypto_box_curve25519xsalsa20poly1305_afternm(workbuffer, workbuffer, length + 32, context->send_nonce, context->send_key);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
79 nonceinc(context->send_nonce);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
80 buffer = workbuffer + 16;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
81 length += 16;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
82 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
83 if (length > 0x7FFF) return errorexit("packet too big for framing");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
84 unsigned char lbuf[2];
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
85 length = (length & 0x7FFF) | (controlflag ? 0x8000 : 0);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
86 lbuf[0] = (length >> 8) & 0xFF;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
87 lbuf[1] = length & 0xFF;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
88 if (!send_all(context->send_socket, lbuf, 2)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
89 if (!send_all(context->send_socket, buffer, length & 0x7FFF)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
90 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
91 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
92 static bool send_command_ack(connection_context* context, unsigned char code) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
93 workbuffer[0] = code;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
94 return send_packet(context, workbuffer, 1, true);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
95 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
96
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
97
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
98 static bool check_tunnel_ready(connection_context* context) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
99 if (context->local_tunnelready) return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
100 if (context->require_key_authentication) return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
101 if (context->require_password_authentication) return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
102 if (context->require_encryption && !context->recv_encrypted) return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
103 if (!send_command_ack(context, 0)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
104 context->local_tunnelready = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
105 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
106 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
107
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
108 static bool process_network_packet(connection_context* context, unsigned char* buffer, int pktlen, int controlflag);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
109 bool connection_read(connection_context* context) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
110 int got = read(context->recv_socket, context->recv_buffer + context->recv_offset, sizeof(context->recv_buffer) - context->recv_offset);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
111 if (got < 0) return errorexitp("read failure on socket");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
112 context->recv_offset += got;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
113 while (context->recv_offset >= 2) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
114 int pktlen = ((unsigned char)context->recv_buffer[0] << 8) | (unsigned char)context->recv_buffer[1];
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
115 int controlflag = pktlen & 0x8000;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
116 pktlen &= 0x7FFF;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
117 if (pktlen > sizeof(context->recv_buffer)) return errorexit("received packet too big for buffer");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
118 if (context->recv_offset < pktlen + 2) break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
119 if (!process_network_packet(context, context->recv_buffer + 2, pktlen, !!controlflag)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
120 context->recv_offset -= 2 + pktlen;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
121 memmove(context->recv_buffer, context->recv_buffer + 2 + pktlen, context->recv_offset);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
122 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
123 if (!context->local_tunnelready) if (!check_tunnel_ready(context)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
124 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
125 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
126 static bool send_start_crypt_auth(connection_context* context, const unsigned char* key) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
127 if (!context->key_updated) return context->startcryptauthsent && !key;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
128 if (key) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
129 memcpy(context->local_seckey_next, key, 32);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
130 } else {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
131 randombytes(context->local_seckey_next, 32);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
132 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
133 workbuffer[0] = 1;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
134 crypto_scalarmult_curve25519_base(workbuffer + 1, context->local_seckey_next);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
135 memcpy(workbuffer + 1 + 32, context->nonce_next, 24);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
136 if (!send_packet(context, workbuffer, 1 + 32 + 24, true)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
137 crypto_box_curve25519xsalsa20poly1305_beforenm(context->send_key, context->remote_pubkey, context->local_seckey_next);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
138 memcpy(context->send_nonce + 12, context->nonce_next + 12, 12);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
139 context->send_encrypted = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
140 context->startcryptauthsent = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
141 context->key_updated = false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
142 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
143 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
144 static bool begin_update_key(connection_context* context, char* seckey) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
145 if (!context->key_updated) return !seckey;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
146 if (seckey) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
147 memcpy(context->local_seckey_next, seckey, 32);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
148 } else {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
149 randombytes(context->local_seckey_next, 32);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
150 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
151 workbuffer[0] = 3;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
152 crypto_scalarmult_curve25519_base(workbuffer + 1, context->local_seckey_next);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
153 if (!send_packet(context, workbuffer, 1 + 32, true)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
154 crypto_box_curve25519xsalsa20poly1305_beforenm(context->send_key, context->remote_pubkey, context->local_seckey_next);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
155 context->send_encrypted = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
156 context->key_updated = false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
157 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
158 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
159 static bool password_hash(unsigned char* output, unsigned char* salt, int saltlength, char* password) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
160 int pwlen = password ? strlen(password) : 0;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
161 if (saltlength + pwlen > sizeof(workbuffer)) return errorexit("password and salt too big for buffer");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
162 if (saltlength) memmove(workbuffer, salt, saltlength);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
163 if (pwlen) memcpy(workbuffer + saltlength, password, pwlen);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
164 crypto_hash_sha512(output, workbuffer, saltlength + pwlen);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
165 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
166 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
167 static bool process_network_packet(connection_context* context, unsigned char* buffer, int pktlen, int controlflag) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
168 if (context->recv_encrypted) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
169 if (pktlen + 16 > sizeof(workbuffer)) return errorexit("received packet too big for decrypt buffer");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
170 memmove(workbuffer + 16, buffer, pktlen);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
171 memset(workbuffer, 0, 16);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
172 if (crypto_box_curve25519xsalsa20poly1305_open_afternm(workbuffer, workbuffer, pktlen + 16, context->recv_nonce, context->recv_key)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
173 nonceinc(context->recv_nonce);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
174 buffer = workbuffer + 32;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
175 pktlen -= 16;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
176 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
177 if (controlflag) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
178 fprintf(stderr, "Received packet (size=%d type=%d control=%d encrypt=%d)\n", pktlen, buffer[0], controlflag, context->recv_encrypted);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
179 if (pktlen < 1) return errorexit("zero length control packet");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
180 switch (buffer[0]) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
181 case 0:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
182 fprintf(stderr, "Control: tunnel ready\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
183 context->remote_tunnelready = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
184 break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
185 case 1:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
186 fprintf(stderr, "Control: crypto auth req\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
187 if (pktlen < 1 + 32 + 24) return errorexit("short control packet 1");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
188 if (context->require_key_authentication) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
189 if (memcmp(buffer + 1, context->remote_pubkey_expect, 32)) return errorexit("incorrect crypto auth key");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
190 context->require_key_authentication = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
191 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
192 if (!context->startcryptauthsent) send_start_crypt_auth(context, NULL);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
193 if (!send_command_ack(context, 2)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
194 memcpy(context->remote_pubkey, buffer + 1, 32);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
195 memcpy(context->send_nonce, buffer + 1 + 32, 12);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
196 memcpy(context->recv_nonce + 12, buffer + 1 + 32 + 12, 12);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
197 crypto_box_curve25519xsalsa20poly1305_beforenm(context->recv_key, context->remote_pubkey, context->local_seckey_current);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
198 crypto_box_curve25519xsalsa20poly1305_beforenm(context->send_key, context->remote_pubkey, context->local_seckey_next);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
199 context->recv_encrypted = context->send_encrypted = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
200 break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
201 case 2:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
202 fprintf(stderr, "Control: crypto auth ack\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
203 memcpy(context->local_seckey_current, context->local_seckey_next, 32);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
204 memcpy(context->recv_nonce, context->nonce_next, 12);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
205 crypto_box_curve25519xsalsa20poly1305_beforenm(context->recv_key, context->remote_pubkey, context->local_seckey_current);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
206 context->recv_encrypted = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
207 context->key_updated = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
208 begin_update_key(context, NULL);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
209 break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
210 case 3:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
211 fprintf(stderr, "Control: key update req\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
212 if (pktlen < 1 + 32) return errorexit("short control packet 3");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
213 if (!send_command_ack(context, 4)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
214 memcpy(context->remote_pubkey, buffer + 1, 32);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
215 crypto_box_curve25519xsalsa20poly1305_beforenm(context->recv_key, context->remote_pubkey, context->local_seckey_current);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
216 crypto_box_curve25519xsalsa20poly1305_beforenm(context->send_key, context->remote_pubkey, context->local_seckey_next);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
217 context->recv_encrypted = context->send_encrypted = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
218 break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
219 case 4:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
220 fprintf(stderr, "Control: key update ack\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
221 memcpy(context->local_seckey_current, context->local_seckey_next, 32);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
222 crypto_box_curve25519xsalsa20poly1305_beforenm(context->recv_key, context->remote_pubkey, context->local_seckey_current);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
223 context->recv_encrypted = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
224 context->key_updated = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
225 break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
226 case 5:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
227 fprintf(stderr, "Control: password authentication req\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
228 unsigned char pwhash[64];
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
229 if (!password_hash(pwhash, buffer + 1, pktlen - 1, context->password)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
230 workbuffer[0] = 6;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
231 memcpy(workbuffer + 1, pwhash, 64);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
232 if (!send_packet(context, workbuffer, 1 + 64, true)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
233 break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
234 case 6:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
235 fprintf(stderr, "Control: password authentication ack\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
236 if (pktlen < 1 + 64) return errorexit("short control packet 6");;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
237 char pwhashcheck[64];
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
238 memcpy(pwhashcheck, buffer + 1, 64);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
239 if (!password_hash(pwhash, context->nonce_next, 12, context->password)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
240 if (memcmp(pwhash, pwhashcheck, 64)) return errorexit("incorrect password auth");;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
241 context->require_password_authentication = false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
242 break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
243 case 7:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
244 fprintf(stderr, "Control: disable encryption req\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
245 context->recv_encrypted = context->send_encrypted = false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
246 if (!send_command_ack(context, 8)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
247 break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
248 case 8:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
249 fprintf(stderr, "Control: disable encryption ack\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
250 context->recv_encrypted = false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
251 break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
252 case 9:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
253 fprintf(stderr, "Control: echo req\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
254 if (pktlen > sizeof(workbuffer)) return errorexit("echo request too big");;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
255 memmove(workbuffer, buffer, pktlen);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
256 workbuffer[0] = 10;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
257 if (!send_packet(context, workbuffer, pktlen, true)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
258 break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
259 case 10:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
260 fprintf(stderr, "Control: echo resp\n");
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
261 context->pong = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
262 break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
263 case 13:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
264 if (!context->local_tunnelready || !context->remote_tunnelready) return errorexit("received data packet while tunnel not ready");;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
265 if (context->tunnel && !tunnel_write_data(context->tunnel, buffer + 1, pktlen - 1)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
266 break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
267 case 11:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
268 case 12:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
269 case 17:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
270 case 81:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
271 break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
272 default:
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
273 fprintf(stderr, "Unknown control type %d\n", buffer[0]);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
274 break;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
275 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
276 } else {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
277 if (!context->local_tunnelready || !context->remote_tunnelready) return errorexit("received data packet while tunnel not ready");;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
278 fprintf(stderr, "Tunnel data %d\n", pktlen);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
279 if (context->tunnel && !tunnel_write_data(context->tunnel, buffer, pktlen)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
280 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
281 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
282 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
283
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
284 bool connection_ping(connection_context* context) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
285 if (!context->pong) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
286 context->pong = false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
287 send_command_ack(context, 9);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
288 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
289 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
290
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
291 bool connection_init(connection_context* context) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
292 memset(context, 0, sizeof(connection_context));
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
293 char localpubkey[32];
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
294 crypto_scalarmult_curve25519_base(context->remote_pubkey, context->local_seckey_current);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
295 randombytes(context->nonce_next, 24);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
296 context->key_updated = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
297 context->pong = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
298 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
299 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
300 bool connection_init_socket(connection_context* context, const int recvsocket, const int sendsocket) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
301 context->recv_socket = recvsocket;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
302 context->send_socket = sendsocket;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
303 if (!send_packet(context, (unsigned char*)"QUICKTUN", 8, true)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
304 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
305 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
306 bool connection_init_encryption(connection_context* context, const unsigned char* localseckey, const unsigned char* remotepubkey) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
307 if (remotepubkey) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
308 memcpy(context->remote_pubkey_expect, remotepubkey, 32);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
309 context->require_key_authentication = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
310 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
311 context->require_encryption = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
312 if (!send_start_crypt_auth(context, localseckey)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
313 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
314 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
315 bool connection_init_passwordauth(connection_context* context, char* password) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
316 context->password = password;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
317 context->require_password_authentication = true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
318 workbuffer[0] = 5;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
319 memcpy(workbuffer + 1, context->nonce_next, 12);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
320 if (!send_packet(context, workbuffer, 1 + 12, true)) return false;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
321 return true;
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
322 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
323
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
324 bool connection_write_data(connection_context* context, unsigned char* buffer, int len) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
325 return send_packet(context, buffer, len, false);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
326 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
327
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
328 bool connection_init_done(connection_context* context) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
329 return check_tunnel_ready(context);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
330 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
331
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
332 bool connection_update_key(connection_context* context) {
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
333 return begin_update_key(context, NULL);
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
334 }
17cb7cdbb8be Working prototype
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
335