GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libssl/bs_cbs.c Lines: 197 219 90.0 %
Date: 2017-11-13 Branches: 99 130 76.2 %

Line Branch Exec Source
1
/*	$OpenBSD: bs_cbs.c,v 1.17 2015/06/24 09:44:18 jsing Exp $	*/
2
/*
3
 * Copyright (c) 2014, Google Inc.
4
 *
5
 * Permission to use, copy, modify, and/or distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
16
17
#include <assert.h>
18
#include <stdlib.h>
19
#include <string.h>
20
21
#include <openssl/opensslconf.h>
22
#include <openssl/buffer.h>
23
#include <openssl/crypto.h>
24
25
#include "bytestring.h"
26
27
void
28
CBS_init(CBS *cbs, const uint8_t *data, size_t len)
29
{
30
485812
	cbs->data = data;
31
242906
	cbs->initial_len = len;
32
242906
	cbs->len = len;
33
242906
}
34
35
void
36
CBS_dup(const CBS *cbs, CBS *out)
37
{
38
444
	CBS_init(out, CBS_data(cbs), CBS_len(cbs));
39
222
	out->initial_len = cbs->initial_len;
40
222
}
41
42
static int
43
cbs_get(CBS *cbs, const uint8_t **p, size_t n)
44
{
45
886074
	if (cbs->len < n)
46
63
		return 0;
47
48
442974
	*p = cbs->data;
49
442974
	cbs->data += n;
50
442974
	cbs->len -= n;
51
442974
	return 1;
52
443037
}
53
54
size_t
55
CBS_offset(const CBS *cbs)
56
{
57
66
	return cbs->initial_len - cbs->len;
58
}
59
60
int
61
CBS_skip(CBS *cbs, size_t len)
62
{
63
5716
	const uint8_t *dummy;
64
5716
	return cbs_get(cbs, &dummy, len);
65
2858
}
66
67
const uint8_t *
68
CBS_data(const CBS *cbs)
69
{
70
87712
	return cbs->data;
71
}
72
73
size_t
74
CBS_len(const CBS *cbs)
75
{
76
362928
	return cbs->len;
77
}
78
79
int
80
CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len)
81
{
82
5238
	free(*out_ptr);
83
2619
	*out_ptr = NULL;
84
2619
	*out_len = 0;
85
86
2619
	if (cbs->len == 0)
87
		return 1;
88
89
2619
	if ((*out_ptr = malloc(cbs->len)) == NULL)
90
		return 0;
91
92
2619
	memcpy(*out_ptr, cbs->data, cbs->len);
93
94
2619
	*out_len = cbs->len;
95
2619
	return 1;
96
2619
}
97
98
int
99
CBS_strdup(const CBS *cbs, char **out_ptr)
100
{
101
36
	free(*out_ptr);
102
18
	*out_ptr = strndup((const char *)cbs->data, cbs->len);
103
18
	return (*out_ptr != NULL);
104
}
105
106
int
107
CBS_write_bytes(const CBS *cbs, uint8_t *dst, size_t dst_len, size_t *copied)
108
{
109
36922
	if (dst_len < cbs->len)
110
		return 0;
111
112
18461
	memmove(dst, cbs->data, cbs->len);
113
114
18461
	if (copied != NULL)
115
1876
		*copied = cbs->len;
116
117
18461
	return 1;
118
18461
}
119
120
int
121
CBS_contains_zero_byte(const CBS *cbs)
122
{
123
2618
	return memchr(cbs->data, 0, cbs->len) != NULL;
124
}
125
126
int
127
CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len)
128
{
129
124866
	if (len != cbs->len)
130
3
		return 0;
131
132
62430
	return timingsafe_memcmp(cbs->data, data, len) == 0;
133
62433
}
134
135
static int
136
cbs_get_u(CBS *cbs, uint32_t *out, size_t len)
137
{
138
	uint32_t result = 0;
139
	size_t i;
140
460034
	const uint8_t *data;
141
142
230017
	if (len < 1 || len > 4)
143
		return 0;
144
145
230017
	if (!cbs_get(cbs, &data, len))
146
6
		return 0;
147
148
1399652
	for (i = 0; i < len; i++) {
149
469815
		result <<= 8;
150
469815
		result |= data[i];
151
	}
152
230011
	*out = result;
153
230011
	return 1;
154
230017
}
155
156
int
157
CBS_get_u8(CBS *cbs, uint8_t *out)
158
{
159
235118
	const uint8_t *v;
160
161
117559
	if (!cbs_get(cbs, &v, 1))
162
6
		return 0;
163
164
117553
	*out = *v;
165
117553
	return 1;
166
117559
}
167
168
int
169
CBS_get_u16(CBS *cbs, uint16_t *out)
170
{
171
296894
	uint32_t v;
172
173
148447
	if (!cbs_get_u(cbs, &v, 2))
174
6
		return 0;
175
176
148441
	*out = v;
177
148441
	return 1;
178
148447
}
179
180
int
181
CBS_get_u24(CBS *cbs, uint32_t *out)
182
{
183
76968
	return cbs_get_u(cbs, out, 3);
184
}
185
186
int
187
CBS_get_u32(CBS *cbs, uint32_t *out)
188
{
189
2582
	return cbs_get_u(cbs, out, 4);
190
}
191
192
int
193
CBS_get_bytes(CBS *cbs, CBS *out, size_t len)
194
{
195
185206
	const uint8_t *v;
196
197
92603
	if (!cbs_get(cbs, &v, len))
198
42
		return 0;
199
200
92561
	CBS_init(out, v, len);
201
92561
	return 1;
202
92603
}
203
204
static int
205
cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len)
206
{
207
83454
	uint32_t len;
208
209
41727
	if (!cbs_get_u(cbs, &len, len_len))
210
		return 0;
211
212
41727
	return CBS_get_bytes(cbs, out, len);
213
41727
}
214
215
int
216
CBS_get_u8_length_prefixed(CBS *cbs, CBS *out)
217
{
218
70116
	return cbs_get_length_prefixed(cbs, out, 1);
219
}
220
221
int
222
CBS_get_u16_length_prefixed(CBS *cbs, CBS *out)
223
{
224
5742
	return cbs_get_length_prefixed(cbs, out, 2);
225
}
226
227
int
228
CBS_get_u24_length_prefixed(CBS *cbs, CBS *out)
229
{
230
7596
	return cbs_get_length_prefixed(cbs, out, 3);
231
}
232
233
int
234
CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned int *out_tag,
235
    size_t *out_header_len)
236
{
237
4870
	return cbs_get_any_asn1_element_internal(cbs, out, out_tag,
238
	    out_header_len, 1);
239
}
240
241
/*
242
 * Review X.690 for details on ASN.1 DER encoding.
243
 *
244
 * If non-strict mode is enabled, then DER rules are relaxed
245
 * for indefinite constructs (violates DER but a little closer to BER).
246
 * Non-strict mode should only be used by bs_ber.c
247
 *
248
 * Sections 8, 10 and 11 for DER encoding
249
 */
250
int
251
cbs_get_any_asn1_element_internal(CBS *cbs, CBS *out, unsigned int *out_tag,
252
    size_t *out_header_len, int strict)
253
{
254
5056
	uint8_t tag, length_byte;
255
2528
	CBS header = *cbs;
256
2528
	CBS throwaway;
257
	size_t len;
258
259
2528
	if (out == NULL)
260
		out = &throwaway;
261
262
	/*
263
	 * Get identifier octet and length octet.  Only 1 octet for each
264
	 * is a CBS limitation.
265
	 */
266

5056
	if (!CBS_get_u8(&header, &tag) || !CBS_get_u8(&header, &length_byte))
267
		return 0;
268
269
	/* CBS limitation: long form tags are not supported. */
270
2528
	if ((tag & 0x1f) == 0x1f)
271
		return 0;
272
273
2528
	if (out_tag != NULL)
274
2528
		*out_tag = tag;
275
276
2528
	if ((length_byte & 0x80) == 0) {
277
		/* Short form length. */
278
2427
		len = ((size_t) length_byte) + 2;
279
2427
		if (out_header_len != NULL)
280
2427
			*out_header_len = 2;
281
282
	} else {
283
		/* Long form length. */
284
101
		const size_t num_bytes = length_byte & 0x7f;
285
101
		uint32_t len32;
286
287
		/* ASN.1 reserved value for future extensions */
288
101
		if (num_bytes == 0x7f)
289
			return 0;
290
291
		/* Handle indefinite form length */
292
101
		if (num_bytes == 0) {
293
			/* DER encoding doesn't allow for indefinite form. */
294
33
			if (strict)
295
3
				return 0;
296
297
			/* Primitive cannot use indefinite in BER or DER. */
298
30
			if ((tag & CBS_ASN1_CONSTRUCTED) == 0)
299
				return 0;
300
301
			/* Constructed, indefinite length allowed in BER. */
302
30
			if (out_header_len != NULL)
303
30
				*out_header_len = 2;
304
30
			return CBS_get_bytes(cbs, out, 2);
305
		}
306
307
		/* CBS limitation. */
308
68
		if (num_bytes > 4)
309
			return 0;
310
311
68
		if (!cbs_get_u(&header, &len32, num_bytes))
312
			return 0;
313
314
		/* DER has a minimum length octet requirement. */
315
68
		if (len32 < 128)
316
			/* Should have used short form instead */
317
3
			return 0;
318
319
65
		if ((len32 >> ((num_bytes - 1) * 8)) == 0)
320
			/* Length should have been at least one byte shorter. */
321
3
			return 0;
322
323
62
		len = len32;
324
62
		if (len + 2 + num_bytes < len)
325
			/* Overflow. */
326
			return 0;
327
328
62
		len += 2 + num_bytes;
329
62
		if (out_header_len != NULL)
330
62
			*out_header_len = 2 + num_bytes;
331
163
	}
332
333
2489
	return CBS_get_bytes(cbs, out, len);
334
2528
}
335
336
static int
337
cbs_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value, int skip_header)
338
{
339
4870
	size_t header_len;
340
2435
	unsigned int tag;
341
2435
	CBS throwaway;
342
343
2435
	if (out == NULL)
344
		out = &throwaway;
345
346

4855
	if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
347
2420
	    tag != tag_value)
348
21
		return 0;
349
350

4828
	if (skip_header && !CBS_skip(out, header_len)) {
351
		assert(0);
352
		return 0;
353
	}
354
355
2414
	return 1;
356
2435
}
357
358
int
359
CBS_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value)
360
{
361
4870
	return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */);
362
}
363
364
int
365
CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned int tag_value)
366
{
367
	return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */);
368
}
369
370
int
371
CBS_peek_asn1_tag(const CBS *cbs, unsigned int tag_value)
372
{
373
3170
	if (CBS_len(cbs) < 1)
374
759
		return 0;
375
376
	/*
377
	 * Tag number 31 indicates the start of a long form number.
378
	 * This is valid in ASN.1, but CBS only supports short form.
379
	 */
380
826
	if ((tag_value & 0x1f) == 0x1f)
381
		return 0;
382
383
826
	return CBS_data(cbs)[0] == tag_value;
384
1585
}
385
386
/* Encoding details are in ASN.1: X.690 section 8.3 */
387
int
388
CBS_get_asn1_uint64(CBS *cbs, uint64_t *out)
389
{
390
1614
	CBS bytes;
391
	const uint8_t *data;
392
	size_t i, len;
393
394
807
	if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER))
395
3
		return 0;
396
397
804
	*out = 0;
398
804
	data = CBS_data(&bytes);
399
804
	len = CBS_len(&bytes);
400
401
804
	if (len == 0)
402
		/* An INTEGER is encoded with at least one content octet. */
403
3
		return 0;
404
405
801
	if ((data[0] & 0x80) != 0)
406
		/* Negative number. */
407
6
		return 0;
408
409

843
	if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0)
410
		/* Violates smallest encoding rule: excessive leading zeros. */
411
3
		return 0;
412
413
5280
	for (i = 0; i < len; i++) {
414
1851
		if ((*out >> 56) != 0)
415
			/* Too large to represent as a uint64_t. */
416
3
			return 0;
417
418
1848
		*out <<= 8;
419
1848
		*out |= data[i];
420
	}
421
422
789
	return 1;
423
807
}
424
425
int
426
CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned int tag)
427
{
428
3152
	if (CBS_peek_asn1_tag(cbs, tag)) {
429
632
		if (!CBS_get_asn1(cbs, out, tag))
430
			return 0;
431
432
632
		*out_present = 1;
433
632
	} else {
434
944
		*out_present = 0;
435
	}
436
1576
	return 1;
437
1576
}
438
439
int
440
CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
441
    unsigned int tag)
442
{
443
1176
	CBS child;
444
588
	int present;
445
446
588
	if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
447
		return 0;
448
449
588
	if (present) {
450

407
		if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
451
202
		    CBS_len(&child) != 0)
452
3
			return 0;
453
	} else {
454
383
		CBS_init(out, NULL, 0);
455
	}
456
585
	if (out_present)
457
582
		*out_present = present;
458
459
585
	return 1;
460
588
}
461
462
int
463
CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned int tag,
464
    uint64_t default_value)
465
{
466
1552
	CBS child;
467
776
	int present;
468
469
776
	if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
470
		return 0;
471
472
776
	if (present) {
473

775
		if (!CBS_get_asn1_uint64(&child, out) ||
474
386
		    CBS_len(&child) != 0)
475
3
			return 0;
476
	} else {
477
387
		*out = default_value;
478
	}
479
773
	return 1;
480
776
}
481
482
int
483
CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned int tag,
484
    int default_value)
485
{
486
24
	CBS child, child2;
487
12
	int present;
488
489
12
	if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
490
		return 0;
491
492
12
	if (present) {
493
		uint8_t boolean;
494
495

18
		if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
496
18
		    CBS_len(&child2) != 1 || CBS_len(&child) != 0)
497
			return 0;
498
499
9
		boolean = CBS_data(&child2)[0];
500
9
		if (boolean == 0)
501
3
			*out = 0;
502
6
		else if (boolean == 0xff)
503
3
			*out = 1;
504
		else
505
3
			return 0;
506
507
6
	} else {
508
3
		*out = default_value;
509
	}
510
9
	return 1;
511
12
}