/* 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/. */

/*
    Optimized ASN.1 DER decoder
*/

#include "secerr.h"
#include "secasn1.h" /* for SEC_ASN1GetSubtemplate */
#include "secitem.h"

/*
 * simple definite-length ASN.1 decoder
 */

static unsigned char*
definite_length_decoder(const unsigned char* buf,
                        const unsigned int buf_length,
                        unsigned int* out_data_length,
                        PRBool includeTag)
{
    unsigned char tag;
    unsigned int used_length = 0;
    unsigned int data_length = 0;
    unsigned char length_field_len = 0;
    unsigned char byte;
    unsigned int i;

    if (used_length >= buf_length) {
        /* Tag field was not found! */
        return NULL;
    }
    tag = buf[used_length++];

    if (tag == 0) {
        /* End-of-contents octects should not be present in DER because
           DER doesn't use the indefinite length form. */
        return NULL;
    }

    if ((tag & 0x1F) == 0x1F) {
        /* High tag number (a tag number > 30) is not supported */
        return NULL;
    }

    if (used_length >= buf_length) {
        /* Length field was not found! */
        return NULL;
    }
    byte = buf[used_length++];

    if (!(byte & 0x80)) {
        /* Short form: The high bit is not set. */
        data_length = byte; /* clarity; we're returning a 32-bit int. */
    } else {
        /* Long form. Extract the field length */
        length_field_len = byte & 0x7F;
        if (length_field_len == 0) {
            /* DER doesn't use the indefinite length form. */
            return NULL;
        }

        if (length_field_len > sizeof(data_length)) {
            /* We don't support an extended length field  longer than
               4 bytes (2^32) */
            return NULL;
        }

        if (length_field_len > (buf_length - used_length)) {
            /* Extended length field was not found */
            return NULL;
        }

        /* Iterate across the extended length field */
        for (i = 0; i < length_field_len; i++) {
            byte = buf[used_length++];
            data_length = (data_length << 8) | byte;

            if (i == 0) {
                PRBool too_long = PR_FALSE;
                if (length_field_len == 1) {
                    too_long = ((byte & 0x80) == 0); /* Short form suffices */
                } else {
                    too_long = (byte == 0); /* This zero byte can be omitted */
                }
                if (too_long) {
                    /* The length is longer than needed. */
                    return NULL;
                }
            }
        }
    }

    if (data_length > (buf_length - used_length)) {
        /* The decoded length exceeds the available buffer */
        return NULL;
    }

    if (includeTag) {
        data_length += used_length;
    }

    *out_data_length = data_length;
    return ((unsigned char*)buf + (includeTag ? 0 : used_length));
}

static SECStatus
GetItem(SECItem* src, SECItem* dest, PRBool includeTag)
{
    if ((!src) || (!dest) || (!src->data && src->len)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (!src->len) {
        /* reaching the end of the buffer is not an error */
        dest->data = NULL;
        dest->len = 0;
        return SECSuccess;
    }

    dest->data = definite_length_decoder(src->data, src->len, &dest->len,
                                         includeTag);
    if (dest->data == NULL) {
        PORT_SetError(SEC_ERROR_BAD_DER);
        return SECFailure;
    }
    src->len -= (int)(dest->data - src->data) + dest->len;
    src->data = dest->data + dest->len;
    return SECSuccess;
}

/* check if the actual component's type matches the type in the template */

static SECStatus
MatchComponentType(const SEC_ASN1Template* templateEntry,
                   SECItem* item, PRBool* match, void* dest)
{
    unsigned long kind = 0;
    unsigned char tag = 0;

    if ((!item) || (!item->data && item->len) || (!templateEntry) || (!match)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (!item->len) {
        *match = PR_FALSE;
        return SECSuccess;
    }

    kind = templateEntry->kind;
    tag = *(unsigned char*)item->data;

    if (((kind & SEC_ASN1_INLINE) ||
         (kind & SEC_ASN1_POINTER)) &&
        (0 == (kind & SEC_ASN1_TAG_MASK))) {
        /* These cases are special because the template's "kind" does not
           give us the information for the ASN.1 tag of the next item. It can
           only be figured out from the subtemplate. */
        if (!(kind & SEC_ASN1_OPTIONAL)) {
            /* This is a required component. If there is a type mismatch,
               the decoding of the subtemplate will fail, so assume this
               is a match at the parent level and let it fail later. This
               avoids a redundant check in matching cases */
            *match = PR_TRUE;
            return SECSuccess;
        } else {
            /* optional component. This is the hard case. Now we need to
               look at the subtemplate to get the expected kind */
            const SEC_ASN1Template* subTemplate =
                SEC_ASN1GetSubtemplate(templateEntry, dest, PR_FALSE);
            if (!subTemplate) {
                PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
                return SECFailure;
            }
            if ((subTemplate->kind & SEC_ASN1_INLINE) ||
                (subTemplate->kind & SEC_ASN1_POINTER)) {
                /* disallow nesting SEC_ASN1_POINTER and SEC_ASN1_INLINE,
                   otherwise you may get a false positive due to the recursion
                   optimization above that always matches the type if the
                   component is required . Nesting these should never be
                   required, so that no one should miss this ability */
                PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
                return SECFailure;
            }
            return MatchComponentType(subTemplate, item, match,
                                      (void*)((char*)dest + templateEntry->offset));
        }
    }

    if (kind & SEC_ASN1_CHOICE) {
        /* we need to check the component's tag against each choice's tag */
        /* XXX it would be nice to save the index of the choice here so that
           DecodeChoice wouldn't have to do this again. However, due to the
           recursivity of MatchComponentType, we don't know if we are in a
           required or optional component, so we can't write anywhere in
           the destination within this function */
        unsigned choiceIndex = 1;
        const SEC_ASN1Template* choiceEntry;
        while ((choiceEntry = &templateEntry[choiceIndex++]) && (choiceEntry->kind)) {
            if ((SECSuccess == MatchComponentType(choiceEntry, item, match,
                                                  (void*)((char*)dest + choiceEntry->offset))) &&
                (PR_TRUE == *match)) {
                return SECSuccess;
            }
        }
        /* no match, caller must decide if this is BAD DER, or not. */
        *match = PR_FALSE;
        return SECSuccess;
    }

    if (kind & SEC_ASN1_ANY) {
        /* SEC_ASN1_ANY always matches */
        *match = PR_TRUE;
        return SECSuccess;
    }

    if ((0 == ((unsigned char)kind & SEC_ASN1_TAGNUM_MASK)) &&
        (!(kind & SEC_ASN1_EXPLICIT)) &&
        (((kind & SEC_ASN1_SAVE) ||
          (kind & SEC_ASN1_SKIP)) &&
         (!(kind & SEC_ASN1_OPTIONAL)))) {
        /* when saving or skipping a required component,  a type is not
           required in the template. This is for legacy support of
           SEC_ASN1_SAVE and SEC_ASN1_SKIP only. XXX I would like to
           deprecate these usages and always require a type, as this
           disables type checking, and effectively forbids us from
           transparently ignoring optional components we aren't aware of */
        *match = PR_TRUE;
        return SECSuccess;
    }

    /* first, do a class check */
    if ((tag & SEC_ASN1_CLASS_MASK) !=
        (((unsigned char)kind) & SEC_ASN1_CLASS_MASK)) {
        /* this is only to help debugging of the decoder in case of problems */
        /* unsigned char tagclass = tag & SEC_ASN1_CLASS_MASK; */
        /* unsigned char expectedclass = (unsigned char)kind & SEC_ASN1_CLASS_MASK; */
        *match = PR_FALSE;
        return SECSuccess;
    }

    /* now do a tag check */
    if (((unsigned char)kind & SEC_ASN1_TAGNUM_MASK) !=
        (tag & SEC_ASN1_TAGNUM_MASK)) {
        *match = PR_FALSE;
        return SECSuccess;
    }

    /* now, do a method check. This depends on the class */
    switch (tag & SEC_ASN1_CLASS_MASK) {
        case SEC_ASN1_UNIVERSAL:
            /* For types of the SEC_ASN1_UNIVERSAL class, we know which must be
               primitive or constructed based on the tag */
            switch (tag & SEC_ASN1_TAGNUM_MASK) {
                case SEC_ASN1_SEQUENCE:
                case SEC_ASN1_SET:
                case SEC_ASN1_EMBEDDED_PDV:
                    /* this component must be a constructed type */
                    /* XXX add any new universal constructed type here */
                    if (tag & SEC_ASN1_CONSTRUCTED) {
                        *match = PR_TRUE;
                        return SECSuccess;
                    }
                    break;

                default:
                    /* this component must be a primitive type */
                    if (!(tag & SEC_ASN1_CONSTRUCTED)) {
                        *match = PR_TRUE;
                        return SECSuccess;
                    }
                    break;
            }
            break;

        default:
            /* for all other classes, we check the method based on the template */
            if ((unsigned char)(kind & SEC_ASN1_METHOD_MASK) ==
                (tag & SEC_ASN1_METHOD_MASK)) {
                *match = PR_TRUE;
                return SECSuccess;
            }
            /* method does not match between template and component */
            break;
    }

    *match = PR_FALSE;
    return SECSuccess;
}

#ifdef DEBUG

static SECStatus
CheckSequenceTemplate(const SEC_ASN1Template* sequenceTemplate)
{
    SECStatus rv = SECSuccess;
    const SEC_ASN1Template* sequenceEntry = NULL;
    unsigned long seqIndex = 0;
    unsigned long lastEntryIndex = 0;
    unsigned long ambiguityIndex = 0;
    PRBool foundAmbiguity = PR_FALSE;

    do {
        sequenceEntry = &sequenceTemplate[seqIndex++];
        if (sequenceEntry->kind) {
            /* ensure that we don't have an optional component of SEC_ASN1_ANY
               in the middle of the sequence, since we could not handle it */
            /* XXX this function needs to dig into the subtemplates to find
               the next tag */
            if ((PR_FALSE == foundAmbiguity) &&
                (sequenceEntry->kind & SEC_ASN1_OPTIONAL) &&
                (sequenceEntry->kind & SEC_ASN1_ANY)) {
                foundAmbiguity = PR_TRUE;
                ambiguityIndex = seqIndex - 1;
            }
        }
    } while (sequenceEntry->kind);

    lastEntryIndex = seqIndex - 2;

    if (PR_FALSE != foundAmbiguity) {
        if (ambiguityIndex < lastEntryIndex) {
            /* ambiguity can only be tolerated on the last entry */
            PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
            rv = SECFailure;
        }
    }

    /* XXX also enforce ASN.1 requirement that tags be
       distinct for consecutive optional components */

    return rv;
}

#endif

static SECStatus DecodeItem(void* dest,
                            const SEC_ASN1Template* templateEntry,
                            SECItem* src, PLArenaPool* arena, PRBool checkTag);

static SECStatus
DecodeSequence(void* dest,
               const SEC_ASN1Template* templateEntry,
               SECItem* src, PLArenaPool* arena)
{
    SECStatus rv = SECSuccess;
    SECItem source;
    SECItem sequence;
    const SEC_ASN1Template* sequenceTemplate = &(templateEntry[1]);
    const SEC_ASN1Template* sequenceEntry = NULL;
    unsigned long seqindex = 0;

#ifdef DEBUG
    /* for a sequence, we need to validate the template. */
    rv = CheckSequenceTemplate(sequenceTemplate);
#endif

    source = *src;

    /* get the sequence */
    if (SECSuccess == rv) {
        rv = GetItem(&source, &sequence, PR_FALSE);
    }

    /* process it */
    if (SECSuccess == rv)
        do {
            sequenceEntry = &sequenceTemplate[seqindex++];
            if ((sequenceEntry && sequenceEntry->kind) &&
                (sequenceEntry->kind != SEC_ASN1_SKIP_REST)) {
                rv = DecodeItem(dest, sequenceEntry, &sequence, arena, PR_TRUE);
            }
        } while ((SECSuccess == rv) &&
                 (sequenceEntry->kind &&
                  sequenceEntry->kind != SEC_ASN1_SKIP_REST));
    /* we should have consumed all the bytes in the sequence by now
       unless the caller doesn't care about the rest of the sequence */
    if (SECSuccess == rv && sequence.len &&
        sequenceEntry && sequenceEntry->kind != SEC_ASN1_SKIP_REST) {
        /* it isn't 100% clear whether this is a bad DER or a bad template.
           The problem is that logically, they don't match - there is extra
           data in the DER that the template doesn't know about */
        PORT_SetError(SEC_ERROR_BAD_DER);
        rv = SECFailure;
    }

    return rv;
}

static SECStatus
DecodeInline(void* dest,
             const SEC_ASN1Template* templateEntry,
             SECItem* src, PLArenaPool* arena, PRBool checkTag)
{
    const SEC_ASN1Template* inlineTemplate =
        SEC_ASN1GetSubtemplate(templateEntry, dest, PR_FALSE);
    return DecodeItem((void*)((char*)dest + templateEntry->offset),
                      inlineTemplate, src, arena, checkTag);
}

static SECStatus
DecodePointer(void* dest,
              const SEC_ASN1Template* templateEntry,
              SECItem* src, PLArenaPool* arena, PRBool checkTag)
{
    const SEC_ASN1Template* ptrTemplate =
        SEC_ASN1GetSubtemplate(templateEntry, dest, PR_FALSE);
    if (!ptrTemplate) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    void* subdata = PORT_ArenaZAlloc(arena, ptrTemplate->size);
    *(void**)((char*)dest + templateEntry->offset) = subdata;
    if (subdata) {
        return DecodeItem(subdata, ptrTemplate, src, arena, checkTag);
    } else {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }
}

static SECStatus
DecodeImplicit(void* dest,
               const SEC_ASN1Template* templateEntry,
               SECItem* src, PLArenaPool* arena)
{
    if (templateEntry->kind & SEC_ASN1_POINTER) {
        return DecodePointer((void*)((char*)dest),
                             templateEntry, src, arena, PR_FALSE);
    } else {
        return DecodeInline((void*)((char*)dest),
                            templateEntry, src, arena, PR_FALSE);
    }
}

static SECStatus
DecodeChoice(void* dest,
             const SEC_ASN1Template* templateEntry,
             SECItem* src, PLArenaPool* arena)
{
    SECStatus rv = SECSuccess;
    SECItem choice;
    const SEC_ASN1Template* choiceTemplate = &(templateEntry[1]);
    const SEC_ASN1Template* choiceEntry = NULL;
    unsigned long choiceindex = 0;

    /* XXX for a choice component, we should validate the template to make
       sure the tags are distinct, in debug builds. This hasn't been
       implemented yet */
    /* rv = CheckChoiceTemplate(sequenceTemplate); */

    /* process it */
    do {
        choice = *src;
        choiceEntry = &choiceTemplate[choiceindex++];
        if (choiceEntry->kind) {
            rv = DecodeItem(dest, choiceEntry, &choice, arena, PR_TRUE);
        }
    } while ((SECFailure == rv) && (choiceEntry->kind));

    if (SECFailure == rv) {
        /* the component didn't match any of the choices */
        PORT_SetError(SEC_ERROR_BAD_DER);
    } else {
        /* set the type in the union here */
        int* which = (int*)((char*)dest + templateEntry->offset);
        *which = (int)choiceEntry->size;
    }

    /* we should have consumed all the bytes by now */
    /* fail if we have not */
    if (SECSuccess == rv && choice.len) {
        /* there is extra data that isn't listed in the template */
        PORT_SetError(SEC_ERROR_BAD_DER);
        rv = SECFailure;
    }
    return rv;
}

static SECStatus
DecodeGroup(void* dest,
            const SEC_ASN1Template* templateEntry,
            SECItem* src, PLArenaPool* arena)
{
    SECStatus rv = SECSuccess;
    SECItem source;
    SECItem group;
    PRUint32 totalEntries = 0;
    PRUint32 entryIndex = 0;
    void** entries = NULL;

    const SEC_ASN1Template* subTemplate =
        SEC_ASN1GetSubtemplate(templateEntry, dest, PR_FALSE);

    source = *src;

    /* get the group */
    if (SECSuccess == rv) {
        rv = GetItem(&source, &group, PR_FALSE);
    }

    /* XXX we should check the subtemplate in debug builds */
    if (SECSuccess == rv) {
        /* first, count the number of entries. Benchmarking showed that this
           counting pass is more efficient than trying to allocate entries as
           we read the DER, even if allocating many entries at a time
        */
        SECItem counter = group;
        do {
            SECItem anitem;
            rv = GetItem(&counter, &anitem, PR_TRUE);
            if (SECSuccess == rv && (anitem.len)) {
                totalEntries++;
            }
        } while ((SECSuccess == rv) && (counter.len));

        if (SECSuccess == rv) {
            /* allocate room for pointer array and entries */
            /* we want to allocate the array even if there is 0 entry */
            entries = (void**)PORT_ArenaZAlloc(arena, sizeof(void*) * (totalEntries + 1) + /* the extra one is for NULL termination */
                                                          subTemplate->size * totalEntries);

            if (entries) {
                entries[totalEntries] = NULL; /* terminate the array */
            } else {
                PORT_SetError(SEC_ERROR_NO_MEMORY);
                rv = SECFailure;
            }
            if (SECSuccess == rv) {
                void* entriesData = (unsigned char*)entries + (unsigned long)(sizeof(void*) * (totalEntries + 1));
                /* and fix the pointers in the array */
                PRUint32 entriesIndex = 0;
                for (entriesIndex = 0; entriesIndex < totalEntries; entriesIndex++) {
                    entries[entriesIndex] =
                        (char*)entriesData + (subTemplate->size * entriesIndex);
                }
            }
        }
    }

    if (SECSuccess == rv && totalEntries)
        do {
            if (!(entryIndex < totalEntries)) {
                rv = SECFailure;
                break;
            }
            rv = DecodeItem(entries[entryIndex++], subTemplate, &group, arena, PR_TRUE);
        } while ((SECSuccess == rv) && (group.len));
    /* we should be at the end of the set by now */
    /* save the entries where requested */
    memcpy(((char*)dest + templateEntry->offset), &entries, sizeof(void**));

    return rv;
}

static SECStatus
DecodeExplicit(void* dest,
               const SEC_ASN1Template* templateEntry,
               SECItem* src, PLArenaPool* arena)
{
    SECStatus rv = SECSuccess;
    SECItem subItem;
    SECItem constructed = *src;

    rv = GetItem(&constructed, &subItem, PR_FALSE);

    if (SECSuccess == rv) {
        if (templateEntry->kind & SEC_ASN1_POINTER) {
            rv = DecodePointer(dest, templateEntry, &subItem, arena, PR_TRUE);
        } else {
            rv = DecodeInline(dest, templateEntry, &subItem, arena, PR_TRUE);
        }
    }

    return rv;
}

/* new decoder implementation. This is a recursive function */

static SECStatus
DecodeItem(void* dest,
           const SEC_ASN1Template* templateEntry,
           SECItem* src, PLArenaPool* arena, PRBool checkTag)
{
    SECStatus rv = SECSuccess;
    SECItem temp;
    SECItem mark = { siBuffer, NULL, 0 };
    PRBool pop = PR_FALSE;
    PRBool decode = PR_TRUE;
    PRBool save = PR_FALSE;
    unsigned long kind;
    PRBool match = PR_TRUE;

    PR_ASSERT(src && dest && templateEntry && arena);
#if 0
    if (!src || !dest || !templateEntry || !arena)
    {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        rv = SECFailure;
    }
#endif

    if (SECSuccess == rv) {
        /* do the template validation */
        kind = templateEntry->kind;
        if (!kind) {
            PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
            rv = SECFailure;
        }
    }

    if (SECSuccess == rv) {
#ifdef DEBUG
        if (kind & SEC_ASN1_DEBUG_BREAK) {
            /* when debugging the decoder or a template that fails to
            decode, put SEC_ASN1_DEBUG in the component that gives you
            trouble. The decoder will then get to this block and assert.
            If you want to debug the rest of the code, you can set a
            breakpoint and set dontassert to PR_TRUE, which will let
            you skip over the assert and continue the debugging session
            past it. */
            PRBool dontassert = PR_FALSE;
            PR_ASSERT(dontassert); /* set bkpoint here & set dontassert*/
        }
#endif

        if ((kind & SEC_ASN1_SKIP) ||
            (kind & SEC_ASN1_SAVE)) {
            /* if skipping or saving this component, don't decode it */
            decode = PR_FALSE;
        }

        if (kind & (SEC_ASN1_SAVE | SEC_ASN1_OPTIONAL)) {
            /* if saving this component, or if it is optional, we may not want to
               move past it, so save the position in case we have to rewind */
            mark = *src;
            if (kind & SEC_ASN1_SAVE) {
                save = PR_TRUE;
                if (0 == (kind & SEC_ASN1_SKIP)) {
                    /* we will for sure have to rewind when saving this
                       component and not skipping it. This is true for all
                       legacy uses of SEC_ASN1_SAVE where the following entry
                       in the template would causes the same component to be
                       processed again */
                    pop = PR_TRUE;
                }
            }
        }

        rv = GetItem(src, &temp, PR_TRUE);
    }

    if (SECSuccess == rv) {
        /* now check if the component matches what we expect in the template */

        if (PR_TRUE == checkTag)

        {
            rv = MatchComponentType(templateEntry, &temp, &match, dest);
        }

        if ((SECSuccess == rv) && (PR_TRUE != match)) {
            if (kind & SEC_ASN1_OPTIONAL) {

                /* the optional component is missing. This is not fatal. */
                /* Rewind, don't decode, and don't save */
                pop = PR_TRUE;
                decode = PR_FALSE;
                save = PR_FALSE;
            } else {
                /* a required component is missing. abort */
                PORT_SetError(SEC_ERROR_BAD_DER);
                rv = SECFailure;
            }
        }
    }

    if ((SECSuccess == rv) && (PR_TRUE == decode)) {
        /* the order of processing here is is the tricky part */
        /* we start with our special cases */
        /* first, check the component class */
        if (kind & SEC_ASN1_INLINE) {
            /* decode inline template */
            rv = DecodeInline(dest, templateEntry, &temp, arena, PR_TRUE);
        }

        else if (kind & SEC_ASN1_EXPLICIT) {
            rv = DecodeExplicit(dest, templateEntry, &temp, arena);
        } else if ((SEC_ASN1_UNIVERSAL != (kind & SEC_ASN1_CLASS_MASK)) &&

                   (!(kind & SEC_ASN1_EXPLICIT))) {

            /* decode implicitly tagged components */
            rv = DecodeImplicit(dest, templateEntry, &temp, arena);
        } else if (kind & SEC_ASN1_POINTER) {
            rv = DecodePointer(dest, templateEntry, &temp, arena, PR_TRUE);
        } else if (kind & SEC_ASN1_CHOICE) {
            rv = DecodeChoice(dest, templateEntry, &temp, arena);
        } else if (kind & SEC_ASN1_ANY) {
            /* catch-all ANY type, don't decode */
            save = PR_TRUE;
            if (kind & SEC_ASN1_INNER) {
                /* skip the tag and length */
                SECItem newtemp = temp;
                rv = GetItem(&newtemp, &temp, PR_FALSE);
            }
        } else if (kind & SEC_ASN1_GROUP) {
            if ((SEC_ASN1_SEQUENCE == (kind & SEC_ASN1_TAGNUM_MASK)) ||
                (SEC_ASN1_SET == (kind & SEC_ASN1_TAGNUM_MASK))) {
                rv = DecodeGroup(dest, templateEntry, &temp, arena);
            } else {
                /* a group can only be a SET OF or SEQUENCE OF */
                PORT_SetError(SEC_ERROR_BAD_TEMPLATE);
                rv = SECFailure;
            }
        } else if (SEC_ASN1_SEQUENCE == (kind & SEC_ASN1_TAGNUM_MASK)) {
            /* plain SEQUENCE */
            rv = DecodeSequence(dest, templateEntry, &temp, arena);
        } else {
            /* handle all other types as "save" */
            /* we should only get here for primitive universal types */
            SECItem newtemp = temp;
            rv = GetItem(&newtemp, &temp, PR_FALSE);
            save = PR_TRUE;
            if ((SECSuccess == rv) &&
                SEC_ASN1_UNIVERSAL == (kind & SEC_ASN1_CLASS_MASK)) {
                unsigned long tagnum = kind & SEC_ASN1_TAGNUM_MASK;
                if (temp.len == 0 && (tagnum == SEC_ASN1_BOOLEAN ||
                                      tagnum == SEC_ASN1_INTEGER ||
                                      tagnum == SEC_ASN1_BIT_STRING ||
                                      tagnum == SEC_ASN1_OBJECT_ID ||
                                      tagnum == SEC_ASN1_ENUMERATED ||
                                      tagnum == SEC_ASN1_UTC_TIME ||
                                      tagnum == SEC_ASN1_GENERALIZED_TIME)) {
                    /* these types MUST have at least one content octet */
                    PORT_SetError(SEC_ERROR_BAD_DER);
                    rv = SECFailure;
                } else
                    switch (tagnum) {
                        /* special cases of primitive types */
                        case SEC_ASN1_INTEGER: {
                            /* remove leading zeroes if the caller requested
                               siUnsignedInteger
                               This is to allow RSA key operations to work */
                            SECItem* destItem = (SECItem*)((char*)dest +
                                                           templateEntry->offset);
                            if (destItem && (siUnsignedInteger == destItem->type)) {
                                while (temp.len > 1 && temp.data[0] == 0) { /* leading 0 */
                                    temp.data++;
                                    temp.len--;
                                }
                            }
                            break;
                        }

                        case SEC_ASN1_BIT_STRING: {
                            /* change the length in the SECItem to be the number
                               of bits */
                            temp.len = (temp.len - 1) * 8 - (temp.data[0] & 0x7);
                            temp.data++;
                            break;
                        }

                        default: {
                            break;
                        }
                    }
            }
        }
    }

    if ((SECSuccess == rv) && (PR_TRUE == save)) {
        SECItem* destItem = (SECItem*)((char*)dest + templateEntry->offset);
        if (destItem) {
            /* we leave the type alone in the destination SECItem.
               If part of the destination was allocated by the decoder, in
               cases of POINTER, SET OF and SEQUENCE OF, then type is set to
               siBuffer due to the use of PORT_ArenaZAlloc*/
            destItem->data = temp.len ? temp.data : NULL;
            destItem->len = temp.len;
        } else {
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            rv = SECFailure;
        }
    }

    if (PR_TRUE == pop) {
        /* we don't want to move ahead, so restore the position */
        *src = mark;
    }
    return rv;
}

/* the function below is the public one */

SECStatus
SEC_QuickDERDecodeItem(PLArenaPool* arena, void* dest,
                       const SEC_ASN1Template* templateEntry,
                       const SECItem* src)
{
    SECStatus rv = SECSuccess;
    SECItem newsrc;

    if (!arena || !templateEntry || !src) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        rv = SECFailure;
    }

    if (SECSuccess == rv) {
        newsrc = *src;
        rv = DecodeItem(dest, templateEntry, &newsrc, arena, PR_TRUE);
        if (SECSuccess == rv && newsrc.len) {
            rv = SECFailure;
            PORT_SetError(SEC_ERROR_EXTRA_INPUT);
        }
    }

    return rv;
}
