5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2003 - 2005 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.
25 /************************** ASN.1 Decoder routines **************************/
27 /* Internal SEQUENCE OF and SET OF decoder. This is used only when decoding
28 these two special tags. Other normal ASN.1 decoding is done in the
29 silc_asn1_decoder function. This parses the sequence of types and returns
30 them as raw BER buffers in an array of SilcBuffers. */
32 static SilcBool silc_asn1_decoder_sof(SilcAsn1 asn1, SilcBuffer src)
40 const unsigned char *rdata;
41 SilcUInt32 rdata_len, len = 0;
42 SilcBool found = FALSE, rindef;
44 struct SilcAsn1SofStruct {
46 struct SilcAsn1SofStruct *next;
49 SILC_LOG_DEBUG(("Decoding sequence of types"));
51 silc_list_init(types, struct SilcAsn1SofStruct, next);
53 /* Take the return arguments */
54 retb = va_arg(asn1->ap, SilcBuffer *);
55 retc = va_arg(asn1->ap, SilcUInt32 *);
59 /* Get the sequence type(s). If the type is CHOICE tag then the sequence
60 may include multiple different types. All types are considered
61 separately. If CHOICE is not given then only single type is expected. */
62 type = va_arg(asn1->ap, SilcUInt32);
63 assert(type != SILC_ASN1_END);
65 if (type == SILC_ASN1_TAG_CHOICE) {
66 /* The sequence may consist of the following types. */
67 type = va_arg(asn1->ap, SilcUInt32);
68 assert(type != SILC_ASN1_END);
69 while (type != SILC_ASN1_END) {
70 t = silc_smalloc(asn1->stack1, sizeof(*t));
74 silc_list_add(types, t);
76 SILC_LOG_DEBUG(("Looking for %s [%d] from sequence of types",
77 silc_asn1_tag_name(type), type));
79 type = va_arg(asn1->ap, SilcUInt32);
82 /* The sequence consists of this type. */
83 t = silc_smalloc(asn1->stack1, sizeof(*t));
87 silc_list_add(types, t);
89 SILC_LOG_DEBUG(("Looking for %s [%d] from sequence of types",
90 silc_asn1_tag_name(type), type));
93 /* END marker for the sequence */
94 type = va_arg(asn1->ap, SilcUInt32);
95 assert(type == SILC_ASN1_END);
97 /* Decode the SEQUENCE or SET */
98 ret = silc_ber_decode(src, NULL, NULL, (SilcUInt32 *)&rtag, &rdata,
99 &rdata_len, &rindef, &len);
101 SILC_LOG_DEBUG(("Error parsing BER block, malformed ASN.1 data"));
104 if (rtag != SILC_ASN1_TAG_SEQUENCE && rtag != SILC_ASN1_TAG_SET) {
105 SILC_LOG_DEBUG(("Invalid sequence of/set of"));
108 silc_buffer_pull(src, len);
110 while (silc_buffer_len(src)) {
111 /* Decode the BER data. */
112 ret = silc_ber_decode(src, NULL, NULL, (SilcUInt32 *)&rtag, &rdata,
113 &rdata_len, &rindef, &len);
115 SILC_LOG_DEBUG(("Error parsing BER block, malformed ASN.1 data"));
119 /* Now check the type(s) that it is supposed to be */
121 silc_list_start(types);
122 while ((t = silc_list_get(types)) != SILC_LIST_END) {
126 *retb = silc_srealloc(asn1->stack1, sizeof(**retb) * (*retc), *retb,
127 sizeof(**retb) * (*retc + 1));
131 SILC_LOG_DEBUG(("Decode %s [%d] from sequence of types",
132 silc_asn1_tag_name(rtag), rtag));
134 /* Data is duplicated only if SILC_ASN1_ALLOC flag is set */
136 rdata = silc_memdup(rdata - len, rdata_len + len);
142 silc_buffer_set(&(*retb)[*retc], (unsigned char *)rdata, rdata_len);
148 /* If type was not found we consider it the end of the sequence */
153 silc_buffer_pull(src, rdata_len);
156 SILC_LOG_DEBUG(("Decoded %d types", *retc));
161 silc_list_start(types);
162 while ((t = silc_list_get(types)) != SILC_LIST_END)
169 /* Macro for decoder to get argument for a type. If OPTIONAL option is
170 set then the argument is a pointer to the type pointer. The `type'
171 must be a non-pointer type, eg. int, SilcBufferStruct. */
172 #define SILC_ASN1_VAD(asn1, opts, type, name) \
174 if ((opts) & SILC_ASN1_OPTIONAL && !choice) { \
175 name = va_arg(asn1->ap, type **); \
183 *name = silc_scalloc(asn1->stack1, 1, sizeof(**name)); \
187 type *name ## tmp = va_arg(asn1->ap, type *); \
188 if (choice && found && !len) \
190 if (name ## tmp == NULL) \
192 name = &name ## tmp; \
195 /* Same as SILC_ASN1_VAD but for unsigned char and SilcUInt32 */
196 #define SILC_ASN1_VAD_UCHAR(asn1, opts, type, name, namelen) \
197 type **name = va_arg(asn1->ap, type **); \
198 SilcUInt32 *namelen = va_arg(asn1->ap, SilcUInt32 *); \
199 if (choice && found && !len) \
209 /* Same as SILC_ASN1_VAD but for char only */
210 #define SILC_ASN1_VAD_CHAR(asn1, opts, type, name) \
211 type **name = va_arg(asn1->ap, type **); \
212 if (choice && found && !len) \
222 #define SILC_ASN1_VA_FREE(opts, name) \
223 if ((opts) & SILC_ASN1_OPTIONAL) \
226 /* Decodes string to UTF-8 string which is our internal representation
228 #define SILC_ASN1_DECODE_STRING(enc, s, s_len) \
229 *s_len = silc_utf8_encoded_len(rdata, rdata_len, (enc)); \
231 SILC_LOG_DEBUG(("Malformed %d string value", (enc))); \
235 *s = silc_smalloc_ua(stack1, *s_len + 1); \
237 silc_utf8_encode(rdata, rdata_len, (enc), *s, *s_len); \
238 (*s)[*s_len] = '\0'; \
242 /* Internal ASN.1 decoder. The `type', `tag' and `opts' are the first
243 arguments (either very first or first for recursion) for a type.
244 The `depth' includes the current depth of recursion. */
247 silc_asn1_decoder(SilcAsn1 asn1, SilcStack stack1, SilcAsn1Tag type,
248 SilcAsn1Tag tag, SilcBerClass ber_class,
249 SilcAsn1Options opts, SilcBuffer src, SilcUInt32 depth,
252 unsigned char *ptr = src->data;
253 SilcAsn1Tag rtype, rtag;
254 SilcAsn1Options ropts;
256 SilcBerEncoding renc;
258 SilcBool ret, indef, rindef, found = FALSE, choice = FALSE;
259 const unsigned char *rdata;
260 SilcUInt32 rdata_len;
264 char sp[SILC_ASN1_RECURSION_DEPTH + 1];
265 memset(sp, 0, sizeof(sp));
267 memset(sp, 32, depth);
268 #endif /* SILC_DEBUG */
270 if (depth >= SILC_ASN1_RECURSION_DEPTH) {
271 SILC_LOG_DEBUG(("Maximum recursion depth reached"));
277 /* If requested type is SEQUENCE OF or SET OF then we decode the sequence
278 of types separately in an own decoder which returns array of buffers. */
279 if (type == SILC_ASN1_TAG_SEQUENCE_OF) {
280 /* Decode the sequence */
281 if (!silc_asn1_decoder_sof(asn1, src)) {
282 SILC_LOG_DEBUG(("Error decoding SEQUENCE OF"));
287 /* Continue with rest of the decodings if any */
288 SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
289 if (type == SILC_ASN1_END) {
295 /* Get length encoding */
296 indef = (opts & SILC_ASN1_INDEFINITE ? TRUE : FALSE);
298 /* By default UNIVERSAL is implied unless the following conditions
299 are met when CONTEXT will apply. For SILC_ASN1_TAG_ANY_PRIMITIVE
300 the class is changed only if flags dictate it. */
301 if (ber_class == SILC_BER_CLASS_UNIVERSAL) {
302 if (type == SILC_ASN1_TAG_ANY_PRIMITIVE) {
303 if (opts & SILC_ASN1_IMPLICIT ||
304 opts & SILC_ASN1_EXPLICIT)
305 ber_class = SILC_BER_CLASS_CONTEXT;
308 opts & SILC_ASN1_IMPLICIT ||
309 opts & SILC_ASN1_EXPLICIT)
310 ber_class = SILC_BER_CLASS_CONTEXT;
314 /* Now decode a BER encoded block from the source buffer. It must be
315 exactly the same user is expecting. */
316 ret = silc_ber_decode(src, &rclass, &renc, (SilcUInt32 *)&rtag, &rdata,
317 &rdata_len, &rindef, &len);
319 SILC_LOG_DEBUG(("Error parsing BER block, malformed ASN.1 data"));
323 /* Now verify that the decoded BER is the one user wanted to get. If
324 requested type is OPTIONAL, then ignore all the sanity tests. The
325 while() loop is for re-considering OPTIONAL types without parsing
326 new BER object. For CHOICE (tag) all the choice considerations are
327 also done within the while(). */
330 /* If type is CHOICE then at least one type must match before next
331 SILC_ASN1_END is reached. The considerations act interally as
332 having OPTIONAL flag set, except that at the end one must have
334 if (type == SILC_ASN1_TAG_CHOICE) {
336 SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
337 opts |= SILC_ASN1_OPTIONAL;
343 ("%04d: %sDecode %s [%d] %s %s %s %s", depth, sp[0] ? sp : "",
344 silc_asn1_tag_name(type), rtag,
345 rclass == SILC_BER_CLASS_UNIVERSAL ? "univ" :
346 rclass == SILC_BER_CLASS_APPLICATION ? "appl" :
347 rclass == SILC_BER_CLASS_CONTEXT ? "cont" : "priv",
348 renc == SILC_BER_ENC_PRIMITIVE ? "primit" : "constr",
349 rindef ? "indef" : "defin",
350 choice ? "choice" : opts & SILC_ASN1_OPTIONAL ? "option" : ""));
351 #endif /* SILC_DEBUG */
353 if (type != SILC_ASN1_TAG_ANY && tag != rtag) {
354 if (!(opts & SILC_ASN1_OPTIONAL)) {
355 SILC_LOG_DEBUG(("Invalid ASN.1 tag %u, expected %u", rtag, tag));
361 } else if (ber_class != rclass) {
362 if (!(opts & SILC_ASN1_OPTIONAL)) {
363 SILC_LOG_DEBUG(("Invalid ASN.1 class %d, expected %d",
370 } else if (!(opts & SILC_ASN1_EXPLICIT) && indef != rindef) {
371 SILC_LOG_DEBUG(("Invalid ASN.1 length encoding %s, expected %s",
372 rindef ? "indefinite" : "definite",
373 indef ? "indefinite" : "definite"));
376 } else if (rindef && renc == SILC_BER_ENC_PRIMITIVE) {
377 SILC_LOG_DEBUG(("Invalid length encoding for primitive type"));
384 /* If tagging is explicit we have additional sequence we need to decode
385 before we decode the actual underlaying type. */
386 if (opts & SILC_ASN1_EXPLICIT) {
387 silc_buffer_pull(src, len);
390 primitive = (type != SILC_ASN1_TAG_SEQUENCE &&
391 type != SILC_ASN1_TAG_SET &&
392 type != SILC_ASN1_TAG_ANY);
393 opts &= ~SILC_ASN1_EXPLICIT;
395 ret = silc_asn1_decoder(asn1, stack1, type, type,
396 SILC_BER_CLASS_UNIVERSAL, opts, src,
397 depth + 1, primitive);
407 /* Decode by the type user expects the data to be. */
410 case SILC_ASN1_TAG_ANY:
412 /* ANY is another ASN.1 node. We return the raw BER buffer as
414 SILC_ASN1_VAD(asn1, opts, SilcBufferStruct, node);
416 *node = silc_buffer_srealloc_size(stack1, *node, len + rdata_len);
417 silc_buffer_put(*node, rdata - len, rdata_len + len);
421 case SILC_ASN1_TAG_ANY_PRIMITIVE:
423 /* ANY_PRIMITIVE returns the raw data blob of any primitive type. */
424 SILC_ASN1_VAD(asn1, opts, SilcBufferStruct, prim);
426 *prim = silc_buffer_srealloc_size(stack1, *prim, rdata_len);
427 silc_buffer_put(*prim, rdata, rdata_len);
431 case SILC_ASN1_TAG_SEQUENCE:
432 case SILC_ASN1_TAG_SET:
434 /* SEQUENCE/SET is a sequence of types. */
435 silc_buffer_pull(src, len);
438 /* Get type, tag and options for the first argument in recursion */
439 SILC_ASN1_ARGS(asn1, rtype, rtag, rclass, ropts);
441 /* Decode the sequence recursively */
442 ret = silc_asn1_decoder(asn1, stack1, rtype, rtag, rclass,
443 ropts, src, depth + 1, FALSE);
449 case SILC_ASN1_TAG_INTEGER:
450 case SILC_ASN1_TAG_ENUM:
452 /* Integer/enum value. */
454 SILC_ASN1_VAD(asn1, opts, SilcMPInt, intval);
457 SILC_LOG_DEBUG(("Malformed integer value"));
458 SILC_ASN1_VA_FREE(opts, intval);
463 silc_mp_sinit(asn1->stack1, *intval);
465 /* Check whether the integer is positive or negative */
466 if (rdata[0] & 0x80) {
467 /* Negative integer stored in 1s complement.*/
468 for (i = 0; i < rdata_len; i++) {
469 silc_mp_mul_2exp(*intval, *intval, 8);
470 silc_mp_add_ui(*intval, *intval, ~rdata[i] & 0xff);
473 /* 2s complement and change sign */
476 silc_mp_add_ui(*intval, *intval, 1);
477 silc_mp_sub(*intval, &z, *intval);
481 silc_mp_bin2mp((unsigned char *)rdata, rdata_len, *intval);
487 case SILC_ASN1_TAG_OID:
489 /* Object identifier */
490 SilcBufferStruct tmpb;
493 SILC_ASN1_VAD_CHAR(asn1, opts, char, oidstr);
496 SILC_LOG_DEBUG(("Malformed object identifier value"));
501 /* Set two OID values */
502 memset(&tmpb, 0, sizeof(tmpb));
503 memset(tmpstr, 0, sizeof(tmpstr));
504 snprintf(tmpstr, sizeof(tmpstr) - 1, "%lu.%lu",
505 (unsigned long)(rdata[0] & 0xff) / 40,
506 (unsigned long)(rdata[0] & 0xff) % 40);
507 silc_buffer_sstrformat(asn1->stack1, &tmpb, tmpstr, SILC_STR_END);
509 /* Set rest of the OID values, each octet having 7 bits of the
510 OID value with bit 8 set. An octet not having bit 8 set
511 means end of that OID value. */
512 for (i = 1; i < rdata_len; i++) {
514 while (rdata[i] & 0x80) {
516 oid |= rdata[i++] & 0x7f;
517 if (i >= rdata_len) {
518 SILC_LOG_DEBUG(("Malformed object identifier value"));
525 memset(tmpstr, 0, sizeof(tmpstr));
526 snprintf(tmpstr, sizeof(tmpstr) - 1, ".%lu", (unsigned long)oid);
527 silc_buffer_sstrformat(asn1->stack1, &tmpb, tmpstr, SILC_STR_END);
534 case SILC_ASN1_TAG_BOOLEAN:
536 /* Decode boolean (TRUE/FALSE) value */
537 SILC_ASN1_VAD(asn1, opts, SilcBool, val);
539 if (rdata_len != 1) {
540 SILC_LOG_DEBUG(("Malformed boolean value"));
541 SILC_ASN1_VA_FREE(opts, val);
546 *(*val) = (rdata[0] == 0xff ? TRUE : FALSE);
550 case SILC_ASN1_TAG_BIT_STRING:
552 /* Bit string contains data with exact bit length of the data */
553 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, d, d_len);
556 SILC_LOG_DEBUG(("Malformed bit string value"));
561 *d = silc_smemdup(stack1, rdata + 1, rdata_len - 1);
562 *d_len = (rdata_len - 1) * 8;
566 case SILC_ASN1_TAG_NULL:
568 /* Decode empty BER block */
569 if (rdata_len != 0) {
570 SILC_LOG_DEBUG(("Malformed null value"));
576 case SILC_ASN1_TAG_UTC_TIME:
578 /* Universal encoded time string */
579 SILC_ASN1_VAD(asn1, opts, SilcTimeStruct, t);
582 SILC_LOG_DEBUG(("Malformed UTC time value"));
587 /* Parse the time string */
588 if (!silc_time_universal(rdata, *t)) {
589 SILC_LOG_DEBUG(("Malformed UTC time value"));
597 case SILC_ASN1_TAG_GENERALIZED_TIME:
599 /* Generalized encoded time string */
600 SILC_ASN1_VAD(asn1, opts, SilcTimeStruct, t);
603 SILC_LOG_DEBUG(("Malformed generalized time value"));
608 /* Parse the time string */
609 if (!silc_time_generalized(rdata, *t)) {
610 SILC_LOG_DEBUG(("Malformed generalized time value"));
618 case SILC_ASN1_TAG_UTF8_STRING:
620 /* UTF-8 encoded string */
621 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
623 if (!silc_utf8_valid(rdata, rdata_len)) {
624 SILC_LOG_DEBUG(("Malformed UTF-8 string value"));
629 *s = silc_smemdup(stack1, rdata, rdata_len);
634 case SILC_ASN1_TAG_OCTET_STRING:
636 /* Octet string. We take it as 8-bit ASCII */
637 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
638 SILC_ASN1_DECODE_STRING(SILC_STRING_ASCII, s, s_len);
642 case SILC_ASN1_TAG_NUMERIC_STRING:
644 /* Numerical (digit) string */
645 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
646 SILC_ASN1_DECODE_STRING(SILC_STRING_NUMERICAL, s, s_len);
650 case SILC_ASN1_TAG_PRINTABLE_STRING:
652 /* Printable string */
653 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
654 SILC_ASN1_DECODE_STRING(SILC_STRING_PRINTABLE, s, s_len);
658 case SILC_ASN1_TAG_TELETEX_STRING:
660 /* Teletex (T61) string */
661 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
662 SILC_ASN1_DECODE_STRING(SILC_STRING_TELETEX, s, s_len);
666 case SILC_ASN1_TAG_IA5_STRING:
668 /* US ASCII string */
669 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
670 SILC_ASN1_DECODE_STRING(SILC_STRING_ASCII, s, s_len);
674 case SILC_ASN1_TAG_VISIBLE_STRING:
677 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
678 SILC_ASN1_DECODE_STRING(SILC_STRING_VISIBLE, s, s_len);
682 case SILC_ASN1_TAG_UNIVERSAL_STRING:
684 /* Universal (UCS-4) string */
685 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
686 SILC_ASN1_DECODE_STRING(SILC_STRING_UNIVERSAL, s, s_len);
690 case SILC_ASN1_TAG_UNRESTRICTED_STRING:
691 case SILC_ASN1_TAG_GENERAL_STRING:
693 /* Handle now unrestricted and general as 8-bit ascii, which
694 probably isn't correct. */
695 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
696 SILC_ASN1_DECODE_STRING(SILC_STRING_ASCII, s, s_len);
700 case SILC_ASN1_TAG_BMP_STRING:
702 /* BMP (UCS-2) string */
703 SILC_ASN1_VAD_UCHAR(asn1, opts, unsigned char, s, s_len);
704 SILC_ASN1_DECODE_STRING(SILC_STRING_BMP, s, s_len);
708 case SILC_ASN1_TAG_ODE:
709 case SILC_ASN1_TAG_ETI:
710 case SILC_ASN1_TAG_REAL:
711 case SILC_ASN1_TAG_EMBEDDED:
712 case SILC_ASN1_TAG_ROI:
713 case SILC_ASN1_TAG_VIDEOTEX_STRING:
714 case SILC_ASN1_TAG_GRAPHIC_STRING:
716 SILC_NOT_IMPLEMENTED("Unsupported ASN.1 tag");
723 SILC_LOG_DEBUG(("Invalid ASN.1 tag `%d'. Cannot decode ASN.1.",
731 /* Pull the current data from source which reveals next BER object */
732 if (found && len + rdata_len)
733 silc_buffer_pull(src, len + rdata_len);
739 /* Get next type, tag and options */
741 SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
742 if (type == SILC_ASN1_END) {
745 /* No choices were found, error */
746 SILC_LOG_DEBUG(("Invalid ASN.1 choice: no choices present"));
751 /* Take next type and new BER object, choices are over */
753 SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
754 if (type == SILC_ASN1_END) {
761 /* SEQUENCE/SET end */
767 /* Even if the choice was found we must go through rest of
770 SILC_LOG_DEBUG(("Found choice %s type", silc_asn1_tag_name(rtype)));
773 opts |= SILC_ASN1_OPTIONAL;
777 /* Optional type not present, check next one for match */
786 SILC_LOG_DEBUG(("Error decoding type %d (depth %d)", type, depth));
790 len = src->data - ptr;
792 len = src->data - src->head;
793 silc_buffer_push(src, len);
798 SilcBool silc_asn1_decode(SilcAsn1 asn1, SilcBuffer src, ...)
800 SilcAsn1Tag type, tag;
801 SilcAsn1Options opts;
802 SilcBerClass ber_class;
803 SilcStackFrame frame1, frame2;
804 SilcStack stack1 = NULL, stack2 = NULL;
810 va_start(asn1->ap, src);
812 /* Get the first arguments and call the decoder. */
813 SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
820 /* Handle internal options for decoder. */
821 if (type == SILC_ASN1_TAG_OPTS) {
822 SilcUInt32 o = va_arg(asn1->ap, SilcUInt32);
824 if (o & SILC_ASN1_ALLOC) {
825 /* User wants to alloate everything. Set the stacks to NULL so
826 that stack aware calls revert to normal allocation routines. */
827 stack1 = asn1->stack1;
828 stack2 = asn1->stack2;
833 if (o & SILC_ASN1_ACCUMUL) {
834 /* If accumul flag is not set yet, then push the stacks. */
835 if (!asn1->accumul) {
836 silc_stack_push(asn1->stack1, NULL);
837 silc_stack_push(asn1->stack2, NULL);
842 /* Take again the arguments */
843 SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
845 /* No flags set, all flags will be reset. */
847 /* If accumul flag is set now pop the stack so that all accumulated
848 memory becomes free again. */
850 silc_stack_pop(asn1->stack1);
851 silc_stack_pop(asn1->stack2);
856 /* Push stacks for normal allocation from stack */
857 if (!asn1->accumul) {
858 silc_stack_push(asn1->stack1, &frame1);
859 silc_stack_push(asn1->stack2, &frame2);
863 ret = silc_asn1_decoder(asn1, asn1->stack1, type, tag, ber_class,
864 opts, src, 0, FALSE);
866 /* Pop stacks to free normal allocations from stack. They remain valid
867 for every second call to this function. */
868 if (!asn1->accumul) {
869 silc_stack_pop(asn1->stack1);
870 silc_stack_pop(asn1->stack2);
872 /* Switch the asn1->stack1 and asn1->stack2. This way next call to
873 this function does not invalidate these results. Every second call
874 invalidates the results of every second previous results. */
875 if (asn1->stack1 && asn1->stack2) {
876 stack1 = asn1->stack1;
877 asn1->stack1 = asn1->stack2;
878 asn1->stack2 = stack1;
882 if (stack1 && stack2 && !asn1->stack1 && !asn1->stack2) {
883 /* SILC_ASN1_ALLOC flag was set, restore the stacks. */
884 asn1->stack1 = stack1;
885 asn1->stack2 = stack2;