tor-browser

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

bfind.c (6824B)


      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 #ifndef BUILTINS_H
      6 #include "builtins.h"
      7 #endif /* BUILTINS_H */
      8 
      9 /*
     10 * builtins/find.c
     11 *
     12 * This file implements the NSSCKMDFindObjects object for the
     13 * "builtin objects" cryptoki module.
     14 */
     15 
     16 struct builtinsFOStr {
     17    NSSArena *arena;
     18    CK_ULONG n;
     19    CK_ULONG i;
     20    builtinsInternalObject **objs;
     21 };
     22 
     23 static void
     24 builtins_mdFindObjects_Final(
     25    NSSCKMDFindObjects *mdFindObjects,
     26    NSSCKFWFindObjects *fwFindObjects,
     27    NSSCKMDSession *mdSession,
     28    NSSCKFWSession *fwSession,
     29    NSSCKMDToken *mdToken,
     30    NSSCKFWToken *fwToken,
     31    NSSCKMDInstance *mdInstance,
     32    NSSCKFWInstance *fwInstance)
     33 {
     34    struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
     35    NSSArena *arena = fo->arena;
     36 
     37    nss_ZFreeIf(fo->objs);
     38    nss_ZFreeIf(fo);
     39    nss_ZFreeIf(mdFindObjects);
     40    if ((NSSArena *)NULL != arena) {
     41        NSSArena_Destroy(arena);
     42    }
     43 
     44    return;
     45 }
     46 
     47 static NSSCKMDObject *
     48 builtins_mdFindObjects_Next(
     49    NSSCKMDFindObjects *mdFindObjects,
     50    NSSCKFWFindObjects *fwFindObjects,
     51    NSSCKMDSession *mdSession,
     52    NSSCKFWSession *fwSession,
     53    NSSCKMDToken *mdToken,
     54    NSSCKFWToken *fwToken,
     55    NSSCKMDInstance *mdInstance,
     56    NSSCKFWInstance *fwInstance,
     57    NSSArena *arena,
     58    CK_RV *pError)
     59 {
     60    struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
     61    builtinsInternalObject *io;
     62 
     63    if (fo->i == fo->n) {
     64        *pError = CKR_OK;
     65        return (NSSCKMDObject *)NULL;
     66    }
     67 
     68    io = fo->objs[fo->i];
     69    fo->i++;
     70 
     71    return nss_builtins_CreateMDObject(arena, io, pError);
     72 }
     73 
     74 static int
     75 builtins_derUnwrapInt(unsigned char *src, int size, unsigned char **dest)
     76 {
     77    unsigned char *start = src;
     78    int len = 0;
     79 
     80    if (*src++ != 2) {
     81        return 0;
     82    }
     83    len = *src++;
     84    if (len & 0x80) {
     85        int count = len & 0x7f;
     86        len = 0;
     87 
     88        if (count + 2 > size) {
     89            return 0;
     90        }
     91        while (count-- > 0) {
     92            len = (len << 8) | *src++;
     93        }
     94    }
     95    if (len + (src - start) != size) {
     96        return 0;
     97    }
     98    *dest = src;
     99    return len;
    100 }
    101 
    102 static CK_BBOOL
    103 builtins_attrmatch(
    104    CK_ATTRIBUTE_PTR a,
    105    const NSSItem *b)
    106 {
    107    PRBool prb;
    108 
    109    if (a->ulValueLen != b->size) {
    110        /* match a decoded serial number */
    111        if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
    112            int len;
    113            unsigned char *data = NULL;
    114 
    115            len = builtins_derUnwrapInt(b->data, b->size, &data);
    116            if (data &&
    117                (len == a->ulValueLen) &&
    118                nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
    119                return CK_TRUE;
    120            }
    121        }
    122        return CK_FALSE;
    123    }
    124 
    125    prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);
    126 
    127    if (PR_TRUE == prb) {
    128        return CK_TRUE;
    129    } else {
    130        return CK_FALSE;
    131    }
    132 }
    133 
    134 static CK_BBOOL
    135 builtins_match(
    136    CK_ATTRIBUTE_PTR pTemplate,
    137    CK_ULONG ulAttributeCount,
    138    builtinsInternalObject *o)
    139 {
    140    CK_ULONG i;
    141 
    142    for (i = 0; i < ulAttributeCount; i++) {
    143        CK_ULONG j;
    144 
    145        for (j = 0; j < o->n; j++) {
    146            if (o->types[j] == pTemplate[i].type) {
    147                if (CK_FALSE == builtins_attrmatch(&pTemplate[i], &o->items[j])) {
    148                    return CK_FALSE;
    149                } else {
    150                    break;
    151                }
    152            }
    153        }
    154 
    155        if (j == o->n) {
    156            /* Loop ran to the end: no matching attribute */
    157            return CK_FALSE;
    158        }
    159    }
    160 
    161    /* Every attribute passed */
    162    return CK_TRUE;
    163 }
    164 
    165 NSS_IMPLEMENT NSSCKMDFindObjects *
    166 nss_builtins_FindObjectsInit(
    167    NSSCKFWSession *fwSession,
    168    CK_ATTRIBUTE_PTR pTemplate,
    169    CK_ULONG ulAttributeCount,
    170    CK_RV *pError)
    171 {
    172    /* This could be made more efficient.  I'm rather rushed. */
    173    NSSArena *arena;
    174    NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
    175    struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL;
    176 
    177 /*
    178 * 99% of the time we get 0 or 1 matches. So we start with a small
    179 * stack-allocated array to hold the matches and switch to a heap-allocated
    180 * array later if the number of matches exceeds STACK_BUF_LENGTH.
    181 */
    182 #define STACK_BUF_LENGTH 1
    183    builtinsInternalObject *stackTemp[STACK_BUF_LENGTH];
    184    builtinsInternalObject **temp = stackTemp;
    185    PRBool tempIsHeapAllocated = PR_FALSE;
    186    PRUint32 i;
    187 
    188    arena = NSSArena_Create();
    189    if ((NSSArena *)NULL == arena) {
    190        goto loser;
    191    }
    192 
    193    rv = nss_ZNEW(arena, NSSCKMDFindObjects);
    194    if ((NSSCKMDFindObjects *)NULL == rv) {
    195        *pError = CKR_HOST_MEMORY;
    196        goto loser;
    197    }
    198 
    199    fo = nss_ZNEW(arena, struct builtinsFOStr);
    200    if ((struct builtinsFOStr *)NULL == fo) {
    201        *pError = CKR_HOST_MEMORY;
    202        goto loser;
    203    }
    204 
    205    fo->arena = arena;
    206    /* fo->n and fo->i are already zero */
    207 
    208    rv->etc = (void *)fo;
    209    rv->Final = builtins_mdFindObjects_Final;
    210    rv->Next = builtins_mdFindObjects_Next;
    211    rv->null = (void *)NULL;
    212 
    213    for (i = 0; i < nss_builtins_nObjects; i++) {
    214        builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i];
    215 
    216        if (CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o)) {
    217            if (fo->n == STACK_BUF_LENGTH) {
    218                /* Switch from the small stack array to a heap-allocated array large
    219                 * enough to handle matches in all remaining cases. */
    220                temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *,
    221                                     fo->n + nss_builtins_nObjects - i);
    222                if ((builtinsInternalObject **)NULL == temp) {
    223                    *pError =
    224                        CKR_HOST_MEMORY;
    225                    goto loser;
    226                }
    227                tempIsHeapAllocated = PR_TRUE;
    228                (void)nsslibc_memcpy(temp, stackTemp,
    229                                     sizeof(builtinsInternalObject *) * fo->n);
    230            }
    231 
    232            temp[fo->n] = o;
    233            fo->n++;
    234        }
    235    }
    236 
    237    fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n);
    238    if ((builtinsInternalObject **)NULL == fo->objs) {
    239        *pError = CKR_HOST_MEMORY;
    240        goto loser;
    241    }
    242 
    243    (void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n);
    244    if (tempIsHeapAllocated) {
    245        nss_ZFreeIf(temp);
    246        temp = (builtinsInternalObject **)NULL;
    247    }
    248 
    249    return rv;
    250 
    251 loser:
    252    if (tempIsHeapAllocated) {
    253        nss_ZFreeIf(temp);
    254    }
    255    nss_ZFreeIf(fo);
    256    nss_ZFreeIf(rv);
    257    if ((NSSArena *)NULL != arena) {
    258        NSSArena_Destroy(arena);
    259    }
    260    return (NSSCKMDFindObjects *)NULL;
    261 }