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