1 /*
2  * asn1.c: ASN.1 decoding functions (DER)
3  *
4  * Copyright (C) 2001, 2002  Juha Yrjölä <juha.yrjola@iki.fi>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 #if HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include <assert.h>
26 #include <ctype.h>
27 #include <stddef.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <limits.h>
32 
33 #include "internal.h"
34 #include "asn1.h"
35 
36 static int asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1,
37 		       const u8 *in, size_t len, const u8 **newp, size_t *len_left,
38 		       int choice, int depth);
39 static int asn1_encode(sc_context_t *ctx, const struct sc_asn1_entry *asn1,
40 		       u8 **ptr, size_t *size, int depth);
41 static int asn1_write_element(sc_context_t *ctx, unsigned int tag,
42 		const u8 * data, size_t datalen, u8 ** out, size_t * outlen);
43 
tag2str(unsigned int tag)44 static const char *tag2str(unsigned int tag)
45 {
46 	static const char *tags[] = {
47 		"EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",	/* 0-4 */
48 		"NULL", "OBJECT IDENTIFIER", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL",	/* 5-9 */
49 		"ENUMERATED", "Universal 11", "UTF8String", "Universal 13",	/* 10-13 */
50 		"Universal 14", "Universal 15", "SEQUENCE", "SET",	/* 15-17 */
51 		"NumericString", "PrintableString", "T61String",	/* 18-20 */
52 		"VideotexString", "IA5String", "UTCTIME", "GENERALIZEDTIME",	/* 21-24 */
53 		"GraphicString", "VisibleString", "GeneralString",	/* 25-27 */
54 		"UniversalString", "Universal 29", "BMPString"	/* 28-30 */
55 	};
56 
57 	if (tag > 30)
58 		return "(unknown)";
59 	return tags[tag];
60 }
61 
sc_asn1_read_tag(const u8 ** buf,size_t buflen,unsigned int * cla_out,unsigned int * tag_out,size_t * taglen)62 int sc_asn1_read_tag(const u8 ** buf, size_t buflen, unsigned int *cla_out,
63 		     unsigned int *tag_out, size_t *taglen)
64 {
65 	const u8 *p = *buf;
66 	size_t left = buflen, len;
67 	unsigned int cla, tag, i;
68 
69 	*buf = NULL;
70 
71 	if (left == 0 || !p)
72 		return SC_ERROR_INVALID_ASN1_OBJECT;
73 	if (*p == 0xff || *p == 0) {
74 		/* end of data reached */
75 		*taglen = 0;
76 		*tag_out = SC_ASN1_TAG_EOC;
77 		return SC_SUCCESS;
78 	}
79 
80 	/* parse tag byte(s)
81 	 * Resulted tag is presented by integer that has not to be
82 	 * confused with the 'tag number' part of ASN.1 tag.
83 	 */
84 	cla = (*p & SC_ASN1_TAG_CLASS) | (*p & SC_ASN1_TAG_CONSTRUCTED);
85 	tag = *p & SC_ASN1_TAG_PRIMITIVE;
86 	p++;
87 	left--;
88 	if (tag == SC_ASN1_TAG_PRIMITIVE) {
89 		/* high tag number */
90 		size_t n = SC_ASN1_TAGNUM_SIZE - 1;
91 		/* search the last tag octet */
92 		do {
93 			if (left == 0 || n == 0)
94 				/* either an invalid tag or it doesn't fit in
95 				 * unsigned int */
96 				return SC_ERROR_INVALID_ASN1_OBJECT;
97 			tag <<= 8;
98 			tag |= *p;
99 			p++;
100 			left--;
101 			n--;
102 		} while (tag & 0x80);
103 	}
104 
105 	/* parse length byte(s) */
106 	if (left == 0)
107 		return SC_ERROR_INVALID_ASN1_OBJECT;
108 	len = *p;
109 	p++;
110 	left--;
111 	if (len & 0x80) {
112 		len &= 0x7f;
113 		unsigned int a = 0;
114 		if (len > sizeof a || len > left)
115 			return SC_ERROR_INVALID_ASN1_OBJECT;
116 		for (i = 0; i < len; i++) {
117 			a <<= 8;
118 			a |= *p;
119 			p++;
120 			left--;
121 		}
122 		len = a;
123 	}
124 
125 	*cla_out = cla;
126 	*tag_out = tag;
127 	*taglen = len;
128 	*buf = p;
129 
130 	if (len > left)
131 		return SC_ERROR_ASN1_END_OF_CONTENTS;
132 
133 	return SC_SUCCESS;
134 }
135 
sc_format_asn1_entry(struct sc_asn1_entry * entry,void * parm,void * arg,int set_present)136 void sc_format_asn1_entry(struct sc_asn1_entry *entry, void *parm, void *arg,
137 			  int set_present)
138 {
139 	entry->parm = parm;
140 	entry->arg  = arg;
141 	if (set_present)
142 		entry->flags |= SC_ASN1_PRESENT;
143 }
144 
sc_copy_asn1_entry(const struct sc_asn1_entry * src,struct sc_asn1_entry * dest)145 void sc_copy_asn1_entry(const struct sc_asn1_entry *src,
146 			struct sc_asn1_entry *dest)
147 {
148 	while (src->name != NULL) {
149 		*dest = *src;
150 		dest++;
151 		src++;
152 	}
153 	dest->name = NULL;
154 }
155 
print_indent(size_t depth)156 static void print_indent(size_t depth)
157 {
158 	for (; depth > 0; depth--) {
159 		putchar(' ');
160 	}
161 }
162 
print_hex(const u8 * buf,size_t buflen,size_t depth)163 static void print_hex(const u8 * buf, size_t buflen, size_t depth)
164 {
165 	size_t lines_len = buflen * 5 + 128;
166 	char *lines = malloc(lines_len);
167 	char *line = lines;
168 
169 	if (buf == NULL || buflen == 0 || lines == NULL) {
170 		free(lines);
171 		return;
172 	}
173 
174 	sc_hex_dump(buf, buflen, lines, lines_len);
175 
176 	while (*line != '\0') {
177 		char *line_end = strchr(line, '\n');
178 		ptrdiff_t width = line_end - line;
179 		if (!line_end || width <= 1) {
180 			/* don't print empty lines */
181 			break;
182 		}
183 		if (buflen > 8) {
184 			putchar('\n');
185 			print_indent(depth);
186 		} else {
187 			printf(": ");
188 		}
189 		printf("%.*s", (int) width, line);
190 		line = line_end + 1;
191 	}
192 
193 	free(lines);
194 }
195 
print_ascii(const u8 * buf,size_t buflen)196 static void print_ascii(const u8 * buf, size_t buflen)
197 {
198 	for (; 0 < buflen; buflen--, buf++) {
199 		if (isprint(*buf))
200 			printf("%c", *buf);
201 		else
202 			putchar('.');
203 	}
204 }
205 
sc_asn1_print_octet_string(const u8 * buf,size_t buflen,size_t depth)206 static void sc_asn1_print_octet_string(const u8 * buf, size_t buflen, size_t depth)
207 {
208 	print_hex(buf, buflen, depth);
209 }
210 
sc_asn1_print_utf8string(const u8 * buf,size_t buflen)211 static void sc_asn1_print_utf8string(const u8 * buf, size_t buflen)
212 {
213 	/* FIXME UTF-8 is not ASCII */
214 	print_ascii(buf, buflen);
215 }
216 
sc_asn1_print_integer(const u8 * buf,size_t buflen)217 static void sc_asn1_print_integer(const u8 * buf, size_t buflen)
218 {
219 	size_t a = 0;
220 
221 	if (buflen > sizeof(a)) {
222 		printf("0x%s", sc_dump_hex(buf, buflen));
223 	} else {
224 		size_t i;
225 		for (i = 0; i < buflen; i++) {
226 			a <<= 8;
227 			a |= buf[i];
228 		}
229 		printf("%"SC_FORMAT_LEN_SIZE_T"u", a);
230 	}
231 }
232 
sc_asn1_print_boolean(const u8 * buf,size_t buflen)233 static void sc_asn1_print_boolean(const u8 * buf, size_t buflen)
234 {
235 	if (!buflen)
236 		return;
237 
238 	if (buf[0])
239 		printf("true");
240 	else
241 		printf("false");
242 }
243 
sc_asn1_print_bit_string(const u8 * buf,size_t buflen,size_t depth)244 static void sc_asn1_print_bit_string(const u8 * buf, size_t buflen, size_t depth)
245 {
246 #ifndef _WIN32
247 	long long a = 0;
248 #else
249 	__int64 a = 0;
250 #endif
251 	int r, i;
252 
253 	if (buflen > sizeof(a) + 1) {
254 		print_hex(buf, buflen, depth);
255 	} else {
256 		r = sc_asn1_decode_bit_string(buf, buflen, &a, sizeof(a), 1);
257 		if (r < 0) {
258 			printf("decode error, ");
259 			/* try again without the strict mode */
260 			r = sc_asn1_decode_bit_string(buf, buflen, &a, sizeof(a), 0);
261 			if (r < 0) {
262 				printf("even for lax decoding");
263 				return ;
264 			}
265 		}
266 		for (i = r - 1; i >= 0; i--) {
267 			printf("%c", ((a >> i) & 1) ? '1' : '0');
268 		}
269 	}
270 }
271 
272 #ifdef ENABLE_OPENSSL
273 #include <openssl/objects.h>
274 
openssl_print_object_sn(const char * s)275 static void openssl_print_object_sn(const char *s)
276 {
277 	ASN1_OBJECT *obj = OBJ_txt2obj(s, 0);
278 	if (obj) {
279 		int nid = OBJ_obj2nid(obj);
280 		if (nid != NID_undef) {
281 			printf(", %s", OBJ_nid2sn(nid));
282 		}
283 		ASN1_OBJECT_free(obj);
284 	}
285 }
286 #else
openssl_print_object_sn(const char * s)287 static void openssl_print_object_sn(const char *s)
288 {
289 }
290 #endif
291 
sc_asn1_print_object_id(const u8 * buf,size_t buflen)292 static void sc_asn1_print_object_id(const u8 * buf, size_t buflen)
293 {
294 	struct sc_object_id oid;
295 	const char *sbuf;
296 
297 	if (sc_asn1_decode_object_id(buf, buflen, &oid)) {
298 		printf("decode error");
299 		return;
300 	}
301 
302 	sbuf = sc_dump_oid(&oid);
303 	printf(" %s", sbuf);
304 	openssl_print_object_sn(sbuf);
305 }
306 
sc_asn1_print_utctime(const u8 * buf,size_t buflen)307 static void sc_asn1_print_utctime(const u8 * buf, size_t buflen)
308 {
309 	if (buflen < 8) {
310 		printf("Error in decoding.\n");
311 		return;
312 	}
313 
314 	print_ascii(buf, 2);		/* YY */
315 	putchar('-');
316 	print_ascii(buf+2, 2);		/* MM */
317 	putchar('-');
318 	print_ascii(buf+4, 2);		/* DD */
319 	putchar(' ');
320 	print_ascii(buf+6, 2);		/* hh */
321 	buf += 8;
322 	buflen -= 8;
323 	if (buflen >= 2 && isdigit(buf[0]) && isdigit(buf[1])) {
324 		putchar(':');
325 		print_ascii(buf, 2);	/* mm */
326 		buf += 2;
327 		buflen -= 2;
328 	}
329 	if (buflen >= 2 && isdigit(buf[0]) && isdigit(buf[1])) {
330 		putchar(':');
331 		print_ascii(buf, 2);	/* ss */
332 		buf += 2;
333 		buflen -= 2;
334 	}
335 	if (buflen >= 4 && '.' == buf[0]) {
336 		print_ascii(buf, 4);	/* fff */
337 		buf += 4;
338 		buflen -= 4;
339 	}
340 
341 	if (buflen >= 1 && 'Z' == buf[0]) {
342 		printf(" UTC");
343 	} else if (buflen >= 5 && ('-' == buf[0] || '+' == buf[0])) {
344 		putchar(' ');
345 		print_ascii(buf, 3);	/* +/-hh */
346 		putchar(':');
347 		print_ascii(buf+3, 2);	/* mm */
348 	}
349 }
350 
sc_asn1_print_generalizedtime(const u8 * buf,size_t buflen)351 static void sc_asn1_print_generalizedtime(const u8 * buf, size_t buflen)
352 {
353 	if (buflen < 8) {
354 		printf("Error in decoding.\n");
355 		return;
356 	}
357 
358 	print_ascii(buf, 2);
359 	sc_asn1_print_utctime(buf + 2, buflen - 2);
360 }
361 
print_tags_recursive(const u8 * buf0,const u8 * buf,size_t buflen,size_t depth)362 static void print_tags_recursive(const u8 * buf0, const u8 * buf,
363 				 size_t buflen, size_t depth)
364 {
365 	int r;
366 	size_t i;
367 	size_t bytesleft = buflen;
368 	const char *classes[4] = {
369 		"Universal",
370 		"Application",
371 		"Context",
372 		"Private"
373 	};
374 	const u8 *p = buf;
375 
376 	while (bytesleft >= 2) {
377 		unsigned int cla = 0, tag = 0, hlen;
378 		const u8 *tagp = p;
379 		size_t len;
380 
381 		r = sc_asn1_read_tag(&tagp, bytesleft, &cla, &tag, &len);
382 		if (r != SC_SUCCESS || (tagp == NULL && tag != SC_ASN1_TAG_EOC)) {
383 			printf("Error in decoding.\n");
384 			return;
385 		}
386 		hlen = tagp - p;
387 		if (cla == 0 && tag == 0) {
388 			printf("Zero tag, finishing\n");
389 			break;
390 		}
391 		print_indent(depth);
392 		/* let i be the length of the tag in bytes */
393 		for (i = 1; i < sizeof tag - 1; i++) {
394 			if (!(tag >> 8*i))
395 				break;
396 		}
397 		printf("%02X", cla<<(i-1)*8 | tag);
398 
399 		if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL) {
400 			printf(" %s", tag2str(tag));
401 		} else {
402 			printf(" %s %-2u",
403 					classes[cla >> 6],
404 					i == 1 ? tag & SC_ASN1_TAG_PRIMITIVE : tag & (((unsigned int) ~0) >> (i-1)*8));
405 		}
406 		if (!((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_UNIVERSAL
407 					&& tag == SC_ASN1_TAG_NULL && len == 0)) {
408 			printf(" (%"SC_FORMAT_LEN_SIZE_T"u byte%s)",
409 					len,
410 					len != 1 ? "s" : "");
411 		}
412 
413 		if (len + hlen > bytesleft) {
414 			printf(" Illegal length!\n");
415 			return;
416 		}
417 		p += hlen + len;
418 		bytesleft -= hlen + len;
419 
420 		if (cla & SC_ASN1_TAG_CONSTRUCTED) {
421 			putchar('\n');
422 			print_tags_recursive(buf0, tagp, len, depth + 2*i + 1);
423 			continue;
424 		}
425 
426 		switch (tag) {
427 			case SC_ASN1_TAG_BIT_STRING:
428 				printf(": ");
429 				sc_asn1_print_bit_string(tagp, len, depth + 2*i + 1);
430 				break;
431 			case SC_ASN1_TAG_OCTET_STRING:
432 				sc_asn1_print_octet_string(tagp, len, depth + 2*i + 1);
433 				break;
434 			case SC_ASN1_TAG_OBJECT:
435 				printf(": ");
436 				sc_asn1_print_object_id(tagp, len);
437 				break;
438 			case SC_ASN1_TAG_INTEGER:
439 			case SC_ASN1_TAG_ENUMERATED:
440 				printf(": ");
441 				sc_asn1_print_integer(tagp, len);
442 				break;
443 			case SC_ASN1_TAG_IA5STRING:
444 			case SC_ASN1_TAG_PRINTABLESTRING:
445 			case SC_ASN1_TAG_T61STRING:
446 			case SC_ASN1_TAG_UTF8STRING:
447 				printf(": ");
448 				sc_asn1_print_utf8string(tagp, len);
449 				break;
450 			case SC_ASN1_TAG_BOOLEAN:
451 				printf(": ");
452 				sc_asn1_print_boolean(tagp, len);
453 				break;
454 			case SC_ASN1_GENERALIZEDTIME:
455 				printf(": ");
456 				sc_asn1_print_generalizedtime(tagp, len);
457 				break;
458 			case SC_ASN1_UTCTIME:
459 				printf(": ");
460 				sc_asn1_print_utctime(tagp, len);
461 				break;
462 		}
463 
464 		if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_APPLICATION) {
465 			print_hex(tagp, len, depth + 2*i + 1);
466 		}
467 
468 		if ((cla & SC_ASN1_TAG_CLASS) == SC_ASN1_TAG_CONTEXT) {
469 			print_hex(tagp, len, depth + 2*i + 1);
470 		}
471 
472 		putchar('\n');
473 	}
474 }
475 
sc_asn1_print_tags(const u8 * buf,size_t buflen)476 void sc_asn1_print_tags(const u8 * buf, size_t buflen)
477 {
478 	print_tags_recursive(buf, buf, buflen, 0);
479 }
480 
sc_asn1_find_tag(sc_context_t * ctx,const u8 * buf,size_t buflen,unsigned int tag_in,size_t * taglen_in)481 const u8 *sc_asn1_find_tag(sc_context_t *ctx, const u8 * buf,
482 	size_t buflen, unsigned int tag_in, size_t *taglen_in)
483 {
484 	size_t left = buflen, taglen;
485 	const u8 *p = buf;
486 
487 	*taglen_in = 0;
488 	while (left >= 2) {
489 		unsigned int cla = 0, tag, mask = 0xff00;
490 
491 		buf = p;
492 		/* read a tag */
493 		if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS
494 				|| p == NULL)
495 			return NULL;
496 
497 		left -= (p - buf);
498 		/* we need to shift the class byte to the leftmost
499 		 * byte of the tag */
500 		while ((tag & mask) != 0) {
501 			cla  <<= 8;
502 			mask <<= 8;
503 		}
504 		/* compare the read tag with the given tag */
505 		if ((tag | cla) == tag_in) {
506 			/* we have a match => return length and value part */
507 			if (taglen > left)
508 				return NULL;
509 			*taglen_in = taglen;
510 			return p;
511 		}
512 		/* otherwise continue reading tags */
513 		left -= taglen;
514 		p += taglen;
515 	}
516 	return NULL;
517 }
518 
sc_asn1_skip_tag(sc_context_t * ctx,const u8 ** buf,size_t * buflen,unsigned int tag_in,size_t * taglen_out)519 const u8 *sc_asn1_skip_tag(sc_context_t *ctx, const u8 ** buf, size_t *buflen,
520 			   unsigned int tag_in, size_t *taglen_out)
521 {
522 	const u8 *p = *buf;
523 	size_t len = *buflen, taglen;
524 	unsigned int cla = 0, tag;
525 
526 	if (sc_asn1_read_tag((const u8 **) &p, len, &cla, &tag, &taglen) != SC_SUCCESS
527 			|| p == NULL)
528 		return NULL;
529 	switch (cla & 0xC0) {
530 	case SC_ASN1_TAG_UNIVERSAL:
531 		if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_UNI)
532 			return NULL;
533 		break;
534 	case SC_ASN1_TAG_APPLICATION:
535 		if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_APP)
536 			return NULL;
537 		break;
538 	case SC_ASN1_TAG_CONTEXT:
539 		if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_CTX)
540 			return NULL;
541 		break;
542 	case SC_ASN1_TAG_PRIVATE:
543 		if ((tag_in & SC_ASN1_CLASS_MASK) != SC_ASN1_PRV)
544 			return NULL;
545 		break;
546 	}
547 	if (cla & SC_ASN1_TAG_CONSTRUCTED) {
548 		if ((tag_in & SC_ASN1_CONS) == 0)
549 			return NULL;
550 	} else
551 		if (tag_in & SC_ASN1_CONS)
552 			return NULL;
553 	if ((tag_in & SC_ASN1_TAG_MASK) != tag)
554 		return NULL;
555 	len -= (p - *buf);	/* header size */
556 	if (taglen > len) {
557 		sc_debug(ctx, SC_LOG_DEBUG_ASN1,
558 			 "too long ASN.1 object (size %"SC_FORMAT_LEN_SIZE_T"u while only %"SC_FORMAT_LEN_SIZE_T"u available)\n",
559 			 taglen, len);
560 		return NULL;
561 	}
562 	*buflen -= (p - *buf) + taglen;
563 	*buf = p + taglen;	/* point to next tag */
564 	*taglen_out = taglen;
565 	return p;
566 }
567 
sc_asn1_verify_tag(sc_context_t * ctx,const u8 * buf,size_t buflen,unsigned int tag_in,size_t * taglen_out)568 const u8 *sc_asn1_verify_tag(sc_context_t *ctx, const u8 * buf, size_t buflen,
569 			     unsigned int tag_in, size_t *taglen_out)
570 {
571 	return sc_asn1_skip_tag(ctx, &buf, &buflen, tag_in, taglen_out);
572 }
573 
decode_bit_string(const u8 * inbuf,size_t inlen,void * outbuf,size_t outlen,int invert,const int strict)574 static int decode_bit_string(const u8 * inbuf, size_t inlen, void *outbuf,
575 			     size_t outlen, int invert, const int strict)
576 {
577 	const u8 *in = inbuf;
578 	u8 *out = (u8 *) outbuf;
579 	int i, count = 0;
580 	int zero_bits;
581 	size_t octets_left;
582 
583 	if (inlen < 1)
584 		return SC_ERROR_INVALID_ASN1_OBJECT;
585 
586 	/* The formatting is only enforced by SHALL keyword so we should accept
587 	 * by default also non-strict values. */
588 	if (strict) {
589 		/* 8.6.2.3 If the bitstring is empty, there shall be no
590 		 * subsequent octets,and the initial octet shall be zero. */
591 		if (inlen == 1 && *in != 0)
592 			return SC_ERROR_INVALID_ASN1_OBJECT;
593 		/* ITU-T Rec. X.690 8.6.2.2: The number shall be in the range zero to seven. */
594 		if ((*in & ~0x07) != 0)
595 			return SC_ERROR_INVALID_ASN1_OBJECT;
596 	}
597 
598 	memset(outbuf, 0, outlen);
599 	zero_bits = *in & 0x07;
600 	in++;
601 	octets_left = inlen - 1;
602 	if (outlen < octets_left)
603 		return SC_ERROR_BUFFER_TOO_SMALL;
604 
605 	while (octets_left) {
606 		/* 1st octet of input:  ABCDEFGH, where A is the MSB */
607 		/* 1st octet of output: HGFEDCBA, where A is the LSB */
608 		/* first bit in bit string is the LSB in first resulting octet */
609 		int bits_to_go;
610 
611 		*out = 0;
612 		if (octets_left == 1 && zero_bits > 0) {
613 			bits_to_go = 8 - zero_bits;
614 			/* Verify the padding is zero bits */
615 			if (*in & (1 << (zero_bits-1))) {
616 				return SC_ERROR_INVALID_ASN1_OBJECT;
617 			}
618 		} else
619 			bits_to_go = 8;
620 		if (invert)
621 			for (i = 0; i < bits_to_go; i++) {
622 				*out |= ((*in >> (7 - i)) & 1) << i;
623 			}
624 		else {
625 			*out = *in;
626 		}
627 		out++;
628 		in++;
629 		octets_left--;
630 		count++;
631 	}
632 	return (count * 8) - zero_bits;
633 }
634 
sc_asn1_decode_bit_string(const u8 * inbuf,size_t inlen,void * outbuf,size_t outlen,const int strict)635 int sc_asn1_decode_bit_string(const u8 * inbuf, size_t inlen,
636 			      void *outbuf, size_t outlen, const int strict)
637 {
638 	return decode_bit_string(inbuf, inlen, outbuf, outlen, 1, strict);
639 }
640 
sc_asn1_decode_bit_string_ni(const u8 * inbuf,size_t inlen,void * outbuf,size_t outlen,const int strict)641 int sc_asn1_decode_bit_string_ni(const u8 * inbuf, size_t inlen,
642 				 void *outbuf, size_t outlen, const int strict)
643 {
644 	return decode_bit_string(inbuf, inlen, outbuf, outlen, 0, strict);
645 }
646 
encode_bit_string(const u8 * inbuf,size_t bits_left,u8 ** outbuf,size_t * outlen,int invert)647 static int encode_bit_string(const u8 * inbuf, size_t bits_left, u8 **outbuf,
648 			     size_t *outlen, int invert)
649 {
650 	const u8 *in = inbuf;
651 	u8 *out;
652 	size_t bytes;
653 	int skipped = 0;
654 
655 	bytes = (bits_left + 7)/8 + 1;
656 	*outbuf = out = malloc(bytes);
657 	if (out == NULL)
658 		return SC_ERROR_OUT_OF_MEMORY;
659 	*outlen = bytes;
660 	out += 1;
661 	while (bits_left) {
662 		int i, bits_to_go = 8;
663 
664 		*out = 0;
665 		if (bits_left < 8) {
666 			bits_to_go = bits_left;
667 			skipped = 8 - bits_left;
668 		}
669 		if (invert) {
670 			for (i = 0; i < bits_to_go; i++)
671 				*out |= ((*in >> i) & 1) << (7 - i);
672 		} else {
673 			*out = *in;
674 			if (bits_left < 8)
675 				return SC_ERROR_NOT_SUPPORTED; /* FIXME */
676 		}
677 		bits_left -= bits_to_go;
678 		out++, in++;
679 	}
680 	out = *outbuf;
681 	out[0] = skipped;
682 	return 0;
683 }
684 
685 /*
686  * Bitfields are just bit strings, stored in an unsigned int
687  * (taking endianness into account)
688  */
decode_bit_field(const u8 * inbuf,size_t inlen,void * outbuf,size_t outlen,const int strict)689 static int decode_bit_field(const u8 * inbuf, size_t inlen, void *outbuf, size_t outlen, const int strict)
690 {
691 	u8		data[sizeof(unsigned int)];
692 	unsigned int	field = 0;
693 	int		i, n;
694 
695 	if (outlen != sizeof(data))
696 		return SC_ERROR_BUFFER_TOO_SMALL;
697 
698 	n = decode_bit_string(inbuf, inlen, data, sizeof(data), 1, strict);
699 	if (n < 0)
700 		return n;
701 
702 	for (i = 0; i < n; i += 8) {
703 		field |= ((unsigned int) data[i/8] << i);
704 	}
705 	memcpy(outbuf, &field, outlen);
706 	return 0;
707 }
708 
encode_bit_field(const u8 * inbuf,size_t inlen,u8 ** outbuf,size_t * outlen)709 static int encode_bit_field(const u8 *inbuf, size_t inlen,
710 			    u8 **outbuf, size_t *outlen)
711 {
712 	u8		data[sizeof(unsigned int)];
713 	unsigned int	field = 0;
714 	size_t		i, bits;
715 
716 	if (inlen != sizeof(data))
717 		return SC_ERROR_BUFFER_TOO_SMALL;
718 
719 	/* count the bits */
720 	memcpy(&field, inbuf, inlen);
721 	for (bits = 0; field; bits++)
722 		field >>= 1;
723 
724 	memcpy(&field, inbuf, inlen);
725 	for (i = 0; i < bits; i += 8)
726 		data[i/8] = field >> i;
727 
728 	return encode_bit_string(data, bits, outbuf, outlen, 1);
729 }
730 
sc_asn1_decode_integer(const u8 * inbuf,size_t inlen,int * out,int strict)731 int sc_asn1_decode_integer(const u8 * inbuf, size_t inlen, int *out, int strict)
732 {
733 	int    a = 0, is_negative = 0;
734 	size_t i = 0;
735 
736 	if (inlen == 0) {
737 		return SC_ERROR_INVALID_ASN1_OBJECT;
738 	}
739 	if (inlen > sizeof(int)) {
740 		return SC_ERROR_NOT_SUPPORTED;
741 	}
742 	if (inbuf[0] & 0x80) {
743 		if (strict && inlen > 1 && inbuf[0] == 0xff && (inbuf[1] & 0x80)) {
744 			return SC_ERROR_INVALID_ASN1_OBJECT;
745 		}
746 		is_negative = 1;
747 		a |= 0xff^(*inbuf++);
748 		i = 1;
749 	} else {
750 		if (strict && inlen > 1 && inbuf[0] == 0x00 && (inbuf[1] & 0x80) == 0) {
751 			return SC_ERROR_INVALID_ASN1_OBJECT;
752 		}
753 	}
754 	for (; i < inlen; i++) {
755 		if (a > (INT_MAX >> 8) || a < (INT_MIN + (1<<8))) {
756 			return SC_ERROR_NOT_SUPPORTED;
757 		}
758 		a <<= 8;
759 		if (is_negative) {
760 			a |= 0xff^(*inbuf++);
761 		} else {
762 			a |= *inbuf++;
763 		}
764 	}
765 	if (is_negative) {
766 		/* Calculate Two's complement from previously positive number */
767 		a = (-1 * a) - 1;
768 	}
769 	*out = a;
770 	return 0;
771 }
772 
asn1_encode_integer(int in,u8 ** obj,size_t * objsize)773 static int asn1_encode_integer(int in, u8 ** obj, size_t * objsize)
774 {
775 	int i = sizeof(in) * 8, skip_zero, skip_sign;
776 	u8 *p, b;
777 
778 	if (in < 0)
779 	{
780 		skip_sign = 1;
781 		skip_zero= 0;
782 	}
783 	else
784 	{
785 		skip_sign = 0;
786 		skip_zero= 1;
787 	}
788 	*obj = p = malloc(sizeof(in)+1);
789 	if (*obj == NULL)
790 		return SC_ERROR_OUT_OF_MEMORY;
791 	do {
792 		i -= 8;
793 		b = in >> i;
794 		if (skip_sign)
795 		{
796 			if (b != 0xff)
797 				skip_sign = 0;
798 			if (b & 0x80)
799 			{
800 				*p = b;
801 				if (0xff == b)
802 					continue;
803 			}
804 			else
805 			{
806 				p++;
807 				skip_sign = 0;
808 			}
809 		}
810 		if (b == 0 && skip_zero)
811 			continue;
812 		if (skip_zero) {
813 			skip_zero = 0;
814 			/* prepend 0x00 if MSb is 1 and integer positive */
815 			if ((b & 0x80) != 0 && in > 0)
816 				*p++ = 0;
817 		}
818 		*p++ = b;
819 	} while (i > 0);
820 	if (skip_sign)
821 		p++;
822 	*objsize = p - *obj;
823 	if (*objsize == 0) {
824 		*objsize = 1;
825 		(*obj)[0] = 0;
826 	}
827 	return 0;
828 }
829 
830 int
sc_asn1_decode_object_id(const u8 * inbuf,size_t inlen,struct sc_object_id * id)831 sc_asn1_decode_object_id(const u8 *inbuf, size_t inlen, struct sc_object_id *id)
832 {
833 	int large_second_octet = 0;
834 	unsigned int a = 0;
835 	const u8 *p = inbuf;
836 	int *octet;
837 
838 	if (inlen == 0 || inbuf == NULL || id == NULL)
839 		return SC_ERROR_INVALID_ARGUMENTS;
840 
841 	sc_init_oid(id);
842 	octet = id->value;
843 
844 	/* The first octet can be 0, 1 or 2 and is derived from the first byte */
845 	a = MIN(*p / 40, 2);
846 	*octet++ = a;
847 
848 	/* The second octet fits here if the previous was 0 or 1 and second one is smaller than 40.
849 	 * for the value 2 we can go up to 47. Otherwise the first bit needs to be set
850 	 * and we continue reading further */
851 	if ((*p & 0x80) == 0) {
852 		*octet++ = *p - (a * 40);
853 		inlen--;
854 	} else {
855 		large_second_octet = 1;
856 	}
857 
858 	while (inlen) {
859 		if (!large_second_octet)
860 			p++;
861 		/* This signalizes empty most significant bits, which means
862 		 * the unsigned integer encoding is not minimal */
863 		if (*p == 0x80) {
864 			sc_init_oid(id);
865 			return SC_ERROR_INVALID_ASN1_OBJECT;
866 		}
867 		/* Use unsigned type here so we can process the whole INT range.
868 		 * Values can not be negative */
869 		a = *p & 0x7F;
870 		inlen--;
871 		while (inlen && *p & 0x80) {
872 			/* Limit the OID values to int size and do not overflow */
873 			if (a > (UINT_MAX>>7)) {
874 				sc_init_oid(id);
875 				return SC_ERROR_NOT_SUPPORTED;
876 			}
877 			p++;
878 			a <<= 7;
879 			a |= *p & 0x7F;
880 			inlen--;
881 		}
882 		if (*p & 0x80) {
883 			/* We dropped out from previous cycle on the end of
884 			 * data while still expecting continuation of value */
885 			sc_init_oid(id);
886 			return SC_ERROR_INVALID_ASN1_OBJECT;
887 		}
888 		if (large_second_octet) {
889 			a -= (2 * 40);
890 		}
891 		if (a > INT_MAX) {
892 			sc_init_oid(id);
893 			return SC_ERROR_NOT_SUPPORTED;
894 		}
895 		*octet++ = a;
896 		if (octet - id->value >= SC_MAX_OBJECT_ID_OCTETS)   {
897 			sc_init_oid(id);
898 			return SC_ERROR_INVALID_ASN1_OBJECT;
899 		}
900 		large_second_octet = 0;
901 	}
902 
903 	return 0;
904 }
905 
906 int
sc_asn1_encode_object_id(u8 ** buf,size_t * buflen,const struct sc_object_id * id)907 sc_asn1_encode_object_id(u8 **buf, size_t *buflen, const struct sc_object_id *id)
908 {
909 	u8 temp[SC_MAX_OBJECT_ID_OCTETS*5], *p = temp;
910 	int	i;
911 
912 	if (!buflen || !id)
913 		return SC_ERROR_INVALID_ARGUMENTS;
914 
915 	/* an OID must have at least two components */
916 	if (id->value[0] == -1 || id->value[1] == -1)
917 		return SC_ERROR_INVALID_ARGUMENTS;
918 
919 	for (i = 0; i < SC_MAX_OBJECT_ID_OCTETS; i++) {
920 		unsigned int k, shift;
921 
922 		if (id->value[i] == -1)
923 			break;
924 
925 		k = id->value[i];
926 		switch (i) {
927 		case 0:
928 			if (k > 2)
929 				return SC_ERROR_INVALID_ARGUMENTS;
930 			*p = k * 40;
931 			break;
932 		case 1:
933 			if (k > 39 && id->value[0] < 2) {
934 				return SC_ERROR_INVALID_ARGUMENTS;
935 			}
936 			/* We can encode larger IDs to multiple bytes
937 			 * similarly as the following IDs */
938 			k += *p;
939 			/* fall through */
940 		default:
941 			shift = 28;
942 			while (shift && (k >> shift) == 0)
943 				shift -= 7;
944 			while (shift) {
945 				*p++ = 0x80 | ((k >> shift) & 0x7f);
946 				shift -= 7;
947 			}
948 			*p++ = k & 0x7F;
949 			break;
950 		}
951 	}
952 
953 	*buflen = p - temp;
954 
955 	if (buf)   {
956 		*buf = malloc(*buflen);
957 		if (!*buf)
958 			return SC_ERROR_OUT_OF_MEMORY;
959 		memcpy(*buf, temp, *buflen);
960 	}
961 	return 0;
962 }
963 
sc_asn1_decode_utf8string(const u8 * inbuf,size_t inlen,u8 * out,size_t * outlen)964 static int sc_asn1_decode_utf8string(const u8 *inbuf, size_t inlen,
965 			      u8 *out, size_t *outlen)
966 {
967 	if (inlen+1 > *outlen)
968 		return SC_ERROR_BUFFER_TOO_SMALL;
969 	*outlen = inlen+1;
970 	memcpy(out, inbuf, inlen);
971 	out[inlen] = 0;
972 	return 0;
973 }
974 
975 /*
976  * This assumes the tag is already encoded
977  */
sc_asn1_put_tag(unsigned int tag,const u8 * data,size_t datalen,u8 * out,size_t outlen,u8 ** ptr)978 int sc_asn1_put_tag(unsigned int tag, const u8 * data, size_t datalen, u8 * out, size_t outlen, u8 **ptr)
979 {
980 	size_t c = 0;
981 	size_t tag_len;
982 	size_t ii;
983 	u8 *p = out;
984 	u8 tag_char[4] = {0, 0, 0, 0};
985 
986 	/* Check tag */
987 	if (tag == 0 || tag > 0xFFFFFFFF) {
988 		/* A tag of 0x00 is not valid and at most 4-byte tag names are supported. */
989 		return SC_ERROR_INVALID_DATA;
990 	}
991 	for (tag_len = 0; tag; tag >>= 8) {
992 		/* Note: tag char will be reversed order. */
993 		tag_char[tag_len++] = tag & 0xFF;
994 	}
995 
996 	if (tag_len > 1)   {
997 		if ((tag_char[tag_len - 1] & SC_ASN1_TAG_PRIMITIVE) != SC_ASN1_TAG_ESCAPE_MARKER) {
998 			/* First byte is not escape marker. */
999 			return SC_ERROR_INVALID_DATA;
1000 		}
1001 		for (ii = 1; ii < tag_len - 1; ii++) {
1002 			if ((tag_char[ii] & 0x80) != 0x80) {
1003 				/* MS bit is not 'one'. */
1004 				return SC_ERROR_INVALID_DATA;
1005 			}
1006 		}
1007 		if ((tag_char[0] & 0x80) != 0x00) {
1008 			/* MS bit of the last byte is not 'zero'. */
1009 			return SC_ERROR_INVALID_DATA;
1010 		}
1011 	}
1012 
1013 	/* Calculate the number of additional bytes necessary to encode the length. */
1014 	/* c+1 is the size of the length field. */
1015 	if (datalen > 127) {
1016 		c = 1;
1017 		while (datalen >> (c << 3))
1018 			c++;
1019 	}
1020 	if (outlen == 0 || out == NULL) {
1021 		/* Caller only asks for the length that would be written. */
1022 		return tag_len + (c+1) + datalen;
1023 	}
1024 	/* We will write the tag, so check the length. */
1025 	if (outlen < tag_len + (c+1) + datalen)
1026 		return SC_ERROR_BUFFER_TOO_SMALL;
1027 	for (ii=0;ii<tag_len;ii++)
1028 		*p++ = tag_char[tag_len - ii - 1];
1029 
1030 	if (c > 0) {
1031 		*p++ = 0x80 | c;
1032 		while (c--)
1033 			*p++ = (datalen >> (c << 3)) & 0xFF;
1034 	}
1035 	else {
1036 		*p++ = datalen & 0x7F;
1037 	}
1038 	if(data && datalen > 0) {
1039 		memcpy(p, data, datalen);
1040 		p += datalen;
1041 	}
1042 	if (ptr != NULL)
1043 		*ptr = p;
1044 	return 0;
1045 }
1046 
sc_asn1_write_element(sc_context_t * ctx,unsigned int tag,const u8 * data,size_t datalen,u8 ** out,size_t * outlen)1047 int sc_asn1_write_element(sc_context_t *ctx, unsigned int tag,
1048 	const u8 * data, size_t datalen, u8 ** out, size_t * outlen)
1049 {
1050 	return asn1_write_element(ctx, tag, data, datalen, out, outlen);
1051 }
1052 
asn1_write_element(sc_context_t * ctx,unsigned int tag,const u8 * data,size_t datalen,u8 ** out,size_t * outlen)1053 static int asn1_write_element(sc_context_t *ctx, unsigned int tag,
1054 	const u8 * data, size_t datalen, u8 ** out, size_t * outlen)
1055 {
1056 	unsigned char t;
1057 	unsigned char *buf, *p;
1058 	int c = 0;
1059 	unsigned short_tag;
1060 	unsigned char tag_char[3] = {0, 0, 0};
1061 	size_t tag_len, ii;
1062 
1063 	short_tag = tag & SC_ASN1_TAG_MASK;
1064 	for (tag_len = 0; short_tag >> (8 * tag_len); tag_len++)
1065 		tag_char[tag_len] = (short_tag >> (8 * tag_len)) & 0xFF;
1066 	if (!tag_len)
1067 		tag_len = 1;
1068 
1069 	if (tag_len > 1)   {
1070 		if ((tag_char[tag_len - 1] & SC_ASN1_TAG_PRIMITIVE) != SC_ASN1_TAG_ESCAPE_MARKER)
1071 			SC_TEST_RET(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_INVALID_DATA, "First byte of the long tag is not 'escape marker'");
1072 
1073 		for (ii = 1; ii < tag_len - 1; ii++)
1074 			if (!(tag_char[ii] & 0x80))
1075 				SC_TEST_RET(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_INVALID_DATA, "MS bit expected to be 'one'");
1076 
1077 		if (tag_char[0] & 0x80)
1078 			SC_TEST_RET(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_INVALID_DATA, "MS bit of the last byte expected to be 'zero'");
1079 	}
1080 
1081 	t = tag_char[tag_len - 1] & 0x1F;
1082 
1083 	switch (tag & SC_ASN1_CLASS_MASK) {
1084 	case SC_ASN1_UNI:
1085 		break;
1086 	case SC_ASN1_APP:
1087 		t |= SC_ASN1_TAG_APPLICATION;
1088 		break;
1089 	case SC_ASN1_CTX:
1090 		t |= SC_ASN1_TAG_CONTEXT;
1091 		break;
1092 	case SC_ASN1_PRV:
1093 		t |= SC_ASN1_TAG_PRIVATE;
1094 		break;
1095 	}
1096 	if (tag & SC_ASN1_CONS)
1097 		t |= SC_ASN1_TAG_CONSTRUCTED;
1098 	if (datalen > 127) {
1099 		c = 1;
1100 		while (datalen >> (c << 3))
1101 			c++;
1102 	}
1103 
1104 	*outlen = tag_len + 1 + c + datalen;
1105 	buf = malloc(*outlen);
1106 	if (buf == NULL)
1107 		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_OUT_OF_MEMORY);
1108 
1109 	*out = p = buf;
1110 	*p++ = t;
1111 	for (ii=1;ii<tag_len;ii++)
1112 		*p++ = tag_char[tag_len - ii - 1];
1113 
1114 	if (c) {
1115 		*p++ = 0x80 | c;
1116 		while (c--)
1117 			*p++ = (datalen >> (c << 3)) & 0xFF;
1118 	}
1119 	else   {
1120 		*p++ = datalen & 0x7F;
1121 	}
1122 	if (datalen && data) {
1123 		memcpy(p, data, datalen);
1124 	}
1125 
1126 	return SC_SUCCESS;
1127 }
1128 
1129 static const struct sc_asn1_entry c_asn1_path_ext[3] = {
1130 	{ "aid",  SC_ASN1_OCTET_STRING, SC_ASN1_APP | 0x0F, 0, NULL, NULL },
1131 	{ "path", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, 0, NULL, NULL },
1132 	{ NULL, 0, 0, 0, NULL, NULL }
1133 };
1134 static const struct sc_asn1_entry c_asn1_path[5] = {
1135 	{ "path",   SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
1136 	{ "index",  SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
1137 	{ "length", SC_ASN1_INTEGER, SC_ASN1_CTX | 0, SC_ASN1_OPTIONAL, NULL, NULL },
1138 /* For some multi-applications PKCS#15 card the ODF records can hold the references to
1139  * the xDF files and objects placed elsewhere then under the application DF of the ODF itself.
1140  * In such a case the 'path' ASN1 data includes also the ID of the target application (AID).
1141  * This path extension do not make a part of PKCS#15 standard.
1142  */
1143 	{ "pathExtended", SC_ASN1_STRUCT, SC_ASN1_CTX | 1 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1144 	{ NULL, 0, 0, 0, NULL, NULL }
1145 };
1146 
asn1_decode_path(sc_context_t * ctx,const u8 * in,size_t len,sc_path_t * path,int depth)1147 static int asn1_decode_path(sc_context_t *ctx, const u8 *in, size_t len,
1148 			    sc_path_t *path, int depth)
1149 {
1150 	int idx, count, r;
1151 	struct sc_asn1_entry asn1_path_ext[3], asn1_path[5];
1152 	unsigned char path_value[SC_MAX_PATH_SIZE], aid_value[SC_MAX_AID_SIZE];
1153 	size_t path_len = sizeof(path_value), aid_len = sizeof(aid_value);
1154 
1155 	memset(path, 0, sizeof(struct sc_path));
1156 
1157 	sc_copy_asn1_entry(c_asn1_path_ext, asn1_path_ext);
1158 	sc_copy_asn1_entry(c_asn1_path, asn1_path);
1159 
1160 	sc_format_asn1_entry(asn1_path_ext + 0, aid_value, &aid_len, 0);
1161 	sc_format_asn1_entry(asn1_path_ext + 1, path_value, &path_len, 0);
1162 
1163 	sc_format_asn1_entry(asn1_path + 0, path_value, &path_len, 0);
1164 	sc_format_asn1_entry(asn1_path + 1, &idx, NULL, 0);
1165 	sc_format_asn1_entry(asn1_path + 2, &count, NULL, 0);
1166 	sc_format_asn1_entry(asn1_path + 3, asn1_path_ext, NULL, 0);
1167 
1168 	r = asn1_decode(ctx, asn1_path, in, len, NULL, NULL, 0, depth + 1);
1169 	if (r)
1170 		return r;
1171 
1172 	if (asn1_path[3].flags & SC_ASN1_PRESENT)   {
1173 		/* extended path present: set 'path' and 'aid' */
1174 		memcpy(path->aid.value, aid_value, aid_len);
1175 		path->aid.len = aid_len;
1176 
1177 		memcpy(path->value, path_value, path_len);
1178 		path->len = path_len;
1179 	}
1180 	else if (asn1_path[0].flags & SC_ASN1_PRESENT)   {
1181 		/* path present: set 'path' */
1182 		memcpy(path->value, path_value, path_len);
1183 		path->len = path_len;
1184 	}
1185 	else   {
1186 		/* failed if both 'path' and 'pathExtended' are absent */
1187 		return SC_ERROR_ASN1_OBJECT_NOT_FOUND;
1188 	}
1189 
1190 	if (path->len == 2)
1191 		path->type = SC_PATH_TYPE_FILE_ID;
1192 	else   if (path->aid.len && path->len > 2)
1193 		path->type = SC_PATH_TYPE_FROM_CURRENT;
1194 	else
1195 		path->type = SC_PATH_TYPE_PATH;
1196 
1197 	if ((asn1_path[1].flags & SC_ASN1_PRESENT) && (asn1_path[2].flags & SC_ASN1_PRESENT)) {
1198 		path->index = idx;
1199 		path->count = count;
1200 	}
1201 	else {
1202 		path->index = 0;
1203 		path->count = -1;
1204 	}
1205 
1206 	return SC_SUCCESS;
1207 }
1208 
asn1_encode_path(sc_context_t * ctx,const sc_path_t * path,u8 ** buf,size_t * bufsize,int depth,unsigned int parent_flags)1209 static int asn1_encode_path(sc_context_t *ctx, const sc_path_t *path,
1210 			    u8 **buf, size_t *bufsize, int depth, unsigned int parent_flags)
1211 {
1212 	int r;
1213  	struct sc_asn1_entry asn1_path[5];
1214 	sc_path_t tpath = *path;
1215 
1216 	sc_copy_asn1_entry(c_asn1_path, asn1_path);
1217 	sc_format_asn1_entry(asn1_path + 0, (void *) &tpath.value, (void *) &tpath.len, 1);
1218 
1219 	asn1_path[0].flags |= parent_flags;
1220 	if (path->count > 0) {
1221 		sc_format_asn1_entry(asn1_path + 1, (void *) &tpath.index, NULL, 1);
1222 		sc_format_asn1_entry(asn1_path + 2, (void *) &tpath.count, NULL, 1);
1223 	}
1224 	r = asn1_encode(ctx, asn1_path, buf, bufsize, depth + 1);
1225 	return r;
1226 }
1227 
1228 
1229 static const struct sc_asn1_entry c_asn1_se[2] = {
1230 	{ "seInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
1231 	{ NULL, 0, 0, 0, NULL, NULL }
1232 };
1233 
1234 static const struct sc_asn1_entry c_asn1_se_info[4] = {
1235 	{ "se",   SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
1236 	{ "owner",SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_OPTIONAL, NULL, NULL },
1237 	{ "aid",  SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
1238 	{ NULL, 0, 0, 0, NULL, NULL }
1239 };
1240 
asn1_decode_se_info(sc_context_t * ctx,const u8 * obj,size_t objlen,sc_pkcs15_sec_env_info_t *** se,size_t * num,int depth)1241 static int asn1_decode_se_info(sc_context_t *ctx, const u8 *obj, size_t objlen,
1242 			       sc_pkcs15_sec_env_info_t ***se, size_t *num, int depth)
1243 {
1244 	struct sc_pkcs15_sec_env_info **ses;
1245 	const unsigned char *ptr = obj;
1246 	size_t idx, ptrlen = objlen;
1247 	int ret;
1248 
1249 	LOG_FUNC_CALLED(ctx);
1250 
1251 	ses = calloc(SC_MAX_SE_NUM, sizeof(sc_pkcs15_sec_env_info_t *));
1252 	if (ses == NULL) {
1253 		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_OUT_OF_MEMORY);
1254 	}
1255 
1256 	for (idx=0; idx < SC_MAX_SE_NUM && ptrlen; )   {
1257 		struct sc_asn1_entry asn1_se[2];
1258 		struct sc_asn1_entry asn1_se_info[4];
1259 		struct sc_pkcs15_sec_env_info si;
1260 
1261 		sc_copy_asn1_entry(c_asn1_se, asn1_se);
1262 		sc_copy_asn1_entry(c_asn1_se_info, asn1_se_info);
1263 
1264 		si.aid.len = sizeof(si.aid.value);
1265 		sc_format_asn1_entry(asn1_se_info + 0, &si.se, NULL, 0);
1266 		sc_format_asn1_entry(asn1_se_info + 1, &si.owner, NULL, 0);
1267 		sc_format_asn1_entry(asn1_se_info + 2, &si.aid.value, &si.aid.len, 0);
1268 		sc_format_asn1_entry(asn1_se + 0, asn1_se_info, NULL, 0);
1269 
1270 		ret = asn1_decode(ctx, asn1_se, ptr, ptrlen, &ptr, &ptrlen, 0, depth+1);
1271 		if (ret != SC_SUCCESS)
1272 			goto err;
1273 		if (!(asn1_se_info[1].flags & SC_ASN1_PRESENT))
1274 			sc_init_oid(&si.owner);
1275 
1276 		ses[idx] = calloc(1, sizeof(sc_pkcs15_sec_env_info_t));
1277 		if (ses[idx] == NULL) {
1278 			ret = SC_ERROR_OUT_OF_MEMORY;
1279 			goto err;
1280 		}
1281 
1282 		memcpy(ses[idx], &si, sizeof(struct sc_pkcs15_sec_env_info));
1283 		idx++;
1284 	}
1285 
1286 	*se  = ses;
1287 	*num = idx;
1288 	ret = SC_SUCCESS;
1289 err:
1290 	if (ret != SC_SUCCESS) {
1291 		size_t i;
1292 		for (i = 0; i < idx; i++)
1293 			if (ses[i])
1294 				free(ses[i]);
1295 		free(ses);
1296 	}
1297 
1298 	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, ret);
1299 }
1300 
1301 
asn1_encode_se_info(sc_context_t * ctx,struct sc_pkcs15_sec_env_info ** se,size_t se_num,unsigned char ** buf,size_t * bufsize,int depth)1302 static int asn1_encode_se_info(sc_context_t *ctx,
1303 		struct sc_pkcs15_sec_env_info **se, size_t se_num,
1304 		unsigned char **buf, size_t *bufsize, int depth)
1305 {
1306 	unsigned char *ptr = NULL, *out = NULL, *p;
1307 	size_t ptrlen = 0, outlen = 0, idx;
1308 	int ret;
1309 
1310 	for (idx=0; idx < se_num; idx++)   {
1311 		struct sc_asn1_entry asn1_se[2];
1312 		struct sc_asn1_entry asn1_se_info[4];
1313 
1314 		sc_copy_asn1_entry(c_asn1_se, asn1_se);
1315 		sc_copy_asn1_entry(c_asn1_se_info, asn1_se_info);
1316 
1317 		sc_format_asn1_entry(asn1_se_info + 0, &se[idx]->se, NULL, 1);
1318 		if (sc_valid_oid(&se[idx]->owner))
1319 			sc_format_asn1_entry(asn1_se_info + 1, &se[idx]->owner, NULL, 1);
1320 		if (se[idx]->aid.len)
1321 			sc_format_asn1_entry(asn1_se_info + 2, &se[idx]->aid.value, &se[idx]->aid.len, 1);
1322 		sc_format_asn1_entry(asn1_se + 0, asn1_se_info, NULL, 1);
1323 
1324 		ret = sc_asn1_encode(ctx, asn1_se, &ptr, &ptrlen);
1325 		if (ret != SC_SUCCESS)
1326 			goto err;
1327 
1328 		if (!ptrlen)
1329 			continue;
1330 		p = (unsigned char *) realloc(out, outlen + ptrlen);
1331 		if (!p)   {
1332 			ret = SC_ERROR_OUT_OF_MEMORY;
1333 			goto err;
1334 		}
1335 		out = p;
1336 		memcpy(out + outlen, ptr, ptrlen);
1337 		outlen += ptrlen;
1338 		free(ptr);
1339 		ptr = NULL;
1340 		ptrlen = 0;
1341 	}
1342 
1343 	*buf = out;
1344 	*bufsize = outlen;
1345 	ret = SC_SUCCESS;
1346 err:
1347 	if (ret != SC_SUCCESS && out != NULL)
1348 		free(out);
1349 	return ret;
1350 }
1351 
1352 /* TODO: According to specification type of 'SecurityCondition' is 'CHOICE'.
1353  *       Do it at least for SC_ASN1_PKCS15_ID(authId), SC_ASN1_STRUCT(authReference) and NULL(always). */
1354 static const struct sc_asn1_entry c_asn1_access_control_rule[3] = {
1355 	{ "accessMode", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
1356 	{ "securityCondition", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
1357 	{ NULL, 0, 0, 0, NULL, NULL }
1358 };
1359 
1360 /*
1361  * in src/libopensc/pkcs15.h SC_PKCS15_MAX_ACCESS_RULES  defined as 8
1362  */
1363 static const struct sc_asn1_entry c_asn1_access_control_rules[SC_PKCS15_MAX_ACCESS_RULES + 1] = {
1364 	{ "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1365 	{ "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1366 	{ "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1367 	{ "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1368 	{ "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1369 	{ "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1370 	{ "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1371 	{ "accessControlRule", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1372 	{ NULL, 0, 0, 0, NULL, NULL }
1373 };
1374 
1375 static const struct sc_asn1_entry c_asn1_com_obj_attr[6] = {
1376 	{ "label", SC_ASN1_UTF8STRING, SC_ASN1_TAG_UTF8STRING, SC_ASN1_OPTIONAL, NULL, NULL },
1377 	{ "flags", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
1378 	{ "authId", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
1379 	{ "userConsent", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
1380 	{ "accessControlRules", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1381 	{ NULL, 0, 0, 0, NULL, NULL }
1382 };
1383 
1384 static const struct sc_asn1_entry c_asn1_p15_obj[5] = {
1385 	{ "commonObjectAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
1386 	{ "classAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
1387 	{ "subClassAttributes", SC_ASN1_STRUCT, SC_ASN1_CTX | 0 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
1388 	{ "typeAttributes", SC_ASN1_STRUCT, SC_ASN1_CTX | 1 | SC_ASN1_CONS, 0, NULL, NULL },
1389 	{ NULL, 0, 0, 0, NULL, NULL }
1390 };
1391 
asn1_decode_p15_object(sc_context_t * ctx,const u8 * in,size_t len,struct sc_asn1_pkcs15_object * obj,int depth)1392 static int asn1_decode_p15_object(sc_context_t *ctx, const u8 *in,
1393 				  size_t len, struct sc_asn1_pkcs15_object *obj,
1394 				  int depth)
1395 {
1396 	struct sc_pkcs15_object *p15_obj = obj->p15_obj;
1397 	struct sc_asn1_entry asn1_c_attr[6], asn1_p15_obj[5];
1398 	struct sc_asn1_entry asn1_ac_rules[SC_PKCS15_MAX_ACCESS_RULES + 1], asn1_ac_rule[SC_PKCS15_MAX_ACCESS_RULES][3];
1399 	size_t flags_len = sizeof(p15_obj->flags);
1400 	size_t label_len = sizeof(p15_obj->label);
1401 	size_t access_mode_len = sizeof(p15_obj->access_rules[0].access_mode);
1402 	int r, ii;
1403 
1404 	for (ii=0; ii<SC_PKCS15_MAX_ACCESS_RULES; ii++)
1405 		sc_copy_asn1_entry(c_asn1_access_control_rule, asn1_ac_rule[ii]);
1406 	sc_copy_asn1_entry(c_asn1_access_control_rules, asn1_ac_rules);
1407 
1408 
1409 	sc_copy_asn1_entry(c_asn1_com_obj_attr, asn1_c_attr);
1410 	sc_copy_asn1_entry(c_asn1_p15_obj, asn1_p15_obj);
1411 	sc_format_asn1_entry(asn1_c_attr + 0, p15_obj->label, &label_len, 0);
1412 	sc_format_asn1_entry(asn1_c_attr + 1, &p15_obj->flags, &flags_len, 0);
1413 	sc_format_asn1_entry(asn1_c_attr + 2, &p15_obj->auth_id, NULL, 0);
1414 	sc_format_asn1_entry(asn1_c_attr + 3, &p15_obj->user_consent, NULL, 0);
1415 
1416 	for (ii=0; ii<SC_PKCS15_MAX_ACCESS_RULES; ii++)   {
1417 		sc_format_asn1_entry(asn1_ac_rule[ii] + 0, &p15_obj->access_rules[ii].access_mode, &access_mode_len, 0);
1418 		sc_format_asn1_entry(asn1_ac_rule[ii] + 1, &p15_obj->access_rules[ii].auth_id, NULL, 0);
1419 		sc_format_asn1_entry(asn1_ac_rules + ii, asn1_ac_rule[ii], NULL, 0);
1420 	}
1421 	sc_format_asn1_entry(asn1_c_attr + 4, asn1_ac_rules, NULL, 0);
1422 
1423 	sc_format_asn1_entry(asn1_p15_obj + 0, asn1_c_attr, NULL, 0);
1424 	sc_format_asn1_entry(asn1_p15_obj + 1, obj->asn1_class_attr, NULL, 0);
1425 	sc_format_asn1_entry(asn1_p15_obj + 2, obj->asn1_subclass_attr, NULL, 0);
1426 	sc_format_asn1_entry(asn1_p15_obj + 3, obj->asn1_type_attr, NULL, 0);
1427 
1428 	r = asn1_decode(ctx, asn1_p15_obj, in, len, NULL, NULL, 0, depth + 1);
1429 	return r;
1430 }
1431 
asn1_encode_p15_object(sc_context_t * ctx,const struct sc_asn1_pkcs15_object * obj,u8 ** buf,size_t * bufsize,int depth)1432 static int asn1_encode_p15_object(sc_context_t *ctx, const struct sc_asn1_pkcs15_object *obj,
1433 				  u8 **buf, size_t *bufsize, int depth)
1434 {
1435 	struct sc_pkcs15_object p15_obj = *obj->p15_obj;
1436 	struct sc_asn1_entry    asn1_c_attr[6], asn1_p15_obj[5];
1437 	struct sc_asn1_entry asn1_ac_rules[SC_PKCS15_MAX_ACCESS_RULES + 1], asn1_ac_rule[SC_PKCS15_MAX_ACCESS_RULES][3];
1438 	size_t label_len = strlen(p15_obj.label);
1439 	size_t flags_len;
1440 	size_t access_mode_len;
1441 	int r, ii;
1442 
1443 	sc_debug(ctx, SC_LOG_DEBUG_ASN1, "encode p15 obj(type:0x%X,access_mode:0x%X)", p15_obj.type, p15_obj.access_rules[0].access_mode);
1444 	if (p15_obj.access_rules[0].access_mode)   {
1445 		for (ii=0; ii<SC_PKCS15_MAX_ACCESS_RULES; ii++)   {
1446 			sc_copy_asn1_entry(c_asn1_access_control_rule, asn1_ac_rule[ii]);
1447 			if (p15_obj.access_rules[ii].auth_id.len == 0)   {
1448 				asn1_ac_rule[ii][1].type = SC_ASN1_NULL;
1449 				asn1_ac_rule[ii][1].tag = SC_ASN1_TAG_NULL;
1450 			}
1451 		}
1452 		sc_copy_asn1_entry(c_asn1_access_control_rules, asn1_ac_rules);
1453 	}
1454 
1455 	sc_copy_asn1_entry(c_asn1_com_obj_attr, asn1_c_attr);
1456 	sc_copy_asn1_entry(c_asn1_p15_obj, asn1_p15_obj);
1457 	if (label_len != 0)
1458 		sc_format_asn1_entry(asn1_c_attr + 0, (void *) p15_obj.label, &label_len, 1);
1459 	if (p15_obj.flags) {
1460 		flags_len = sizeof(p15_obj.flags);
1461 		sc_format_asn1_entry(asn1_c_attr + 1, (void *) &p15_obj.flags, &flags_len, 1);
1462 	}
1463 	if (p15_obj.auth_id.len)
1464 		sc_format_asn1_entry(asn1_c_attr + 2, (void *) &p15_obj.auth_id, NULL, 1);
1465 	if (p15_obj.user_consent)
1466 		sc_format_asn1_entry(asn1_c_attr + 3, (void *) &p15_obj.user_consent, NULL, 1);
1467 
1468 	if (p15_obj.access_rules[0].access_mode)   {
1469 		for (ii=0; p15_obj.access_rules[ii].access_mode; ii++)   {
1470 			access_mode_len = sizeof(p15_obj.access_rules[ii].access_mode);
1471 			sc_format_asn1_entry(asn1_ac_rule[ii] + 0, (void *) &p15_obj.access_rules[ii].access_mode, &access_mode_len, 1);
1472 			sc_format_asn1_entry(asn1_ac_rule[ii] + 1, (void *) &p15_obj.access_rules[ii].auth_id, NULL, 1);
1473 			sc_format_asn1_entry(asn1_ac_rules + ii, asn1_ac_rule[ii], NULL, 1);
1474 		}
1475 		sc_format_asn1_entry(asn1_c_attr + 4, asn1_ac_rules, NULL, 1);
1476 	}
1477 
1478 	sc_format_asn1_entry(asn1_p15_obj + 0, asn1_c_attr, NULL, 1);
1479 	sc_format_asn1_entry(asn1_p15_obj + 1, obj->asn1_class_attr, NULL, 1);
1480 	if (obj->asn1_subclass_attr != NULL && obj->asn1_subclass_attr->name)
1481 		sc_format_asn1_entry(asn1_p15_obj + 2, obj->asn1_subclass_attr, NULL, 1);
1482 	sc_format_asn1_entry(asn1_p15_obj + 3, obj->asn1_type_attr, NULL, 1);
1483 
1484 	r = asn1_encode(ctx, asn1_p15_obj, buf, bufsize, depth + 1);
1485 	return r;
1486 }
1487 
asn1_decode_entry(sc_context_t * ctx,struct sc_asn1_entry * entry,const u8 * obj,size_t objlen,int depth)1488 static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry,
1489 			     const u8 *obj, size_t objlen, int depth)
1490 {
1491 	void *parm = entry->parm;
1492 	int (*callback_func)(sc_context_t *nctx, void *arg, const u8 *nobj,
1493 			     size_t nobjlen, int ndepth);
1494 	size_t *len = (size_t *) entry->arg;
1495 	int r = 0;
1496 
1497 	callback_func = parm;
1498 
1499 	sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sdecoding '%s', raw data:%s%s\n",
1500 		depth, depth, "", entry->name,
1501 		sc_dump_hex(obj, objlen > 16  ? 16 : objlen),
1502 		objlen > 16 ? "..." : "");
1503 
1504 	switch (entry->type) {
1505 	case SC_ASN1_STRUCT:
1506 		if (parm != NULL)
1507 			r = asn1_decode(ctx, (struct sc_asn1_entry *) parm, obj,
1508 				       objlen, NULL, NULL, 0, depth + 1);
1509 		break;
1510 	case SC_ASN1_NULL:
1511 		break;
1512 	case SC_ASN1_BOOLEAN:
1513 		if (parm != NULL) {
1514 			if (objlen != 1) {
1515 				sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1516 					 "invalid ASN.1 object length: %"SC_FORMAT_LEN_SIZE_T"u\n",
1517 					 objlen);
1518 				r = SC_ERROR_INVALID_ASN1_OBJECT;
1519 			} else
1520 				*((int *) parm) = obj[0] ? 1 : 0;
1521 		}
1522 		break;
1523 	case SC_ASN1_INTEGER:
1524 	case SC_ASN1_ENUMERATED:
1525 		if (parm != NULL) {
1526 			r = sc_asn1_decode_integer(obj, objlen, (int *) entry->parm, 0);
1527 			sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sdecoding '%s' returned %d\n", depth, depth, "",
1528 					entry->name, *((int *) entry->parm));
1529 		}
1530 		break;
1531 	case SC_ASN1_BIT_STRING_NI:
1532 	case SC_ASN1_BIT_STRING:
1533 		if (parm != NULL) {
1534 			int invert = entry->type == SC_ASN1_BIT_STRING ? 1 : 0;
1535 			assert(len != NULL);
1536 			if (objlen < 1) {
1537 				r = SC_ERROR_INVALID_ASN1_OBJECT;
1538 				break;
1539 			}
1540 			if (entry->flags & SC_ASN1_ALLOC) {
1541 				u8 **buf = (u8 **) parm;
1542 				if (objlen > 1) {
1543 					*buf = malloc(objlen-1);
1544 					if (*buf == NULL) {
1545 						r = SC_ERROR_OUT_OF_MEMORY;
1546 						break;
1547 					}
1548 				}
1549 				*len = objlen-1;
1550 				parm = *buf;
1551 			}
1552 			r = decode_bit_string(obj, objlen, (u8 *) parm, *len, invert, 0);
1553 			if (r >= 0) {
1554 				*len = r;
1555 				r = 0;
1556 			}
1557 		}
1558 		break;
1559 	case SC_ASN1_BIT_FIELD:
1560 		if (parm != NULL)
1561 			r = decode_bit_field(obj, objlen, (u8 *) parm, *len, 0);
1562 		break;
1563 	case SC_ASN1_OCTET_STRING:
1564 		if (parm != NULL) {
1565 			size_t c;
1566 			assert(len != NULL);
1567 
1568 			/* Strip off padding zero */
1569 			if ((entry->flags & SC_ASN1_UNSIGNED)
1570 					&& objlen > 1 && obj[0] == 0x00) {
1571 				objlen--;
1572 				obj++;
1573 			}
1574 
1575 			/* Allocate buffer if needed */
1576 			if (entry->flags & SC_ASN1_ALLOC) {
1577 				u8 **buf = (u8 **) parm;
1578 				if (objlen > 0) {
1579 					*buf = malloc(objlen);
1580 					if (*buf == NULL) {
1581 						r = SC_ERROR_OUT_OF_MEMORY;
1582 						break;
1583 					}
1584 				}
1585 				c = *len = objlen;
1586 				parm = *buf;
1587 			} else
1588 				c = objlen > *len ? *len : objlen;
1589 
1590 			memcpy(parm, obj, c);
1591 			*len = c;
1592 		}
1593 		break;
1594 	case SC_ASN1_GENERALIZEDTIME:
1595 		if (parm != NULL) {
1596 			size_t c;
1597 			assert(len != NULL);
1598 			if (entry->flags & SC_ASN1_ALLOC) {
1599 				u8 **buf = (u8 **) parm;
1600 				if (objlen > 0) {
1601 					*buf = malloc(objlen);
1602 					if (*buf == NULL) {
1603 						r = SC_ERROR_OUT_OF_MEMORY;
1604 						break;
1605 					}
1606 				}
1607 				c = *len = objlen;
1608 				parm = *buf;
1609 			} else
1610 				c = objlen > *len ? *len : objlen;
1611 
1612 			memcpy(parm, obj, c);
1613 			*len = c;
1614 		}
1615 		break;
1616 	case SC_ASN1_OBJECT:
1617 		if (parm != NULL)
1618 			r = sc_asn1_decode_object_id(obj, objlen, (struct sc_object_id *) parm);
1619 		break;
1620 	case SC_ASN1_PRINTABLESTRING:
1621 	case SC_ASN1_UTF8STRING:
1622 		if (parm != NULL) {
1623 			assert(len != NULL);
1624 			if (entry->flags & SC_ASN1_ALLOC) {
1625 				u8 **buf = (u8 **) parm;
1626 				*buf = malloc(objlen+1);
1627 				if (*buf == NULL) {
1628 					r = SC_ERROR_OUT_OF_MEMORY;
1629 					break;
1630 				}
1631 				*len = objlen+1;
1632 				parm = *buf;
1633 			}
1634 			r = sc_asn1_decode_utf8string(obj, objlen, (u8 *) parm, len);
1635 			if (entry->flags & SC_ASN1_ALLOC) {
1636 				*len -= 1;
1637 			}
1638 		}
1639 		break;
1640 	case SC_ASN1_PATH:
1641 		if (entry->parm != NULL)
1642 			r = asn1_decode_path(ctx, obj, objlen, (sc_path_t *) parm, depth);
1643 		break;
1644 	case SC_ASN1_PKCS15_ID:
1645 		if (entry->parm != NULL) {
1646 			struct sc_pkcs15_id *id = (struct sc_pkcs15_id *) parm;
1647 			size_t c = objlen > sizeof(id->value) ? sizeof(id->value) : objlen;
1648 
1649 			memcpy(id->value, obj, c);
1650 			id->len = c;
1651 		}
1652 		break;
1653 	case SC_ASN1_PKCS15_OBJECT:
1654 		if (entry->parm != NULL)
1655 			r = asn1_decode_p15_object(ctx, obj, objlen, (struct sc_asn1_pkcs15_object *) parm, depth);
1656 		break;
1657 	case SC_ASN1_ALGORITHM_ID:
1658 		if (entry->parm != NULL)
1659 			r = sc_asn1_decode_algorithm_id(ctx, obj, objlen, (struct sc_algorithm_id *) parm, depth);
1660 		break;
1661 	case SC_ASN1_SE_INFO:
1662 		if (entry->parm != NULL)
1663 			r = asn1_decode_se_info(ctx, obj, objlen, (sc_pkcs15_sec_env_info_t ***)entry->parm, len, depth);
1664 		break;
1665 	case SC_ASN1_CALLBACK:
1666 		if (entry->parm != NULL)
1667 			r = callback_func(ctx, entry->arg, obj, objlen, depth);
1668 		break;
1669 	default:
1670 		sc_debug(ctx, SC_LOG_DEBUG_ASN1, "invalid ASN.1 type: %d\n", entry->type);
1671 		return SC_ERROR_INVALID_ASN1_OBJECT;
1672 	}
1673 	if (r) {
1674 		sc_debug(ctx, SC_LOG_DEBUG_ASN1, "decoding of ASN.1 object '%s' failed: %s\n", entry->name,
1675 		      sc_strerror(r));
1676 		return r;
1677 	}
1678 	entry->flags |= SC_ASN1_PRESENT;
1679 	return 0;
1680 }
1681 
asn1_decode(sc_context_t * ctx,struct sc_asn1_entry * asn1,const u8 * in,size_t len,const u8 ** newp,size_t * len_left,int choice,int depth)1682 static int asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1,
1683 		       const u8 *in, size_t len, const u8 **newp, size_t *len_left,
1684 		       int choice, int depth)
1685 {
1686 	int r, idx = 0;
1687 	const u8 *p = in, *obj;
1688 	struct sc_asn1_entry *entry = asn1;
1689 	size_t left = len, objlen;
1690 
1691 	sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1692 		 "%*.*scalled, left=%"SC_FORMAT_LEN_SIZE_T"u, depth %d%s\n",
1693 		 depth, depth, "", left, depth, choice ? ", choice" : "");
1694 
1695 	if (!p)
1696 		return SC_ERROR_ASN1_OBJECT_NOT_FOUND;
1697 	if (left < 2) {
1698 		while (asn1->name && (asn1->flags & SC_ASN1_OPTIONAL))
1699 			asn1++;
1700 		/* If all elements were optional, there's nothing
1701 		 * to complain about */
1702 		if (asn1->name == NULL)
1703 			return 0;
1704 		sc_debug(ctx, SC_LOG_DEBUG_ASN1, "End of ASN.1 stream, "
1705 			      "non-optional field \"%s\" not found\n",
1706 			      asn1->name);
1707 		return SC_ERROR_ASN1_OBJECT_NOT_FOUND;
1708 	}
1709 	if (p[0] == 0 || p[0] == 0xFF || len == 0)
1710 		return SC_ERROR_ASN1_END_OF_CONTENTS;
1711 
1712 	for (idx = 0; asn1[idx].name != NULL; idx++) {
1713 		entry = &asn1[idx];
1714 
1715 		sc_debug(ctx, SC_LOG_DEBUG_ASN1, "Looking for '%s', tag 0x%x%s%s\n",
1716 			entry->name, entry->tag, choice? ", CHOICE" : "",
1717 			(entry->flags & SC_ASN1_OPTIONAL)? ", OPTIONAL": "");
1718 
1719 		/* Special case CHOICE has no tag */
1720 		if (entry->type == SC_ASN1_CHOICE) {
1721 			r = asn1_decode(ctx,
1722 				(struct sc_asn1_entry *) entry->parm,
1723 				p, left, &p, &left, 1, depth + 1);
1724 			if (r >= 0)
1725 				r = 0;
1726 			goto decode_ok;
1727 		}
1728 
1729 		obj = sc_asn1_skip_tag(ctx, &p, &left, entry->tag, &objlen);
1730 		if (obj == NULL) {
1731 			sc_debug(ctx, SC_LOG_DEBUG_ASN1, "'%s' not present\n", entry->name);
1732 			if (choice)
1733 				continue;
1734 			if (entry->flags & SC_ASN1_OPTIONAL)
1735 				continue;
1736 			sc_debug(ctx, SC_LOG_DEBUG_ASN1, "mandatory ASN.1 object '%s' not found\n", entry->name);
1737 			if (left) {
1738 				u8 line[128], *linep = line;
1739 				size_t i;
1740 
1741 				line[0] = 0;
1742 				for (i = 0; i < 10 && i < left; i++) {
1743 					sprintf((char *) linep, "%02X ", p[i]);
1744 					linep += 3;
1745 				}
1746 				sc_debug(ctx, SC_LOG_DEBUG_ASN1, "next tag: %s\n", line);
1747 			}
1748 			SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_ASN1_OBJECT_NOT_FOUND);
1749 		}
1750 		r = asn1_decode_entry(ctx, entry, obj, objlen, depth);
1751 
1752 decode_ok:
1753 		if (r)
1754 			return r;
1755 		if (choice)
1756 			break;
1757  	}
1758  	if (choice && asn1[idx].name == NULL) /* No match */
1759 		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, SC_ERROR_ASN1_OBJECT_NOT_FOUND);
1760  	if (newp != NULL)
1761 		*newp = p;
1762  	if (len_left != NULL)
1763 		*len_left = left;
1764 	if (choice)
1765 		SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, idx);
1766 	SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_ASN1, 0);
1767 }
1768 
sc_asn1_decode(sc_context_t * ctx,struct sc_asn1_entry * asn1,const u8 * in,size_t len,const u8 ** newp,size_t * len_left)1769 int sc_asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1,
1770 		   const u8 *in, size_t len, const u8 **newp, size_t *len_left)
1771 {
1772 	return asn1_decode(ctx, asn1, in, len, newp, len_left, 0, 0);
1773 }
1774 
sc_asn1_decode_choice(sc_context_t * ctx,struct sc_asn1_entry * asn1,const u8 * in,size_t len,const u8 ** newp,size_t * len_left)1775 int sc_asn1_decode_choice(sc_context_t *ctx, struct sc_asn1_entry *asn1,
1776 			  const u8 *in, size_t len, const u8 **newp, size_t *len_left)
1777 {
1778 	return asn1_decode(ctx, asn1, in, len, newp, len_left, 1, 0);
1779 }
1780 
asn1_encode_entry(sc_context_t * ctx,const struct sc_asn1_entry * entry,u8 ** obj,size_t * objlen,int depth)1781 static int asn1_encode_entry(sc_context_t *ctx, const struct sc_asn1_entry *entry,
1782 			     u8 **obj, size_t *objlen, int depth)
1783 {
1784 	void *parm = entry->parm;
1785 	int (*callback_func)(sc_context_t *nctx, void *arg, u8 **nobj,
1786 			     size_t *nobjlen, int ndepth);
1787 	const size_t *len = (const size_t *) entry->arg;
1788 	int r = 0;
1789 	u8 * buf = NULL;
1790 	size_t buflen = 0;
1791 
1792 	callback_func = parm;
1793 
1794 	sc_debug(ctx, SC_LOG_DEBUG_ASN1, "%*.*sencoding '%s'%s\n",
1795 	       	depth, depth, "", entry->name,
1796 		(entry->flags & SC_ASN1_PRESENT)? "" : " (not present)");
1797 	if (!(entry->flags & SC_ASN1_PRESENT))
1798 		goto no_object;
1799 	sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1800 		 "%*.*stype=%d, tag=0x%02x, parm=%p, len=%"SC_FORMAT_LEN_SIZE_T"u\n",
1801 		 depth, depth, "", entry->type, entry->tag, parm,
1802 		 len ? *len : 0);
1803 
1804 	if (entry->type == SC_ASN1_CHOICE) {
1805 		const struct sc_asn1_entry *list, *choice = NULL;
1806 
1807 		list = (const struct sc_asn1_entry *) parm;
1808 		while (list->name != NULL) {
1809 			if (list->flags & SC_ASN1_PRESENT) {
1810 				if (choice) {
1811 					sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1812 						"ASN.1 problem: more than "
1813 						"one CHOICE when encoding %s: "
1814 						"%s and %s both present\n",
1815 						entry->name,
1816 						choice->name,
1817 						list->name);
1818 					return SC_ERROR_INVALID_ASN1_OBJECT;
1819 				}
1820 				choice = list;
1821 			}
1822 			list++;
1823 		}
1824 		if (choice == NULL)
1825 			goto no_object;
1826 		return asn1_encode_entry(ctx, choice, obj, objlen, depth + 1);
1827 	}
1828 
1829 	if (entry->type != SC_ASN1_NULL && parm == NULL) {
1830 		sc_debug(ctx, SC_LOG_DEBUG_ASN1, "unexpected parm == NULL\n");
1831 		return SC_ERROR_INVALID_ASN1_OBJECT;
1832 	}
1833 
1834 	switch (entry->type) {
1835 	case SC_ASN1_STRUCT:
1836 		r = asn1_encode(ctx, (const struct sc_asn1_entry *) parm, &buf,
1837 				&buflen, depth + 1);
1838 		break;
1839 	case SC_ASN1_NULL:
1840 		buf = NULL;
1841 		buflen = 0;
1842 		break;
1843 	case SC_ASN1_BOOLEAN:
1844 		buf = malloc(1);
1845 		if (buf == NULL) {
1846 			r = SC_ERROR_OUT_OF_MEMORY;
1847 			break;
1848 		}
1849 		buf[0] = *((int *) parm) ? 0xFF : 0;
1850 		buflen = 1;
1851 		break;
1852 	case SC_ASN1_INTEGER:
1853 	case SC_ASN1_ENUMERATED:
1854 		r = asn1_encode_integer(*((int *) entry->parm), &buf, &buflen);
1855 		break;
1856 	case SC_ASN1_BIT_STRING_NI:
1857 	case SC_ASN1_BIT_STRING:
1858 		if (len != NULL) {
1859 			if (entry->type == SC_ASN1_BIT_STRING)
1860 				r = encode_bit_string((const u8 *) parm, *len, &buf, &buflen, 1);
1861 			else
1862 				r = encode_bit_string((const u8 *) parm, *len, &buf, &buflen, 0);
1863 		} else {
1864 			r = SC_ERROR_INVALID_ARGUMENTS;
1865 		}
1866 		break;
1867 	case SC_ASN1_BIT_FIELD:
1868 		if (len != NULL) {
1869 			r = encode_bit_field((const u8 *) parm, *len, &buf, &buflen);
1870 		} else {
1871 			r = SC_ERROR_INVALID_ARGUMENTS;
1872 		}
1873 		break;
1874 	case SC_ASN1_PRINTABLESTRING:
1875 	case SC_ASN1_OCTET_STRING:
1876 	case SC_ASN1_UTF8STRING:
1877 		if (len != NULL) {
1878 			buf = malloc(*len + 1);
1879 			if (buf == NULL) {
1880 				r = SC_ERROR_OUT_OF_MEMORY;
1881 				break;
1882 			}
1883 			buflen = 0;
1884 			/* If the integer is supposed to be unsigned, insert
1885 			 * a padding byte if the MSB is one */
1886 			if ((entry->flags & SC_ASN1_UNSIGNED)
1887 					&& (((u8 *) parm)[0] & 0x80)) {
1888 				buf[buflen++] = 0x00;
1889 			}
1890 			memcpy(buf + buflen, parm, *len);
1891 			buflen += *len;
1892 		} else {
1893 			r = SC_ERROR_INVALID_ARGUMENTS;
1894 		}
1895 		break;
1896 	case SC_ASN1_GENERALIZEDTIME:
1897 		if (len != NULL) {
1898 			buf = malloc(*len);
1899 			if (buf == NULL) {
1900 				r = SC_ERROR_OUT_OF_MEMORY;
1901 				break;
1902 			}
1903 			memcpy(buf, parm, *len);
1904 			buflen = *len;
1905 		} else {
1906 			r = SC_ERROR_INVALID_ARGUMENTS;
1907 		}
1908 		break;
1909 	case SC_ASN1_OBJECT:
1910 		r = sc_asn1_encode_object_id(&buf, &buflen, (struct sc_object_id *) parm);
1911 		break;
1912 	case SC_ASN1_PATH:
1913 		r = asn1_encode_path(ctx, (const sc_path_t *) parm, &buf, &buflen, depth, entry->flags);
1914 		break;
1915 	case SC_ASN1_PKCS15_ID:
1916 		{
1917 			const struct sc_pkcs15_id *id = (const struct sc_pkcs15_id *) parm;
1918 
1919 			buf = malloc(id->len);
1920 			if (buf == NULL) {
1921 				r = SC_ERROR_OUT_OF_MEMORY;
1922 				break;
1923 			}
1924 			memcpy(buf, id->value, id->len);
1925 			buflen = id->len;
1926 		}
1927 		break;
1928 	case SC_ASN1_PKCS15_OBJECT:
1929 		r = asn1_encode_p15_object(ctx, (const struct sc_asn1_pkcs15_object *) parm, &buf, &buflen, depth);
1930 		break;
1931 	case SC_ASN1_ALGORITHM_ID:
1932 		r = sc_asn1_encode_algorithm_id(ctx, &buf, &buflen, (const struct sc_algorithm_id *) parm, depth);
1933 		break;
1934 	case SC_ASN1_SE_INFO:
1935 		if (!len)
1936 			return SC_ERROR_INVALID_ASN1_OBJECT;
1937 		r = asn1_encode_se_info(ctx, (struct sc_pkcs15_sec_env_info **)parm, *len, &buf, &buflen, depth);
1938 		break;
1939 	case SC_ASN1_CALLBACK:
1940 		r = callback_func(ctx, entry->arg, &buf, &buflen, depth);
1941 		break;
1942 	default:
1943 		sc_debug(ctx, SC_LOG_DEBUG_ASN1, "invalid ASN.1 type: %d\n", entry->type);
1944 		return SC_ERROR_INVALID_ASN1_OBJECT;
1945 	}
1946 	if (r) {
1947 		sc_debug(ctx, SC_LOG_DEBUG_ASN1, "encoding of ASN.1 object '%s' failed: %s\n", entry->name,
1948 		      sc_strerror(r));
1949 		if (buf)
1950 			free(buf);
1951 		return r;
1952 	}
1953 
1954 	/* Treatment of OPTIONAL elements:
1955 	 *  -	if the encoding has 0 length, and the element is OPTIONAL,
1956 	 *	we don't write anything (unless it's an ASN1 NULL and the
1957 	 *      SC_ASN1_PRESENT flag is set).
1958 	 *  -	if the encoding has 0 length, but the element is non-OPTIONAL,
1959 	 *	constructed, we write a empty element (e.g. a SEQUENCE of
1960 	 *      length 0). In case of an ASN1 NULL just write the tag and
1961 	 *      length (i.e. 0x05,0x00).
1962 	 *  -	any other empty objects are considered bogus
1963 	 */
1964 no_object:
1965 	if (!buflen && entry->flags & SC_ASN1_OPTIONAL && !(entry->flags & SC_ASN1_PRESENT)) {
1966 		/* This happens when we try to encode e.g. the
1967 		 * subClassAttributes, which may be empty */
1968 		*obj = NULL;
1969 		*objlen = 0;
1970 		r = 0;
1971 	} else if (!buflen && (entry->flags & SC_ASN1_EMPTY_ALLOWED)) {
1972 		*obj = NULL;
1973 		*objlen = 0;
1974 		r = asn1_write_element(ctx, entry->tag, buf, buflen, obj, objlen);
1975 		if (r)
1976 			sc_debug(ctx, SC_LOG_DEBUG_ASN1, "error writing ASN.1 tag and length: %s\n", sc_strerror(r));
1977 	} else if (buflen || entry->type == SC_ASN1_NULL || entry->tag & SC_ASN1_CONS) {
1978 		r = asn1_write_element(ctx, entry->tag, buf, buflen, obj, objlen);
1979 		if (r)
1980 			sc_debug(ctx, SC_LOG_DEBUG_ASN1, "error writing ASN.1 tag and length: %s\n",
1981 					sc_strerror(r));
1982 	} else if (!(entry->flags & SC_ASN1_PRESENT)) {
1983 		sc_debug(ctx, SC_LOG_DEBUG_ASN1, "cannot encode non-optional ASN.1 object: not given by caller\n");
1984 		r = SC_ERROR_INVALID_ASN1_OBJECT;
1985 	} else {
1986 		sc_debug(ctx, SC_LOG_DEBUG_ASN1, "cannot encode empty non-optional ASN.1 object\n");
1987 		r = SC_ERROR_INVALID_ASN1_OBJECT;
1988 	}
1989 	if (buf)
1990 		free(buf);
1991 	if (r >= 0)
1992 		sc_debug(ctx, SC_LOG_DEBUG_ASN1,
1993 			 "%*.*slength of encoded item=%"SC_FORMAT_LEN_SIZE_T"u\n",
1994 			 depth, depth, "", *objlen);
1995 	return r;
1996 }
1997 
asn1_encode(sc_context_t * ctx,const struct sc_asn1_entry * asn1,u8 ** ptr,size_t * size,int depth)1998 static int asn1_encode(sc_context_t *ctx, const struct sc_asn1_entry *asn1,
1999 		      u8 **ptr, size_t *size, int depth)
2000 {
2001 	int r, idx = 0;
2002 	u8 *obj = NULL, *buf = NULL, *tmp;
2003 	size_t total = 0, objsize;
2004 
2005 	if (asn1 == NULL) {
2006 		return SC_ERROR_INVALID_ARGUMENTS;
2007 	}
2008 
2009 	for (idx = 0; asn1[idx].name != NULL; idx++) {
2010 		r = asn1_encode_entry(ctx, &asn1[idx], &obj, &objsize, depth);
2011 		if (r) {
2012 			if (obj)
2013 				free(obj);
2014 			if (buf)
2015 				free(buf);
2016 			return r;
2017 		}
2018 		/* in case of an empty (optional) element continue with
2019 		 * the next asn1 element */
2020 		if (!objsize)
2021 			continue;
2022 		tmp = (u8 *) realloc(buf, total + objsize);
2023 		if (!tmp) {
2024 			if (obj)
2025 				free(obj);
2026 			if (buf)
2027 				free(buf);
2028 			return SC_ERROR_OUT_OF_MEMORY;
2029 		}
2030 		buf = tmp;
2031 		memcpy(buf + total, obj, objsize);
2032 		free(obj);
2033 		obj = NULL;
2034 		total += objsize;
2035 	}
2036 	*ptr = buf;
2037 	*size = total;
2038 	return 0;
2039 }
2040 
sc_asn1_encode(sc_context_t * ctx,const struct sc_asn1_entry * asn1,u8 ** ptr,size_t * size)2041 int sc_asn1_encode(sc_context_t *ctx, const struct sc_asn1_entry *asn1,
2042 		   u8 **ptr, size_t *size)
2043 {
2044 	return asn1_encode(ctx, asn1, ptr, size, 0);
2045 }
2046 
_sc_asn1_encode(sc_context_t * ctx,const struct sc_asn1_entry * asn1,u8 ** ptr,size_t * size,int depth)2047 int _sc_asn1_encode(sc_context_t *ctx, const struct sc_asn1_entry *asn1,
2048 		    u8 **ptr, size_t *size, int depth)
2049 {
2050 	return asn1_encode(ctx, asn1, ptr, size, depth);
2051 }
2052 
2053 int
_sc_asn1_decode(sc_context_t * ctx,struct sc_asn1_entry * asn1,const u8 * in,size_t len,const u8 ** newp,size_t * left,int choice,int depth)2054 _sc_asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1,
2055 		       const u8 *in, size_t len, const u8 **newp, size_t *left,
2056 		       int choice, int depth)
2057 {
2058 	return asn1_decode(ctx, asn1, in, len, newp, left, choice, depth);
2059 }
2060 
2061 int
sc_der_copy(sc_pkcs15_der_t * dst,const sc_pkcs15_der_t * src)2062 sc_der_copy(sc_pkcs15_der_t *dst, const sc_pkcs15_der_t *src)
2063 {
2064 	if (!dst)
2065 		return SC_ERROR_INVALID_ARGUMENTS;
2066 	memset(dst, 0, sizeof(*dst));
2067 	if (src->len) {
2068 		dst->value = malloc(src->len);
2069 		if (!dst->value)
2070 			return SC_ERROR_OUT_OF_MEMORY;
2071 		dst->len = src->len;
2072 		memcpy(dst->value, src->value, src->len);
2073 	}
2074 	return SC_SUCCESS;
2075 }
2076 
2077 int
sc_encode_oid(struct sc_context * ctx,struct sc_object_id * id,unsigned char ** out,size_t * size)2078 sc_encode_oid (struct sc_context *ctx, struct sc_object_id *id,
2079 		unsigned char **out, size_t *size)
2080 {
2081 	static const struct sc_asn1_entry c_asn1_object_id[2] = {
2082 		{ "oid", SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_ALLOC, NULL, NULL },
2083 		{ NULL, 0, 0, 0, NULL, NULL }
2084 	};
2085 	struct sc_asn1_entry asn1_object_id[2];
2086 	int rv;
2087 
2088 	sc_copy_asn1_entry(c_asn1_object_id, asn1_object_id);
2089 	sc_format_asn1_entry(asn1_object_id + 0, id, NULL, 1);
2090 
2091 	rv = _sc_asn1_encode(ctx, asn1_object_id, out, size, 1);
2092 	LOG_TEST_RET(ctx, rv, "Cannot encode object ID");
2093 
2094 	return SC_SUCCESS;
2095 }
2096 
2097 
2098 #define C_ASN1_SIG_VALUE_SIZE 2
2099 static struct sc_asn1_entry c_asn1_sig_value[C_ASN1_SIG_VALUE_SIZE] = {
2100 		{ "ECDSA-Sig-Value", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
2101 		{ NULL, 0, 0, 0, NULL, NULL }
2102 };
2103 
2104 #define C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE 3
2105 static struct sc_asn1_entry c_asn1_sig_value_coefficients[C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE] = {
2106 		{ "r", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL },
2107 		{ "s", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC|SC_ASN1_UNSIGNED, NULL, NULL },
2108 		{ NULL, 0, 0, 0, NULL, NULL }
2109 };
2110 
2111 
2112 int
sc_asn1_sig_value_rs_to_sequence(struct sc_context * ctx,unsigned char * in,size_t inlen,unsigned char ** buf,size_t * buflen)2113 sc_asn1_sig_value_rs_to_sequence(struct sc_context *ctx, unsigned char *in, size_t inlen,
2114 		unsigned char **buf, size_t *buflen)
2115 {
2116 	struct sc_asn1_entry asn1_sig_value[C_ASN1_SIG_VALUE_SIZE];
2117 	struct sc_asn1_entry asn1_sig_value_coefficients[C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE];
2118 	unsigned char *r = in, *s = in + inlen/2;
2119 	size_t r_len = inlen/2, s_len = inlen/2;
2120 	int rv;
2121 
2122 	LOG_FUNC_CALLED(ctx);
2123 
2124 	/* R/S are filled up with zeroes, we do not want that in sequence format */
2125 	while(r_len > 1 && *r == 0x00) {
2126 		r++;
2127 		r_len--;
2128 	}
2129 	while(s_len > 1 && *s == 0x00) {
2130 		s++;
2131 		s_len--;
2132 	}
2133 
2134 	sc_copy_asn1_entry(c_asn1_sig_value, asn1_sig_value);
2135 	sc_format_asn1_entry(asn1_sig_value + 0, asn1_sig_value_coefficients, NULL, 1);
2136 
2137 	sc_copy_asn1_entry(c_asn1_sig_value_coefficients, asn1_sig_value_coefficients);
2138 	sc_format_asn1_entry(asn1_sig_value_coefficients + 0, r, &r_len, 1);
2139 	sc_format_asn1_entry(asn1_sig_value_coefficients + 1, s, &s_len, 1);
2140 
2141 	rv = sc_asn1_encode(ctx, asn1_sig_value, buf, buflen);
2142 	LOG_TEST_RET(ctx, rv, "ASN.1 encoding ECDSA-SIg-Value failed");
2143 
2144 	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2145 }
2146 
2147 
2148 int
sc_asn1_sig_value_sequence_to_rs(struct sc_context * ctx,const unsigned char * in,size_t inlen,unsigned char * buf,size_t buflen)2149 sc_asn1_sig_value_sequence_to_rs(struct sc_context *ctx, const unsigned char *in, size_t inlen,
2150 		unsigned char *buf, size_t buflen)
2151 {
2152 	struct sc_asn1_entry asn1_sig_value[C_ASN1_SIG_VALUE_SIZE];
2153 	struct sc_asn1_entry asn1_sig_value_coefficients[C_ASN1_SIG_VALUE_COEFFICIENTS_SIZE];
2154 	unsigned char *r = NULL, *s = NULL;
2155 	size_t r_len = 0, s_len = 0, halflen = buflen/2;
2156 	int rv;
2157 
2158 	LOG_FUNC_CALLED(ctx);
2159 	if (!buf || !buflen)
2160 		LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
2161 
2162 	sc_copy_asn1_entry(c_asn1_sig_value, asn1_sig_value);
2163 	sc_format_asn1_entry(asn1_sig_value + 0, asn1_sig_value_coefficients, NULL, 0);
2164 
2165 	sc_copy_asn1_entry(c_asn1_sig_value_coefficients, asn1_sig_value_coefficients);
2166 	sc_format_asn1_entry(asn1_sig_value_coefficients + 0, &r, &r_len, 0);
2167 	sc_format_asn1_entry(asn1_sig_value_coefficients + 1, &s, &s_len, 0);
2168 
2169 	rv = sc_asn1_decode(ctx, asn1_sig_value, in, inlen, NULL, NULL);
2170 	LOG_TEST_GOTO_ERR(ctx, rv, "ASN.1 decoding ECDSA-Sig-Value failed");
2171 
2172 	if (halflen < r_len || halflen < s_len)   {
2173 		rv = SC_ERROR_BUFFER_TOO_SMALL;
2174 		goto err;
2175 	}
2176 
2177 	memset(buf, 0, buflen);
2178 	if (r_len > 0)
2179 		memcpy(buf + (halflen - r_len), r, r_len);
2180 	if (s_len > 0)
2181 		memcpy(buf + (buflen - s_len), s, s_len);
2182 
2183 	sc_log(ctx, "r(%"SC_FORMAT_LEN_SIZE_T"u): %s", halflen,
2184 	       sc_dump_hex(buf, halflen));
2185 	sc_log(ctx, "s(%"SC_FORMAT_LEN_SIZE_T"u): %s", halflen,
2186 	       sc_dump_hex(buf + halflen, halflen));
2187 
2188 	rv = SC_SUCCESS;
2189 err:
2190 	free(r);
2191 	free(s);
2192 
2193 	LOG_FUNC_RETURN(ctx, rv);
2194 }
2195