5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2003 - 2006 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
24 /************************** ASN.1 Decoder routines **************************/
26 /* Internal SEQUENCE OF and SET OF decoder. This is used only when decoding
27 these two special tags. Other normal ASN.1 decoding is done in the
28 silc_asn1_decoder function. This parses the sequence of types and returns
29 them as raw BER buffers in an array of SilcBuffers. */
31 static SilcBool silc_asn1_decoder_sof(SilcAsn1 asn1, SilcBuffer src)
39 const unsigned char *rdata;
40 SilcUInt32 rdata_len, len = 0;
41 SilcBool found = FALSE, rindef;
43 struct SilcAsn1SofStruct {
45 struct SilcAsn1SofStruct *next;
48 SILC_LOG_DEBUG(("Decoding sequence of types"));
50 silc_list_init(types, struct SilcAsn1SofStruct, next);
52 /* Take the return arguments */
53 retb = va_arg(asn1->ap, SilcBuffer *);
54 retc = va_arg(asn1->ap, SilcUInt32 *);
58 /* Get the sequence type(s). If the type is CHOICE tag then the sequence
59 may include multiple different types. All types are considered
60 separately. If CHOICE is not given then only single type is expected. */
61 type = va_arg(asn1->ap, SilcUInt32);
62 assert(type != SILC_ASN1_END);
64 if (type == SILC_ASN1_TAG_CHOICE) {
65 /* The sequence may consist of the following types. */
66 type = va_arg(asn1->ap, SilcUInt32);
67 assert(type != SILC_ASN1_END);
68 while (type != SILC_ASN1_END) {
69 t = silc_smalloc(asn1->stack1, sizeof(*t));
73 silc_list_add(types, t);
75 SILC_LOG_DEBUG(("Looking for %s [%d] from sequence of types",
76 silc_asn1_tag_name(type), type));
78 type = va_arg(asn1->ap, SilcUInt32);
81 /* The sequence consists of this type. */
82 t = silc_smalloc(asn1->stack1, sizeof(*t));
86 silc_list_add(types, t);
88 SILC_LOG_DEBUG(("Looking for %s [%d] from sequence of types",
89 silc_asn1_tag_name(type), type));
92 /* END marker for the sequence */
93 type = va_arg(asn1->ap, SilcUInt32);
94 assert(type == SILC_ASN1_END);
96 /* Decode the SEQUENCE or SET */
97 ret = silc_ber_decode(src, NULL, NULL, (SilcUInt32 *)&rtag, &rdata,
98 &rdata_len, &rindef, &len);
100 SILC_LOG_DEBUG(("Error parsing BER block, malformed ASN.1 data"));
103 if (rtag != SILC_ASN1_TAG_SEQUENCE && rtag != SILC_ASN1_TAG_SET) {
104 SILC_LOG_DEBUG(("Invalid sequence of/set of"));
107 silc_buffer_pull(src, len);
109 while (silc_buffer_len(src)) {
110 /* Decode the BER data. */
111 ret = silc_ber_decode(src, NULL, NULL, (SilcUInt32 *)&rtag, &rdata,
112 &rdata_len, &rindef, &len);
114 SILC_LOG_DEBUG(("Error parsing BER block, malformed ASN.1 data"));
118 /* Now check the type(s) that it is supposed to be */
120 silc_list_start(types);
121 while ((t = silc_list_get(types)) != SILC_LIST_END) {
125 *retb = silc_srealloc(asn1->stack1, sizeof(**retb) * (*retc), *retb,
126 sizeof(**retb) * (*retc + 1));
130 SILC_LOG_DEBUG(("Decode %s [%d] from sequence of types",
131 silc_asn1_tag_name(rtag), rtag));
133 /* Data is duplicated only if SILC_ASN1_ALLOC flag is set */
135 rdata = silc_memdup(rdata - len, rdata_len + len);
141 silc_buffer_set(&(*retb)[*retc], (unsigned char *)rdata, rdata_len);
147 /* If type was not found we consider it the end of the sequence */
152 silc_buffer_pull(src, rdata_len);
155 SILC_LOG_DEBUG(("Decoded %d types", *retc));
160 silc_list_start(types);
161 while ((t = silc_list_get(types)) != SILC_LIST_END)
168 /* Macro for decoder to get argument for a type. If OPTIONAL option is
169 set then the argument is a pointer to the type pointer. The `type'
170 must be a non-pointer type, eg. int, SilcBufferStruct. */
171 #define SILC_ASN1_VAD(asn1, opts, type, name) \
173 if ((opts) & SILC_ASN1_OPTIONAL && !choice) { \
174 name = va_arg(asn1->ap, type **); \
182 *name = silc_scalloc(asn1->stack1, 1, sizeof(**name)); \
186 type *name ## tmp = va_arg(asn1->ap, type *); \
187 if (choice && found && !len) \
189 if (name ## tmp == NULL) \
191 name = &name ## tmp; \
194 /* Same as SILC_ASN1_VAD but for unsigned char and SilcUInt32 */
195 #define SILC_ASN1_VAD_UCHAR(asn1, opts, type, name, namelen) \
196 type **name = va_arg(asn1->ap, type **); \
197 SilcUInt32 *namelen = va_arg(asn1->ap, SilcUInt32 *); \
198 if (choice && found && !len) \
208 /* Same as SILC_ASN1_VAD but for char only */
209 #define SILC_ASN1_VAD_CHAR(asn1, opts, type, name) \
210 type **name = va_arg(asn1->ap, type **); \
211 if (choice && found && !len) \
221 #define SILC_ASN1_VA_FREE(opts, name) \
222 if ((opts) & SILC_ASN1_OPTIONAL) \
225 /* Decodes string to UTF-8 string which is our internal representation
227 #define SILC_ASN1_DECODE_STRING(enc, s, s_len) \
228 *s_len = silc_utf8_encoded_len(rdata, rdata_len, (enc)); \
230 SILC_LOG_DEBUG(("Malformed %d string value", (enc))); \
234 *s = silc_smalloc_ua(stack1, *s_len + 1); \
236 silc_utf8_encode(rdata, rdata_len, (enc), *s, *s_len); \
237 (*s)[*s_len] = '\0'; \
241 /* Internal ASN.1 decoder. The `type', `tag' and `opts' are the first
242 arguments (either very first or first for recursion) for a type.
243 The `depth' includes the current depth of recursion. */
246 silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
247 SilcAsn1Tag tag, SilcBerClass ber_class,
248 SilcAsn1Options opts, SilcBuffer src, SilcUInt32 depth,
251 unsigned char *ptr = src->data;
252 SilcAsn1Tag rtype, rtag;
253 SilcAsn1Options ropts;
255 SilcBerEncoding renc;
257 SilcBool ret, indef, rindef, found = FALSE, choice = FALSE;
258 const unsigned char *rdata;
259 SilcUInt32 rdata_len;
263 char sp[SILC_ASN1_RECURSION_DEPTH + 1];
264 memset(sp, 0, sizeof(sp));
266 memset(sp, 32, depth);
267 #endif /* SILC_DEBUG */
269 if (depth >= SILC_ASN1_RECURSION_DEPTH) {
270 SILC_LOG_DEBUG(("Maximum recursion depth reached"));
276 /* If requested type is SEQUENCE OF or SET OF then we decode the sequence
277 of types separately in an own decoder which returns array of buffers. */
278 if (type == SILC_ASN1_TAG_SEQUENCE_OF) {
279 /* Decode the sequence */
280 if (!silc_asn1_decoder_sof(asn1, src)) {
281 SILC_LOG_DEBUG(("Error decoding SEQUENCE OF"));
286 /* Continue with rest of the decodings if any */
287 SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
288 if (type == SILC_ASN1_END) {
294 /* Get length encoding */
295 indef = (opts & SILC_ASN1_INDEFINITE ? TRUE : FALSE);
297 /* By default UNIVERSAL is implied unless the following conditions
298 are met when CONTEXT will apply. For SILC_ASN1_TAG_ANY_PRIMITIVE
299 the class is changed only if flags dictate it. */
300 if (ber_class == SILC_BER_CLASS_UNIVERSAL) {
301 if (type == SILC_ASN1_TAG_ANY_PRIMITIVE) {
302 if (opts & SILC_ASN1_IMPLICIT ||
303 opts & SILC_ASN1_EXPLICIT)
304 ber_class = SILC_BER_CLASS_CONTEXT;
307 opts & SILC_ASN1_IMPLICIT ||
308 opts & SILC_ASN1_EXPLICIT)
309 ber_class = SILC_BER_CLASS_CONTEXT;
313 /* Now decode a BER encoded block from the source buffer. It must be
314 exactly the same user is expecting. */
315 ret = silc_ber_decode(src, &rclass, &renc, (SilcUInt32 *)&rtag, &rdata,
316 &rdata_len, &rindef, &len);
318 SILC_LOG_DEBUG(("Error parsing BER block, malformed ASN.1 data"));
322 /* Now verify that the decoded BER is the one user wanted to get. If
323 requested type is OPTIONAL, then ignore all the sanity tests. The
324 while() loop is for re-considering OPTIONAL types without parsing
325 new BER object. For CHOICE (tag) all the choice considerations are
326 also done within the while(). */
329 /* If type is CHOICE then at least one type must match before next
330 SILC_ASN1_END is reached. The considerations act interally as
331 having OPTIONAL flag set, except that at the end one must have
333 if (type == SILC_ASN1_TAG_CHOICE) {
335 SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
336 opts |= SILC_ASN1_OPTIONAL;
342 ("%04d: %sDecode %s [%d] %s %s %s %s", depth, sp[0] ? sp : "",
343 silc_asn1_tag_name(type), rtag,
344 rclass == SILC_BER_CLASS_UNIVERSAL ? "univ" :
345 rclass == SILC_BER_CLASS_APPLICATION ? "appl" :
346 rclass == SILC_BER_CLASS_CONTEXT ? "cont" : "priv",
347 renc == SILC_BER_ENC_PRIMITIVE ? "primit" : "constr",
348 rindef ? "indef" : "defin",
349 choice ? "choice" : opts & SILC_ASN1_OPTIONAL ? "option" : ""));
350 #endif /* SILC_DEBUG */
352 if (type != SILC_ASN1_TAG_ANY && tag != rtag) {
353 if (!(opts & SILC_ASN1_OPTIONAL)) {
354 SILC_LOG_DEBUG(("Invalid ASN.1 tag %u, expected %u", rtag, tag));
360 } else if (ber_class != rclass) {
361 if (!(opts & SILC_ASN1_OPTIONAL)) {
362 SILC_LOG_DEBUG(("Invalid ASN.1 class %d, expected %d",
369 } else if (!(opts & SILC_ASN1_EXPLICIT) && indef != rindef) {
370 SILC_LOG_DEBUG(("Invalid ASN.1 length encoding %s, expected %s",
371 rindef ? "indefinite" : "definite",
372 indef ? "indefinite" : "definite"));
375 } else if (rindef && renc == SILC_BER_ENC_PRIMITIVE) {
376 SILC_LOG_DEBUG(("Invalid length encoding for primitive type"));
383 /* If tagging is explicit we have additional sequence we need to decode
384 before we decode the actual underlaying type. */
385 if (opts & SILC_ASN1_EXPLICIT) {
386 silc_buffer_pull(src, len);
389 primitive = (type != SILC_ASN1_TAG_SEQUENCE &&
390 type != SILC_ASN1_TAG_SET &&
391 type != SILC_ASN1_TAG_ANY);
392 opts &= ~SILC_ASN1_EXPLICIT;
394 ret = silc_asn1_decoder(asn1, stack1, type, type,
395 SILC_BER_CLASS_UNIVERSAL, opts, src,
396 depth + 1, primitive);
406 /* Decode by the type user expects the data to be. */
409 case SILC_ASN1_TAG_ANY:
411 /* ANY is another ASN.1 node. We return the raw BER buffer as
413 SILC_ASN1_VAD(asn1, opts, SilcBufferStruct, node);
415 *node = silc_buffer_srealloc_size(stack1, *node, len + rdata_len);
416 silc_buffer_put(*node, rdata - len, rdata_len + len);
420 case SILC_ASN1_TAG_ANY_PRIMITIVE:
422 /* ANY_PRIMITIVE returns the raw data blob of any primitive type. */
423 SILC_ASN1_VAD(asn1, opts, SilcBufferStruct, prim);
425 *prim = silc_buffer_srealloc_size(stack1, *prim, rdata_len);
426 silc_buffer_put(*prim, rdata, rdata_len);
430 case SILC_ASN1_TAG_SEQUENCE:
431 case SILC_ASN1_TAG_SET:
433 /* SEQUENCE/SET is a sequence of types. */
434 silc_buffer_pull(src, len);
437 /* Get type, tag and options for the first argument in recursion */
438 SILC_ASN1_ARGS(asn1, rtype, rtag, rclass, ropts);
440 /* Decode the sequence recursively */
441 ret = silc_asn1_decoder(asn1, stack1, rtype, rtag, rclass,
442 ropts, src, depth + 1, FALSE);
448 case SILC_ASN1_TAG_INTEGER:
449 case SILC_ASN1_TAG_ENUM:
451 /* Integer/enum value. */
453 SILC_ASN1_VAD(asn1, opts, SilcMPInt, intval);
456 SILC_LOG_DEBUG(("Malformed integer value"));
457 SILC_ASN1_VA_FREE(opts, intval);
462 silc_mp_sinit(asn1->stack1, *intval);
464 /* Check whether the integer is positive or negative */
465 if (rdata[0] & 0x80) {
466 /* Negative integer stored in 1s complement.*/
467 for (i = 0; i < rdata_len; i++) {
468 silc_mp_mul_2exp(*intval, *intval, 8);
469 silc_mp_add_ui(*intval, *intval, ~rdata[i] & 0xff);
472 /* 2s complement and change sign */
474 silc_mp_set_ui(&z, 0);
475 silc_mp_add_ui(*intval, *intval, 1);
476 silc_mp_sub(*intval, &z, *intval);
480 silc_mp_bin2mp((unsigned char *)rdata, rdata_len, *intval);
486 case SILC_ASN1_TAG_OID:
488 /* Object identifier */
489 SilcBufferStruct tmpb;
492 SILC_ASN1_VAD_CHAR(asn1, opts, char, oidstr);
495 SILC_LOG_DEBUG(("Malformed object identifier value"));
500 /* Set two OID values */
501 memset(&tmpb, 0, sizeof(tmpb));
502 memset(tmpstr, 0, sizeof(tmpstr));
503 snprintf(tmpstr, sizeof(tmpstr) - 1, "%lu.%lu",
504 (unsigned long)(rdata[0] & 0xff) / 40,
505 (unsigned long)(rdata[0] & 0xff) % 40);
506 silc_buffer_sstrformat(asn1->stack1, &tmpb, tmpstr, SILC_STR_END);
508 /* Set rest of the OID values, each octet having 7 bits of the
509 OID value with bit 8 set. An octet not having bit 8 set
510 means end of that OID value. */
511 for (i = 1; i < rdata_len; i++) {
513 while (rdata[i] & 0x80) {
515 oid |= rdata[i++] & 0x7f;
516 if (i >= rdata_len) {
517 SILC_LOG_DEBUG(("Malformed object identifier value"));
524 memset(tmpstr, 0, sizeof(tmpstr));
525 snprintf(tmpstr, sizeof(tmpstr) - 1, ".%lu", (unsigned long)oid);
526 silc_buffer_sstrformat(asn1->stack1, &tmpb, tmpstr, SILC_STR_END);
533 case SILC_ASN1_TAG_BOOLEAN:
535 /* Decode boolean (TRUE/FALSE) value */
536 SILC_ASN1_VAD(asn1, opts, SilcBool, val);
538 if (rdata_len != 1) {
539 SILC_LOG_DEBUG(("Malformed boolean value"));
540 SILC_ASN1_VA_FREE(opts, val);
545 *(*val) = (rdata[0] == 0xff ? TRUE : FALSE);
549 case SILC_ASN1_TAG_BIT_STRING:
551 /* Bit string contains data with exact bit length of the data */
552 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, d, d_len);
555 SILC_LOG_DEBUG(("Malformed bit string value"));
560 *d = silc_smemdup(stack1, rdata + 1, rdata_len - 1);
561 *d_len = (rdata_len - 1) * 8;
565 case SILC_ASN1_TAG_NULL:
567 /* Decode empty BER block */
568 if (rdata_len != 0) {
569 SILC_LOG_DEBUG(("Malformed null value"));
575 case SILC_ASN1_TAG_UTC_TIME:
577 /* Universal encoded time string */
578 SILC_ASN1_VAD(asn1, opts, SilcTimeStruct, t);
581 SILC_LOG_DEBUG(("Malformed UTC time value"));
586 /* Parse the time string */
587 if (!silc_time_universal(rdata, *t)) {
588 SILC_LOG_DEBUG(("Malformed UTC time value"));
596 case SILC_ASN1_TAG_GENERALIZED_TIME:
598 /* Generalized encoded time string */
599 SILC_ASN1_VAD(asn1, opts, SilcTimeStruct, t);
602 SILC_LOG_DEBUG(("Malformed generalized time value"));
607 /* Parse the time string */
608 if (!silc_time_generalized(rdata, *t)) {
609 SILC_LOG_DEBUG(("Malformed generalized time value"));
617 case SILC_ASN1_TAG_UTF8_STRING:
619 /* UTF-8 encoded string */
620 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
622 if (!silc_utf8_valid(rdata, rdata_len)) {
623 SILC_LOG_DEBUG(("Malformed UTF-8 string value"));
628 *s = silc_smemdup(stack1, rdata, rdata_len);
633 case SILC_ASN1_TAG_OCTET_STRING:
635 /* Octet string. We take it as 8-bit ASCII */
636 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
637 SILC_ASN1_DECODE_STRING(SILC_STRING_ASCII, s, s_len);
641 case SILC_ASN1_TAG_NUMERIC_STRING:
643 /* Numerical (digit) string */
644 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
645 SILC_ASN1_DECODE_STRING(SILC_STRING_NUMERICAL, s, s_len);
649 case SILC_ASN1_TAG_PRINTABLE_STRING:
651 /* Printable string */
652 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
653 SILC_ASN1_DECODE_STRING(SILC_STRING_PRINTABLE, s, s_len);
657 case SILC_ASN1_TAG_TELETEX_STRING:
659 /* Teletex (T61) string */
660 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
661 SILC_ASN1_DECODE_STRING(SILC_STRING_TELETEX, s, s_len);
665 case SILC_ASN1_TAG_IA5_STRING:
667 /* US ASCII string */
668 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
669 SILC_ASN1_DECODE_STRING(SILC_STRING_ASCII, s, s_len);
673 case SILC_ASN1_TAG_VISIBLE_STRING:
676 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
677 SILC_ASN1_DECODE_STRING(SILC_STRING_VISIBLE, s, s_len);
681 case SILC_ASN1_TAG_UNIVERSAL_STRING:
683 /* Universal (UCS-4) string */
684 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
685 SILC_ASN1_DECODE_STRING(SILC_STRING_UNIVERSAL, s, s_len);
689 case SILC_ASN1_TAG_UNRESTRICTED_STRING:
690 case SILC_ASN1_TAG_GENERAL_STRING:
692 /* Handle now unrestricted and general as 8-bit ascii, which
693 probably isn't correct. */
694 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
695 SILC_ASN1_DECODE_STRING(SILC_STRING_ASCII, s, s_len);
699 case SILC_ASN1_TAG_BMP_STRING:
701 /* BMP (UCS-2) string */
702 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
703 SILC_ASN1_DECODE_STRING(SILC_STRING_BMP, s, s_len);
707 case SILC_ASN1_TAG_ODE:
708 case SILC_ASN1_TAG_ETI:
709 case SILC_ASN1_TAG_REAL:
710 case SILC_ASN1_TAG_EMBEDDED:
711 case SILC_ASN1_TAG_ROI:
712 case SILC_ASN1_TAG_VIDEOTEX_STRING:
713 case SILC_ASN1_TAG_GRAPHIC_STRING:
715 SILC_NOT_IMPLEMENTED("Unsupported ASN.1 tag");
722 SILC_LOG_DEBUG(("Invalid ASN.1 tag `%d'. Cannot decode ASN.1.",
730 /* Pull the current data from source which reveals next BER object */
731 if (found && len + rdata_len)
732 silc_buffer_pull(src, len + rdata_len);
738 /* Get next type, tag and options */
740 SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
741 if (type == SILC_ASN1_END) {
744 /* No choices were found, error */
745 SILC_LOG_DEBUG(("Invalid ASN.1 choice: no choices present"));
750 /* Take next type and new BER object, choices are over */
752 SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
753 if (type == SILC_ASN1_END) {
760 /* SEQUENCE/SET end */
766 /* Even if the choice was found we must go through rest of
769 SILC_LOG_DEBUG(("Found choice %s type", silc_asn1_tag_name(rtype)));
772 opts |= SILC_ASN1_OPTIONAL;
776 /* Optional type not present, check next one for match */
785 SILC_LOG_DEBUG(("Error decoding type %d (depth %d)", type, depth));
789 len = src->data - ptr;
791 len = src->data - src->head;
792 silc_buffer_push(src, len);
797 SilcBool silc_asn1_decode(SilcAsn1 asn1, SilcBuffer src, ...)
799 SilcAsn1Tag type, tag;
800 SilcAsn1Options opts;
801 SilcBerClass ber_class;
802 SilcStackFrame frame1, frame2;
803 SilcStack stack1 = NULL, stack2 = NULL;
809 va_start(asn1->ap, src);
811 /* Get the first arguments and call the decoder. */
812 SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
819 /* Handle internal options for decoder. */
820 if (type == SILC_ASN1_TAG_OPTS) {
821 SilcUInt32 o = va_arg(asn1->ap, SilcUInt32);
823 if (o & SILC_ASN1_ALLOC) {
824 /* User wants to alloate everything. Set the stacks to NULL so
825 that stack aware calls revert to normal allocation routines. */
826 stack1 = asn1->stack1;
827 stack2 = asn1->stack2;
832 if (o & SILC_ASN1_ACCUMUL) {
833 /* If accumul flag is not set yet, then push the stacks. */
834 if (!asn1->accumul) {
835 silc_stack_push(asn1->stack1, NULL);
836 silc_stack_push(asn1->stack2, NULL);
841 /* Take again the arguments */
842 SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
844 /* No flags set, all flags will be reset. */
846 /* If accumul flag is set now pop the stack so that all accumulated
847 memory becomes free again. */
849 silc_stack_pop(asn1->stack1);
850 silc_stack_pop(asn1->stack2);
855 /* Push stacks for normal allocation from stack */
856 if (!asn1->accumul) {
857 silc_stack_push(asn1->stack1, &frame1);
858 silc_stack_push(asn1->stack2, &frame2);
862 ret = silc_asn1_decoder(asn1, asn1->stack1, type, tag, ber_class,
863 opts, src, 0, FALSE);
865 /* Pop stacks to free normal allocations from stack. They remain valid
866 for every second call to this function. */
867 if (!asn1->accumul) {
868 silc_stack_pop(asn1->stack1);
869 silc_stack_pop(asn1->stack2);
871 /* Switch the asn1->stack1 and asn1->stack2. This way next call to
872 this function does not invalidate these results. Every second call
873 invalidates the results of every second previous results. */
874 if (asn1->stack1 && asn1->stack2) {
875 stack1 = asn1->stack1;
876 asn1->stack1 = asn1->stack2;
877 asn1->stack2 = stack1;
881 if (stack1 && stack2 && !asn1->stack1 && !asn1->stack2) {
882 /* SILC_ASN1_ALLOC flag was set, restore the stacks. */
883 asn1->stack1 = stack1;
884 asn1->stack2 = stack2;