diff options
-rw-r--r-- | build/Makefile.am | 1 | ||||
-rw-r--r-- | libtoxcore.pc.in | 2 | ||||
-rw-r--r-- | toxdns/Makefile.inc | 28 | ||||
-rw-r--r-- | toxdns/toxdns.c | 224 | ||||
-rw-r--r-- | toxdns/toxdns.h | 78 |
5 files changed, 332 insertions, 1 deletions
diff --git a/build/Makefile.am b/build/Makefile.am index aa004388..c2667d5d 100644 --- a/build/Makefile.am +++ b/build/Makefile.am | |||
@@ -5,6 +5,7 @@ noinst_bindir = $(top_builddir)/build | |||
5 | EXTRA_DIST= | 5 | EXTRA_DIST= |
6 | 6 | ||
7 | include ../toxcore/Makefile.inc | 7 | include ../toxcore/Makefile.inc |
8 | include ../toxdns/Makefile.inc | ||
8 | include ../toxav/Makefile.inc | 9 | include ../toxav/Makefile.inc |
9 | include ../other/Makefile.inc | 10 | include ../other/Makefile.inc |
10 | include ../testing/Makefile.inc | 11 | include ../testing/Makefile.inc |
diff --git a/libtoxcore.pc.in b/libtoxcore.pc.in index e05e51cd..a91a1fb7 100644 --- a/libtoxcore.pc.in +++ b/libtoxcore.pc.in | |||
@@ -7,5 +7,5 @@ Name: libtoxcore | |||
7 | Description: Tox protocol library | 7 | Description: Tox protocol library |
8 | Requires: | 8 | Requires: |
9 | Version: @PACKAGE_VERSION@ | 9 | Version: @PACKAGE_VERSION@ |
10 | Libs: @NACL_OBJECTS_PKGCONFIG@ -L${libdir} @NACL_LDFLAGS@ -ltoxcore @NACL_LIBS@ @LIBS@ @MATH_LDFLAGS@ | 10 | Libs: @NACL_OBJECTS_PKGCONFIG@ -L${libdir} @NACL_LDFLAGS@ -ltoxdns -ltoxcore @NACL_LIBS@ @LIBS@ @MATH_LDFLAGS@ |
11 | Cflags: -I${includedir} | 11 | Cflags: -I${includedir} |
diff --git a/toxdns/Makefile.inc b/toxdns/Makefile.inc new file mode 100644 index 00000000..1e66ab3f --- /dev/null +++ b/toxdns/Makefile.inc | |||
@@ -0,0 +1,28 @@ | |||
1 | lib_LTLIBRARIES += libtoxdns.la | ||
2 | |||
3 | libtoxdns_la_include_HEADERS = \ | ||
4 | ../toxdns/toxdns.h | ||
5 | |||
6 | libtoxdns_la_includedir = $(includedir)/tox | ||
7 | |||
8 | libtoxdns_la_SOURCES = ../toxdns/toxdns.h \ | ||
9 | ../toxdns/toxdns.c | ||
10 | |||
11 | libtoxdns_la_CFLAGS = -I$(top_srcdir) \ | ||
12 | -I$(top_srcdir)/toxcore \ | ||
13 | $(LIBSODIUM_CFLAGS) \ | ||
14 | $(NACL_CFLAGS) \ | ||
15 | $(PTHREAD_CFLAGS) | ||
16 | |||
17 | libtoxdns_la_LDFLAGS = $(TOXCORE_LT_LDFLAGS) \ | ||
18 | $(EXTRA_LT_LDFLAGS) \ | ||
19 | $(LIBSODIUM_LDFLAGS) \ | ||
20 | $(NACL_LDFLAGS) \ | ||
21 | $(MATH_LDFLAGS) \ | ||
22 | $(RT_LIBS) \ | ||
23 | $(WINSOCK2_LIBS) | ||
24 | |||
25 | libtoxdns_la_LIBADD = $(LIBSODIUM_LIBS) \ | ||
26 | $(NACL_OBJECTS) \ | ||
27 | $(NAC_LIBS) \ | ||
28 | $(PTHREAD_LIBS) | ||
diff --git a/toxdns/toxdns.c b/toxdns/toxdns.c new file mode 100644 index 00000000..20a4486c --- /dev/null +++ b/toxdns/toxdns.c | |||
@@ -0,0 +1,224 @@ | |||
1 | /* toxdns.c | ||
2 | * | ||
3 | * Tox secure username DNS toxid resolving functions. | ||
4 | * | ||
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | ||
6 | * | ||
7 | * This file is part of Tox. | ||
8 | * | ||
9 | * Tox is free software: you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation, either version 3 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * Tox is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifdef HAVE_CONFIG_H | ||
25 | #include "config.h" | ||
26 | #endif | ||
27 | |||
28 | #include "../toxcore/Messenger.h" | ||
29 | |||
30 | static const char base32[32] = {"abcdefghijklmnopqrstuvwxyz012345"}; | ||
31 | |||
32 | #define _encode(a, b, c) \ | ||
33 | { \ | ||
34 | uint8_t i = 0; \ | ||
35 | while(i != c) { \ | ||
36 | *a++ = base32[((b[0] >> bits) | (b[1] << (8 - bits))) & 0x1F]; \ | ||
37 | bits += 5; \ | ||
38 | if(bits >= 8) { \ | ||
39 | bits -= 8; \ | ||
40 | b++; \ | ||
41 | i++; \ | ||
42 | } \ | ||
43 | } \ | ||
44 | } \ | ||
45 | |||
46 | typedef struct { | ||
47 | uint8_t temp_pk[crypto_box_PUBLICKEYBYTES]; | ||
48 | uint8_t temp_sk[crypto_box_SECRETKEYBYTES]; | ||
49 | uint8_t server_public_key[crypto_box_PUBLICKEYBYTES]; | ||
50 | uint8_t shared_key[crypto_box_KEYBYTES]; | ||
51 | uint32_t nonce; | ||
52 | uint32_t nonce_start; | ||
53 | } DNS_Object; | ||
54 | |||
55 | static void dns_new_temp_keys(DNS_Object *d) | ||
56 | { | ||
57 | d->nonce = d->nonce_start = random_int(); | ||
58 | crypto_box_keypair(d->temp_pk, d->temp_sk); | ||
59 | encrypt_precompute(d->server_public_key, d->temp_sk, d->shared_key); | ||
60 | } | ||
61 | |||
62 | /* Create a new tox_dns3 object for server with server_public_key. | ||
63 | * | ||
64 | * return Null on failure. | ||
65 | * return pointer object on success. | ||
66 | */ | ||
67 | void *tox_dns3_new(uint8_t *server_public_key) | ||
68 | { | ||
69 | DNS_Object *d = malloc(sizeof(DNS_Object)); | ||
70 | |||
71 | if (d == NULL) | ||
72 | return NULL; | ||
73 | |||
74 | memcpy(d->server_public_key, server_public_key, crypto_box_PUBLICKEYBYTES); | ||
75 | dns_new_temp_keys(d); | ||
76 | return d; | ||
77 | } | ||
78 | |||
79 | /* Destroy the tox dns3 object. | ||
80 | */ | ||
81 | void tox_dns3_kill(void *dns3_object) | ||
82 | { | ||
83 | memset(dns3_object, 0, sizeof(DNS_Object)); | ||
84 | free(dns3_object); | ||
85 | } | ||
86 | |||
87 | /* Generate a dns3 string of string_max_len used to query the dns server reffered to by to | ||
88 | * dns3_object for a tox id registered to user with name of name_len. | ||
89 | * | ||
90 | * This is what the string returned looks like: | ||
91 | * 4haaaaipr1o3mz0bxweox541airydbovqlbju51mb4p0ebxq.rlqdj4kkisbep2ks3fj2nvtmk4daduqiueabmexqva1jc | ||
92 | * | ||
93 | * returns length of string on sucess. | ||
94 | * returns -1 on failure. | ||
95 | */ | ||
96 | int tox_generate_dns3_string(void *dns3_object, uint8_t *string, uint16_t string_max_len, uint8_t *name, | ||
97 | uint8_t name_len) | ||
98 | { | ||
99 | #define DOT_INTERVAL (6 * 5) | ||
100 | int base = (sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES + name_len + crypto_box_MACBYTES); | ||
101 | int end_len = ((base * 8) / 5) + (base / DOT_INTERVAL) + !!(base % 5); | ||
102 | |||
103 | if (end_len > string_max_len) | ||
104 | return -1; | ||
105 | |||
106 | DNS_Object *d = dns3_object; | ||
107 | uint8_t buffer[1024]; | ||
108 | uint8_t nonce[crypto_box_NONCEBYTES] = {0}; | ||
109 | memcpy(nonce, &d->nonce, sizeof(uint32_t)); | ||
110 | memcpy(buffer, &d->nonce, sizeof(uint32_t)); | ||
111 | memcpy(buffer + sizeof(uint32_t), d->temp_pk, crypto_box_PUBLICKEYBYTES); | ||
112 | int len = encrypt_data_symmetric(d->shared_key, nonce, name, name_len, | ||
113 | buffer + sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES); | ||
114 | |||
115 | if (len == -1) | ||
116 | return -1; | ||
117 | |||
118 | int total_len = len + sizeof(uint32_t) + crypto_box_PUBLICKEYBYTES; | ||
119 | uint8_t *buff = buffer, *old_str = string; | ||
120 | buffer[total_len] = 0; | ||
121 | uint8_t bits = 0; | ||
122 | int i; | ||
123 | |||
124 | for (i = 0; i < (total_len / DOT_INTERVAL); ++i) { | ||
125 | _encode(string, buff, DOT_INTERVAL); | ||
126 | *string = '.'; | ||
127 | ++string; | ||
128 | } | ||
129 | |||
130 | _encode(string, buff, total_len % DOT_INTERVAL); | ||
131 | #undef DOT_INTERVAL | ||
132 | ++d->nonce; | ||
133 | |||
134 | if (d->nonce == d->nonce_start) { | ||
135 | dns_new_temp_keys(d); | ||
136 | } | ||
137 | |||
138 | if (end_len != string - old_str) { | ||
139 | printf("tox_generate_dns3_string Fail\n"); | ||
140 | return -1; | ||
141 | } | ||
142 | |||
143 | return string - old_str; | ||
144 | } | ||
145 | |||
146 | |||
147 | static int decode(uint8_t *dest, uint8_t *src) | ||
148 | { | ||
149 | uint8_t *p = src, *op = dest, bits = 0; | ||
150 | *op = 0; | ||
151 | |||
152 | while (*p) { | ||
153 | uint8_t ch = *p++; | ||
154 | |||
155 | switch (ch) { | ||
156 | case 'A' ... 'Z': { | ||
157 | ch = ch - 'A'; | ||
158 | break; | ||
159 | } | ||
160 | |||
161 | case 'a' ... 'z': { | ||
162 | ch = ch - 'a'; | ||
163 | break; | ||
164 | } | ||
165 | |||
166 | case '0' ... '5': { | ||
167 | ch = ch - '0' + 26; | ||
168 | break; | ||
169 | } | ||
170 | |||
171 | default: { | ||
172 | return - 1; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | *op |= (ch << bits); | ||
177 | bits += 5; | ||
178 | |||
179 | if (bits >= 8) { | ||
180 | bits -= 8; | ||
181 | ++op; | ||
182 | *op = (ch >> (5 - bits)); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | return op - dest; | ||
187 | } | ||
188 | |||
189 | /* Decode and decrypt the id_record returned of length id_record_len into | ||
190 | * tox_id (needs to be at least TOX_FRIEND_ADDRESS_SIZE). | ||
191 | * | ||
192 | * the id_record passed to this function should look somewhat like this: | ||
193 | * 4haaaa2vgcxuycbuctvauik3plsv3d3aadv4zfjfhi3thaizwxinelrvigchv0ah3qjcsx5qhmaksb2lv2hm5cwbtx0yp | ||
194 | * | ||
195 | * returns -1 on failure. | ||
196 | * returns 0 on success. | ||
197 | * | ||
198 | */ | ||
199 | int tox_decrypt_dns3_TXT(void *dns3_object, uint8_t *tox_id, uint8_t *id_record, uint32_t id_record_len) | ||
200 | { | ||
201 | DNS_Object *d = dns3_object; | ||
202 | |||
203 | if (id_record_len != 93) | ||
204 | return -1; | ||
205 | |||
206 | /*if (id_record_len > 255 || id_record_len <= (sizeof(uint32_t) + crypto_box_MACBYTES)) | ||
207 | return -1;*/ | ||
208 | |||
209 | uint8_t data[id_record_len]; | ||
210 | int length = decode(data, id_record); | ||
211 | |||
212 | if (length == -1) | ||
213 | return -1; | ||
214 | |||
215 | uint8_t nonce[crypto_box_NONCEBYTES] = {0}; | ||
216 | memcpy(nonce, data, sizeof(uint32_t)); | ||
217 | nonce[sizeof(uint32_t)] = 1; | ||
218 | int len = decrypt_data_symmetric(d->shared_key, nonce, data + sizeof(uint32_t), length - sizeof(uint32_t), tox_id); | ||
219 | |||
220 | if (len != FRIEND_ADDRESS_SIZE) | ||
221 | return -1; | ||
222 | |||
223 | return 0; | ||
224 | } \ No newline at end of file | ||
diff --git a/toxdns/toxdns.h b/toxdns/toxdns.h new file mode 100644 index 00000000..ac84af9c --- /dev/null +++ b/toxdns/toxdns.h | |||
@@ -0,0 +1,78 @@ | |||
1 | /* toxdns.h | ||
2 | * | ||
3 | * Tox secure username DNS toxid resolving functions. | ||
4 | * | ||
5 | * Copyright (C) 2013 Tox project All Rights Reserved. | ||
6 | * | ||
7 | * This file is part of Tox. | ||
8 | * | ||
9 | * Tox is free software: you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation, either version 3 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * Tox is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with Tox. If not, see <http://www.gnu.org/licenses/>. | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #ifndef TOXDNS_H | ||
25 | #define TOXDNS_H | ||
26 | |||
27 | #include <stdint.h> | ||
28 | |||
29 | /* How to use this api to make secure tox dns3 requests: | ||
30 | * | ||
31 | * 1. Get the public key of a server that supports tox dns3. | ||
32 | * 2. use tox_dns3_new() to create a new object to create DNS requests | ||
33 | * and handle responses for that server. | ||
34 | * 3. Use tox_generate_dns3_string() to generate a string based on the name we want to query. | ||
35 | * 4. take the string and use it for your DNS request like this: | ||
36 | * _4haaaaipr1o3mz0bxweox541airydbovqlbju51mb4p0ebxq.rlqdj4kkisbep2ks3fj2nvtmk4daduqiueabmexqva1jc_._tox.utox.org | ||
37 | * | ||
38 | * 5. The TXT in the DNS you recieve should look like this: | ||
39 | * v=tox3;id=4haaaa2vgcxuycbuctvauik3plsv3d3aadv4zfjfhi3thaizwxinelrvigchv0ah3qjcsx5qhmaksb2lv2hm5cwbtx0yp | ||
40 | * 6. Take the id string and use it with tox_decrypt_dns3_TXT() to get the Tox id returned by the DNS server. | ||
41 | */ | ||
42 | |||
43 | /* Create a new tox_dns3 object for server with server_public_key of size TOX_CLIENT_ID_SIZE. | ||
44 | * | ||
45 | * return Null on failure. | ||
46 | * return pointer object on success. | ||
47 | */ | ||
48 | void *tox_dns3_new(uint8_t *server_public_key); | ||
49 | |||
50 | /* Destroy the tox dns3 object. | ||
51 | */ | ||
52 | void tox_dns3_kill(void *dns3_object); | ||
53 | |||
54 | /* Generate a dns3 string of string_max_len used to query the dns server reffered to by to | ||
55 | * dns3_object for a tox id registered to user with name of name_len. | ||
56 | * | ||
57 | * This is what the string returned looks like: | ||
58 | * 4haaaaipr1o3mz0bxweox541airydbovqlbju51mb4p0ebxq.rlqdj4kkisbep2ks3fj2nvtmk4daduqiueabmexqva1jc | ||
59 | * | ||
60 | * returns length of string on sucess. | ||
61 | * returns -1 on failure. | ||
62 | */ | ||
63 | int tox_generate_dns3_string(void *dns3_object, uint8_t *string, uint16_t string_max_len, uint8_t *name, | ||
64 | uint8_t name_len); | ||
65 | |||
66 | /* Decode and decrypt the id_record returned of length id_record_len into | ||
67 | * tox_id (needs to be at least TOX_FRIEND_ADDRESS_SIZE). | ||
68 | * | ||
69 | * the id_record passed to this function should look somewhat like this: | ||
70 | * 4haaaa2vgcxuycbuctvauik3plsv3d3aadv4zfjfhi3thaizwxinelrvigchv0ah3qjcsx5qhmaksb2lv2hm5cwbtx0yp | ||
71 | * | ||
72 | * returns -1 on failure. | ||
73 | * returns 0 on success. | ||
74 | * | ||
75 | */ | ||
76 | int tox_decrypt_dns3_TXT(void *dns3_object, uint8_t *tox_id, uint8_t *id_record, uint32_t id_record_len); | ||
77 | |||
78 | #endif | ||