0ff4cccf3b071dd214fe5f4734eab18934f3013c
[openssl.git] / ssl / packet_locl.h
1 /*
2  * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #ifndef HEADER_PACKET_LOCL_H
11 # define HEADER_PACKET_LOCL_H
12
13 # include <string.h>
14 # include <openssl/bn.h>
15 # include <openssl/buffer.h>
16 # include <openssl/crypto.h>
17 # include <openssl/e_os2.h>
18
19 # include "internal/numbers.h"
20
21 # ifdef __cplusplus
22 extern "C" {
23 # endif
24
25 typedef struct {
26     /* Pointer to where we are currently reading from */
27     const unsigned char *curr;
28     /* Number of bytes remaining */
29     size_t remaining;
30 } PACKET;
31
32 /* Internal unchecked shorthand; don't use outside this file. */
33 static ossl_inline void packet_forward(PACKET *pkt, size_t len)
34 {
35     pkt->curr += len;
36     pkt->remaining -= len;
37 }
38
39 /*
40  * Returns the number of bytes remaining to be read in the PACKET
41  */
42 static ossl_inline size_t PACKET_remaining(const PACKET *pkt)
43 {
44     return pkt->remaining;
45 }
46
47 /*
48  * Returns a pointer to the first byte after the packet data.
49  * Useful for integrating with non-PACKET parsing code.
50  * Specifically, we use PACKET_end() to verify that a d2i_... call
51  * has consumed the entire packet contents.
52  */
53 static ossl_inline const unsigned char *PACKET_end(const PACKET *pkt)
54 {
55     return pkt->curr + pkt->remaining;
56 }
57 /*
58  * Returns a pointer to the PACKET's current position.
59  * For use in non-PACKETized APIs.
60  */
61 static ossl_inline const unsigned char *PACKET_data(const PACKET *pkt)
62 {
63     return pkt->curr;
64 }
65
66 /*
67  * Initialise a PACKET with |len| bytes held in |buf|. This does not make a
68  * copy of the data so |buf| must be present for the whole time that the PACKET
69  * is being used.
70  */
71 __owur static ossl_inline int PACKET_buf_init(PACKET *pkt,
72                                               const unsigned char *buf,
73                                               size_t len)
74 {
75     /* Sanity check for negative values. */
76     if (len > (size_t)(SIZE_MAX / 2))
77         return 0;
78
79     pkt->curr = buf;
80     pkt->remaining = len;
81     return 1;
82 }
83
84 /* Initialize a PACKET to hold zero bytes. */
85 static ossl_inline void PACKET_null_init(PACKET *pkt)
86 {
87     pkt->curr = NULL;
88     pkt->remaining = 0;
89 }
90
91 /*
92  * Returns 1 if the packet has length |num| and its contents equal the |num|
93  * bytes read from |ptr|. Returns 0 otherwise (lengths or contents not equal).
94  * If lengths are equal, performs the comparison in constant time.
95  */
96 __owur static ossl_inline int PACKET_equal(const PACKET *pkt, const void *ptr,
97                                            size_t num)
98 {
99     if (PACKET_remaining(pkt) != num)
100         return 0;
101     return CRYPTO_memcmp(pkt->curr, ptr, num) == 0;
102 }
103
104 /*
105  * Peek ahead and initialize |subpkt| with the next |len| bytes read from |pkt|.
106  * Data is not copied: the |subpkt| packet will share its underlying buffer with
107  * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
108  */
109 __owur static ossl_inline int PACKET_peek_sub_packet(const PACKET *pkt,
110                                                      PACKET *subpkt,
111                                                      size_t len)
112 {
113     if (PACKET_remaining(pkt) < len)
114         return 0;
115
116     return PACKET_buf_init(subpkt, pkt->curr, len);
117 }
118
119 /*
120  * Initialize |subpkt| with the next |len| bytes read from |pkt|. Data is not
121  * copied: the |subpkt| packet will share its underlying buffer with the
122  * original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
123  */
124 __owur static ossl_inline int PACKET_get_sub_packet(PACKET *pkt,
125                                                     PACKET *subpkt,
126                                                     size_t len)
127 {
128     if (!PACKET_peek_sub_packet(pkt, subpkt, len))
129         return 0;
130
131     packet_forward(pkt, len);
132
133     return 1;
134 }
135
136 /*
137  * Peek ahead at 2 bytes in network order from |pkt| and store the value in
138  * |*data|
139  */
140 __owur static ossl_inline int PACKET_peek_net_2(const PACKET *pkt,
141                                                 unsigned int *data)
142 {
143     if (PACKET_remaining(pkt) < 2)
144         return 0;
145
146     *data = ((unsigned int)(*pkt->curr)) << 8;
147     *data |= *(pkt->curr + 1);
148
149     return 1;
150 }
151
152 /* Equivalent of n2s */
153 /* Get 2 bytes in network order from |pkt| and store the value in |*data| */
154 __owur static ossl_inline int PACKET_get_net_2(PACKET *pkt,
155                                                unsigned int *data)
156 {
157     if (!PACKET_peek_net_2(pkt, data))
158         return 0;
159
160     packet_forward(pkt, 2);
161
162     return 1;
163 }
164
165 /*
166  * Peek ahead at 3 bytes in network order from |pkt| and store the value in
167  * |*data|
168  */
169 __owur static ossl_inline int PACKET_peek_net_3(const PACKET *pkt,
170                                                 unsigned long *data)
171 {
172     if (PACKET_remaining(pkt) < 3)
173         return 0;
174
175     *data = ((unsigned long)(*pkt->curr)) << 16;
176     *data |= ((unsigned long)(*(pkt->curr + 1))) << 8;
177     *data |= *(pkt->curr + 2);
178
179     return 1;
180 }
181
182 /* Equivalent of n2l3 */
183 /* Get 3 bytes in network order from |pkt| and store the value in |*data| */
184 __owur static ossl_inline int PACKET_get_net_3(PACKET *pkt,
185                                                unsigned long *data)
186 {
187     if (!PACKET_peek_net_3(pkt, data))
188         return 0;
189
190     packet_forward(pkt, 3);
191
192     return 1;
193 }
194
195 /*
196  * Peek ahead at 4 bytes in network order from |pkt| and store the value in
197  * |*data|
198  */
199 __owur static ossl_inline int PACKET_peek_net_4(const PACKET *pkt,
200                                                 unsigned long *data)
201 {
202     if (PACKET_remaining(pkt) < 4)
203         return 0;
204
205     *data = ((unsigned long)(*pkt->curr)) << 24;
206     *data |= ((unsigned long)(*(pkt->curr + 1))) << 16;
207     *data |= ((unsigned long)(*(pkt->curr + 2))) << 8;
208     *data |= *(pkt->curr + 3);
209
210     return 1;
211 }
212
213 /* Equivalent of n2l */
214 /* Get 4 bytes in network order from |pkt| and store the value in |*data| */
215 __owur static ossl_inline int PACKET_get_net_4(PACKET *pkt,
216                                                unsigned long *data)
217 {
218     if (!PACKET_peek_net_4(pkt, data))
219         return 0;
220
221     packet_forward(pkt, 4);
222
223     return 1;
224 }
225
226 /* Peek ahead at 1 byte from |pkt| and store the value in |*data| */
227 __owur static ossl_inline int PACKET_peek_1(const PACKET *pkt,
228                                             unsigned int *data)
229 {
230     if (!PACKET_remaining(pkt))
231         return 0;
232
233     *data = *pkt->curr;
234
235     return 1;
236 }
237
238 /* Get 1 byte from |pkt| and store the value in |*data| */
239 __owur static ossl_inline int PACKET_get_1(PACKET *pkt, unsigned int *data)
240 {
241     if (!PACKET_peek_1(pkt, data))
242         return 0;
243
244     packet_forward(pkt, 1);
245
246     return 1;
247 }
248
249 /*
250  * Peek ahead at 4 bytes in reverse network order from |pkt| and store the value
251  * in |*data|
252  */
253 __owur static ossl_inline int PACKET_peek_4(const PACKET *pkt,
254                                             unsigned long *data)
255 {
256     if (PACKET_remaining(pkt) < 4)
257         return 0;
258
259     *data = *pkt->curr;
260     *data |= ((unsigned long)(*(pkt->curr + 1))) << 8;
261     *data |= ((unsigned long)(*(pkt->curr + 2))) << 16;
262     *data |= ((unsigned long)(*(pkt->curr + 3))) << 24;
263
264     return 1;
265 }
266
267 /* Equivalent of c2l */
268 /*
269  * Get 4 bytes in reverse network order from |pkt| and store the value in
270  * |*data|
271  */
272 __owur static ossl_inline int PACKET_get_4(PACKET *pkt, unsigned long *data)
273 {
274     if (!PACKET_peek_4(pkt, data))
275         return 0;
276
277     packet_forward(pkt, 4);
278
279     return 1;
280 }
281
282 /*
283  * Peek ahead at |len| bytes from the |pkt| and store a pointer to them in
284  * |*data|. This just points at the underlying buffer that |pkt| is using. The
285  * caller should not free this data directly (it will be freed when the
286  * underlying buffer gets freed
287  */
288 __owur static ossl_inline int PACKET_peek_bytes(const PACKET *pkt,
289                                                 const unsigned char **data,
290                                                 size_t len)
291 {
292     if (PACKET_remaining(pkt) < len)
293         return 0;
294
295     *data = pkt->curr;
296
297     return 1;
298 }
299
300 /*
301  * Read |len| bytes from the |pkt| and store a pointer to them in |*data|. This
302  * just points at the underlying buffer that |pkt| is using. The caller should
303  * not free this data directly (it will be freed when the underlying buffer gets
304  * freed
305  */
306 __owur static ossl_inline int PACKET_get_bytes(PACKET *pkt,
307                                                const unsigned char **data,
308                                                size_t len)
309 {
310     if (!PACKET_peek_bytes(pkt, data, len))
311         return 0;
312
313     packet_forward(pkt, len);
314
315     return 1;
316 }
317
318 /* Peek ahead at |len| bytes from |pkt| and copy them to |data| */
319 __owur static ossl_inline int PACKET_peek_copy_bytes(const PACKET *pkt,
320                                                      unsigned char *data,
321                                                      size_t len)
322 {
323     if (PACKET_remaining(pkt) < len)
324         return 0;
325
326     memcpy(data, pkt->curr, len);
327
328     return 1;
329 }
330
331 /*
332  * Read |len| bytes from |pkt| and copy them to |data|.
333  * The caller is responsible for ensuring that |data| can hold |len| bytes.
334  */
335 __owur static ossl_inline int PACKET_copy_bytes(PACKET *pkt,
336                                                 unsigned char *data,
337                                                 size_t len)
338 {
339     if (!PACKET_peek_copy_bytes(pkt, data, len))
340         return 0;
341
342     packet_forward(pkt, len);
343
344     return 1;
345 }
346
347 /*
348  * Copy packet data to |dest|, and set |len| to the number of copied bytes.
349  * If the packet has more than |dest_len| bytes, nothing is copied.
350  * Returns 1 if the packet data fits in |dest_len| bytes, 0 otherwise.
351  * Does not forward PACKET position (because it is typically the last thing
352  * done with a given PACKET).
353  */
354 __owur static ossl_inline int PACKET_copy_all(const PACKET *pkt,
355                                               unsigned char *dest,
356                                               size_t dest_len, size_t *len)
357 {
358     if (PACKET_remaining(pkt) > dest_len) {
359         *len = 0;
360         return 0;
361     }
362     *len = pkt->remaining;
363     memcpy(dest, pkt->curr, pkt->remaining);
364     return 1;
365 }
366
367 /*
368  * Copy |pkt| bytes to a newly allocated buffer and store a pointer to the
369  * result in |*data|, and the length in |len|.
370  * If |*data| is not NULL, the old data is OPENSSL_free'd.
371  * If the packet is empty, or malloc fails, |*data| will be set to NULL.
372  * Returns 1 if the malloc succeeds and 0 otherwise.
373  * Does not forward PACKET position (because it is typically the last thing
374  * done with a given PACKET).
375  */
376 __owur static ossl_inline int PACKET_memdup(const PACKET *pkt,
377                                             unsigned char **data, size_t *len)
378 {
379     size_t length;
380
381     OPENSSL_free(*data);
382     *data = NULL;
383     *len = 0;
384
385     length = PACKET_remaining(pkt);
386
387     if (length == 0)
388         return 1;
389
390     *data = OPENSSL_memdup(pkt->curr, length);
391     if (*data == NULL)
392         return 0;
393
394     *len = length;
395     return 1;
396 }
397
398 /*
399  * Read a C string from |pkt| and copy to a newly allocated, NUL-terminated
400  * buffer. Store a pointer to the result in |*data|.
401  * If |*data| is not NULL, the old data is OPENSSL_free'd.
402  * If the data in |pkt| does not contain a NUL-byte, the entire data is
403  * copied and NUL-terminated.
404  * Returns 1 if the malloc succeeds and 0 otherwise.
405  * Does not forward PACKET position (because it is typically the last thing done
406  * with a given PACKET).
407  */
408 __owur static ossl_inline int PACKET_strndup(const PACKET *pkt, char **data)
409 {
410     OPENSSL_free(*data);
411
412     /* This will succeed on an empty packet, unless pkt->curr == NULL. */
413     *data = OPENSSL_strndup((const char *)pkt->curr, PACKET_remaining(pkt));
414     return (*data != NULL);
415 }
416
417 /* Returns 1 if |pkt| contains at least one 0-byte, 0 otherwise. */
418 static ossl_inline int PACKET_contains_zero_byte(const PACKET *pkt)
419 {
420   return memchr(pkt->curr, 0, pkt->remaining) != NULL;
421 }
422
423 /* Move the current reading position forward |len| bytes */
424 __owur static ossl_inline int PACKET_forward(PACKET *pkt, size_t len)
425 {
426     if (PACKET_remaining(pkt) < len)
427         return 0;
428
429     packet_forward(pkt, len);
430
431     return 1;
432 }
433
434 /*
435  * Reads a variable-length vector prefixed with a one-byte length, and stores
436  * the contents in |subpkt|. |pkt| can equal |subpkt|.
437  * Data is not copied: the |subpkt| packet will share its underlying buffer with
438  * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
439  * Upon failure, the original |pkt| and |subpkt| are not modified.
440  */
441 __owur static ossl_inline int PACKET_get_length_prefixed_1(PACKET *pkt,
442                                                            PACKET *subpkt)
443 {
444     unsigned int length;
445     const unsigned char *data;
446     PACKET tmp = *pkt;
447     if (!PACKET_get_1(&tmp, &length) ||
448         !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
449         return 0;
450     }
451
452     *pkt = tmp;
453     subpkt->curr = data;
454     subpkt->remaining = length;
455
456     return 1;
457 }
458
459 /*
460  * Like PACKET_get_length_prefixed_1, but additionally, fails when there are
461  * leftover bytes in |pkt|.
462  */
463 __owur static ossl_inline int PACKET_as_length_prefixed_1(PACKET *pkt, PACKET *subpkt)
464 {
465   unsigned int length;
466   const unsigned char *data;
467   PACKET tmp = *pkt;
468   if (!PACKET_get_1(&tmp, &length) ||
469       !PACKET_get_bytes(&tmp, &data, (size_t)length) ||
470       PACKET_remaining(&tmp) != 0) {
471       return 0;
472   }
473
474   *pkt = tmp;
475   subpkt->curr = data;
476   subpkt->remaining = length;
477
478   return 1;
479 }
480
481 /*
482  * Reads a variable-length vector prefixed with a two-byte length, and stores
483  * the contents in |subpkt|. |pkt| can equal |subpkt|.
484  * Data is not copied: the |subpkt| packet will share its underlying buffer with
485  * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
486  * Upon failure, the original |pkt| and |subpkt| are not modified.
487  */
488 __owur static ossl_inline int PACKET_get_length_prefixed_2(PACKET *pkt,
489                                                            PACKET *subpkt)
490 {
491     unsigned int length;
492     const unsigned char *data;
493     PACKET tmp = *pkt;
494
495     if (!PACKET_get_net_2(&tmp, &length) ||
496         !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
497         return 0;
498     }
499
500     *pkt = tmp;
501     subpkt->curr = data;
502     subpkt->remaining = length;
503
504     return 1;
505 }
506
507 /*
508  * Like PACKET_get_length_prefixed_2, but additionally, fails when there are
509  * leftover bytes in |pkt|.
510  */
511 __owur static ossl_inline int PACKET_as_length_prefixed_2(PACKET *pkt,
512                                                           PACKET *subpkt)
513 {
514   unsigned int length;
515   const unsigned char *data;
516   PACKET tmp = *pkt;
517
518   if (!PACKET_get_net_2(&tmp, &length) ||
519       !PACKET_get_bytes(&tmp, &data, (size_t)length) ||
520       PACKET_remaining(&tmp) != 0) {
521       return 0;
522   }
523
524   *pkt = tmp;
525   subpkt->curr = data;
526   subpkt->remaining = length;
527
528   return 1;
529 }
530
531 /*
532  * Reads a variable-length vector prefixed with a three-byte length, and stores
533  * the contents in |subpkt|. |pkt| can equal |subpkt|.
534  * Data is not copied: the |subpkt| packet will share its underlying buffer with
535  * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
536  * Upon failure, the original |pkt| and |subpkt| are not modified.
537  */
538 __owur static ossl_inline int PACKET_get_length_prefixed_3(PACKET *pkt,
539                                                            PACKET *subpkt)
540 {
541     unsigned long length;
542     const unsigned char *data;
543     PACKET tmp = *pkt;
544     if (!PACKET_get_net_3(&tmp, &length) ||
545         !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
546         return 0;
547     }
548
549     *pkt = tmp;
550     subpkt->curr = data;
551     subpkt->remaining = length;
552
553     return 1;
554 }
555 # ifdef __cplusplus
556 }
557 # endif
558
559 #endif                          /* HEADER_PACKET_LOCL_H */