GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/crypto/../../libssl/src/crypto/asn1/a_object.c Lines: 51 209 24.4 %
Date: 2016-12-06 Branches: 23 132 17.4 %

Line Branch Exec Source
1
/* $OpenBSD: a_object.c,v 1.26 2016/03/17 03:51:49 beck Exp $ */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 *
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 *
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 *
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 *
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
#include <limits.h>
60
#include <stdio.h>
61
#include <string.h>
62
63
#include <openssl/asn1.h>
64
#include <openssl/bn.h>
65
#include <openssl/err.h>
66
#include <openssl/buffer.h>
67
#include <openssl/objects.h>
68
69
int
70
i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
71
{
72
	unsigned char *p;
73
	int objsize;
74
75
	if ((a == NULL) || (a->data == NULL))
76
		return (0);
77
78
	objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
79
	if (pp == NULL)
80
		return objsize;
81
82
	p = *pp;
83
	ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
84
	memcpy(p, a->data, a->length);
85
	p += a->length;
86
87
	*pp = p;
88
	return (objsize);
89
}
90
91
int
92
a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
93
{
94
	int i, first, len = 0, c, use_bn;
95
	char ftmp[24], *tmp = ftmp;
96
	int tmpsize = sizeof ftmp;
97
	const char *p;
98
	unsigned long l;
99
	BIGNUM *bl = NULL;
100
101
	if (num == 0)
102
		return (0);
103
	else if (num == -1)
104
		num = strlen(buf);
105
106
	p = buf;
107
	c = *(p++);
108
	num--;
109
	if ((c >= '0') && (c <= '2')) {
110
		first= c-'0';
111
	} else {
112
		ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
113
		goto err;
114
	}
115
116
	if (num <= 0) {
117
		ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
118
		goto err;
119
	}
120
	c = *(p++);
121
	num--;
122
	for (;;) {
123
		if (num <= 0)
124
			break;
125
		if ((c != '.') && (c != ' ')) {
126
			ASN1err(ASN1_F_A2D_ASN1_OBJECT,
127
			    ASN1_R_INVALID_SEPARATOR);
128
			goto err;
129
		}
130
		l = 0;
131
		use_bn = 0;
132
		for (;;) {
133
			if (num <= 0)
134
				break;
135
			num--;
136
			c = *(p++);
137
			if ((c == ' ') || (c == '.'))
138
				break;
139
			if ((c < '0') || (c > '9')) {
140
				ASN1err(ASN1_F_A2D_ASN1_OBJECT,
141
				    ASN1_R_INVALID_DIGIT);
142
				goto err;
143
			}
144
			if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
145
				use_bn = 1;
146
				if (!bl)
147
					bl = BN_new();
148
				if (!bl || !BN_set_word(bl, l))
149
					goto err;
150
			}
151
			if (use_bn) {
152
				if (!BN_mul_word(bl, 10L) ||
153
				    !BN_add_word(bl, c-'0'))
154
					goto err;
155
			} else
156
				l = l * 10L + (long)(c - '0');
157
		}
158
		if (len == 0) {
159
			if ((first < 2) && (l >= 40)) {
160
				ASN1err(ASN1_F_A2D_ASN1_OBJECT,
161
				    ASN1_R_SECOND_NUMBER_TOO_LARGE);
162
				goto err;
163
			}
164
			if (use_bn) {
165
				if (!BN_add_word(bl, first * 40))
166
					goto err;
167
			} else
168
				l += (long)first * 40;
169
		}
170
		i = 0;
171
		if (use_bn) {
172
			int blsize;
173
			blsize = BN_num_bits(bl);
174
			blsize = (blsize + 6) / 7;
175
			if (blsize > tmpsize) {
176
				if (tmp != ftmp)
177
					free(tmp);
178
				tmpsize = blsize + 32;
179
				tmp = malloc(tmpsize);
180
				if (!tmp)
181
					goto err;
182
			}
183
			while (blsize--)
184
				tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
185
		} else {
186
187
			for (;;) {
188
				tmp[i++] = (unsigned char)l & 0x7f;
189
				l >>= 7L;
190
				if (l == 0L)
191
					break;
192
			}
193
194
		}
195
		if (out != NULL) {
196
			if (len + i > olen) {
197
				ASN1err(ASN1_F_A2D_ASN1_OBJECT,
198
				    ASN1_R_BUFFER_TOO_SMALL);
199
				goto err;
200
			}
201
			while (--i > 0)
202
				out[len++] = tmp[i]|0x80;
203
			out[len++] = tmp[0];
204
		} else
205
			len += i;
206
	}
207
	if (tmp != ftmp)
208
		free(tmp);
209
	BN_free(bl);
210
	return (len);
211
212
err:
213
	if (tmp != ftmp)
214
		free(tmp);
215
	BN_free(bl);
216
	return (0);
217
}
218
219
int
220
i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
221
2
{
222
2
	return OBJ_obj2txt(buf, buf_len, a, 0);
223
}
224
225
int
226
i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
227
{
228
	char *tmp = NULL;
229
	size_t tlen = 256;
230
	int i = -1;
231
232
	if ((a == NULL) || (a->data == NULL))
233
		return(BIO_write(bp, "NULL", 4));
234
	if ((tmp = malloc(tlen)) == NULL)
235
		return -1;
236
	i = i2t_ASN1_OBJECT(tmp, tlen, a);
237
	if (i > (int)(tlen - 1)) {
238
		explicit_bzero(tmp, tlen);
239
		free(tmp);
240
		if ((tmp = malloc(i + 1)) == NULL)
241
			return -1;
242
		tlen = i + 1;
243
		i = i2t_ASN1_OBJECT(tmp, tlen, a);
244
	}
245
	if (i <= 0)
246
		i = BIO_write(bp, "<INVALID>", 9);
247
	else
248
		i = BIO_write(bp, tmp, i);
249
	explicit_bzero(tmp, tlen);
250
	free(tmp);
251
	return (i);
252
}
253
254
ASN1_OBJECT *
255
d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, long length)
256
{
257
	const unsigned char *p;
258
	long len;
259
	int tag, xclass;
260
	int inf, i;
261
	ASN1_OBJECT *ret = NULL;
262
263
	p = *pp;
264
	inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
265
	if (inf & 0x80) {
266
		i = ASN1_R_BAD_OBJECT_HEADER;
267
		goto err;
268
	}
269
270
	if (tag != V_ASN1_OBJECT) {
271
		i = ASN1_R_EXPECTING_AN_OBJECT;
272
		goto err;
273
	}
274
	ret = c2i_ASN1_OBJECT(a, &p, len);
275
	if (ret)
276
		*pp = p;
277
	return ret;
278
279
err:
280
	ASN1err(ASN1_F_D2I_ASN1_OBJECT, i);
281
	return (NULL);
282
}
283
284
ASN1_OBJECT *
285
c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, long len)
286
2468
{
287
2468
	ASN1_OBJECT *ret = NULL;
288
	const unsigned char *p;
289
	unsigned char *data;
290
	int i, length;
291
292
	/*
293
	 * Sanity check OID encoding:
294
	 * - need at least one content octet
295
	 * - MSB must be clear in the last octet
296
	 * - can't have leading 0x80 in subidentifiers, see: X.690 8.19.2
297
	 */
298

2468
	if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
299
	    p[len - 1] & 0x80) {
300
		ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
301
		return (NULL);
302
	}
303
304
	/* Now 0 < len <= INT_MAX, so the cast is safe. */
305
2468
	length = (int)len;
306
13255
	for (i = 0; i < length; i++, p++) {
307

10787
		if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
308
			ASN1err(ASN1_F_C2I_ASN1_OBJECT,
309
			    ASN1_R_INVALID_OBJECT_ENCODING);
310
			return NULL;
311
		}
312
	}
313
314
	/* only the ASN1_OBJECTs from the 'table' will have values
315
	 * for ->sn or ->ln */
316

2468
	if ((a == NULL) || ((*a) == NULL) ||
317
	    !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
318
2468
		if ((ret = ASN1_OBJECT_new()) == NULL)
319
			return (NULL);
320
	} else
321
		ret = (*a);
322
323
2468
	p = *pp;
324
	/* detach data from object */
325
2468
	data = (unsigned char *)ret->data;
326
2468
	if (data != NULL)
327
		explicit_bzero(data, ret->length);
328
2468
	free(data);
329
2468
	data = malloc(length);
330
2468
	if (data == NULL) {
331
		i = ERR_R_MALLOC_FAILURE;
332
		goto err;
333
	}
334
2468
	ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
335
2468
	memcpy(data, p, length);
336
	/* reattach data to object, after which it remains const */
337
2468
	ret->data = data;
338
2468
	ret->length = length;
339
2468
	ret->sn = NULL;
340
2468
	ret->ln = NULL;
341
	/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
342
2468
	p += length;
343
344
2468
	if (a != NULL)
345
2468
		(*a) = ret;
346
2468
	*pp = p;
347
2468
	return (ret);
348
349
err:
350
	ASN1err(ASN1_F_C2I_ASN1_OBJECT, i);
351
	if ((ret != NULL) && ((a == NULL) || (*a != ret)))
352
		ASN1_OBJECT_free(ret);
353
	return (NULL);
354
}
355
356
ASN1_OBJECT *
357
ASN1_OBJECT_new(void)
358
3820
{
359
	ASN1_OBJECT *ret;
360
361
3820
	ret = malloc(sizeof(ASN1_OBJECT));
362
3820
	if (ret == NULL) {
363
		ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
364
		return (NULL);
365
	}
366
3820
	ret->length = 0;
367
3820
	ret->data = NULL;
368
3820
	ret->nid = 0;
369
3820
	ret->sn = NULL;
370
3820
	ret->ln = NULL;
371
3820
	ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
372
3820
	return (ret);
373
}
374
375
void
376
ASN1_OBJECT_free(ASN1_OBJECT *a)
377
1478
{
378
1478
	if (a == NULL)
379
		return;
380
1478
	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
381
1352
		free((void *)a->sn);
382
1352
		free((void *)a->ln);
383
1352
		a->sn = a->ln = NULL;
384
	}
385
1478
	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
386
1377
		if (a->data != NULL)
387
1377
			explicit_bzero((void *)a->data, a->length);
388
1377
		free((void *)a->data);
389
1377
		a->data = NULL;
390
1377
		a->length = 0;
391
	}
392
1478
	if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
393
1377
		free(a);
394
}
395
396
ASN1_OBJECT *
397
ASN1_OBJECT_create(int nid, unsigned char *data, int len,
398
    const char *sn, const char *ln)
399
{
400
	ASN1_OBJECT o;
401
402
	o.sn = sn;
403
	o.ln = ln;
404
	o.data = data;
405
	o.nid = nid;
406
	o.length = len;
407
	o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
408
	    ASN1_OBJECT_FLAG_DYNAMIC_DATA;
409
	return (OBJ_dup(&o));
410
}