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