Coverage Report

Created: 2023-09-25 06:41

/src/openssl111/ssl/packet.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2015-2022 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
#include "internal/cryptlib.h"
11
#include "packet_local.h"
12
#include <openssl/sslerr.h>
13
14
6.16k
#define DEFAULT_BUF_SIZE    256
15
16
int WPACKET_allocate_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes)
17
257k
{
18
257k
    if (!WPACKET_reserve_bytes(pkt, len, allocbytes))
19
0
        return 0;
20
21
257k
    pkt->written += len;
22
257k
    pkt->curr += len;
23
257k
    return 1;
24
257k
}
25
26
int WPACKET_sub_allocate_bytes__(WPACKET *pkt, size_t len,
27
                                 unsigned char **allocbytes, size_t lenbytes)
28
4.06k
{
29
4.06k
    if (!WPACKET_start_sub_packet_len__(pkt, lenbytes)
30
4.06k
            || !WPACKET_allocate_bytes(pkt, len, allocbytes)
31
4.06k
            || !WPACKET_close(pkt))
32
0
        return 0;
33
34
4.06k
    return 1;
35
4.06k
}
36
37
405k
#define GETBUF(p)   (((p)->staticbuf != NULL) \
38
405k
                     ? (p)->staticbuf : (unsigned char *)(p)->buf->data)
39
40
int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes)
41
293k
{
42
    /* Internal API, so should not fail */
43
293k
    if (!ossl_assert(pkt->subs != NULL && len != 0))
44
0
        return 0;
45
46
293k
    if (pkt->maxsize - pkt->written < len)
47
0
        return 0;
48
49
293k
    if (pkt->staticbuf == NULL && (pkt->buf->length - pkt->written < len)) {
50
4.68k
        size_t newlen;
51
4.68k
        size_t reflen;
52
53
4.68k
        reflen = (len > pkt->buf->length) ? len : pkt->buf->length;
54
55
4.68k
        if (reflen > SIZE_MAX / 2) {
56
0
            newlen = SIZE_MAX;
57
4.68k
        } else {
58
4.68k
            newlen = reflen * 2;
59
4.68k
            if (newlen < DEFAULT_BUF_SIZE)
60
1.47k
                newlen = DEFAULT_BUF_SIZE;
61
4.68k
        }
62
4.68k
        if (BUF_MEM_grow(pkt->buf, newlen) == 0)
63
0
            return 0;
64
4.68k
    }
65
293k
    if (allocbytes != NULL)
66
256k
        *allocbytes = WPACKET_get_curr(pkt);
67
68
293k
    return 1;
69
293k
}
70
71
int WPACKET_sub_reserve_bytes__(WPACKET *pkt, size_t len,
72
                                unsigned char **allocbytes, size_t lenbytes)
73
803
{
74
803
    if (!WPACKET_reserve_bytes(pkt, lenbytes + len, allocbytes))
75
0
        return 0;
76
77
803
    *allocbytes += lenbytes;
78
79
803
    return 1;
80
803
}
81
82
static size_t maxmaxsize(size_t lenbytes)
83
51.8k
{
84
51.8k
    if (lenbytes >= sizeof(size_t) || lenbytes == 0)
85
51.8k
        return SIZE_MAX;
86
87
0
    return ((size_t)1 << (lenbytes * 8)) - 1 + lenbytes;
88
51.8k
}
89
90
static int wpacket_intern_init_len(WPACKET *pkt, size_t lenbytes)
91
51.8k
{
92
51.8k
    unsigned char *lenchars;
93
94
51.8k
    pkt->curr = 0;
95
51.8k
    pkt->written = 0;
96
97
51.8k
    if ((pkt->subs = OPENSSL_zalloc(sizeof(*pkt->subs))) == NULL) {
98
0
        SSLerr(SSL_F_WPACKET_INTERN_INIT_LEN, ERR_R_MALLOC_FAILURE);
99
0
        return 0;
100
0
    }
101
102
51.8k
    if (lenbytes == 0)
103
51.8k
        return 1;
104
105
0
    pkt->subs->pwritten = lenbytes;
106
0
    pkt->subs->lenbytes = lenbytes;
107
108
0
    if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars)) {
109
0
        OPENSSL_free(pkt->subs);
110
0
        pkt->subs = NULL;
111
0
        return 0;
112
0
    }
113
0
    pkt->subs->packet_len = lenchars - GETBUF(pkt);
114
115
0
    return 1;
116
0
}
117
118
int WPACKET_init_static_len(WPACKET *pkt, unsigned char *buf, size_t len,
119
                            size_t lenbytes)
120
38.6k
{
121
38.6k
    size_t max = maxmaxsize(lenbytes);
122
123
    /* Internal API, so should not fail */
124
38.6k
    if (!ossl_assert(buf != NULL && len > 0))
125
0
        return 0;
126
127
38.6k
    pkt->staticbuf = buf;
128
38.6k
    pkt->buf = NULL;
129
38.6k
    pkt->maxsize = (max < len) ? max : len;
130
131
38.6k
    return wpacket_intern_init_len(pkt, lenbytes);
132
38.6k
}
133
134
int WPACKET_init_len(WPACKET *pkt, BUF_MEM *buf, size_t lenbytes)
135
13.1k
{
136
    /* Internal API, so should not fail */
137
13.1k
    if (!ossl_assert(buf != NULL))
138
0
        return 0;
139
140
13.1k
    pkt->staticbuf = NULL;
141
13.1k
    pkt->buf = buf;
142
13.1k
    pkt->maxsize = maxmaxsize(lenbytes);
143
144
13.1k
    return wpacket_intern_init_len(pkt, lenbytes);
145
13.1k
}
146
147
int WPACKET_init(WPACKET *pkt, BUF_MEM *buf)
148
13.1k
{
149
13.1k
    return WPACKET_init_len(pkt, buf, 0);
150
13.1k
}
151
152
int WPACKET_set_flags(WPACKET *pkt, unsigned int flags)
153
2.92k
{
154
    /* Internal API, so should not fail */
155
2.92k
    if (!ossl_assert(pkt->subs != NULL))
156
0
        return 0;
157
158
2.92k
    pkt->subs->flags = flags;
159
160
2.92k
    return 1;
161
2.92k
}
162
163
/* Store the |value| of length |len| at location |data| */
164
static int put_value(unsigned char *data, uint64_t value, size_t len)
165
186k
{
166
503k
    for (data += len - 1; len > 0; len--) {
167
316k
        *data = (unsigned char)(value & 0xff);
168
316k
        data--;
169
316k
        value >>= 8;
170
316k
    }
171
172
    /* Check whether we could fit the value in the assigned number of bytes */
173
186k
    if (value > 0)
174
0
        return 0;
175
176
186k
    return 1;
177
186k
}
178
179
180
/*
181
 * Internal helper function used by WPACKET_close(), WPACKET_finish() and
182
 * WPACKET_fill_lengths() to close a sub-packet and write out its length if
183
 * necessary. If |doclose| is 0 then it goes through the motions of closing
184
 * (i.e. it fills in all the lengths), but doesn't actually close anything.
185
 */
186
static int wpacket_intern_close(WPACKET *pkt, WPACKET_SUB *sub, int doclose)
187
118k
{
188
118k
    size_t packlen = pkt->written - sub->pwritten;
189
190
118k
    if (packlen == 0
191
118k
            && (sub->flags & WPACKET_FLAGS_NON_ZERO_LENGTH) != 0)
192
0
        return 0;
193
194
118k
    if (packlen == 0
195
118k
            && sub->flags & WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) {
196
        /* We can't handle this case. Return an error */
197
1.99k
        if (!doclose)
198
0
            return 0;
199
200
        /* Deallocate any bytes allocated for the length of the WPACKET */
201
1.99k
        if ((pkt->curr - sub->lenbytes) == sub->packet_len) {
202
1.99k
            pkt->written -= sub->lenbytes;
203
1.99k
            pkt->curr -= sub->lenbytes;
204
1.99k
        }
205
206
        /* Don't write out the packet length */
207
1.99k
        sub->packet_len = 0;
208
1.99k
        sub->lenbytes = 0;
209
1.99k
    }
210
211
    /* Write out the WPACKET length if needed */
212
118k
    if (sub->lenbytes > 0
213
118k
                && !put_value(&GETBUF(pkt)[sub->packet_len], packlen,
214
64.8k
                              sub->lenbytes))
215
0
            return 0;
216
217
118k
    if (doclose) {
218
118k
        pkt->subs = sub->parent;
219
118k
        OPENSSL_free(sub);
220
118k
    }
221
222
118k
    return 1;
223
118k
}
224
225
int WPACKET_fill_lengths(WPACKET *pkt)
226
0
{
227
0
    WPACKET_SUB *sub;
228
229
0
    if (!ossl_assert(pkt->subs != NULL))
230
0
        return 0;
231
232
0
    for (sub = pkt->subs; sub != NULL; sub = sub->parent) {
233
0
        if (!wpacket_intern_close(pkt, sub, 0))
234
0
            return 0;
235
0
    }
236
237
0
    return 1;
238
0
}
239
240
int WPACKET_close(WPACKET *pkt)
241
66.7k
{
242
    /*
243
     * Internal API, so should not fail - but we do negative testing of this
244
     * so no assert (otherwise the tests fail)
245
     */
246
66.7k
    if (pkt->subs == NULL || pkt->subs->parent == NULL)
247
0
        return 0;
248
249
66.7k
    return wpacket_intern_close(pkt, pkt->subs, 1);
250
66.7k
}
251
252
int WPACKET_finish(WPACKET *pkt)
253
51.8k
{
254
51.8k
    int ret;
255
256
    /*
257
     * Internal API, so should not fail - but we do negative testing of this
258
     * so no assert (otherwise the tests fail)
259
     */
260
51.8k
    if (pkt->subs == NULL || pkt->subs->parent != NULL)
261
0
        return 0;
262
263
51.8k
    ret = wpacket_intern_close(pkt, pkt->subs, 1);
264
51.8k
    if (ret) {
265
51.8k
        OPENSSL_free(pkt->subs);
266
51.8k
        pkt->subs = NULL;
267
51.8k
    }
268
269
51.8k
    return ret;
270
51.8k
}
271
272
int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes)
273
66.8k
{
274
66.8k
    WPACKET_SUB *sub;
275
66.8k
    unsigned char *lenchars;
276
277
    /* Internal API, so should not fail */
278
66.8k
    if (!ossl_assert(pkt->subs != NULL))
279
0
        return 0;
280
281
66.8k
    if ((sub = OPENSSL_zalloc(sizeof(*sub))) == NULL) {
282
0
        SSLerr(SSL_F_WPACKET_START_SUB_PACKET_LEN__, ERR_R_MALLOC_FAILURE);
283
0
        return 0;
284
0
    }
285
286
66.8k
    sub->parent = pkt->subs;
287
66.8k
    pkt->subs = sub;
288
66.8k
    sub->pwritten = pkt->written + lenbytes;
289
66.8k
    sub->lenbytes = lenbytes;
290
291
66.8k
    if (lenbytes == 0) {
292
0
        sub->packet_len = 0;
293
0
        return 1;
294
0
    }
295
296
66.8k
    if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars))
297
0
        return 0;
298
    /* Convert to an offset in case the underlying BUF_MEM gets realloc'd */
299
66.8k
    sub->packet_len = lenchars - GETBUF(pkt);
300
301
66.8k
    return 1;
302
66.8k
}
303
304
int WPACKET_start_sub_packet(WPACKET *pkt)
305
0
{
306
0
    return WPACKET_start_sub_packet_len__(pkt, 0);
307
0
}
308
309
int WPACKET_put_bytes__(WPACKET *pkt, uint64_t val, size_t size)
310
121k
{
311
121k
    unsigned char *data;
312
313
    /* Internal API, so should not fail */
314
121k
    if (!ossl_assert(size <= sizeof(uint64_t))
315
121k
            || !WPACKET_allocate_bytes(pkt, size, &data)
316
121k
            || !put_value(data, val, size))
317
0
        return 0;
318
319
121k
    return 1;
320
121k
}
321
322
int WPACKET_set_max_size(WPACKET *pkt, size_t maxsize)
323
0
{
324
0
    WPACKET_SUB *sub;
325
0
    size_t lenbytes;
326
327
    /* Internal API, so should not fail */
328
0
    if (!ossl_assert(pkt->subs != NULL))
329
0
        return 0;
330
331
    /* Find the WPACKET_SUB for the top level */
332
0
    for (sub = pkt->subs; sub->parent != NULL; sub = sub->parent)
333
0
        continue;
334
335
0
    lenbytes = sub->lenbytes;
336
0
    if (lenbytes == 0)
337
0
        lenbytes = sizeof(pkt->maxsize);
338
339
0
    if (maxmaxsize(lenbytes) < maxsize || maxsize < pkt->written)
340
0
        return 0;
341
342
0
    pkt->maxsize = maxsize;
343
344
0
    return 1;
345
0
}
346
347
int WPACKET_memset(WPACKET *pkt, int ch, size_t len)
348
0
{
349
0
    unsigned char *dest;
350
351
0
    if (len == 0)
352
0
        return 1;
353
354
0
    if (!WPACKET_allocate_bytes(pkt, len, &dest))
355
0
        return 0;
356
357
0
    memset(dest, ch, len);
358
359
0
    return 1;
360
0
}
361
362
int WPACKET_memcpy(WPACKET *pkt, const void *src, size_t len)
363
52.0k
{
364
52.0k
    unsigned char *dest;
365
366
52.0k
    if (len == 0)
367
6.29k
        return 1;
368
369
45.7k
    if (!WPACKET_allocate_bytes(pkt, len, &dest))
370
0
        return 0;
371
372
45.7k
    memcpy(dest, src, len);
373
374
45.7k
    return 1;
375
45.7k
}
376
377
int WPACKET_sub_memcpy__(WPACKET *pkt, const void *src, size_t len,
378
                         size_t lenbytes)
379
13.8k
{
380
13.8k
    if (!WPACKET_start_sub_packet_len__(pkt, lenbytes)
381
13.8k
            || !WPACKET_memcpy(pkt, src, len)
382
13.8k
            || !WPACKET_close(pkt))
383
0
        return 0;
384
385
13.8k
    return 1;
386
13.8k
}
387
388
int WPACKET_get_total_written(WPACKET *pkt, size_t *written)
389
22.3k
{
390
    /* Internal API, so should not fail */
391
22.3k
    if (!ossl_assert(written != NULL))
392
0
        return 0;
393
394
22.3k
    *written = pkt->written;
395
396
22.3k
    return 1;
397
22.3k
}
398
399
int WPACKET_get_length(WPACKET *pkt, size_t *len)
400
65.7k
{
401
    /* Internal API, so should not fail */
402
65.7k
    if (!ossl_assert(pkt->subs != NULL && len != NULL))
403
0
        return 0;
404
405
65.7k
    *len = pkt->written - pkt->subs->pwritten;
406
407
65.7k
    return 1;
408
65.7k
}
409
410
unsigned char *WPACKET_get_curr(WPACKET *pkt)
411
273k
{
412
273k
    return GETBUF(pkt) + pkt->curr;
413
273k
}
414
415
void WPACKET_cleanup(WPACKET *pkt)
416
3
{
417
3
    WPACKET_SUB *sub, *parent;
418
419
12
    for (sub = pkt->subs; sub != NULL; sub = parent) {
420
9
        parent = sub->parent;
421
9
        OPENSSL_free(sub);
422
9
    }
423
3
    pkt->subs = NULL;
424
3
}