summaryrefslogtreecommitdiff
path: root/toxcore/crypto_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxcore/crypto_core.c')
-rw-r--r--toxcore/crypto_core.c71
1 files changed, 70 insertions, 1 deletions
diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c
index 22612442..59053bc4 100644
--- a/toxcore/crypto_core.c
+++ b/toxcore/crypto_core.c
@@ -166,4 +166,73 @@ void new_nonce(uint8_t *nonce)
166 166
167 increment_nonce(base_nonce); 167 increment_nonce(base_nonce);
168 memcpy(nonce, base_nonce, crypto_box_NONCEBYTES); 168 memcpy(nonce, base_nonce, crypto_box_NONCEBYTES);
169} \ No newline at end of file 169}
170
171/* Create a request to peer.
172 * send_public_key and send_secret_key are the pub/secret keys of the sender.
173 * recv_public_key is public key of reciever.
174 * packet must be an array of MAX_CRYPTO_REQUEST_SIZE big.
175 * Data represents the data we send with the request with length being the length of the data.
176 * request_id is the id of the request (32 = friend request, 254 = ping request).
177 *
178 * return -1 on failure.
179 * return the length of the created packet on success.
180 */
181int create_request(uint8_t *send_public_key, uint8_t *send_secret_key, uint8_t *packet, uint8_t *recv_public_key,
182 uint8_t *data, uint32_t length, uint8_t request_id)
183{
184 if (MAX_CRYPTO_REQUEST_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 +
185 crypto_box_MACBYTES)
186 return -1;
187
188 uint8_t nonce[crypto_box_NONCEBYTES];
189 uint8_t temp[MAX_CRYPTO_REQUEST_SIZE];
190 memcpy(temp + 1, data, length);
191 temp[0] = request_id;
192 new_nonce(nonce);
193 int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1,
194 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
195
196 if (len == -1)
197 return -1;
198
199 packet[0] = NET_PACKET_CRYPTO;
200 memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES);
201 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES);
202 memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES);
203
204 return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES;
205}
206
207/* Puts the senders public key in the request in public_key, the data from the request
208 * in data if a friend or ping request was sent to us and returns the length of the data.
209 * packet is the request packet and length is its length.
210 *
211 * return -1 if not valid request.
212 */
213int handle_request(uint8_t *self_public_key, uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
214 uint8_t *request_id, uint8_t *packet, uint16_t length)
215{
216 if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES &&
217 length <= MAX_CRYPTO_REQUEST_SIZE) {
218 if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
219 memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
220 uint8_t nonce[crypto_box_NONCEBYTES];
221 uint8_t temp[MAX_CRYPTO_REQUEST_SIZE];
222 memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES);
223 int len1 = decrypt_data(public_key, self_secret_key, nonce,
224 packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES,
225 length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp);
226
227 if (len1 == -1 || len1 == 0)
228 return -1;
229
230 request_id[0] = temp[0];
231 --len1;
232 memcpy(data, temp + 1, len1);
233 return len1;
234 }
235 }
236
237 return -1;
238}