GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libssl/bs_cbs.c Lines: 197 219 90.0 %
Date: 2017-11-07 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
287330
	cbs->data = data;
31
143665
	cbs->initial_len = len;
32
143665
	cbs->len = len;
33
143665
}
34
35
void
36
CBS_dup(const CBS *cbs, CBS *out)
37
{
38
556
	CBS_init(out, CBS_data(cbs), CBS_len(cbs));
39
278
	out->initial_len = cbs->initial_len;
40
278
}
41
42
static int
43
cbs_get(CBS *cbs, const uint8_t **p, size_t n)
44
{
45
541372
	if (cbs->len < n)
46
50
		return 0;
47
48
270636
	*p = cbs->data;
49
270636
	cbs->data += n;
50
270636
	cbs->len -= n;
51
270636
	return 1;
52
270686
}
53
54
size_t
55
CBS_offset(const CBS *cbs)
56
{
57
88
	return cbs->initial_len - cbs->len;
58
}
59
60
int
61
CBS_skip(CBS *cbs, size_t len)
62
{
63
7596
	const uint8_t *dummy;
64
7596
	return cbs_get(cbs, &dummy, len);
65
3798
}
66
67
const uint8_t *
68
CBS_data(const CBS *cbs)
69
{
70
57082
	return cbs->data;
71
}
72
73
size_t
74
CBS_len(const CBS *cbs)
75
{
76
226216
	return cbs->len;
77
}
78
79
int
80
CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len)
81
{
82
4582
	free(*out_ptr);
83
2291
	*out_ptr = NULL;
84
2291
	*out_len = 0;
85
86
2291
	if (cbs->len == 0)
87
		return 1;
88
89
2291
	if ((*out_ptr = malloc(cbs->len)) == NULL)
90
		return 0;
91
92
2291
	memcpy(*out_ptr, cbs->data, cbs->len);
93
94
2291
	*out_len = cbs->len;
95
2291
	return 1;
96
2291
}
97
98
int
99
CBS_strdup(const CBS *cbs, char **out_ptr)
100
{
101
48
	free(*out_ptr);
102
24
	*out_ptr = strndup((const char *)cbs->data, cbs->len);
103
24
	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
22060
	if (dst_len < cbs->len)
110
		return 0;
111
112
11030
	memmove(dst, cbs->data, cbs->len);
113
114
11030
	if (copied != NULL)
115
1901
		*copied = cbs->len;
116
117
11030
	return 1;
118
11030
}
119
120
int
121
CBS_contains_zero_byte(const CBS *cbs)
122
{
123
2294
	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
63810
	if (len != cbs->len)
130
4
		return 0;
131
132
31901
	return timingsafe_memcmp(cbs->data, data, len) == 0;
133
31905
}
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
277480
	const uint8_t *data;
141
142
138740
	if (len < 1 || len > 4)
143
		return 0;
144
145
138740
	if (!cbs_get(cbs, &data, len))
146
1
		return 0;
147
148
850296
	for (i = 0; i < len; i++) {
149
286409
		result <<= 8;
150
286409
		result |= data[i];
151
	}
152
138739
	*out = result;
153
138739
	return 1;
154
138740
}
155
156
int
157
CBS_get_u8(CBS *cbs, uint8_t *out)
158
{
159
146658
	const uint8_t *v;
160
161
73329
	if (!cbs_get(cbs, &v, 1))
162
8
		return 0;
163
164
73321
	*out = *v;
165
73321
	return 1;
166
73329
}
167
168
int
169
CBS_get_u16(CBS *cbs, uint16_t *out)
170
{
171
177258
	uint32_t v;
172
173
88629
	if (!cbs_get_u(cbs, &v, 2))
174
1
		return 0;
175
176
88628
	*out = v;
177
88628
	return 1;
178
88629
}
179
180
int
181
CBS_get_u24(CBS *cbs, uint32_t *out)
182
{
183
45900
	return cbs_get_u(cbs, out, 3);
184
}
185
186
int
187
CBS_get_u32(CBS *cbs, uint32_t *out)
188
{
189
2246
	return cbs_get_u(cbs, out, 4);
190
}
191
192
int
193
CBS_get_bytes(CBS *cbs, CBS *out, size_t len)
194
{
195
109638
	const uint8_t *v;
196
197
54819
	if (!cbs_get(cbs, &v, len))
198
29
		return 0;
199
200
54790
	CBS_init(out, v, len);
201
54790
	return 1;
202
54819
}
203
204
static int
205
cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len)
206
{
207
51900
	uint32_t len;
208
209
25950
	if (!cbs_get_u(cbs, &len, len_len))
210
		return 0;
211
212
25950
	return CBS_get_bytes(cbs, out, len);
213
25950
}
214
215
int
216
CBS_get_u8_length_prefixed(CBS *cbs, CBS *out)
217
{
218
39036
	return cbs_get_length_prefixed(cbs, out, 1);
219
}
220
221
int
222
CBS_get_u16_length_prefixed(CBS *cbs, CBS *out)
223
{
224
6326
	return cbs_get_length_prefixed(cbs, out, 2);
225
}
226
227
int
228
CBS_get_u24_length_prefixed(CBS *cbs, CBS *out)
229
{
230
6538
	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
6468
	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
6716
	uint8_t tag, length_byte;
255
3358
	CBS header = *cbs;
256
3358
	CBS throwaway;
257
	size_t len;
258
259
3358
	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

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

6448
	if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) ||
347
3214
	    tag != tag_value)
348
28
		return 0;
349
350

6412
	if (skip_header && !CBS_skip(out, header_len)) {
351
		assert(0);
352
		return 0;
353
	}
354
355
3206
	return 1;
356
3234
}
357
358
int
359
CBS_get_asn1(CBS *cbs, CBS *out, unsigned int tag_value)
360
{
361
6468
	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
4216
	if (CBS_len(cbs) < 1)
374
1012
		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
1096
	if ((tag_value & 0x1f) == 0x1f)
381
		return 0;
382
383
1096
	return CBS_data(cbs)[0] == tag_value;
384
2108
}
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
2144
	CBS bytes;
391
	const uint8_t *data;
392
	size_t i, len;
393
394
1072
	if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER))
395
4
		return 0;
396
397
1068
	*out = 0;
398
1068
	data = CBS_data(&bytes);
399
1068
	len = CBS_len(&bytes);
400
401
1068
	if (len == 0)
402
		/* An INTEGER is encoded with at least one content octet. */
403
4
		return 0;
404
405
1064
	if ((data[0] & 0x80) != 0)
406
		/* Negative number. */
407
8
		return 0;
408
409

1120
	if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0)
410
		/* Violates smallest encoding rule: excessive leading zeros. */
411
4
		return 0;
412
413
7016
	for (i = 0; i < len; i++) {
414
2460
		if ((*out >> 56) != 0)
415
			/* Too large to represent as a uint64_t. */
416
4
			return 0;
417
418
2456
		*out <<= 8;
419
2456
		*out |= data[i];
420
	}
421
422
1048
	return 1;
423
1072
}
424
425
int
426
CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned int tag)
427
{
428
4192
	if (CBS_peek_asn1_tag(cbs, tag)) {
429
838
		if (!CBS_get_asn1(cbs, out, tag))
430
			return 0;
431
432
838
		*out_present = 1;
433
838
	} else {
434
1258
		*out_present = 0;
435
	}
436
2096
	return 1;
437
2096
}
438
439
int
440
CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present,
441
    unsigned int tag)
442
{
443
1564
	CBS child;
444
782
	int present;
445
446
782
	if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
447
		return 0;
448
449
782
	if (present) {
450

540
		if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) ||
451
268
		    CBS_len(&child) != 0)
452
4
			return 0;
453
	} else {
454
510
		CBS_init(out, NULL, 0);
455
	}
456
778
	if (out_present)
457
774
		*out_present = present;
458
459
778
	return 1;
460
782
}
461
462
int
463
CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned int tag,
464
    uint64_t default_value)
465
{
466
2064
	CBS child;
467
1032
	int present;
468
469
1032
	if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
470
		return 0;
471
472
1032
	if (present) {
473

1028
		if (!CBS_get_asn1_uint64(&child, out) ||
474
512
		    CBS_len(&child) != 0)
475
4
			return 0;
476
	} else {
477
516
		*out = default_value;
478
	}
479
1028
	return 1;
480
1032
}
481
482
int
483
CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned int tag,
484
    int default_value)
485
{
486
32
	CBS child, child2;
487
16
	int present;
488
489
16
	if (!CBS_get_optional_asn1(cbs, &child, &present, tag))
490
		return 0;
491
492
16
	if (present) {
493
		uint8_t boolean;
494
495

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