Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/security/nss/lib/util/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 13 kB image not shown  

Quelle  derenc.c   Sprache: C

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


#include "secder.h"
#include "secerr.h"

#if 0
/*
 * Generic templates for individual/simple items.
 */


DERTemplate SECAnyTemplate[] = {
    { DER_ANY,
   0, NULL, sizeof(SECItem) }
};

DERTemplate SECBitStringTemplate[] = {
    { DER_BIT_STRING,
   0, NULL, sizeof(SECItem) }
};

DERTemplate SECBooleanTemplate[] = {
    { DER_BOOLEAN,
   0, NULL, sizeof(SECItem) }
};

DERTemplate SECIA5StringTemplate[] = {
    { DER_IA5_STRING,
   0, NULL, sizeof(SECItem) }
};

DERTemplate SECIntegerTemplate[] = {
    { DER_INTEGER,
   0, NULL, sizeof(SECItem) }
};

DERTemplate SECNullTemplate[] = {
    { DER_NULL,
   0, NULL, sizeof(SECItem) }
};

DERTemplate SECObjectIDTemplate[] = {
    { DER_OBJECT_ID,
   0, NULL, sizeof(SECItem) }
};

DERTemplate SECOctetStringTemplate[] = {
    { DER_OCTET_STRING,
   0, NULL, sizeof(SECItem) }
};

DERTemplate SECPrintableStringTemplate[] = {
    { DER_PRINTABLE_STRING,
   0, NULL, sizeof(SECItem) }
};

DERTemplate SECT61StringTemplate[] = {
    { DER_T61_STRING,
   0, NULL, sizeof(SECItem) }
};

DERTemplate SECUTCTimeTemplate[] = {
    { DER_UTC_TIME,
   0, NULL, sizeof(SECItem) }
};

#endif

static int
header_length(DERTemplate *dtemplate, PRUint32 contents_len)
{
    PRUint32 len;
    unsigned long encode_kind, under_kind;
    PRBool explicit, optional, universal;

    encode_kind = dtemplate->kind;

    explicit = (encode_kind & DER_EXPLICIT) ? PR_TRUE : PR_FALSE;
    optional = (encode_kind & DER_OPTIONAL) ? PR_TRUE : PR_FALSE;
    universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
                    ? PR_TRUE
                    : PR_FALSE;

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

    if (encode_kind & DER_POINTER) {
        if (dtemplate->sub != NULL) {
            under_kind = dtemplate->sub->kind;
            if (universal) {
                encode_kind = under_kind;
            }
        } else if (universal) {
            under_kind = encode_kind & ~DER_POINTER;
        } else {
            under_kind = dtemplate->arg;
        }
    } else if (encode_kind & DER_INLINE) {
        PORT_Assert(dtemplate->sub != NULL);
        under_kind = dtemplate->sub->kind;
        if (universal) {
            encode_kind = under_kind;
        }
    } else if (universal) {
        under_kind = encode_kind;
    } else {
        under_kind = dtemplate->arg;
    }

    /* This is only used in decoding; it plays no part in encoding.  */
    if (under_kind & DER_DERPTR)
        return 0;

    /* No header at all for an "empty" optional.  */
    if ((contents_len == 0) && optional)
        return 0;

    /* And no header for a full DER_ANY.  */
    if (encode_kind & DER_ANY)
        return 0;

    /*
     * The common case: one octet for identifier and as many octets
     * as necessary to hold the content length.
     */

    len = 1 + DER_LengthLength(contents_len);

    /* Account for the explicit wrapper, if necessary.  */
    if (explicit) {
#if 0 /*                                                         \
       * Well, I was trying to do something useful, but these    \
       * assertions are too restrictive on valid templates.      \
       * I wanted to make sure that the top-level "kind" of      \
       * a template does not also specify DER_EXPLICIT, which    \
       * should only modify a component field.  Maybe later      \
       * I can figure out a better way to detect such a problem, \
       * but for now I must remove these checks altogether.      \
       */

 /*
 * This modifier applies only to components of a set or sequence;
 * it should never be used on a set/sequence itself -- confirm.
 */

 PORT_Assert (under_kind != DER_SEQUENCE);
 PORT_Assert (under_kind != DER_SET);
#endif

        len += 1 + DER_LengthLength(len + contents_len);
    }

    return len;
}

static PRUint32
contents_length(DERTemplate *dtemplate, void *src)
{
    PRUint32 len;
    unsigned long encode_kind, under_kind;
    PRBool universal;

    PORT_Assert(src != NULL);

    encode_kind = dtemplate->kind;

    universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
                    ? PR_TRUE
                    : PR_FALSE;
    encode_kind &= ~DER_OPTIONAL;

    if (encode_kind & DER_POINTER) {
        src = *(void **)src;
        if (src == NULL) {
            return 0;
        }
        if (dtemplate->sub != NULL) {
            dtemplate = dtemplate->sub;
            under_kind = dtemplate->kind;
            src = (void *)((char *)src + dtemplate->offset);
        } else if (universal) {
            under_kind = encode_kind & ~DER_POINTER;
        } else {
            under_kind = dtemplate->arg;
        }
    } else if (encode_kind & DER_INLINE) {
        PORT_Assert(dtemplate->sub != NULL);
        dtemplate = dtemplate->sub;
        under_kind = dtemplate->kind;
        src = (void *)((char *)src + dtemplate->offset);
    } else if (universal) {
        under_kind = encode_kind;
    } else {
        under_kind = dtemplate->arg;
    }

    /* Having any of these bits is not expected here...  */
    PORT_Assert((under_kind & (DER_EXPLICIT | DER_INLINE | DER_OPTIONAL | DER_POINTER | DER_SKIP)) == 0);

    /* This is only used in decoding; it plays no part in encoding.  */
    if (under_kind & DER_DERPTR)
        return 0;

    if (under_kind & DER_INDEFINITE) {
        PRUint32 sub_len;
        void **indp = *(void ***)src;

        if (indp == NULL)
            return 0;

        len = 0;
        under_kind &= ~DER_INDEFINITE;

        if (under_kind == DER_SET || under_kind == DER_SEQUENCE) {
            DERTemplate *tmpt = dtemplate->sub;
            PORT_Assert(tmpt != NULL);

            for (; *indp != NULL; indp++) {
                void *sub_src = (void *)((char *)(*indp) + tmpt->offset);
                sub_len = contents_length(tmpt, sub_src);
                len += sub_len + header_length(tmpt, sub_len);
            }
        } else {
            /*
             * XXX Lisa is not sure this code (for handling, for example,
             * DER_INDEFINITE | DER_OCTET_STRING) is right.
             */

            for (; *indp != NULL; indp++) {
                SECItem *item = (SECItem *)(*indp);
                sub_len = item->len;
                if (under_kind == DER_BIT_STRING) {
                    sub_len = (sub_len + 7) >> 3;
                    /* bit string contents involve an extra octet */
                    if (sub_len)
                        sub_len++;
                }
                if (under_kind != DER_ANY)
                    len += 1 + DER_LengthLength(sub_len);
            }
        }

        return len;
    }

    switch (under_kind) {
        case DER_SEQUENCE:
        case DER_SET: {
            DERTemplate *tmpt;
            void *sub_src;
            PRUint32 sub_len;

            len = 0;
            for (tmpt = dtemplate + 1; tmpt->kind; tmpt++) {
                sub_src = (void *)((char *)src + tmpt->offset);
                sub_len = contents_length(tmpt, sub_src);
                len += sub_len + header_length(tmpt, sub_len);
            }
        } break;

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

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

    return len;
}

static unsigned char *
der_encode(unsigned char *buf, DERTemplate *dtemplate, void *src)
{
    int header_len;
    PRUint32 contents_len;
    unsigned long encode_kind, under_kind;
    PRBool explicit, universal;

    /*
     * First figure out how long the encoding will be.  Do this by
     * traversing the template from top to bottom and accumulating
     * the length of each leaf item.
     */

    contents_len = contents_length(dtemplate, src);
    header_len = header_length(dtemplate, contents_len);

    /*
     * Enough smarts was involved already, so that if both the
     * header and the contents have a length of zero, then we
     * are not doing any encoding for this element.
     */

    if (header_len == 0 && contents_len == 0)
        return buf;

    encode_kind = dtemplate->kind;

    explicit = (encode_kind & DER_EXPLICIT) ? PR_TRUE : PR_FALSE;
    encode_kind &= ~DER_OPTIONAL;
    universal = ((encode_kind & DER_CLASS_MASK) == DER_UNIVERSAL)
                    ? PR_TRUE
                    : PR_FALSE;

    if (encode_kind & DER_POINTER) {
        if (contents_len) {
            src = *(void **)src;
            PORT_Assert(src != NULL);
        }
        if (dtemplate->sub != NULL) {
            dtemplate = dtemplate->sub;
            under_kind = dtemplate->kind;
            if (universal) {
                encode_kind = under_kind;
            }
            src = (void *)((char *)src + dtemplate->offset);
        } else if (universal) {
            under_kind = encode_kind & ~DER_POINTER;
        } else {
            under_kind = dtemplate->arg;
        }
    } else if (encode_kind & DER_INLINE) {
        dtemplate = dtemplate->sub;
        under_kind = dtemplate->kind;
        if (universal) {
            encode_kind = under_kind;
        }
        src = (void *)((char *)src + dtemplate->offset);
    } else if (universal) {
        under_kind = encode_kind;
    } else {
        under_kind = dtemplate->arg;
    }

    if (explicit) {
        buf = DER_StoreHeader(buf, encode_kind,
                              (1 + DER_LengthLength(contents_len) + contents_len));
        encode_kind = under_kind;
    }

    if ((encode_kind & DER_ANY) == 0) { /* DER_ANY already contains header */
        buf = DER_StoreHeader(buf, encode_kind, contents_len);
    }

    /* If no real contents to encode, then we are done.  */
    if (contents_len == 0)
        return buf;

    if (under_kind & DER_INDEFINITE) {
        void **indp;

        indp = *(void ***)src;
        PORT_Assert(indp != NULL);

        under_kind &= ~DER_INDEFINITE;
        if (under_kind == DER_SET || under_kind == DER_SEQUENCE) {
            DERTemplate *tmpt = dtemplate->sub;
            PORT_Assert(tmpt != NULL);
            for (; *indp != NULL; indp++) {
                void *sub_src = (void *)((char *)(*indp) + tmpt->offset);
                buf = der_encode(buf, tmpt, sub_src);
            }
        } else {
            for (; *indp != NULL; indp++) {
                SECItem *item;
                int sub_len;

                item = (SECItem *)(*indp);
                sub_len = item->len;
                if (under_kind == DER_BIT_STRING) {
                    if (sub_len) {
                        int rem;

                        sub_len = (sub_len + 7) >> 3;
                        buf = DER_StoreHeader(buf, under_kind, sub_len + 1);
                        rem = (sub_len << 3) - item->len;
                        *buf++ = rem; /* remaining bits */
                    } else {
                        buf = DER_StoreHeader(buf, under_kind, 0);
                    }
                } else if (under_kind != DER_ANY) {
                    buf = DER_StoreHeader(buf, under_kind, sub_len);
                }
                PORT_Memcpy(buf, item->data, sub_len);
                buf += sub_len;
            }
        }
        return buf;
    }

    switch (under_kind) {
        case DER_SEQUENCE:
        case DER_SET: {
            DERTemplate *tmpt;
            void *sub_src;

            for (tmpt = dtemplate + 1; tmpt->kind; tmpt++) {
                sub_src = (void *)((char *)src + tmpt->offset);
                buf = der_encode(buf, tmpt, sub_src);
            }
        } break;

        case DER_BIT_STRING: {
            SECItem *item;
            int rem;

            /*
             * The contents length includes our extra octet; subtract
             * it off so we just have the real string length there.
             */

            contents_len--;
            item = (SECItem *)src;
            PORT_Assert(contents_len == ((item->len + 7) >> 3));
            rem = (contents_len << 3) - item->len;
            *buf++ = rem; /* remaining bits */
            PORT_Memcpy(buf, item->data, contents_len);
            buf += contents_len;
        } break;

        default: {
            SECItem *item;

            item = (SECItem *)src;
            PORT_Assert(contents_len == item->len);
            PORT_Memcpy(buf, item->data, contents_len);
            buf += contents_len;
        } break;
    }

    return buf;
}

SECStatus
DER_Encode(PLArenaPool *arena, SECItem *dest, DERTemplate *dtemplate, void *src)
{
    unsigned int contents_len, header_len;

    src = (void **)((char *)src + dtemplate->offset);

    /*
     * First figure out how long the encoding will be. Do this by
     * traversing the template from top to bottom and accumulating
     * the length of each leaf item.
     */

    contents_len = contents_length(dtemplate, src);
    header_len = header_length(dtemplate, contents_len);

    dest->len = contents_len + header_len;

    /* Allocate storage to hold the encoding */
    dest->data = (unsigned char *)PORT_ArenaAlloc(arena, dest->len);
    if (dest->data == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }

    /* Now encode into the buffer */
    (void)der_encode(dest->data, dtemplate, src);

    return SECSuccess;
}

Messung V0.5
C=95 H=93 G=93

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.