tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

secasn1u.c (2810B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 /*
      6 * Utility routines to complement the ASN.1 encoding and decoding functions.
      7 */
      8 
      9 #include "secasn1.h"
     10 
     11 /*
     12 * We have a length that needs to be encoded; how many bytes will the
     13 * encoding take?
     14 *
     15 * The rules are that 0 - 0x7f takes one byte (the length itself is the
     16 * entire encoding); everything else takes one plus the number of bytes
     17 * in the length.
     18 */
     19 int
     20 SEC_ASN1LengthLength(unsigned long len)
     21 {
     22    int lenlen = 1;
     23 
     24    if (len > 0x7f) {
     25        do {
     26            lenlen++;
     27            len >>= 8;
     28        } while (len);
     29    }
     30 
     31    return lenlen;
     32 }
     33 
     34 /*
     35 * XXX Move over (and rewrite as appropriate) the rest of the
     36 * stuff in dersubr.c!
     37 */
     38 
     39 /*
     40 * Find the appropriate subtemplate for the given template.
     41 * This may involve calling a "chooser" function, or it may just
     42 * be right there.  In either case, it is expected to *have* a
     43 * subtemplate; this is asserted in debug builds (in non-debug
     44 * builds, NULL will be returned).
     45 *
     46 * "thing" is a pointer to the structure being encoded/decoded
     47 * "encoding", when true, means that we are in the process of encoding
     48 *	(as opposed to in the process of decoding)
     49 */
     50 const SEC_ASN1Template *
     51 SEC_ASN1GetSubtemplate(const SEC_ASN1Template *theTemplate, void *thing,
     52                       PRBool encoding)
     53 {
     54    const SEC_ASN1Template *subt = NULL;
     55 
     56    PORT_Assert(theTemplate->sub != NULL);
     57    if (theTemplate->sub != NULL) {
     58        if (theTemplate->kind & SEC_ASN1_DYNAMIC) {
     59            SEC_ASN1TemplateChooserPtr chooserp;
     60 
     61            chooserp = *(SEC_ASN1TemplateChooserPtr *)theTemplate->sub;
     62            if (chooserp) {
     63                if (thing != NULL)
     64                    thing = (char *)thing - theTemplate->offset;
     65                subt = (*chooserp)(thing, encoding);
     66            }
     67        } else {
     68            subt = (SEC_ASN1Template *)theTemplate->sub;
     69        }
     70    }
     71    return subt;
     72 }
     73 
     74 PRBool
     75 SEC_ASN1IsTemplateSimple(const SEC_ASN1Template *theTemplate)
     76 {
     77    if (!theTemplate) {
     78        return PR_TRUE; /* it doesn't get any simpler than NULL */
     79    }
     80    /* only templates made of one primitive type or a choice of primitive
     81       types are considered simple */
     82    if (!(theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK))) {
     83        return PR_TRUE; /* primitive type */
     84    }
     85    if (!(theTemplate->kind & SEC_ASN1_CHOICE)) {
     86        return PR_FALSE; /* no choice means not simple */
     87    }
     88    while (++theTemplate && theTemplate->kind) {
     89        if (theTemplate->kind & (~SEC_ASN1_TAGNUM_MASK)) {
     90            return PR_FALSE; /* complex type */
     91        }
     92    }
     93    return PR_TRUE; /* choice of primitive types */
     94 }