/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/*
 * Support for ENcoding ASN.1 data based on BER/DER (Basic/Distinguished
 * Encoding Rules).
 */

#include "secasn1.h"

typedef enum {
    beforeHeader,
    duringContents,
    duringGroup,
    duringSequence,
    afterContents,
    afterImplicit,
    afterInline,
    afterPointer,
    afterChoice,
    notInUse
} sec_asn1e_parse_place;

typedef enum {
    allDone,
    encodeError,
    keepGoing,
    needBytes
} sec_asn1e_parse_status;

typedef enum {
    hdr_normal = 0,     /* encode header normally */
    hdr_any = 1,        /* header already encoded in content */
    hdr_decoder = 2,    /* template only used by decoder. skip it. */
    hdr_optional = 3,   /* optional component, to be omitted */
    hdr_placeholder = 4 /* place holder for from_buf content */
} sec_asn1e_hdr_encoding;

typedef struct sec_asn1e_state_struct {
    SEC_ASN1EncoderContext *top;
    const SEC_ASN1Template *theTemplate;
    void *src;

    struct sec_asn1e_state_struct *parent; /* aka prev */
    struct sec_asn1e_state_struct *child;  /* aka next */

    sec_asn1e_parse_place place; /* where we are in encoding process */

    /*
     * XXX explain the next fields as clearly as possible...
     */
    unsigned char tag_modifiers;
    unsigned char tag_number;
    unsigned long underlying_kind;

    int depth;

    PRBool isExplicit,     /* we are handling an isExplicit header */
        indefinite,        /* need end-of-contents */
        is_string,         /* encoding a simple string or an ANY */
        may_stream,        /* when streaming, do indefinite encoding */
        optional,          /* omit field if it has no contents */
        disallowStreaming; /* disallow streaming in all sub-templates */
} sec_asn1e_state;

/*
 * An "outsider" will have an opaque pointer to this, created by calling
 * SEC_ASN1EncoderStart().  It will be passed back in to all subsequent
 * calls to SEC_ASN1EncoderUpdate() and related routines, and when done
 * it is passed to SEC_ASN1EncoderFinish().
 */
struct sec_EncoderContext_struct {
    PLArenaPool *our_pool; /* for our internal allocs */

    sec_asn1e_state *current;
    sec_asn1e_parse_status status;

    PRBool streaming;
    PRBool from_buf;

    SEC_ASN1NotifyProc notify_proc; /* call before/after handling field */
    void *notify_arg;               /* argument to notify_proc */
    PRBool during_notify;           /* true during call to notify_proc */

    SEC_ASN1WriteProc output_proc; /* pass encoded bytes to this  */
    void *output_arg;              /* argument to that function */
};

static sec_asn1e_state *
sec_asn1e_push_state(SEC_ASN1EncoderContext *cx,
                     const SEC_ASN1Template *theTemplate,
                     const void *src, PRBool new_depth)
{
    sec_asn1e_state *state, *new_state;

    state = cx->current;

    new_state = (sec_asn1e_state *)PORT_ArenaZAlloc(cx->our_pool,
                                                    sizeof(*new_state));
    if (new_state == NULL) {
        cx->status = encodeError;
        return NULL;
    }

    new_state->top = cx;
    new_state->parent = state;
    new_state->theTemplate = theTemplate;
    new_state->place = notInUse;
    if (src != NULL)
        new_state->src = (char *)src + theTemplate->offset;

    if (state != NULL) {
        new_state->depth = state->depth;
        if (new_depth)
            new_state->depth++;
        state->child = new_state;
    }

    cx->current = new_state;
    return new_state;
}

static void
sec_asn1e_scrub_state(sec_asn1e_state *state)
{
    /*
     * Some default "scrubbing".
     * XXX right set of initializations?
     */
    state->place = beforeHeader;
    state->indefinite = PR_FALSE;
}

static void
sec_asn1e_notify_before(SEC_ASN1EncoderContext *cx, void *src, int depth)
{
    if (cx->notify_proc == NULL)
        return;

    cx->during_notify = PR_TRUE;
    (*cx->notify_proc)(cx->notify_arg, PR_TRUE, src, depth);
    cx->during_notify = PR_FALSE;
}

static void
sec_asn1e_notify_after(SEC_ASN1EncoderContext *cx, void *src, int depth)
{
    if (cx->notify_proc == NULL)
        return;

    cx->during_notify = PR_TRUE;
    (*cx->notify_proc)(cx->notify_arg, PR_FALSE, src, depth);
    cx->during_notify = PR_FALSE;
}

static sec_asn1e_state *
sec_asn1e_init_state_based_on_template(sec_asn1e_state *state)
{
    PRBool isExplicit, is_string, may_stream, optional, universal;
    PRBool disallowStreaming;
    unsigned char tag_modifiers;
    unsigned long encode_kind, under_kind;
    unsigned long tag_number;
    PRBool isInline = PR_FALSE;

    encode_kind = state->theTemplate->kind;

    universal = ((encode_kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL)
                    ? PR_TRUE
                    : PR_FALSE;

    isExplicit = (encode_kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE;
    encode_kind &= ~SEC_ASN1_EXPLICIT;

    optional = (encode_kind & SEC_ASN1_OPTIONAL) ? PR_TRUE : PR_FALSE;
    encode_kind &= ~SEC_ASN1_OPTIONAL;

    PORT_Assert(!(isExplicit && universal)); /* bad templates */

    may_stream = (encode_kind & SEC_ASN1_MAY_STREAM) ? PR_TRUE : PR_FALSE;
    encode_kind &= ~SEC_ASN1_MAY_STREAM;

    disallowStreaming = (encode_kind & SEC_ASN1_NO_STREAM) ? PR_TRUE : PR_FALSE;
    encode_kind &= ~SEC_ASN1_NO_STREAM;

    /* Just clear this to get it out of the way; we do not need it here */
    encode_kind &= ~SEC_ASN1_DYNAMIC;

    if (encode_kind & SEC_ASN1_CHOICE) {
        under_kind = SEC_ASN1_CHOICE;
    } else if ((encode_kind & (SEC_ASN1_POINTER | SEC_ASN1_INLINE)) ||
               (!universal && !isExplicit)) {
        const SEC_ASN1Template *subt;
        void *src = NULL;

        PORT_Assert((encode_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP)) == 0);

        sec_asn1e_scrub_state(state);

        if (encode_kind & SEC_ASN1_POINTER) {
            src = *(void **)state->src;
            state->place = afterPointer;

            if (src == NULL) {
                /*
                 * If this is optional, but NULL, then the field does
                 * not need to be encoded.  In this case we are done;
                 * we do not want to push a subtemplate.
                 */
                if (optional)
                    return state;

                /*
                 * XXX this is an error; need to figure out
                 * how to handle this
                 */
            }
        } else {
            src = state->src;
            if (encode_kind & SEC_ASN1_INLINE) {
                /* check that there are no extraneous bits */
                /* PORT_Assert (encode_kind == SEC_ASN1_INLINE && !optional); */
                state->place = afterInline;
                isInline = PR_TRUE;
            } else {
                /*
                 * Save the tag modifiers and tag number here before moving
                 * on to the next state in case this is a member of a
                 * SEQUENCE OF
                 */
                state->tag_modifiers = (unsigned char)(encode_kind & (SEC_ASN1_TAG_MASK & ~SEC_ASN1_TAGNUM_MASK));
                state->tag_number = (unsigned char)(encode_kind & SEC_ASN1_TAGNUM_MASK);

                state->place = afterImplicit;
                state->optional = optional;
            }
        }

        subt = SEC_ASN1GetSubtemplate(state->theTemplate, state->src, PR_TRUE);
        if (isInline && optional) {
            /* we only handle a very limited set of optional inline cases at
               this time */
            if (PR_FALSE != SEC_ASN1IsTemplateSimple(subt)) {
                /* we now know that the target is a SECItem*, so we can check
                   if the source contains one */
                SECItem *target = (SECItem *)state->src;
                if (!target || !target->data || !target->len) {
                    /* no valid data to encode subtemplate */
                    return state;
                }
            } else {
                PORT_Assert(0); /* complex templates are not handled as
                                   inline optional */
            }
        }
        state = sec_asn1e_push_state(state->top, subt, src, PR_FALSE);
        if (state == NULL)
            return state;

        if (universal) {
            /*
             * This is a POINTER or INLINE; just init based on that
             * and we are done.
             */
            return sec_asn1e_init_state_based_on_template(state);
        }

        /*
         * This is an implicit, non-universal (meaning, application-private
         * or context-specific) field.  This results in a "magic" tag but
         * encoding based on the underlying type.  We pushed a new state
         * that is based on the subtemplate (the underlying type), but
         * now we will sort of alias it to give it some of our properties
         * (tag, optional status, etc.).
         *
         * NB: ALL the following flags in the subtemplate are disallowed
         *     and/or ignored: EXPLICIT, OPTIONAL, INNER, INLINE, POINTER.
         */

        under_kind = state->theTemplate->kind;
        if ((under_kind & SEC_ASN1_MAY_STREAM) && !disallowStreaming) {
            may_stream = PR_TRUE;
        }
        under_kind &= ~(SEC_ASN1_MAY_STREAM | SEC_ASN1_DYNAMIC);
    } else {
        under_kind = encode_kind;
    }

/*
     * Sanity check that there are no unwanted bits marked in under_kind.
     * These bits were either removed above (after we recorded them) or
     * they simply should not be found (signalling a bad/broken template).
     * XXX is this the right set of bits to test here? (i.e. need to add
     * or remove any?)
     */
#define UNEXPECTED_FLAGS                                                      \
    (SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_SKIP | SEC_ASN1_INNER | \
     SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM | SEC_ASN1_INLINE | SEC_ASN1_POINTER)

    PORT_Assert((under_kind & UNEXPECTED_FLAGS) == 0);
    under_kind &= ~UNEXPECTED_FLAGS;
#undef UNEXPECTED_FLAGS

    if (encode_kind & SEC_ASN1_ANY) {
        PORT_Assert(encode_kind == under_kind);
        tag_modifiers = 0;
        tag_number = 0;
        is_string = PR_TRUE;
    } else {
        tag_modifiers = (unsigned char)(encode_kind & (SEC_ASN1_TAG_MASK & ~SEC_ASN1_TAGNUM_MASK));
        /*
         * XXX This assumes only single-octet identifiers.  To handle
         * the HIGH TAG form we would need to do some more work, especially
         * in how to specify them in the template, because right now we
         * do not provide a way to specify more *tag* bits in encode_kind.
         */
        tag_number = encode_kind & SEC_ASN1_TAGNUM_MASK;

        is_string = PR_FALSE;
        switch (under_kind & SEC_ASN1_TAGNUM_MASK) {
            case SEC_ASN1_SET:
                /*
                 * XXX A plain old SET (as opposed to a SET OF) is not implemented.
                 * If it ever is, remove this assert...
                 */
                PORT_Assert((under_kind & SEC_ASN1_GROUP) != 0);
            /* fallthru */
            case SEC_ASN1_SEQUENCE:
                tag_modifiers |= SEC_ASN1_CONSTRUCTED;
                break;
            case SEC_ASN1_BIT_STRING:
            case SEC_ASN1_BMP_STRING:
            case SEC_ASN1_GENERALIZED_TIME:
            case SEC_ASN1_IA5_STRING:
            case SEC_ASN1_OCTET_STRING:
            case SEC_ASN1_PRINTABLE_STRING:
            case SEC_ASN1_T61_STRING:
            case SEC_ASN1_UNIVERSAL_STRING:
            case SEC_ASN1_UTC_TIME:
            case SEC_ASN1_UTF8_STRING:
            case SEC_ASN1_VISIBLE_STRING:
                /*
                 * We do not yet know if we will be constructing the string,
                 * so we have to wait to do this final tag modification.
                 */
                is_string = PR_TRUE;
                break;
        }
    }

    state->tag_modifiers = tag_modifiers;
    state->tag_number = (unsigned char)tag_number;
    state->underlying_kind = under_kind;
    state->isExplicit = isExplicit;
    state->may_stream = may_stream;
    state->is_string = is_string;
    state->optional = optional;
    state->disallowStreaming = disallowStreaming;

    sec_asn1e_scrub_state(state);

    return state;
}

static void
sec_asn1e_write_part(sec_asn1e_state *state,
                     const char *buf, unsigned long len,
                     SEC_ASN1EncodingPart part)
{
    SEC_ASN1EncoderContext *cx;

    cx = state->top;
    (*cx->output_proc)(cx->output_arg, buf, len, state->depth, part);
}

/*
 * XXX This assumes only single-octet identifiers.  To handle
 * the HIGH TAG form we would need to modify this interface and
 * teach it to properly encode the special form.
 */
static void
sec_asn1e_write_identifier_bytes(sec_asn1e_state *state, unsigned char value)
{
    char byte;

    byte = (char)value;
    sec_asn1e_write_part(state, &byte, 1, SEC_ASN1_Identifier);
}

int
SEC_ASN1EncodeLength(unsigned char *buf, int value)
{
    int lenlen;

    lenlen = SEC_ASN1LengthLength(value);
    if (lenlen == 1) {
        buf[0] = value;
    } else {
        int i;

        i = lenlen - 1;
        buf[0] = 0x80 | i;
        while (i) {
            buf[i--] = value;
            value >>= 8;
        }
        PORT_Assert(value == 0);
    }
    return lenlen;
}

static void
sec_asn1e_write_length_bytes(sec_asn1e_state *state, unsigned long value,
                             PRBool indefinite)
{
    int lenlen;
    unsigned char buf[sizeof(unsigned long) + 1];

    if (indefinite) {
        PORT_Assert(value == 0);
        buf[0] = 0x80;
        lenlen = 1;
    } else {
        lenlen = SEC_ASN1EncodeLength(buf, value);
    }

    sec_asn1e_write_part(state, (char *)buf, lenlen, SEC_ASN1_Length);
}

static void
sec_asn1e_write_contents_bytes(sec_asn1e_state *state,
                               const char *buf, unsigned long len)
{
    sec_asn1e_write_part(state, buf, len, SEC_ASN1_Contents);
}

static void
sec_asn1e_write_end_of_contents_bytes(sec_asn1e_state *state)
{
    const char eoc[2] = { 0, 0 };

    sec_asn1e_write_part(state, eoc, 2, SEC_ASN1_EndOfContents);
}

static int
sec_asn1e_which_choice(
    void *src,
    const SEC_ASN1Template *theTemplate)
{
    int rv;
    unsigned int which = *(unsigned int *)src;

    for (rv = 1, theTemplate++; theTemplate->kind != 0; rv++, theTemplate++) {
        if (which == theTemplate->size) {
            return rv;
        }
    }

    return 0;
}

static unsigned long
sec_asn1e_contents_length(const SEC_ASN1Template *theTemplate, void *src,
                          PRBool disallowStreaming, PRBool insideIndefinite,
                          sec_asn1e_hdr_encoding *pHdrException)
{
    unsigned long encode_kind, underlying_kind;
    PRBool isExplicit, optional, universal, may_stream;
    unsigned long len;

    /*
     * This function currently calculates the length in all cases
     * except the following: when writing out the contents of a
     * template that belongs to a state where it was a sub-template
     * with the SEC_ASN1_MAY_STREAM bit set and it's parent had the
     * optional bit set.  The information that the parent is optional
     * and that we should return the length of 0 when that length is
     * present since that means the optional field is no longer present.
     * So we add the disallowStreaming flag which is passed in when
     * writing the contents, but for all recursive calls to
     * sec_asn1e_contents_length, we pass PR_FALSE, because this
     * function correctly calculates the length for children templates
     * from that point on.  Confused yet?  At least you didn't have
     * to figure it out.  ;)  -javi
     */
    encode_kind = theTemplate->kind;

    universal = ((encode_kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL)
                    ? PR_TRUE
                    : PR_FALSE;

    isExplicit = (encode_kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE;
    encode_kind &= ~SEC_ASN1_EXPLICIT;

    optional = (encode_kind & SEC_ASN1_OPTIONAL) ? PR_TRUE : PR_FALSE;
    encode_kind &= ~SEC_ASN1_OPTIONAL;

    PORT_Assert(!(isExplicit && universal)); /* bad templates */

    may_stream = (encode_kind & SEC_ASN1_MAY_STREAM) ? PR_TRUE : PR_FALSE;
    encode_kind &= ~SEC_ASN1_MAY_STREAM;

    /* Just clear this to get it out of the way; we do not need it here */
    encode_kind &= ~SEC_ASN1_DYNAMIC;

    if (encode_kind & SEC_ASN1_NO_STREAM) {
        disallowStreaming = PR_TRUE;
    }
    encode_kind &= ~SEC_ASN1_NO_STREAM;

    if (encode_kind & SEC_ASN1_CHOICE) {
        void *src2;
        int indx = sec_asn1e_which_choice(src, theTemplate);
        if (0 == indx) {
            /* XXX set an error? "choice not found" */
            /* state->top->status = encodeError; */
            return 0;
        }

        src2 = (void *)((char *)src - theTemplate->offset + theTemplate[indx].offset);

        return sec_asn1e_contents_length(&theTemplate[indx], src2,
                                         disallowStreaming, insideIndefinite,
                                         pHdrException);
    }

    if ((encode_kind & (SEC_ASN1_POINTER | SEC_ASN1_INLINE)) || !universal) {
        /* XXX any bits we want to disallow (PORT_Assert against) here? */
        theTemplate = SEC_ASN1GetSubtemplate(theTemplate, src, PR_TRUE);
        if (encode_kind & SEC_ASN1_POINTER) {
            src = *(void **)src;
            if (src == NULL) {
                *pHdrException = optional ? hdr_optional : hdr_normal;
                return 0;
            }
        } else if (encode_kind & SEC_ASN1_INLINE) {
            /* check that there are no extraneous bits */
            if (optional) {
                if (PR_FALSE != SEC_ASN1IsTemplateSimple(theTemplate)) {
                    /* we now know that the target is a SECItem*, so we can check
                       if the source contains one */
                    SECItem *target = (SECItem *)src;
                    if (!target || !target->data || !target->len) {
                        /* no valid data to encode subtemplate */
                        *pHdrException = hdr_optional;
                        return 0;
                    }
                } else {
                    PORT_Assert(0); /* complex templates not handled as inline
                                       optional */
                }
            }
        }

        src = (char *)src + theTemplate->offset;

        /* recurse to find the length of the subtemplate */
        len = sec_asn1e_contents_length(theTemplate, src, disallowStreaming,
                                        insideIndefinite, pHdrException);
        if (len == 0 && optional) {
            *pHdrException = hdr_optional;
        } else if (isExplicit) {
            if (*pHdrException == hdr_any) {
                /* *we* do not want to add in a header,
                ** but our caller still does.
                */
                *pHdrException = hdr_normal;
            } else if (*pHdrException == hdr_normal) {
                /* if the inner content exists, our length is
                 * len(identifier) + len(length) + len(innercontent)
                 * XXX we currently assume len(identifier) == 1;
                 * to support a high-tag-number this would need to be smarter.
                 */
                len += 1 + SEC_ASN1LengthLength(len);
            }
        }
        return len;
    }
    underlying_kind = encode_kind;

    /* This is only used in decoding; it plays no part in encoding.  */
    if (underlying_kind & SEC_ASN1_SAVE) {
        /* check that there are no extraneous bits */
        PORT_Assert(underlying_kind == SEC_ASN1_SAVE);
        *pHdrException = hdr_decoder;
        return 0;
    }

#define UNEXPECTED_FLAGS                                                          \
    (SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_INLINE | SEC_ASN1_POINTER | \
     SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM | SEC_ASN1_SAVE | SEC_ASN1_SKIP)

    /* Having any of these bits is not expected here...  */
    PORT_Assert((underlying_kind & UNEXPECTED_FLAGS) == 0);
    underlying_kind &= ~UNEXPECTED_FLAGS;
#undef UNEXPECTED_FLAGS

    if (underlying_kind & SEC_ASN1_CHOICE) {
        void *src2;
        int indx = sec_asn1e_which_choice(src, theTemplate);
        if (0 == indx) {
            /* XXX set an error? "choice not found" */
            /* state->top->status = encodeError; */
            return 0;
        }

        src2 = (void *)((char *)src - theTemplate->offset + theTemplate[indx].offset);
        len = sec_asn1e_contents_length(&theTemplate[indx], src2,
                                        disallowStreaming, insideIndefinite,
                                        pHdrException);
    } else {
        switch (underlying_kind) {
            case SEC_ASN1_SEQUENCE_OF:
            case SEC_ASN1_SET_OF: {
                const SEC_ASN1Template *tmpt;
                void *sub_src;
                unsigned long sub_len;
                void **group;

                len = 0;

                group = *(void ***)src;
                if (group == NULL)
                    break;

                tmpt = SEC_ASN1GetSubtemplate(theTemplate, src, PR_TRUE);

                for (; *group != NULL; group++) {
                    sub_src = (char *)(*group) + tmpt->offset;
                    sub_len = sec_asn1e_contents_length(tmpt, sub_src,
                                                        disallowStreaming,
                                                        insideIndefinite,
                                                        pHdrException);
                    len += sub_len;
                    /*
                     * XXX The 1 below is the presumed length of the identifier;
                     * to support a high-tag-number this would need to be smarter.
                     */
                    if (*pHdrException == hdr_normal)
                        len += 1 + SEC_ASN1LengthLength(sub_len);
                }
            } break;

            case SEC_ASN1_SEQUENCE:
            case SEC_ASN1_SET: {
                const SEC_ASN1Template *tmpt;
                void *sub_src;
                unsigned long sub_len;

                len = 0;
                for (tmpt = theTemplate + 1; tmpt->kind; tmpt++) {
                    sub_src = (char *)src + tmpt->offset;
                    sub_len = sec_asn1e_contents_length(tmpt, sub_src,
                                                        disallowStreaming,
                                                        insideIndefinite,
                                                        pHdrException);
                    len += sub_len;
                    /*
                     * XXX The 1 below is the presumed length of the identifier;
                     * to support a high-tag-number this would need to be smarter.
                     */
                    if (*pHdrException == hdr_normal)
                        len += 1 + SEC_ASN1LengthLength(sub_len);
                }
            } break;

            case SEC_ASN1_BIT_STRING:
                /* convert bit length to byte */
                len = (((SECItem *)src)->len + 7) >> 3;
                /* bit string contents involve an extra octet */
                if (len)
                    len++;
                break;

            case SEC_ASN1_INTEGER:
                /* ASN.1 INTEGERs are signed.
                 * If the source is an unsigned integer, the encoder will need
                 * to handle the conversion here.
                 */
                {
                    unsigned char *buf = ((SECItem *)src)->data;
                    SECItemType integerType = ((SECItem *)src)->type;
                    len = ((SECItem *)src)->len;
                    while (len > 0) {
                        if (*buf != 0) {
                            if (*buf & 0x80 && integerType == siUnsignedInteger) {
                                len++; /* leading zero needed to make number signed */
                            }
                            break; /* reached beginning of number */
                        }
                        if (len == 1) {
                            break; /* the number 0 */
                        }
                        if (buf[1] & 0x80) {
                            break; /* leading zero already present */
                        }
                        /* extraneous leading zero, keep going */
                        buf++;
                        len--;
                    }
                }
                break;

            default:
                len = ((SECItem *)src)->len;
                break;
        } /* end switch */

#ifndef WHAT_PROBLEM_DOES_THIS_SOLVE
        /* if we're streaming, we may have a secitem w/len 0 as placeholder */
        if (!len && insideIndefinite && may_stream && !disallowStreaming) {
            len = 1;
        }
#endif
    } /* end else */

    if (len == 0 && optional)
        *pHdrException = hdr_optional;
    else if (underlying_kind == SEC_ASN1_ANY)
        *pHdrException = hdr_any;
    else
        *pHdrException = hdr_normal;

    return len;
}

static void
sec_asn1e_write_header(sec_asn1e_state *state)
{
    unsigned long contents_length;
    unsigned char tag_number, tag_modifiers;
    sec_asn1e_hdr_encoding hdrException = hdr_normal;
    PRBool indefinite = PR_FALSE;

    PORT_Assert(state->place == beforeHeader);

    tag_number = state->tag_number;
    tag_modifiers = state->tag_modifiers;

    if (state->underlying_kind == SEC_ASN1_ANY) {
        state->place = duringContents;
        return;
    }

    if (state->underlying_kind & SEC_ASN1_CHOICE) {
        int indx = sec_asn1e_which_choice(state->src, state->theTemplate);
        if (0 == indx) {
            /* XXX set an error? "choice not found" */
            state->top->status = encodeError;
            return;
        }
        state->place = afterChoice;
        state = sec_asn1e_push_state(state->top, &state->theTemplate[indx],
                                     (char *)state->src - state->theTemplate->offset,
                                     PR_TRUE);
        if (state) {
            /*
             * Do the "before" field notification.
             */
            sec_asn1e_notify_before(state->top, state->src, state->depth);
            (void)sec_asn1e_init_state_based_on_template(state);
        }
        return;
    }

    /* The !isString test below is apparently intended to ensure that all
    ** constructed types receive indefinite length encoding.
    */
    indefinite = (PRBool)(state->top->streaming && state->may_stream &&
                          (state->top->from_buf || !state->is_string));

    /*
     * If we are doing a definite-length encoding, first we have to
     * walk the data structure to calculate the entire contents length.
     * If we are doing an indefinite-length encoding, we still need to
     * know if the contents is:
     *    optional and to be omitted, or
     *    an ANY (header is pre-encoded), or
     *    a SAVE or some other kind of template used only by the decoder.
     * So, we call this function either way.
     */
    contents_length = sec_asn1e_contents_length(state->theTemplate,
                                                state->src,
                                                state->disallowStreaming,
                                                indefinite,
                                                &hdrException);
    /*
     * We might be told explicitly not to put out a header.
     * But it can also be the case, via a pushed subtemplate, that
     * sec_asn1e_contents_length could not know that this field is
     * really optional.  So check for that explicitly, too.
     */
    if (hdrException != hdr_normal ||
        (contents_length == 0 && state->optional)) {
        state->place = afterContents;
        if (state->top->streaming &&
            state->may_stream &&
            state->top->from_buf) {
            /* we did not find an optional indefinite string, so we
             * don't encode it.  However, if TakeFromBuf is on, we stop
             * here anyway to give our caller a chance to intercept at the
             * same point where we would stop if the field were present.
             */
            state->top->status = needBytes;
        }
        return;
    }

    if (indefinite) {
        /*
         * We need to put out an indefinite-length encoding.
         * The only universal types that can be constructed are SETs,
         * SEQUENCEs, and strings; so check that it is one of those,
         * or that it is not universal (e.g. context-specific).
         */
        state->indefinite = PR_TRUE;
        PORT_Assert((tag_number == SEC_ASN1_SET) || (tag_number == SEC_ASN1_SEQUENCE) || ((tag_modifiers & SEC_ASN1_CLASS_MASK) != 0) || state->is_string);
        tag_modifiers |= SEC_ASN1_CONSTRUCTED;
        contents_length = 0;
    }

    sec_asn1e_write_identifier_bytes(state,
                                     (unsigned char)(tag_number | tag_modifiers));
    sec_asn1e_write_length_bytes(state, contents_length, state->indefinite);

    if (contents_length == 0 && !state->indefinite) {
        /*
         * If no real contents to encode, then we are done with this field.
         */
        state->place = afterContents;
        return;
    }

    /*
     * An EXPLICIT is nothing but an outer header, which we have already
     * written.  Now we need to do the inner header and contents.
     */
    if (state->isExplicit) {
        const SEC_ASN1Template *subt =
            SEC_ASN1GetSubtemplate(state->theTemplate, state->src, PR_TRUE);
        state->place = afterContents;
        state = sec_asn1e_push_state(state->top, subt, state->src, PR_TRUE);
        if (state != NULL) {
            (void)sec_asn1e_init_state_based_on_template(state);
        }
        return;
    }

    switch (state->underlying_kind) {
        case SEC_ASN1_SET_OF:
        case SEC_ASN1_SEQUENCE_OF:
            /*
             * We need to push a child to handle each member.
             */
            {
                void **group;
                const SEC_ASN1Template *subt;

                group = *(void ***)state->src;
                if (group == NULL || *group == NULL) {
                    /*
                     * Group is empty; we are done.
                     */
                    state->place = afterContents;
                    return;
                }
                state->place = duringGroup;
                subt = SEC_ASN1GetSubtemplate(state->theTemplate, state->src,
                                              PR_TRUE);
                state = sec_asn1e_push_state(state->top, subt, *group, PR_TRUE);
                if (state != NULL) {
                    (void)sec_asn1e_init_state_based_on_template(state);
                }
            }
            break;

        case SEC_ASN1_SEQUENCE:
        case SEC_ASN1_SET:
            /*
             * We need to push a child to handle the individual fields.
             */
            state->place = duringSequence;
            state = sec_asn1e_push_state(state->top, state->theTemplate + 1,
                                         state->src, PR_TRUE);
            if (state != NULL) {
                /*
                 * Do the "before" field notification.
                 */
                sec_asn1e_notify_before(state->top, state->src, state->depth);
                (void)sec_asn1e_init_state_based_on_template(state);
            }
            break;

        default:
            /*
             * I think we do not need to do anything else.
             * XXX Correct?
             */
            state->place = duringContents;
            break;
    }
}

static void
sec_asn1e_write_contents_from_buf(sec_asn1e_state *state,
                                  const char *buf, unsigned long len)
{
    PORT_Assert(state->place == duringContents);
    PORT_Assert(state->top->from_buf);
    PORT_Assert(state->may_stream && !state->disallowStreaming);

    /*
     * Probably they just turned on "take from buf", but have not
     * yet given us any bytes.  If there is nothing in the buffer
     * then we have nothing to do but return and wait.
     */
    if (buf == NULL || len == 0) {
        state->top->status = needBytes;
        return;
    }
    /*
     * We are streaming, reading from a passed-in buffer.
     * This means we are encoding a simple string or an ANY.
     * For the former, we need to put out a substring, with its
     * own identifier and length.  For an ANY, we just write it
     * out as is (our caller is required to ensure that it
     * is a properly encoded entity).
     */
    PORT_Assert(state->is_string); /* includes ANY */
    if (state->underlying_kind != SEC_ASN1_ANY) {
        unsigned char identifier;

        /*
         * Create the identifier based on underlying_kind.  We cannot
         * use tag_number and tag_modifiers because this can be an
         * implicitly encoded field.  In that case, the underlying
         * substrings *are* encoded with their real tag.
         */
        identifier = (unsigned char)(state->underlying_kind & SEC_ASN1_TAG_MASK);
        /*
         * The underlying kind should just be a simple string; there
         * should be no bits like CONTEXT_SPECIFIC or CONSTRUCTED set.
         */
        PORT_Assert((identifier & SEC_ASN1_TAGNUM_MASK) == identifier);
        /*
         * Write out the tag and length for the substring.
         */
        sec_asn1e_write_identifier_bytes(state, identifier);
        if (state->underlying_kind == SEC_ASN1_BIT_STRING) {
            char byte;
            /*
             * Assume we have a length in bytes but we need to output
             * a proper bit string.  This interface only works for bit
             * strings that are full multiples of 8.  If support for
             * real, variable length bit strings is needed then the
             * caller will have to know to pass in a bit length instead
             * of a byte length and then this code will have to
             * perform the encoding necessary (length written is length
             * in bytes plus 1, and the first octet of string is the
             * number of bits remaining between the end of the bit
             * string and the next byte boundary).
             */
            sec_asn1e_write_length_bytes(state, len + 1, PR_FALSE);
            byte = 0;
            sec_asn1e_write_contents_bytes(state, &byte, 1);
        } else {
            sec_asn1e_write_length_bytes(state, len, PR_FALSE);
        }
    }
    sec_asn1e_write_contents_bytes(state, buf, len);
    state->top->status = needBytes;
}

static void
sec_asn1e_write_contents(sec_asn1e_state *state)
{
    unsigned long len = 0;

    PORT_Assert(state->place == duringContents);

    switch (state->underlying_kind) {
        case SEC_ASN1_SET:
        case SEC_ASN1_SEQUENCE:
            PORT_Assert(0);
            break;

        case SEC_ASN1_BIT_STRING: {
            SECItem *item;
            char rem;

            item = (SECItem *)state->src;
            len = (item->len + 7) >> 3;
            rem = (unsigned char)((len << 3) - item->len); /* remaining bits */
            sec_asn1e_write_contents_bytes(state, &rem, 1);
            sec_asn1e_write_contents_bytes(state, (char *)item->data, len);
        } break;

        case SEC_ASN1_BMP_STRING:
            /* The number of bytes must be divisable by 2 */
            if ((((SECItem *)state->src)->len) % 2) {
                SEC_ASN1EncoderContext *cx;

                cx = state->top;
                cx->status = encodeError;
                break;
            }
            /* otherwise, fall through to write the content */
            goto process_string;

        case SEC_ASN1_UNIVERSAL_STRING:
            /* The number of bytes must be divisable by 4 */
            if ((((SECItem *)state->src)->len) % 4) {
                SEC_ASN1EncoderContext *cx;

                cx = state->top;
                cx->status = encodeError;
                break;
            }
            /* otherwise, fall through to write the content */
            goto process_string;

        case SEC_ASN1_INTEGER:
            /* ASN.1 INTEGERs are signed.  If the source is an unsigned
             * integer, the encoder will need to handle the conversion here.
             */
            {
                unsigned int blen;
                unsigned char *buf;
                SECItemType integerType;
                blen = ((SECItem *)state->src)->len;
                buf = ((SECItem *)state->src)->data;
                integerType = ((SECItem *)state->src)->type;
                while (blen > 0) {
                    if (*buf & 0x80 && integerType == siUnsignedInteger) {
                        char zero = 0; /* write a leading 0 */
                        sec_asn1e_write_contents_bytes(state, &zero, 1);
                        /* and then the remaining buffer */
                        sec_asn1e_write_contents_bytes(state,
                                                       (char *)buf, blen);
                        break;
                    }
                    /* Check three possibilities:
                     * 1.  No leading zeros, msb of MSB is not 1;
                     * 2.  The number is zero itself;
                     * 3.  Encoding a signed integer with a leading zero,
                     *     keep the zero so that the number is positive.
                     */
                    if (*buf != 0 ||
                        blen == 1 ||
                        (buf[1] & 0x80 && integerType != siUnsignedInteger)) {
                        sec_asn1e_write_contents_bytes(state,
                                                       (char *)buf, blen);
                        break;
                    }
                    /* byte is 0, continue */
                    buf++;
                    blen--;
                }
            }
            /* done with this content */
            break;

        process_string:
        default: {
            SECItem *item;

            item = (SECItem *)state->src;
            sec_asn1e_write_contents_bytes(state, (char *)item->data,
                                           item->len);
        } break;
    }
    state->place = afterContents;
}

/*
 * We are doing a SET OF or SEQUENCE OF, and have just finished an item.
 */
static void
sec_asn1e_next_in_group(sec_asn1e_state *state)
{
    sec_asn1e_state *child;
    void **group;
    void *member;

    PORT_Assert(state->place == duringGroup);
    PORT_Assert(state->child != NULL);

    child = state->child;

    group = *(void ***)state->src;

    /*
     * Find placement of current item.
     */
    member = (char *)(state->child->src) - child->theTemplate->offset;
    while (*group != member)
        group++;

    /*
     * Move forward to next item.
     */
    group++;
    if (*group == NULL) {
        /*
         * That was our last one; we are done now.
         */
        child->place = notInUse;
        state->place = afterContents;
        return;
    }
    child->src = (char *)(*group) + child->theTemplate->offset;

    /*
     * Re-"push" child.
     */
    sec_asn1e_scrub_state(child);
    state->top->current = child;
}

/*
 * We are moving along through a sequence; move forward by one,
 * (detecting end-of-sequence when it happens).
 */
static void
sec_asn1e_next_in_sequence(sec_asn1e_state *state)
{
    sec_asn1e_state *child;

    PORT_Assert(state->place == duringSequence);
    PORT_Assert(state->child != NULL);

    child = state->child;

    /*
     * Do the "after" field notification.
     */
    sec_asn1e_notify_after(state->top, child->src, child->depth);

    /*
     * Move forward.
     */
    child->theTemplate++;
    if (child->theTemplate->kind == 0) {
        /*
         * We are done with this sequence.
         */
        child->place = notInUse;
        state->place = afterContents;
        return;
    }

    /*
     * Reset state and push.
     */

    child->src = (char *)state->src + child->theTemplate->offset;

    /*
     * Do the "before" field notification.
     */
    sec_asn1e_notify_before(state->top, child->src, child->depth);

    state->top->current = child;
    (void)sec_asn1e_init_state_based_on_template(child);
}

static void
sec_asn1e_after_contents(sec_asn1e_state *state)
{
    PORT_Assert(state->place == afterContents);

    if (state->indefinite)
        sec_asn1e_write_end_of_contents_bytes(state);

    /*
     * Just make my parent be the current state.  It will then clean
     * up after me and free me (or reuse me).
     */
    state->top->current = state->parent;
}

/*
 * This function is called whether or not we are streaming; if we
 * *are* streaming, our caller can also instruct us to take bytes
 * from the passed-in buffer (at buf, for length len, which is likely
 * bytes but could even mean bits if the current field is a bit string).
 * If we have been so instructed, we will gobble up bytes from there
 * (rather than from our src structure) and output them, and then
 * we will just return, expecting to be called again -- either with
 * more bytes or after our caller has instructed us that we are done
 * (for now) with the buffer.
 */
SECStatus
SEC_ASN1EncoderUpdate(SEC_ASN1EncoderContext *cx,
                      const char *buf, unsigned long len)
{
    sec_asn1e_state *state;

    if (cx->status == needBytes) {
        cx->status = keepGoing;
    }

    while (cx->status == keepGoing) {
        state = cx->current;
        switch (state->place) {
            case beforeHeader:
                sec_asn1e_write_header(state);
                break;
            case duringContents:
                if (cx->from_buf)
                    sec_asn1e_write_contents_from_buf(state, buf, len);
                else
                    sec_asn1e_write_contents(state);
                break;
            case duringGroup:
                sec_asn1e_next_in_group(state);
                break;
            case duringSequence:
                sec_asn1e_next_in_sequence(state);
                break;
            case afterContents:
                sec_asn1e_after_contents(state);
                break;
            case afterImplicit:
            case afterInline:
            case afterPointer:
            case afterChoice:
                /*
                 * These states are more documentation than anything.
                 * They just need to force a pop.
                 */
                PORT_Assert(!state->indefinite);
                state->place = afterContents;
                break;
            case notInUse:
            default:
                /* This is not an error, but rather a plain old BUG! */
                PORT_Assert(0);
                cx->status = encodeError;
                break;
        }

        if (cx->status == encodeError)
            break;

        /* It might have changed, so we have to update our local copy.  */
        state = cx->current;

        /* If it is NULL, we have popped all the way to the top.  */
        if (state == NULL) {
            cx->status = allDone;
            break;
        }
    }

    if (cx->status == encodeError) {
        return SECFailure;
    }

    return SECSuccess;
}

void
SEC_ASN1EncoderFinish(SEC_ASN1EncoderContext *cx)
{
    /*
     * XXX anything else that needs to be finished?
     */

    PORT_FreeArena(cx->our_pool, PR_FALSE);
}

SEC_ASN1EncoderContext *
SEC_ASN1EncoderStart(const void *src, const SEC_ASN1Template *theTemplate,
                     SEC_ASN1WriteProc output_proc, void *output_arg)
{
    PLArenaPool *our_pool;
    SEC_ASN1EncoderContext *cx;

    our_pool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
    if (our_pool == NULL)
        return NULL;

    cx = (SEC_ASN1EncoderContext *)PORT_ArenaZAlloc(our_pool, sizeof(*cx));
    if (cx == NULL) {
        PORT_FreeArena(our_pool, PR_FALSE);
        return NULL;
    }

    cx->our_pool = our_pool;
    cx->output_proc = output_proc;
    cx->output_arg = output_arg;

    cx->status = keepGoing;

    if (sec_asn1e_push_state(cx, theTemplate, src, PR_FALSE) == NULL ||
        sec_asn1e_init_state_based_on_template(cx->current) == NULL) {
        /*
         * Trouble initializing (probably due to failed allocations)
         * requires that we just give up.
         */
        PORT_FreeArena(our_pool, PR_FALSE);
        return NULL;
    }

    return cx;
}

/*
 * XXX Do we need a FilterProc, too?
 */

void
SEC_ASN1EncoderSetNotifyProc(SEC_ASN1EncoderContext *cx,
                             SEC_ASN1NotifyProc fn, void *arg)
{
    cx->notify_proc = fn;
    cx->notify_arg = arg;
}

void
SEC_ASN1EncoderClearNotifyProc(SEC_ASN1EncoderContext *cx)
{
    cx->notify_proc = NULL;
    cx->notify_arg = NULL; /* not necessary; just being clean */
}

void
SEC_ASN1EncoderAbort(SEC_ASN1EncoderContext *cx, int error)
{
    PORT_Assert(cx);
    PORT_SetError(error);
    cx->status = encodeError;
}

void
SEC_ASN1EncoderSetStreaming(SEC_ASN1EncoderContext *cx)
{
    /* XXX is there a way to check that we are "between" fields here? */

    cx->streaming = PR_TRUE;
}

void
SEC_ASN1EncoderClearStreaming(SEC_ASN1EncoderContext *cx)
{
    /* XXX is there a way to check that we are "between" fields here? */

    cx->streaming = PR_FALSE;
}

void
SEC_ASN1EncoderSetTakeFromBuf(SEC_ASN1EncoderContext *cx)
{
    /*
     * XXX is there a way to check that we are "between" fields here?  this
     * needs to include a check for being in between groups of items in
     * a SET_OF or SEQUENCE_OF.
     */
    PORT_Assert(cx->streaming);

    cx->from_buf = PR_TRUE;
}

void
SEC_ASN1EncoderClearTakeFromBuf(SEC_ASN1EncoderContext *cx)
{
    /* we should actually be taking from buf *now* */
    PORT_Assert(cx->from_buf);
    if (!cx->from_buf) /* if not, just do nothing */
        return;

    cx->from_buf = PR_FALSE;

    if (cx->status == needBytes) {
        cx->status = keepGoing;
        cx->current->place = afterContents;
    }
}

SECStatus
SEC_ASN1Encode(const void *src, const SEC_ASN1Template *theTemplate,
               SEC_ASN1WriteProc output_proc, void *output_arg)
{
    SEC_ASN1EncoderContext *ecx;
    SECStatus rv;

    ecx = SEC_ASN1EncoderStart(src, theTemplate, output_proc, output_arg);
    if (ecx == NULL)
        return SECFailure;

    rv = SEC_ASN1EncoderUpdate(ecx, NULL, 0);

    SEC_ASN1EncoderFinish(ecx);
    return rv;
}

/*
 * XXX depth and data_kind are unused; is there a PC way to silence warnings?
 * (I mean "politically correct", not anything to do with intel/win platform)
 */
static void
sec_asn1e_encode_item_count(void *arg, const char *buf, unsigned long len,
                            int depth, SEC_ASN1EncodingPart data_kind)
{
    unsigned long *count;

    count = (unsigned long *)arg;
    PORT_Assert(count != NULL);

    *count += len;
}

/* XXX depth and data_kind are unused; is there a PC way to silence warnings? */
static void
sec_asn1e_encode_item_store(void *arg, const char *buf, unsigned long len,
                            int depth, SEC_ASN1EncodingPart data_kind)
{
    SECItem *dest;

    dest = (SECItem *)arg;
    PORT_Assert(dest != NULL);

    if (len > 0) {
        PORT_Memcpy(dest->data + dest->len, buf, len);
        dest->len += len;
    }
}

/*
 * Allocate an entire SECItem, or just the data part of it, to hold
 * "len" bytes of stuff.  Allocate from the given pool, if specified,
 * otherwise just do a vanilla PORT_Alloc.
 *
 * XXX This seems like a reasonable general-purpose function (for SECITEM_)?
 */
static SECItem *
sec_asn1e_allocate_item(PLArenaPool *poolp, SECItem *dest, unsigned long len)
{
    if (poolp != NULL) {
        void *release;

        release = PORT_ArenaMark(poolp);
        if (dest == NULL)
            dest = (SECItem *)PORT_ArenaAlloc(poolp, sizeof(SECItem));
        if (dest != NULL) {
            dest->data = (unsigned char *)PORT_ArenaAlloc(poolp, len);
            if (dest->data == NULL) {
                dest = NULL;
            }
        }
        if (dest == NULL) {
            /* one or both allocations failed; release everything */
            PORT_ArenaRelease(poolp, release);
        } else {
            /* everything okay; unmark the arena */
            PORT_ArenaUnmark(poolp, release);
        }
    } else {
        SECItem *indest;

        indest = dest;
        if (dest == NULL)
            dest = (SECItem *)PORT_Alloc(sizeof(SECItem));
        if (dest != NULL) {
            dest->type = siBuffer;
            dest->data = (unsigned char *)PORT_Alloc(len);
            if (dest->data == NULL) {
                if (indest == NULL)
                    PORT_Free(dest);
                dest = NULL;
            }
        }
    }

    return dest;
}

SECItem *
SEC_ASN1EncodeItem(PLArenaPool *poolp, SECItem *dest, const void *src,
                   const SEC_ASN1Template *theTemplate)
{
    unsigned long encoding_length;
    SECStatus rv;

    PORT_Assert(dest == NULL || dest->data == NULL);

    encoding_length = 0;
    rv = SEC_ASN1Encode(src, theTemplate,
                        sec_asn1e_encode_item_count, &encoding_length);
    if (rv != SECSuccess)
        return NULL;

    dest = sec_asn1e_allocate_item(poolp, dest, encoding_length);
    if (dest == NULL)
        return NULL;

    /* XXX necessary?  This really just checks for a bug in the allocate fn */
    PORT_Assert(dest->data != NULL);
    if (dest->data == NULL)
        return NULL;

    dest->len = 0;
    (void)SEC_ASN1Encode(src, theTemplate, sec_asn1e_encode_item_store, dest);

    PORT_Assert(encoding_length == dest->len);
    return dest;
}

static SECItem *
sec_asn1e_integer(PLArenaPool *poolp, SECItem *dest, unsigned long value,
                  PRBool is_unsigned)
{
    unsigned long copy;
    unsigned char sign;
    int len = 0;

    /*
     * Determine the length of the encoded value (minimum of 1).
     */
    copy = value;
    do {
        len++;
        sign = (unsigned char)(copy & 0x80);
        copy >>= 8;
    } while (copy);

    /*
     * If 'value' is non-negative, and the high bit of the last
     * byte we counted was set, we need to add one to the length so
     * we put a high-order zero byte in the encoding.
     */
    if (sign && (is_unsigned || (long)value >= 0))
        len++;

    /*
     * Allocate the item (if necessary) and the data pointer within.
     */
    dest = sec_asn1e_allocate_item(poolp, dest, len);
    if (dest == NULL)
        return NULL;

    /*
     * Store the value, byte by byte, in the item.
     */
    dest->len = len;
    while (len) {
        dest->data[--len] = (unsigned char)value;
        value >>= 8;
    }
    PORT_Assert(value == 0);

    return dest;
}

SECItem *
SEC_ASN1EncodeInteger(PLArenaPool *poolp, SECItem *dest, long value)
{
    return sec_asn1e_integer(poolp, dest, (unsigned long)value, PR_FALSE);
}

SECItem *
SEC_ASN1EncodeUnsignedInteger(PLArenaPool *poolp,
                              SECItem *dest, unsigned long value)
{
    return sec_asn1e_integer(poolp, dest, value, PR_TRUE);
}
