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

#ifndef BUILTINS_H
#include "builtins.h"
#endif /* BUILTINS_H */

/*
 * builtins/find.c
 *
 * This file implements the NSSCKMDFindObjects object for the
 * "builtin objects" cryptoki module.
 */

struct builtinsFOStr {
    NSSArena *arena;
    CK_ULONG n;
    CK_ULONG i;
    builtinsInternalObject **objs;
};

static void
builtins_mdFindObjects_Final(
    NSSCKMDFindObjects *mdFindObjects,
    NSSCKFWFindObjects *fwFindObjects,
    NSSCKMDSession *mdSession,
    NSSCKFWSession *fwSession,
    NSSCKMDToken *mdToken,
    NSSCKFWToken *fwToken,
    NSSCKMDInstance *mdInstance,
    NSSCKFWInstance *fwInstance)
{
    struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
    NSSArena *arena = fo->arena;

    nss_ZFreeIf(fo->objs);
    nss_ZFreeIf(fo);
    nss_ZFreeIf(mdFindObjects);
    if ((NSSArena *)NULL != arena) {
        NSSArena_Destroy(arena);
    }

    return;
}

static NSSCKMDObject *
builtins_mdFindObjects_Next(
    NSSCKMDFindObjects *mdFindObjects,
    NSSCKFWFindObjects *fwFindObjects,
    NSSCKMDSession *mdSession,
    NSSCKFWSession *fwSession,
    NSSCKMDToken *mdToken,
    NSSCKFWToken *fwToken,
    NSSCKMDInstance *mdInstance,
    NSSCKFWInstance *fwInstance,
    NSSArena *arena,
    CK_RV *pError)
{
    struct builtinsFOStr *fo = (struct builtinsFOStr *)mdFindObjects->etc;
    builtinsInternalObject *io;

    if (fo->i == fo->n) {
        *pError = CKR_OK;
        return (NSSCKMDObject *)NULL;
    }

    io = fo->objs[fo->i];
    fo->i++;

    return nss_builtins_CreateMDObject(arena, io, pError);
}

static int
builtins_derUnwrapInt(unsigned char *src, int size, unsigned char **dest)
{
    unsigned char *start = src;
    int len = 0;

    if (*src++ != 2) {
        return 0;
    }
    len = *src++;
    if (len & 0x80) {
        int count = len & 0x7f;
        len = 0;

        if (count + 2 > size) {
            return 0;
        }
        while (count-- > 0) {
            len = (len << 8) | *src++;
        }
    }
    if (len + (src - start) != size) {
        return 0;
    }
    *dest = src;
    return len;
}

static CK_BBOOL
builtins_attrmatch(
    CK_ATTRIBUTE_PTR a,
    const NSSItem *b)
{
    PRBool prb;

    if (a->ulValueLen != b->size) {
        /* match a decoded serial number */
        if ((a->type == CKA_SERIAL_NUMBER) && (a->ulValueLen < b->size)) {
            int len;
            unsigned char *data = NULL;

            len = builtins_derUnwrapInt(b->data, b->size, &data);
            if (data &&
                (len == a->ulValueLen) &&
                nsslibc_memequal(a->pValue, data, len, (PRStatus *)NULL)) {
                return CK_TRUE;
            }
        }
        return CK_FALSE;
    }

    prb = nsslibc_memequal(a->pValue, b->data, b->size, (PRStatus *)NULL);

    if (PR_TRUE == prb) {
        return CK_TRUE;
    } else {
        return CK_FALSE;
    }
}

static CK_BBOOL
builtins_match(
    CK_ATTRIBUTE_PTR pTemplate,
    CK_ULONG ulAttributeCount,
    builtinsInternalObject *o)
{
    CK_ULONG i;

    for (i = 0; i < ulAttributeCount; i++) {
        CK_ULONG j;

        for (j = 0; j < o->n; j++) {
            if (o->types[j] == pTemplate[i].type) {
                if (CK_FALSE == builtins_attrmatch(&pTemplate[i], &o->items[j])) {
                    return CK_FALSE;
                } else {
                    break;
                }
            }
        }

        if (j == o->n) {
            /* Loop ran to the end: no matching attribute */
            return CK_FALSE;
        }
    }

    /* Every attribute passed */
    return CK_TRUE;
}

NSS_IMPLEMENT NSSCKMDFindObjects *
nss_builtins_FindObjectsInit(
    NSSCKFWSession *fwSession,
    CK_ATTRIBUTE_PTR pTemplate,
    CK_ULONG ulAttributeCount,
    CK_RV *pError)
{
    /* This could be made more efficient.  I'm rather rushed. */
    NSSArena *arena;
    NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL;
    struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL;

/*
   * 99% of the time we get 0 or 1 matches. So we start with a small
   * stack-allocated array to hold the matches and switch to a heap-allocated
   * array later if the number of matches exceeds STACK_BUF_LENGTH.
   */
#define STACK_BUF_LENGTH 1
    builtinsInternalObject *stackTemp[STACK_BUF_LENGTH];
    builtinsInternalObject **temp = stackTemp;
    PRBool tempIsHeapAllocated = PR_FALSE;
    PRUint32 i;

    arena = NSSArena_Create();
    if ((NSSArena *)NULL == arena) {
        goto loser;
    }

    rv = nss_ZNEW(arena, NSSCKMDFindObjects);
    if ((NSSCKMDFindObjects *)NULL == rv) {
        *pError = CKR_HOST_MEMORY;
        goto loser;
    }

    fo = nss_ZNEW(arena, struct builtinsFOStr);
    if ((struct builtinsFOStr *)NULL == fo) {
        *pError = CKR_HOST_MEMORY;
        goto loser;
    }

    fo->arena = arena;
    /* fo->n and fo->i are already zero */

    rv->etc = (void *)fo;
    rv->Final = builtins_mdFindObjects_Final;
    rv->Next = builtins_mdFindObjects_Next;
    rv->null = (void *)NULL;

    for (i = 0; i < nss_builtins_nObjects; i++) {
        builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i];

        if (CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o)) {
            if (fo->n == STACK_BUF_LENGTH) {
                /* Switch from the small stack array to a heap-allocated array large
         * enough to handle matches in all remaining cases. */
                temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *,
                                     fo->n + nss_builtins_nObjects - i);
                if ((builtinsInternalObject **)NULL == temp) {
                    *pError =
                        CKR_HOST_MEMORY;
                    goto loser;
                }
                tempIsHeapAllocated = PR_TRUE;
                (void)nsslibc_memcpy(temp, stackTemp,
                                     sizeof(builtinsInternalObject *) * fo->n);
            }

            temp[fo->n] = o;
            fo->n++;
        }
    }

    fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n);
    if ((builtinsInternalObject **)NULL == fo->objs) {
        *pError = CKR_HOST_MEMORY;
        goto loser;
    }

    (void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n);
    if (tempIsHeapAllocated) {
        nss_ZFreeIf(temp);
        temp = (builtinsInternalObject **)NULL;
    }

    return rv;

loser:
    if (tempIsHeapAllocated) {
        nss_ZFreeIf(temp);
    }
    nss_ZFreeIf(fo);
    nss_ZFreeIf(rv);
    if ((NSSArena *)NULL != arena) {
        NSSArena_Destroy(arena);
    }
    return (NSSCKMDFindObjects *)NULL;
}
