1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/asn.1/asn1_encode.c */
4 * Copyright 1994, 2008 by the Massachusetts Institute of Technology.
7 * Export of this software from the United States of America may
8 * require a specific license from the United States Government.
9 * It is the responsibility of any person or organization contemplating
10 * export to obtain such a license before exporting.
12 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13 * distribute this software and its documentation for any purpose and
14 * without fee is hereby granted, provided that the above copyright
15 * notice appear in all copies and that both that copyright notice and
16 * this permission notice appear in supporting documentation, and that
17 * the name of M.I.T. not be used in advertising or publicity pertaining
18 * to distribution of the software without specific, written prior
19 * permission. Furthermore if you modify this software you must label
20 * your software as modified software and not distribute it in such a
21 * fashion that it might be confused with the original M.I.T. software.
22 * M.I.T. makes no representations about the suitability of
23 * this software for any purpose. It is provided "as is" without express
24 * or implied warranty.
27 #include "asn1_encode.h"
30 uint8_t *ptr; /* Position, moving backwards; may be NULL */
31 size_t count; /* Count of bytes written so far */
34 /**** Functions for encoding primitive types ****/
36 /* Insert one byte into buf going backwards. */
38 insert_byte(asn1buf *buf, uint8_t o)
40 if (buf->ptr != NULL) {
47 /* Insert a block of bytes into buf going backwards (but without reversing
50 insert_bytes(asn1buf *buf, const void *bytes, size_t len)
52 if (buf->ptr != NULL) {
53 memcpy(buf->ptr - len, bytes, len);
60 k5_asn1_encode_bool(asn1buf *buf, intmax_t val)
62 insert_byte(buf, val ? 0xFF : 0x00);
66 k5_asn1_encode_int(asn1buf *buf, intmax_t val)
73 digit = valcopy & 0xFF;
74 insert_byte(buf, digit);
75 valcopy = valcopy >> 8;
76 } while (valcopy != 0 && valcopy != ~0);
78 /* Make sure the high bit is of the proper signed-ness. */
79 if (val > 0 && (digit & 0x80) == 0x80)
81 else if (val < 0 && (digit & 0x80) != 0x80)
82 insert_byte(buf, 0xFF);
86 k5_asn1_encode_uint(asn1buf *buf, uintmax_t val)
93 digit = valcopy & 0xFF;
94 insert_byte(buf, digit);
95 valcopy = valcopy >> 8;
96 } while (valcopy != 0);
98 /* Make sure the high bit is of the proper signed-ness. */
104 k5_asn1_encode_bytestring(asn1buf *buf, uint8_t *const *val, size_t len)
106 if (len > 0 && val == NULL)
107 return ASN1_MISSING_FIELD;
108 insert_bytes(buf, *val, len);
113 k5_asn1_encode_generaltime(asn1buf *buf, time_t val)
115 struct tm *gtime, gtimebuf;
117 time_t gmt_time = val;
121 * Time encoding: YYYYMMDDhhmmssZ
124 sp = "19700101000000Z";
127 * Sanity check this just to be paranoid, as gmtime can return NULL,
128 * and some bogus implementations might overrun on the sprintf.
131 #ifdef GMTIME_R_RETURNS_INT
132 if (gmtime_r(&gmt_time, >imebuf) != 0)
133 return ASN1_BAD_GMTIME;
135 if (gmtime_r(&gmt_time, >imebuf) == NULL)
136 return ASN1_BAD_GMTIME;
138 #else /* HAVE_GMTIME_R */
139 gtime = gmtime(&gmt_time);
141 return ASN1_BAD_GMTIME;
142 memcpy(>imebuf, gtime, sizeof(gtimebuf));
143 #endif /* HAVE_GMTIME_R */
146 if (gtime->tm_year > 8099 || gtime->tm_mon > 11 ||
147 gtime->tm_mday > 31 || gtime->tm_hour > 23 ||
148 gtime->tm_min > 59 || gtime->tm_sec > 59)
149 return ASN1_BAD_GMTIME;
150 len = snprintf(s, sizeof(s), "%04d%02d%02d%02d%02d%02dZ",
151 1900 + gtime->tm_year, gtime->tm_mon + 1,
152 gtime->tm_mday, gtime->tm_hour,
153 gtime->tm_min, gtime->tm_sec);
154 if (SNPRINTF_OVERFLOW(len, sizeof(s)))
155 /* Shouldn't be possible given above tests. */
156 return ASN1_BAD_GMTIME;
160 insert_bytes(buf, sp, 15);
165 k5_asn1_encode_bitstring(asn1buf *buf, uint8_t *const *val, size_t len)
167 insert_bytes(buf, *val, len);
172 /**** Functions for decoding primitive types ****/
175 k5_asn1_decode_bool(const uint8_t *asn1, size_t len, intmax_t *val)
178 return ASN1_BAD_LENGTH;
183 /* Decode asn1/len as the contents of a DER integer, placing the signed result
186 k5_asn1_decode_int(const uint8_t *asn1, size_t len, intmax_t *val)
192 return ASN1_BAD_LENGTH;
193 n = (asn1[0] & 0x80) ? -1 : 0;
194 /* Check length; allow extra octet if first octet is 0. */
195 if (len > sizeof(intmax_t) + (asn1[0] == 0))
196 return ASN1_OVERFLOW;
197 for (i = 0; i < len; i++)
198 n = (n << 8) | asn1[i];
203 /* Decode asn1/len as the contents of a DER integer, placing the unsigned
206 k5_asn1_decode_uint(const uint8_t *asn1, size_t len, uintmax_t *val)
212 return ASN1_BAD_LENGTH;
213 /* Check for negative values and check length. */
214 if ((asn1[0] & 0x80) || len > sizeof(uintmax_t) + (asn1[0] == 0))
215 return ASN1_OVERFLOW;
216 for (i = 0, n = 0; i < len; i++)
217 n = (n << 8) | asn1[i];
223 k5_asn1_decode_bytestring(const uint8_t *asn1, size_t len,
224 uint8_t **str_out, size_t *len_out)
235 memcpy(str, asn1, len);
242 k5_asn1_decode_generaltime(const uint8_t *asn1, size_t len, time_t *time_out)
244 const char *s = (char *)asn1;
250 return ASN1_BAD_LENGTH;
251 /* Time encoding: YYYYMMDDhhmmssZ */
253 return ASN1_BAD_FORMAT;
254 if (memcmp(s, "19700101000000Z", 15) == 0) {
258 #define c2i(c) ((c) - '0')
259 ts.tm_year = 1000 * c2i(s[0]) + 100 * c2i(s[1]) + 10 * c2i(s[2]) +
261 ts.tm_mon = 10 * c2i(s[4]) + c2i(s[5]) - 1;
262 ts.tm_mday = 10 * c2i(s[6]) + c2i(s[7]);
263 ts.tm_hour = 10 * c2i(s[8]) + c2i(s[9]);
264 ts.tm_min = 10 * c2i(s[10]) + c2i(s[11]);
265 ts.tm_sec = 10 * c2i(s[12]) + c2i(s[13]);
267 t = krb5int_gmt_mktime(&ts);
269 return ASN1_BAD_TIMEFORMAT;
275 * Note: we return the number of bytes, not bits, in the bit string. If the
276 * number of bits is not a multiple of 8 we effectively round up to the next
280 k5_asn1_decode_bitstring(const uint8_t *asn1, size_t len,
281 uint8_t **bits_out, size_t *len_out)
283 uint8_t unused, *bits;
288 return ASN1_BAD_LENGTH;
292 return ASN1_BAD_FORMAT;
297 memcpy(bits, asn1, len);
299 bits[len - 1] &= (0xff << unused);
306 /**** Functions for encoding and decoding tags ****/
308 /* Encode a DER tag into buf with the tag parameters in t and the content
309 * length len. Place the length of the encoded tag in *retlen. */
310 static krb5_error_code
311 make_tag(asn1buf *buf, const taginfo *t, size_t len)
313 asn1_tagnum tag_copy;
314 size_t len_copy, oldcount;
316 if (t->tagnum > ASN1_TAGNUM_MAX)
317 return ASN1_OVERFLOW;
319 /* Encode the length of the content within the tag. */
321 insert_byte(buf, len & 0x7F);
323 oldcount = buf->count;
324 for (len_copy = len; len_copy != 0; len_copy >>= 8)
325 insert_byte(buf, len_copy & 0xFF);
326 insert_byte(buf, 0x80 | ((buf->count - oldcount) & 0x7F));
329 /* Encode the tag and construction bit. */
330 if (t->tagnum < 31) {
331 insert_byte(buf, t->asn1class | t->construction | t->tagnum);
333 tag_copy = t->tagnum;
334 insert_byte(buf, tag_copy & 0x7F);
337 for (; tag_copy != 0; tag_copy >>= 7)
338 insert_byte(buf, 0x80 | (tag_copy & 0x7F));
340 insert_byte(buf, t->asn1class | t->construction | 0x1F);
347 * Read a BER tag and length from asn1/len. Place the tag parameters in
348 * tag_out. Set contents_out/clen_out to the octet range of the tag's
349 * contents, and remainder_out/rlen_out to the octet range after the end of the
352 * (krb5 ASN.1 encodings should be in DER, but for compatibility with some
353 * really ancient implementations we handle the indefinite length form in tags.
354 * However, we still insist on the primitive form of string types.)
356 static krb5_error_code
357 get_tag(const uint8_t *asn1, size_t len, taginfo *tag_out,
358 const uint8_t **contents_out, size_t *clen_out,
359 const uint8_t **remainder_out, size_t *rlen_out)
363 const uint8_t *c, *p, *tag_start = asn1;
364 size_t clen, llen, i;
367 *contents_out = *remainder_out = NULL;
368 *clen_out = *rlen_out = 0;
373 tag_out->asn1class = o & 0xC0;
374 tag_out->construction = o & 0x20;
375 if ((o & 0x1F) != 0x1F) {
376 tag_out->tagnum = o & 0x1F;
384 tag_out->tagnum = (tag_out->tagnum << 7) | (o & 0x7F);
394 /* Indefinite form (should not be present in DER, but we accept it). */
395 if (tag_out->construction != CONSTRUCTED)
396 return ASN1_MISMATCH_INDEF;
398 while (!(len >= 2 && p[0] == 0 && p[1] == 0)) {
399 ret = get_tag(p, len, &t, &c, &clen, &p, &len);
403 tag_out->tag_end_len = 2;
404 *contents_out = asn1;
405 *clen_out = p - asn1;
406 *remainder_out = p + 2;
408 } else if ((o & 0x80) == 0) {
409 /* Short form (first octet gives content length). */
412 tag_out->tag_end_len = 0;
413 *contents_out = asn1;
415 *remainder_out = asn1 + *clen_out;
416 *rlen_out = len - (*remainder_out - asn1);
418 /* Long form (first octet gives number of base-256 length octets). */
422 if (llen > sizeof(*clen_out))
423 return ASN1_OVERFLOW;
424 for (i = 0, clen = 0; i < llen; i++)
425 clen = (clen << 8) | asn1[i];
426 if (clen > len - llen)
428 tag_out->tag_end_len = 0;
429 *contents_out = asn1 + llen;
431 *remainder_out = *contents_out + clen;
432 *rlen_out = len - (*remainder_out - asn1);
434 tag_out->tag_len = *contents_out - tag_start;
438 #ifdef POINTERS_ARE_ALL_THE_SAME
439 #define LOADPTR(PTR, TYPE) (*(const void *const *)(PTR))
440 #define STOREPTR(PTR, TYPE, VAL) (*(void **)(VAL) = (PTR))
442 #define LOADPTR(PTR, PTRINFO) \
443 (assert((PTRINFO)->loadptr != NULL), (PTRINFO)->loadptr(PTR))
444 #define STOREPTR(PTR, PTRINFO, VAL) \
445 (assert((PTRINFO)->storeptr != NULL), (PTRINFO)->storeptr(PTR, VAL))
449 get_nullterm_sequence_len(const void *valp, const struct atype_info *seq)
452 const struct atype_info *a;
453 const struct ptr_info *ptr;
454 const void *elt, *eltptr;
458 assert(a->type == atype_ptr);
459 assert(seq->size != 0);
463 eltptr = (const char *)valp + i * seq->size;
464 elt = LOADPTR(eltptr, ptr);
471 static krb5_error_code
472 encode_sequence_of(asn1buf *buf, size_t seqlen, const void *val,
473 const struct atype_info *eltinfo);
475 static krb5_error_code
476 encode_nullterm_sequence_of(asn1buf *buf, const void *val,
477 const struct atype_info *type, int can_be_empty)
479 size_t len = get_nullterm_sequence_len(val, type);
481 if (!can_be_empty && len == 0)
482 return ASN1_MISSING_FIELD;
483 return encode_sequence_of(buf, len, val, type);
487 load_int(const void *val, size_t size)
490 case 1: return *(int8_t *)val;
491 case 2: return *(int16_t *)val;
492 case 4: return *(int32_t *)val;
493 case 8: return *(int64_t *)val;
499 load_uint(const void *val, size_t size)
502 case 1: return *(uint8_t *)val;
503 case 2: return *(uint16_t *)val;
504 case 4: return *(uint32_t *)val;
505 case 8: return *(uint64_t *)val;
510 static krb5_error_code
511 load_count(const void *val, const struct counted_info *counted,
514 const void *countptr = (const char *)val + counted->lenoff;
516 assert(sizeof(size_t) <= sizeof(uintmax_t));
517 if (counted->lensigned) {
518 intmax_t xlen = load_int(countptr, counted->lensize);
519 if (xlen < 0 || (uintmax_t)xlen > SIZE_MAX)
523 uintmax_t xlen = load_uint(countptr, counted->lensize);
524 if ((size_t)xlen != xlen || xlen > SIZE_MAX)
531 static krb5_error_code
532 store_int(intmax_t intval, size_t size, void *val)
536 if ((int8_t)intval != intval)
537 return ASN1_OVERFLOW;
538 *(int8_t *)val = intval;
541 if ((int16_t)intval != intval)
542 return ASN1_OVERFLOW;
543 *(int16_t *)val = intval;
546 if ((int32_t)intval != intval)
547 return ASN1_OVERFLOW;
548 *(int32_t *)val = intval;
551 if ((int64_t)intval != intval)
552 return ASN1_OVERFLOW;
553 *(int64_t *)val = intval;
560 static krb5_error_code
561 store_uint(uintmax_t intval, size_t size, void *val)
565 if ((uint8_t)intval != intval)
566 return ASN1_OVERFLOW;
567 *(uint8_t *)val = intval;
570 if ((uint16_t)intval != intval)
571 return ASN1_OVERFLOW;
572 *(uint16_t *)val = intval;
575 if ((uint32_t)intval != intval)
576 return ASN1_OVERFLOW;
577 *(uint32_t *)val = intval;
580 if ((uint64_t)intval != intval)
581 return ASN1_OVERFLOW;
582 *(uint64_t *)val = intval;
589 /* Store a count value in an integer field of a structure. If count is
590 * SIZE_MAX and the target is a signed field, store -1. */
591 static krb5_error_code
592 store_count(size_t count, const struct counted_info *counted, void *val)
594 void *countptr = (char *)val + counted->lenoff;
596 if (counted->lensigned) {
597 if (count == SIZE_MAX)
598 return store_int(-1, counted->lensize, countptr);
599 else if ((intmax_t)count < 0)
600 return ASN1_OVERFLOW;
602 return store_int(count, counted->lensize, countptr);
604 return store_uint(count, counted->lensize, countptr);
607 /* Split a DER encoding into tag and contents. Insert the contents into buf,
608 * then return the length of the contents and the tag. */
609 static krb5_error_code
610 split_der(asn1buf *buf, uint8_t *const *der, size_t len, taginfo *tag_out)
613 const uint8_t *contents, *remainder;
616 ret = get_tag(*der, len, tag_out, &contents, &clen, &remainder, &rlen);
620 return ASN1_BAD_LENGTH;
621 insert_bytes(buf, contents, clen);
626 * Store the DER encoding given by t and asn1/len into the char * or
627 * uint8_t * pointed to by val. Set *count_out to the length of the
630 static krb5_error_code
631 store_der(const taginfo *t, const uint8_t *asn1, size_t len, void *val,
638 der_len = t->tag_len + len + t->tag_end_len;
639 der = malloc(der_len);
642 memcpy(der, asn1 - t->tag_len, der_len);
643 *(uint8_t **)val = der;
644 *count_out = der_len;
648 static krb5_error_code
649 encode_sequence(asn1buf *buf, const void *val, const struct seq_info *seq);
650 static krb5_error_code
651 encode_cntype(asn1buf *buf, const void *val, size_t len,
652 const struct cntype_info *c, taginfo *tag_out);
654 /* Encode a value (contents only, no outer tag) according to a type, and return
655 * its encoded tag information. */
656 static krb5_error_code
657 encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
663 return ASN1_MISSING_FIELD;
667 const struct fn_info *fn = a->tinfo;
668 assert(fn->enc != NULL);
669 return fn->enc(buf, val, tag_out);
672 assert(a->tinfo != NULL);
673 ret = encode_sequence(buf, val, a->tinfo);
676 tag_out->asn1class = UNIVERSAL;
677 tag_out->construction = CONSTRUCTED;
678 tag_out->tagnum = ASN1_SEQUENCE;
681 const struct ptr_info *ptr = a->tinfo;
682 assert(ptr->basetype != NULL);
683 return encode_atype(buf, LOADPTR(val, ptr), ptr->basetype, tag_out);
686 const struct offset_info *off = a->tinfo;
687 assert(off->basetype != NULL);
688 return encode_atype(buf, (const char *)val + off->dataoff,
689 off->basetype, tag_out);
691 case atype_optional: {
692 const struct optional_info *opt = a->tinfo;
693 assert(opt->is_present != NULL);
694 if (opt->is_present(val))
695 return encode_atype(buf, val, opt->basetype, tag_out);
699 case atype_counted: {
700 const struct counted_info *counted = a->tinfo;
701 const void *dataptr = (const char *)val + counted->dataoff;
703 assert(counted->basetype != NULL);
704 ret = load_count(val, counted, &count);
707 return encode_cntype(buf, dataptr, count, counted->basetype, tag_out);
709 case atype_nullterm_sequence_of:
710 case atype_nonempty_nullterm_sequence_of:
711 assert(a->tinfo != NULL);
712 ret = encode_nullterm_sequence_of(buf, val, a->tinfo,
714 atype_nullterm_sequence_of);
717 tag_out->asn1class = UNIVERSAL;
718 tag_out->construction = CONSTRUCTED;
719 tag_out->tagnum = ASN1_SEQUENCE;
721 case atype_tagged_thing: {
722 const struct tagged_info *tag = a->tinfo;
723 size_t oldcount = buf->count;
724 ret = encode_atype(buf, val, tag->basetype, tag_out);
727 if (!tag->implicit) {
728 ret = make_tag(buf, tag_out, buf->count - oldcount);
731 tag_out->construction = tag->construction;
733 tag_out->asn1class = tag->tagtype;
734 tag_out->tagnum = tag->tagval;
738 k5_asn1_encode_bool(buf, load_int(val, a->size));
739 tag_out->asn1class = UNIVERSAL;
740 tag_out->construction = PRIMITIVE;
741 tag_out->tagnum = ASN1_BOOLEAN;
744 k5_asn1_encode_int(buf, load_int(val, a->size));
745 tag_out->asn1class = UNIVERSAL;
746 tag_out->construction = PRIMITIVE;
747 tag_out->tagnum = ASN1_INTEGER;
750 k5_asn1_encode_uint(buf, load_uint(val, a->size));
751 tag_out->asn1class = UNIVERSAL;
752 tag_out->construction = PRIMITIVE;
753 tag_out->tagnum = ASN1_INTEGER;
755 case atype_int_immediate: {
756 const struct immediate_info *imm = a->tinfo;
757 k5_asn1_encode_int(buf, imm->val);
758 tag_out->asn1class = UNIVERSAL;
759 tag_out->construction = PRIMITIVE;
760 tag_out->tagnum = ASN1_INTEGER;
764 assert(a->type > atype_min);
765 assert(a->type < atype_max);
772 static krb5_error_code
773 encode_atype_and_tag(asn1buf *buf, const void *val, const struct atype_info *a)
777 size_t oldcount = buf->count;
779 ret = encode_atype(buf, val, a, &t);
782 ret = make_tag(buf, &t, buf->count - oldcount);
789 * Encode an object and count according to a cntype_info structure. val is a
790 * pointer to the object being encoded, which in most cases is itself a
791 * pointer (but is a union in the cntype_choice case).
793 static krb5_error_code
794 encode_cntype(asn1buf *buf, const void *val, size_t count,
795 const struct cntype_info *c, taginfo *tag_out)
800 case cntype_string: {
801 const struct string_info *string = c->tinfo;
802 assert(string->enc != NULL);
803 ret = string->enc(buf, val, count);
806 tag_out->asn1class = UNIVERSAL;
807 tag_out->construction = PRIMITIVE;
808 tag_out->tagnum = string->tagval;
812 return split_der(buf, val, count, tag_out);
814 const struct atype_info *a = c->tinfo;
815 const struct ptr_info *ptr = a->tinfo;
816 assert(a->type == atype_ptr);
817 val = LOADPTR(val, ptr);
818 ret = encode_sequence_of(buf, count, val, ptr->basetype);
821 tag_out->asn1class = UNIVERSAL;
822 tag_out->construction = CONSTRUCTED;
823 tag_out->tagnum = ASN1_SEQUENCE;
826 case cntype_choice: {
827 const struct choice_info *choice = c->tinfo;
828 if (count >= choice->n_options)
829 return ASN1_MISSING_FIELD;
830 return encode_atype(buf, val, choice->options[count], tag_out);
834 assert(c->type > cntype_min);
835 assert(c->type < cntype_max);
842 static krb5_error_code
843 encode_sequence(asn1buf *buf, const void *val, const struct seq_info *seq)
848 for (i = seq->n_fields; i > 0; i--) {
849 ret = encode_atype_and_tag(buf, val, seq->fields[i - 1]);
850 if (ret == ASN1_OMITTED)
858 static krb5_error_code
859 encode_sequence_of(asn1buf *buf, size_t seqlen, const void *val,
860 const struct atype_info *eltinfo)
866 assert(eltinfo->size != 0);
867 for (i = seqlen; i > 0; i--) {
868 eltptr = (const char *)val + (i - 1) * eltinfo->size;
869 ret = encode_atype_and_tag(buf, eltptr, eltinfo);
876 /**** Functions for freeing C objects based on type info ****/
878 static void free_atype_ptr(const struct atype_info *a, void *val);
879 static void free_sequence(const struct seq_info *seq, void *val);
880 static void free_sequence_of(const struct atype_info *eltinfo, void *val,
882 static void free_cntype(const struct cntype_info *a, void *val, size_t count);
885 * Free a C object according to a type description. Do not free pointers at
886 * the first level; they may be referenced by other fields of a sequence, and
887 * will be freed by free_atype_ptr in a second pass.
890 free_atype(const struct atype_info *a, void *val)
894 const struct fn_info *fn = a->tinfo;
895 if (fn->free_func != NULL)
900 free_sequence(a->tinfo, val);
903 const struct ptr_info *ptrinfo = a->tinfo;
904 void *ptr = LOADPTR(val, ptrinfo);
906 free_atype(ptrinfo->basetype, ptr);
907 free_atype_ptr(ptrinfo->basetype, ptr);
912 const struct offset_info *off = a->tinfo;
913 assert(off->basetype != NULL);
914 free_atype(off->basetype, (char *)val + off->dataoff);
917 case atype_optional: {
918 const struct optional_info *opt = a->tinfo;
919 free_atype(opt->basetype, val);
922 case atype_counted: {
923 const struct counted_info *counted = a->tinfo;
924 void *dataptr = (char *)val + counted->dataoff;
926 if (load_count(val, counted, &count) == 0)
927 free_cntype(counted->basetype, dataptr, count);
930 case atype_nullterm_sequence_of:
931 case atype_nonempty_nullterm_sequence_of: {
932 size_t count = get_nullterm_sequence_len(val, a->tinfo);
933 free_sequence_of(a->tinfo, val, count);
936 case atype_tagged_thing: {
937 const struct tagged_info *tag = a->tinfo;
938 free_atype(tag->basetype, val);
944 case atype_int_immediate:
952 free_atype_ptr(const struct atype_info *a, void *val)
958 case atype_nullterm_sequence_of:
959 case atype_nonempty_nullterm_sequence_of:
963 case atype_int_immediate:
966 const struct ptr_info *ptrinfo = a->tinfo;
967 void *ptr = LOADPTR(val, ptrinfo);
969 STOREPTR(NULL, ptrinfo, val);
973 const struct offset_info *off = a->tinfo;
974 assert(off->basetype != NULL);
975 free_atype_ptr(off->basetype, (char *)val + off->dataoff);
978 case atype_optional: {
979 const struct optional_info *opt = a->tinfo;
980 free_atype_ptr(opt->basetype, val);
983 case atype_tagged_thing: {
984 const struct tagged_info *tag = a->tinfo;
985 free_atype_ptr(tag->basetype, val);
994 free_cntype(const struct cntype_info *c, void *val, size_t count)
1000 *(char **)val = NULL;
1002 case cntype_seqof: {
1003 const struct atype_info *a = c->tinfo;
1004 const struct ptr_info *ptrinfo = a->tinfo;
1005 void *seqptr = LOADPTR(val, ptrinfo);
1006 free_sequence_of(ptrinfo->basetype, seqptr, count);
1008 STOREPTR(NULL, ptrinfo, val);
1011 case cntype_choice: {
1012 const struct choice_info *choice = c->tinfo;
1013 if (count < choice->n_options) {
1014 free_atype(choice->options[count], val);
1015 free_atype_ptr(choice->options[count], val);
1025 free_sequence(const struct seq_info *seq, void *val)
1029 for (i = 0; i < seq->n_fields; i++)
1030 free_atype(seq->fields[i], val);
1031 for (i = 0; i < seq->n_fields; i++)
1032 free_atype_ptr(seq->fields[i], val);
1036 free_sequence_of(const struct atype_info *eltinfo, void *val, size_t count)
1040 assert(eltinfo->size != 0);
1041 while (count-- > 0) {
1042 eltptr = (char *)val + count * eltinfo->size;
1043 free_atype(eltinfo, eltptr);
1044 free_atype_ptr(eltinfo, eltptr);
1048 /**** Functions for decoding objects based on type info ****/
1050 /* Return nonzero if t is an expected tag for an ASN.1 object of type a. */
1052 check_atype_tag(const struct atype_info *a, const taginfo *t)
1056 const struct fn_info *fn = a->tinfo;
1057 assert(fn->check_tag != NULL);
1058 return fn->check_tag(t);
1060 case atype_sequence:
1061 case atype_nullterm_sequence_of:
1062 case atype_nonempty_nullterm_sequence_of:
1063 return (t->asn1class == UNIVERSAL && t->construction == CONSTRUCTED &&
1064 t->tagnum == ASN1_SEQUENCE);
1066 const struct ptr_info *ptrinfo = a->tinfo;
1067 return check_atype_tag(ptrinfo->basetype, t);
1069 case atype_offset: {
1070 const struct offset_info *off = a->tinfo;
1071 return check_atype_tag(off->basetype, t);
1073 case atype_optional: {
1074 const struct optional_info *opt = a->tinfo;
1075 return check_atype_tag(opt->basetype, t);
1077 case atype_counted: {
1078 const struct counted_info *counted = a->tinfo;
1079 switch (counted->basetype->type) {
1080 case cntype_string: {
1081 const struct string_info *string = counted->basetype->tinfo;
1082 return (t->asn1class == UNIVERSAL &&
1083 t->construction == PRIMITIVE &&
1084 t->tagnum == string->tagval);
1087 return (t->asn1class == UNIVERSAL &&
1088 t->construction == CONSTRUCTED &&
1089 t->tagnum == ASN1_SEQUENCE);
1092 * We treat any tag as matching a stored DER encoding. In some
1093 * cases we know what the tag should be; in others, we truly want
1094 * to accept any tag. If it ever becomes an issue, we could add
1095 * optional tag info to the type and check it here.
1100 * ASN.1 choices may or may not be extensible. For now, we treat
1101 * all choices as extensible and match any tag. We should consider
1102 * modeling whether choices are extensible before making the
1103 * encoder visible to plugins.
1110 case atype_tagged_thing: {
1111 const struct tagged_info *tag = a->tinfo;
1112 /* NOTE: Doesn't check construction bit for implicit tags. */
1113 if (!tag->implicit && t->construction != tag->construction)
1115 return (t->asn1class == tag->tagtype && t->tagnum == tag->tagval);
1118 return (t->asn1class == UNIVERSAL && t->construction == PRIMITIVE &&
1119 t->tagnum == ASN1_BOOLEAN);
1122 case atype_int_immediate:
1123 return (t->asn1class == UNIVERSAL && t->construction == PRIMITIVE &&
1124 t->tagnum == ASN1_INTEGER);
1130 static krb5_error_code
1131 decode_cntype(const taginfo *t, const uint8_t *asn1, size_t len,
1132 const struct cntype_info *c, void *val, size_t *count_out);
1133 static krb5_error_code
1134 decode_atype_to_ptr(const taginfo *t, const uint8_t *asn1, size_t len,
1135 const struct atype_info *basetype, void **ptr_out);
1136 static krb5_error_code
1137 decode_sequence(const uint8_t *asn1, size_t len, const struct seq_info *seq,
1139 static krb5_error_code
1140 decode_sequence_of(const uint8_t *asn1, size_t len,
1141 const struct atype_info *elemtype, void **seq_out,
1144 /* Given the enclosing tag t, decode from asn1/len the contents of the ASN.1
1145 * type specified by a, placing the result into val (caller-allocated). */
1146 static krb5_error_code
1147 decode_atype(const taginfo *t, const uint8_t *asn1, size_t len,
1148 const struct atype_info *a, void *val)
1150 krb5_error_code ret;
1154 const struct fn_info *fn = a->tinfo;
1155 assert(fn->dec != NULL);
1156 return fn->dec(t, asn1, len, val);
1158 case atype_sequence:
1159 return decode_sequence(asn1, len, a->tinfo, val);
1161 const struct ptr_info *ptrinfo = a->tinfo;
1162 void *ptr = LOADPTR(val, ptrinfo);
1163 assert(ptrinfo->basetype != NULL);
1165 /* Container was already allocated by a previous sequence field. */
1166 return decode_atype(t, asn1, len, ptrinfo->basetype, ptr);
1168 ret = decode_atype_to_ptr(t, asn1, len, ptrinfo->basetype, &ptr);
1171 STOREPTR(ptr, ptrinfo, val);
1175 case atype_offset: {
1176 const struct offset_info *off = a->tinfo;
1177 assert(off->basetype != NULL);
1178 return decode_atype(t, asn1, len, off->basetype,
1179 (char *)val + off->dataoff);
1181 case atype_optional: {
1182 const struct optional_info *opt = a->tinfo;
1183 return decode_atype(t, asn1, len, opt->basetype, val);
1185 case atype_counted: {
1186 const struct counted_info *counted = a->tinfo;
1187 void *dataptr = (char *)val + counted->dataoff;
1189 assert(counted->basetype != NULL);
1190 ret = decode_cntype(t, asn1, len, counted->basetype, dataptr, &count);
1193 return store_count(count, counted, val);
1195 case atype_tagged_thing: {
1196 const struct tagged_info *tag = a->tinfo;
1198 const taginfo *tp = t;
1201 if (!tag->implicit) {
1202 ret = get_tag(asn1, len, &inner_tag, &asn1, &len, &rem, &rlen);
1205 /* Note: we don't check rlen (it should be 0). */
1207 if (!check_atype_tag(tag->basetype, tp))
1210 return decode_atype(tp, asn1, len, tag->basetype, val);
1214 ret = k5_asn1_decode_bool(asn1, len, &intval);
1217 return store_int(intval, a->size, val);
1221 ret = k5_asn1_decode_int(asn1, len, &intval);
1224 return store_int(intval, a->size, val);
1228 ret = k5_asn1_decode_uint(asn1, len, &intval);
1231 return store_uint(intval, a->size, val);
1233 case atype_int_immediate: {
1234 const struct immediate_info *imm = a->tinfo;
1236 ret = k5_asn1_decode_int(asn1, len, &intval);
1239 if (intval != imm->val && imm->err != 0)
1244 /* Null-terminated sequence types are handled in decode_atype_to_ptr,
1245 * since they create variable-sized objects. */
1246 assert(a->type != atype_nullterm_sequence_of);
1247 assert(a->type != atype_nonempty_nullterm_sequence_of);
1248 assert(a->type > atype_min);
1249 assert(a->type < atype_max);
1256 * Given the enclosing tag t, decode from asn1/len the contents of the
1257 * ASN.1 type described by c, placing the counted result into val/count_out.
1258 * If the resulting count should be -1 (for an unknown union distinguisher),
1259 * set *count_out to SIZE_MAX.
1261 static krb5_error_code
1262 decode_cntype(const taginfo *t, const uint8_t *asn1, size_t len,
1263 const struct cntype_info *c, void *val, size_t *count_out)
1265 krb5_error_code ret;
1268 case cntype_string: {
1269 const struct string_info *string = c->tinfo;
1270 assert(string->dec != NULL);
1271 return string->dec(asn1, len, val, count_out);
1274 return store_der(t, asn1, len, val, count_out);
1275 case cntype_seqof: {
1276 const struct atype_info *a = c->tinfo;
1277 const struct ptr_info *ptrinfo = a->tinfo;
1279 assert(a->type == atype_ptr);
1280 ret = decode_sequence_of(asn1, len, ptrinfo->basetype, &seq,
1284 STOREPTR(seq, ptrinfo, val);
1287 case cntype_choice: {
1288 const struct choice_info *choice = c->tinfo;
1290 for (i = 0; i < choice->n_options; i++) {
1291 if (check_atype_tag(choice->options[i], t)) {
1292 ret = decode_atype(t, asn1, len, choice->options[i], val);
1299 /* SIZE_MAX will be stored as -1 in the distinguisher. If we start
1300 * modeling non-extensible choices we should check that here. */
1301 *count_out = SIZE_MAX;
1305 assert(c->type > cntype_min);
1306 assert(c->type < cntype_max);
1312 /* Add a null pointer to the end of a sequence. ptr is consumed on success
1313 * (to be replaced by *ptr_out), left alone on failure. */
1314 static krb5_error_code
1315 null_terminate(const struct atype_info *eltinfo, void *ptr, size_t count,
1318 const struct ptr_info *ptrinfo = eltinfo->tinfo;
1321 assert(eltinfo->type == atype_ptr);
1322 ptr = realloc(ptr, (count + 1) * eltinfo->size);
1325 endptr = (char *)ptr + count * eltinfo->size;
1326 STOREPTR(NULL, ptrinfo, endptr);
1331 static krb5_error_code
1332 decode_atype_to_ptr(const taginfo *t, const uint8_t *asn1, size_t len,
1333 const struct atype_info *a, void **ptr_out)
1335 krb5_error_code ret;
1341 case atype_nullterm_sequence_of:
1342 case atype_nonempty_nullterm_sequence_of:
1343 ret = decode_sequence_of(asn1, len, a->tinfo, &ptr, &count);
1346 ret = null_terminate(a->tinfo, ptr, count, &ptr);
1348 free_sequence_of(a->tinfo, ptr, count);
1351 /* Historically we do not enforce non-emptiness of sequences when
1352 * decoding, even when it is required by the ASN.1 type. */
1355 ptr = calloc(a->size, 1);
1358 ret = decode_atype(t, asn1, len, a, ptr);
1369 /* Initialize a C object when the corresponding ASN.1 type was omitted within a
1370 * sequence. If the ASN.1 type is not optional, return ASN1_MISSING_FIELD. */
1371 static krb5_error_code
1372 omit_atype(const struct atype_info *a, void *val)
1377 case atype_sequence:
1378 case atype_nullterm_sequence_of:
1379 case atype_nonempty_nullterm_sequence_of:
1384 case atype_int_immediate:
1385 return ASN1_MISSING_FIELD;
1387 const struct ptr_info *ptrinfo = a->tinfo;
1388 return omit_atype(ptrinfo->basetype, val);
1390 case atype_offset: {
1391 const struct offset_info *off = a->tinfo;
1392 return omit_atype(off->basetype, (char *)val + off->dataoff);
1394 case atype_tagged_thing: {
1395 const struct tagged_info *tag = a->tinfo;
1396 return omit_atype(tag->basetype, val);
1398 case atype_optional: {
1399 const struct optional_info *opt = a->tinfo;
1400 if (opt->init != NULL)
1409 /* Decode an ASN.1 sequence into a C object. */
1410 static krb5_error_code
1411 decode_sequence(const uint8_t *asn1, size_t len, const struct seq_info *seq,
1414 krb5_error_code ret;
1415 const uint8_t *contents;
1419 assert(seq->n_fields > 0);
1420 for (i = 0; i < seq->n_fields; i++) {
1423 ret = get_tag(asn1, len, &t, &contents, &clen, &asn1, &len);
1427 * Find the applicable sequence field. This logic is a little
1428 * oversimplified; we could match an element to an optional extensible
1429 * choice or optional stored-DER type when we ought to match a
1430 * subsequent non-optional field. But it's unwise and (hopefully) very
1431 * rare for ASN.1 modules to require such precision.
1433 for (; i < seq->n_fields; i++) {
1434 if (check_atype_tag(seq->fields[i], &t))
1436 ret = omit_atype(seq->fields[i], val);
1440 /* We currently model all sequences as extensible. We should consider
1441 * changing this before making the encoder visible to plugins. */
1442 if (i == seq->n_fields)
1444 ret = decode_atype(&t, contents, clen, seq->fields[i], val);
1448 /* Initialize any fields in the C object which were not accounted for in
1449 * the sequence. Error out if any of them aren't optional. */
1450 for (; i < seq->n_fields; i++) {
1451 ret = omit_atype(seq->fields[i], val);
1458 /* Free what we've decoded so far. Free pointers in a second pass in
1459 * case multiple fields refer to the same pointer. */
1460 for (j = 0; j < i; j++)
1461 free_atype(seq->fields[j], val);
1462 for (j = 0; j < i; j++)
1463 free_atype_ptr(seq->fields[j], val);
1467 static krb5_error_code
1468 decode_sequence_of(const uint8_t *asn1, size_t len,
1469 const struct atype_info *elemtype, void **seq_out,
1472 krb5_error_code ret;
1473 void *seq = NULL, *elem, *newseq;
1474 const uint8_t *contents;
1475 size_t clen, count = 0;
1481 ret = get_tag(asn1, len, &t, &contents, &clen, &asn1, &len);
1484 if (!check_atype_tag(elemtype, &t)) {
1488 newseq = realloc(seq, (count + 1) * elemtype->size);
1489 if (newseq == NULL) {
1494 elem = (char *)seq + count * elemtype->size;
1495 memset(elem, 0, elemtype->size);
1496 ret = decode_atype(&t, contents, clen, elemtype, elem);
1506 free_sequence_of(elemtype, seq, count);
1511 /* These three entry points are only needed for the kdc_req_body hack and may
1512 * go away at some point. Define them here so we can use short names above. */
1515 k5_asn1_encode_atype(asn1buf *buf, const void *val, const struct atype_info *a,
1518 return encode_atype(buf, val, a, tag_out);
1522 k5_asn1_decode_atype(const taginfo *t, const uint8_t *asn1, size_t len,
1523 const struct atype_info *a, void *val)
1525 return decode_atype(t, asn1, len, a, val);
1529 k5_asn1_full_encode(const void *rep, const struct atype_info *a,
1530 krb5_data **code_out)
1532 krb5_error_code ret;
1540 return ASN1_MISSING_FIELD;
1542 /* Make a first pass over rep to count the encoding size. */
1545 ret = encode_atype_and_tag(&buf, rep, a);
1549 /* Allocate space for the encoding. */
1550 bytes = malloc(buf.count + 1);
1553 bytes[buf.count] = 0;
1555 /* Make a second pass over rep to encode it. buf.ptr moves backwards as we
1556 * encode, and will always exactly return to the base. */
1557 buf.ptr = bytes + buf.count;
1559 ret = encode_atype_and_tag(&buf, rep, a);
1564 assert(buf.ptr == bytes);
1566 /* Create the output data object. */
1567 *code_out = malloc(sizeof(*d));
1568 if (*code_out == NULL) {
1572 **code_out = make_data(bytes, buf.count);
1577 k5_asn1_full_decode(const krb5_data *code, const struct atype_info *a,
1580 krb5_error_code ret;
1581 const uint8_t *contents, *remainder;
1586 ret = get_tag((uint8_t *)code->data, code->length, &t, &contents,
1587 &clen, &remainder, &rlen);
1590 /* rlen should be 0, but we don't check it (and due to padding in
1591 * non-length-preserving enctypes, it will sometimes be nonzero). */
1592 if (!check_atype_tag(a, &t))
1594 return decode_atype_to_ptr(&t, contents, clen, a, retrep);