GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: lib/libcrypto/asn1/tasn_enc.c Lines: 219 253 86.6 %
Date: 2017-11-13 Branches: 149 188 79.3 %

Line Branch Exec Source
1
/* $OpenBSD: tasn_enc.c,v 1.21 2016/12/30 16:04:34 jsing Exp $ */
2
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3
 * project 2000.
4
 */
5
/* ====================================================================
6
 * Copyright (c) 2000-2004 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
 *    licensing@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
#include <stddef.h>
60
#include <string.h>
61
62
#include <openssl/asn1.h>
63
#include <openssl/asn1t.h>
64
#include <openssl/objects.h>
65
66
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
67
    const ASN1_ITEM *it, int tag, int aclass);
68
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
69
    int skcontlen, const ASN1_ITEM *item, int do_sort, int iclass);
70
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
71
    const ASN1_TEMPLATE *tt, int tag, int aclass);
72
static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
73
    const ASN1_ITEM *it, int flags);
74
static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
75
    const ASN1_ITEM *it);
76
77
/* Top level i2d equivalents: the 'ndef' variant instructs the encoder
78
 * to use indefinite length constructed encoding, where appropriate
79
 */
80
81
int
82
ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
83
{
84
	return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
85
}
86
87
int
88
ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
89
{
90
20496
	return asn1_item_flags_i2d(val, out, it, 0);
91
}
92
93
/* Encode an ASN1 item, this is use by the
94
 * standard 'i2d' function. 'out' points to
95
 * a buffer to output the data to.
96
 *
97
 * The new i2d has one additional feature. If the output
98
 * buffer is NULL (i.e. *out == NULL) then a buffer is
99
 * allocated and populated with the encoding.
100
 */
101
102
static int
103
asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it,
104
    int flags)
105
{
106

18996
	if (out && !*out) {
107
6800
		unsigned char *p, *buf;
108
		int len;
109
6800
		len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
110
6800
		if (len <= 0)
111
			return len;
112
6800
		buf = malloc(len);
113
6800
		if (!buf)
114
			return -1;
115
6800
		p = buf;
116
6800
		ASN1_item_ex_i2d(&val, &p, it, -1, flags);
117
6800
		*out = buf;
118
6800
		return len;
119
6800
	}
120
121
3448
	return ASN1_item_ex_i2d(&val, out, it, -1, flags);
122
10248
}
123
124
/* Encode an item, taking care of IMPLICIT tagging (if any).
125
 * This function performs the normal item handling: it can be
126
 * used in external types.
127
 */
128
129
int
130
ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it,
131
    int tag, int aclass)
132
{
133
	const ASN1_TEMPLATE *tt = NULL;
134
3013906
	int i, seqcontlen, seqlen, ndef = 1;
135
	const ASN1_EXTERN_FUNCS *ef;
136
1506953
	const ASN1_AUX *aux = it->funcs;
137
	ASN1_aux_cb *asn1_cb = NULL;
138
139

2288067
	if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
140
114
		return 0;
141
142

1555163
	if (aux && aux->asn1_cb)
143
34490
		asn1_cb = aux->asn1_cb;
144
145

1507050
	switch (it->itype) {
146
147
	case ASN1_ITYPE_PRIMITIVE:
148
725839
		if (it->templates)
149
208059
			return asn1_template_ex_i2d(pval, out, it->templates,
150
			    tag, aclass);
151
517780
		return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
152
		break;
153
154
	case ASN1_ITYPE_MSTRING:
155
416200
		return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
156
157
	case ASN1_ITYPE_CHOICE:
158

2958
		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
159
			return 0;
160
2950
		i = asn1_get_choice_selector(pval, it);
161

5900
		if ((i >= 0) && (i < it->tcount)) {
162
			ASN1_VALUE **pchval;
163
			const ASN1_TEMPLATE *chtt;
164
2950
			chtt = it->templates + i;
165
2950
			pchval = asn1_get_field_ptr(pval, chtt);
166
2950
			return asn1_template_ex_i2d(pchval, out, chtt,
167
			    -1, aclass);
168
		}
169
		/* Fixme: error condition if selector out of range */
170
		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
171
			return 0;
172
		break;
173
174
	case ASN1_ITYPE_EXTERN:
175
		/* If new style i2d it does all the work */
176
968
		ef = it->funcs;
177
968
		return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
178
179
	case ASN1_ITYPE_NDEF_SEQUENCE:
180
		/* Use indefinite length constructed if requested */
181
211
		if (aclass & ASN1_TFLG_NDEF)
182
			ndef = 2;
183
		/* fall through */
184
185
	case ASN1_ITYPE_SEQUENCE:
186
360882
		i = asn1_enc_restore(&seqcontlen, out, pval, it);
187
		/* An error occurred */
188
360882
		if (i < 0)
189
			return 0;
190
		/* We have a valid cached encoding... */
191
360882
		if (i > 0)
192
12786
			return seqcontlen;
193
		/* Otherwise carry on */
194
348096
		seqcontlen = 0;
195
		/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
196
348096
		if (tag == -1) {
197
			tag = V_ASN1_SEQUENCE;
198
			/* Retain any other flags in aclass */
199
348032
			aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) |
200
			    V_ASN1_UNIVERSAL;
201
348032
		}
202

357118
		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
203
			return 0;
204
		/* First work out sequence content length */
205
2140706
		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
206
			const ASN1_TEMPLATE *seqtt;
207
			ASN1_VALUE **pseqval;
208
722257
			seqtt = asn1_do_adb(pval, tt, 1);
209
722257
			if (!seqtt)
210
				return 0;
211
722257
			pseqval = asn1_get_field_ptr(pval, seqtt);
212
			/* FIXME: check for errors in enhanced version */
213
722257
			seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
214
			    -1, aclass);
215
722257
		}
216
217
348096
		seqlen = ASN1_object_size(ndef, seqcontlen, tag);
218
348096
		if (!out)
219
230877
			return seqlen;
220
		/* Output SEQUENCE header */
221
117219
		ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
222
722626
		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
223
			const ASN1_TEMPLATE *seqtt;
224
			ASN1_VALUE **pseqval;
225
244094
			seqtt = asn1_do_adb(pval, tt, 1);
226
244094
			if (!seqtt)
227
				return 0;
228
244094
			pseqval = asn1_get_field_ptr(pval, seqtt);
229
			/* FIXME: check for errors in enhanced version */
230
244094
			asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
231
244094
		}
232
117219
		if (ndef == 2)
233
			ASN1_put_eoc(out);
234

121583
		if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
235
			return 0;
236
117219
		return seqlen;
237
238
	default:
239
		return 0;
240
241
	}
242
	return 0;
243
1506953
}
244
245
int
246
ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
247
    const ASN1_TEMPLATE *tt)
248
{
249
	return asn1_template_ex_i2d(pval, out, tt, -1, 0);
250
}
251
252
static int
253
asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
254
    const ASN1_TEMPLATE *tt, int tag, int iclass)
255
{
256
	int i, ret, flags, ttag, tclass, ndef;
257
2354720
	flags = tt->flags;
258
	/* Work out tag and class to use: tagging may come
259
	 * either from the template or the arguments, not both
260
	 * because this would create ambiguity. Additionally
261
	 * the iclass argument may contain some additional flags
262
	 * which should be noted and passed down to other levels.
263
	 */
264
1177360
	if (flags & ASN1_TFLG_TAG_MASK) {
265
		/* Error if argument and template tagging */
266
4829
		if (tag != -1)
267
			/* FIXME: error code here */
268
			return -1;
269
		/* Get tagging from template */
270
4829
		ttag = tt->tag;
271
4829
		tclass = flags & ASN1_TFLG_TAG_CLASS;
272
1177360
	} else if (tag != -1) {
273
		/* No template tagging, get from arguments */
274
		ttag = tag;
275
		tclass = iclass & ASN1_TFLG_TAG_CLASS;
276
	} else {
277
		ttag = -1;
278
		tclass = 0;
279
	}
280
	/*
281
	 * Remove any class mask from iflag.
282
	 */
283
1177360
	iclass &= ~ASN1_TFLG_TAG_CLASS;
284
285
	/* At this point 'ttag' contains the outer tag to use,
286
	 * 'tclass' is the class and iclass is any flags passed
287
	 * to this function.
288
	 */
289
290
	/* if template and arguments require ndef, use it */
291

1177491
	if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
292
		ndef = 2;
293
	else
294
		ndef = 1;
295
296
1177360
	if (flags & ASN1_TFLG_SK_MASK) {
297
		/* SET OF, SEQUENCE OF */
298
210212
		STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
299
		int isset, sktag, skaclass;
300
		int skcontlen, sklen;
301
210212
		ASN1_VALUE *skitem;
302
303
210212
		if (!*pval)
304
872
			return 0;
305
306
209340
		if (flags & ASN1_TFLG_SET_OF) {
307
			isset = 1;
308
			/* 2 means we reorder */
309
208670
			if (flags & ASN1_TFLG_SEQUENCE_OF)
310
				isset = 2;
311
208670
		} else
312
			isset = 0;
313
314
		/* Work out inner tag value: if EXPLICIT
315
		 * or no tagging use underlying type.
316
		 */
317

209696
		if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
318
			sktag = ttag;
319
			skaclass = tclass;
320
222
		} else {
321
			skaclass = V_ASN1_UNIVERSAL;
322
209118
			if (isset)
323
208590
				sktag = V_ASN1_SET;
324
			else
325
				sktag = V_ASN1_SEQUENCE;
326
		}
327
328
		/* Determine total length of items */
329
		skcontlen = 0;
330
838950
		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
331
210135
			skitem = sk_ASN1_VALUE_value(sk, i);
332
210135
			skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
333
210135
			    tt->item, -1, iclass);
334
		}
335
209340
		sklen = ASN1_object_size(ndef, skcontlen, sktag);
336
		/* If EXPLICIT need length of surrounding tag */
337
209340
		if (flags & ASN1_TFLG_EXPTAG)
338
134
			ret = ASN1_object_size(ndef, sklen, ttag);
339
		else
340
			ret = sklen;
341
342
209340
		if (!out)
343
105150
			return ret;
344
345
		/* Now encode this lot... */
346
		/* EXPLICIT tag */
347
104190
		if (flags & ASN1_TFLG_EXPTAG)
348
38
			ASN1_put_object(out, ndef, sklen, ttag, tclass);
349
		/* SET or SEQUENCE and IMPLICIT tag */
350
104190
		ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
351
		/* And the stuff itself */
352
104190
		asn1_set_seq_out(sk, out, skcontlen, tt->item,
353
		    isset, iclass);
354
104190
		if (ndef == 2) {
355
			ASN1_put_eoc(out);
356
			if (flags & ASN1_TFLG_EXPTAG)
357
				ASN1_put_eoc(out);
358
		}
359
360
104190
		return ret;
361
210212
	}
362
363
967148
	if (flags & ASN1_TFLG_EXPTAG) {
364
		/* EXPLICIT tagging */
365
		/* Find length of tagged item */
366
2937
		i = ASN1_item_ex_i2d(pval, NULL, tt->item,
367
		    -1, iclass);
368
2937
		if (!i)
369
490
			return 0;
370
		/* Find length of EXPLICIT tag */
371
2447
		ret = ASN1_object_size(ndef, i, ttag);
372
2447
		if (out) {
373
			/* Output tag and item */
374
794
			ASN1_put_object(out, ndef, i, ttag, tclass);
375
794
			ASN1_item_ex_i2d(pval, out, tt->item,
376
			    -1, iclass);
377
794
			if (ndef == 2)
378
				ASN1_put_eoc(out);
379
		}
380
2447
		return ret;
381
	}
382
383
	/* Either normal or IMPLICIT tagging: combine class and flags */
384
1928422
	return ASN1_item_ex_i2d(pval, out, tt->item,
385
964211
	    ttag, tclass | iclass);
386
1177360
}
387
388
/* Temporary structure used to hold DER encoding of items for SET OF */
389
390
typedef	struct {
391
	unsigned char *data;
392
	int length;
393
	ASN1_VALUE *field;
394
} DER_ENC;
395
396
static int
397
der_cmp(const void *a, const void *b)
398
{
399
100
	const DER_ENC *d1 = a, *d2 = b;
400
	int cmplen, i;
401
402
50
	cmplen = (d1->length < d2->length) ? d1->length : d2->length;
403
50
	i = memcmp(d1->data, d2->data, cmplen);
404
50
	if (i)
405
50
		return i;
406
	return d1->length - d2->length;
407
50
}
408
409
/* Output the content octets of SET OF or SEQUENCE OF */
410
411
static int
412
asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, int skcontlen,
413
    const ASN1_ITEM *item, int do_sort, int iclass)
414
{
415
	int i;
416
208380
	ASN1_VALUE *skitem;
417
104190
	unsigned char *tmpdat = NULL, *p = NULL;
418
	DER_ENC *derlst = NULL, *tder;
419
420
104190
	if (do_sort) {
421
		/* Don't need to sort less than 2 items */
422
103940
		if (sk_ASN1_VALUE_num(sk) < 2)
423
103930
			do_sort = 0;
424
		else {
425
10
			derlst = reallocarray(NULL, sk_ASN1_VALUE_num(sk),
426
			    sizeof(*derlst));
427
10
			tmpdat = malloc(skcontlen);
428
10
			if (!derlst || !tmpdat) {
429
				free(derlst);
430
				free(tmpdat);
431
				return 0;
432
			}
433
		}
434
	}
435
	/* If not sorting just output each item */
436
104190
	if (!do_sort) {
437
417276
		for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
438
104458
			skitem = sk_ASN1_VALUE_value(sk, i);
439
104458
			ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
440
		}
441
104180
		return 1;
442
	}
443
10
	p = tmpdat;
444
445
	/* Doing sort: build up a list of each member's DER encoding */
446
100
	for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
447
40
		skitem = sk_ASN1_VALUE_value(sk, i);
448
40
		tder->data = p;
449
40
		tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
450
40
		tder->field = skitem;
451
	}
452
453
	/* Now sort them */
454
10
	qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
455
	/* Output sorted DER encoding */
456
10
	p = *out;
457
100
	for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
458
40
		memcpy(p, tder->data, tder->length);
459
40
		p += tder->length;
460
	}
461
10
	*out = p;
462
	/* If do_sort is 2 then reorder the STACK */
463
10
	if (do_sort == 2) {
464
100
		for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
465
40
			(void)sk_ASN1_VALUE_set(sk, i, tder->field);
466
	}
467
10
	free(derlst);
468
10
	free(tmpdat);
469
10
	return 1;
470
104190
}
471
472
static int
473
asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
474
    const ASN1_ITEM *it, int tag, int aclass)
475
{
476
	int len;
477
1867960
	int utype;
478
	int usetag;
479
	int ndef = 0;
480
481
933980
	utype = it->utype;
482
483
	/* Get length of content octets and maybe find
484
	 * out the underlying type.
485
	 */
486
487
933980
	len = asn1_ex_i2c(pval, NULL, &utype, it);
488
489
	/* If SEQUENCE, SET or OTHER then header is
490
	 * included in pseudo content octets so don't
491
	 * include tag+length. We need to check here
492
	 * because the call to asn1_ex_i2c() could change
493
	 * utype.
494
	 */
495
1867960
	if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
496
933980
	    (utype == V_ASN1_OTHER))
497
430
		usetag = 0;
498
	else
499
		usetag = 1;
500
501
	/* -1 means omit type */
502
933980
	if (len == -1)
503
4562
		return 0;
504
505
	/* -2 return is special meaning use ndef */
506
929418
	if (len == -2) {
507
		ndef = 2;
508
		len = 0;
509
	}
510
511
	/* If not implicitly tagged get tag from underlying type */
512
929418
	if (tag == -1)
513
929106
		tag = utype;
514
515
	/* Output tag+length followed by content octets */
516
929418
	if (out) {
517
233153
		if (usetag)
518
233071
			ASN1_put_object(out, ndef, len, tag, aclass);
519
233153
		asn1_ex_i2c(pval, *out, &utype, it);
520
233153
		if (ndef)
521
			ASN1_put_eoc(out);
522
		else
523
233153
			*out += len;
524
	}
525
526
929418
	if (usetag)
527
928988
		return ASN1_object_size(ndef, len, tag);
528
430
	return len;
529
933980
}
530
531
/* Produce content octets from a structure */
532
533
static int
534
asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
535
    const ASN1_ITEM *it)
536
{
537
	ASN1_BOOLEAN *tbool = NULL;
538
	ASN1_STRING *strtmp;
539
	ASN1_OBJECT *otmp;
540
	int utype;
541
	const unsigned char *cont;
542
1167133
	unsigned char c;
543
	int len;
544
	const ASN1_PRIMITIVE_FUNCS *pf;
545
546
1167133
	pf = it->funcs;
547

1199933
	if (pf && pf->prim_i2c)
548
32800
		return pf->prim_i2c(pval, cout, putype, it);
549
550
	/* Should type be omitted? */
551

1748428
	if ((it->itype != ASN1_ITYPE_PRIMITIVE) ||
552
614095
	    (it->utype != V_ASN1_BOOLEAN)) {
553
1133969
		if (!*pval)
554
2788
			return -1;
555
	}
556
557
1131545
	if (it->itype == ASN1_ITYPE_MSTRING) {
558
		/* If MSTRING type set the underlying type */
559
520238
		strtmp = (ASN1_STRING *)*pval;
560
520238
		utype = strtmp->type;
561
520238
		*putype = utype;
562
1131545
	} else if (it->utype == V_ASN1_ANY) {
563
		/* If ANY set type and pointer to value */
564
		ASN1_TYPE *typ;
565
21686
		typ = (ASN1_TYPE *)*pval;
566
21686
		utype = typ->type;
567
21686
		*putype = utype;
568
21686
		pval = &typ->value.asn1_value;
569
21686
	} else
570
589621
		utype = *putype;
571
572

1131545
	switch (utype) {
573
	case V_ASN1_OBJECT:
574
547405
		otmp = (ASN1_OBJECT *)*pval;
575
547405
		cont = otmp->data;
576
547405
		len = otmp->length;
577
547405
		break;
578
579
	case V_ASN1_NULL:
580
		cont = NULL;
581
		len = 0;
582
19738
		break;
583
584
	case V_ASN1_BOOLEAN:
585
364
		tbool = (ASN1_BOOLEAN *)pval;
586
364
		if (*tbool == -1)
587
244
			return -1;
588
120
		if (it->utype != V_ASN1_ANY) {
589
			/* Default handling if value == size field then omit */
590

216
			if (*tbool && (it->size > 0))
591
				return -1;
592

144
			if (!*tbool && !it->size)
593
24
				return -1;
594
		}
595
96
		c = (unsigned char)*tbool;
596
		cont = &c;
597
		len = 1;
598
96
		break;
599
600
	case V_ASN1_BIT_STRING:
601
35040
		return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
602
17520
		    cout ? &cout : NULL);
603
		break;
604
605
	case V_ASN1_INTEGER:
606
	case V_ASN1_ENUMERATED:
607
		/* These are all have the same content format
608
		 * as ASN1_INTEGER
609
		 */
610
21382
		return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval,
611
10691
		    cout ? &cout : NULL);
612
		break;
613
614
	case V_ASN1_OCTET_STRING:
615
	case V_ASN1_NUMERICSTRING:
616
	case V_ASN1_PRINTABLESTRING:
617
	case V_ASN1_T61STRING:
618
	case V_ASN1_VIDEOTEXSTRING:
619
	case V_ASN1_IA5STRING:
620
	case V_ASN1_UTCTIME:
621
	case V_ASN1_GENERALIZEDTIME:
622
	case V_ASN1_GRAPHICSTRING:
623
	case V_ASN1_VISIBLESTRING:
624
	case V_ASN1_GENERALSTRING:
625
	case V_ASN1_UNIVERSALSTRING:
626
	case V_ASN1_BMPSTRING:
627
	case V_ASN1_UTF8STRING:
628
	case V_ASN1_SEQUENCE:
629
	case V_ASN1_SET:
630
	default:
631
		/* All based on ASN1_STRING and handled the same */
632
535827
		strtmp = (ASN1_STRING *)*pval;
633
		/* Special handling for NDEF */
634

535912
		if ((it->size == ASN1_TFLG_NDEF) &&
635
85
		    (strtmp->flags & ASN1_STRING_FLAG_NDEF)) {
636
			if (cout) {
637
				strtmp->data = cout;
638
				strtmp->length = 0;
639
			}
640
			/* Special return code */
641
			return -2;
642
		}
643
535827
		cont = strtmp->data;
644
535827
		len = strtmp->length;
645
646
535827
		break;
647
648
	}
649
1103066
	if (cout && len)
650
215912
		memcpy(cout, cont, len);
651
1103066
	return len;
652
1167133
}