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

/*
 * CMS User Define Types
 */

#include "cmslocal.h"

#include "prinit.h"
#include "pk11func.h"
#include "secitem.h"
#include "secoid.h"
#include "secerr.h"
#include "nss.h"

typedef struct nsscmstypeInfoStr nsscmstypeInfo;
struct nsscmstypeInfoStr {
    SECOidTag type;
    SEC_ASN1Template *template;
    size_t size;
    PRBool isData;
    NSSCMSGenericWrapperDataDestroy destroy;
    NSSCMSGenericWrapperDataCallback decode_before;
    NSSCMSGenericWrapperDataCallback decode_after;
    NSSCMSGenericWrapperDataCallback decode_end;
    NSSCMSGenericWrapperDataCallback encode_start;
    NSSCMSGenericWrapperDataCallback encode_before;
    NSSCMSGenericWrapperDataCallback encode_after;
};

/* make sure the global tables are only initialized once */
static PRCallOnceType nsscmstypeOnce;
static PRCallOnceType nsscmstypeClearOnce;
/* lock for adding a new entry */
static PRLock *nsscmstypeAddLock;
/* lock for the hash table */
static PRLock *nsscmstypeHashLock;
/* the hash table itself */
static PLHashTable *nsscmstypeHash;
/* arena to hold all the hash table data */
static PLArenaPool *nsscmstypeArena;

/*
 * clean up our global tables
 */
SECStatus
nss_cmstype_shutdown(void *appData, void *reserved)
{
    if (nsscmstypeHashLock) {
        PR_Lock(nsscmstypeHashLock);
    }
    if (nsscmstypeHash) {
        PL_HashTableDestroy(nsscmstypeHash);
        nsscmstypeHash = NULL;
    }
    if (nsscmstypeArena) {
        PORT_FreeArena(nsscmstypeArena, PR_FALSE);
        nsscmstypeArena = NULL;
    }
    if (nsscmstypeAddLock) {
        PR_DestroyLock(nsscmstypeAddLock);
    }
    if (nsscmstypeHashLock) {
        PRLock *oldLock = nsscmstypeHashLock;
        nsscmstypeHashLock = NULL;
        PR_Unlock(oldLock);
        PR_DestroyLock(oldLock);
    }

    /* don't clear out the PR_ONCE data if we failed our inital call */
    if (appData == NULL) {
        nsscmstypeOnce = nsscmstypeClearOnce;
    }
    return SECSuccess;
}

static PLHashNumber
nss_cmstype_hash_key(const void *key)
{
    return (PLHashNumber)((char *)key - (char *)NULL);
}

static PRIntn
nss_cmstype_compare_keys(const void *v1, const void *v2)
{
    PLHashNumber value1 = nss_cmstype_hash_key(v1);
    PLHashNumber value2 = nss_cmstype_hash_key(v2);

    return (value1 == value2);
}

/*
 * initialize our hash tables, called once on the first attemat to register
 * a new SMIME type.
 */
static PRStatus
nss_cmstype_init(void)
{
    SECStatus rv;

    nsscmstypeHashLock = PR_NewLock();
    if (nsscmstypeHashLock == NULL) {
        return PR_FAILURE;
    }
    nsscmstypeAddLock = PR_NewLock();
    if (nsscmstypeHashLock == NULL) {
        goto fail;
    }
    nsscmstypeHash = PL_NewHashTable(64, nss_cmstype_hash_key,
                                     nss_cmstype_compare_keys,
                                     PL_CompareValues, NULL, NULL);
    if (nsscmstypeHash == NULL) {
        goto fail;
    }
    nsscmstypeArena = PORT_NewArena(2048);
    if (nsscmstypeArena == NULL) {
        goto fail;
    }
    rv = NSS_RegisterShutdown(nss_cmstype_shutdown, NULL);
    if (rv != SECSuccess) {
        goto fail;
    }
    return PR_SUCCESS;

fail:
    nss_cmstype_shutdown(&nsscmstypeOnce, NULL);
    return PR_FAILURE;
}

/*
 * look up and registered SIME type
 */
static const nsscmstypeInfo *
nss_cmstype_lookup(SECOidTag type)
{
    nsscmstypeInfo *typeInfo = NULL;
    ;
    if (!nsscmstypeHash) {
        return NULL;
    }
    PR_Lock(nsscmstypeHashLock);
    if (nsscmstypeHash) {
        typeInfo = PL_HashTableLookupConst(nsscmstypeHash, (void *)type);
    }
    PR_Unlock(nsscmstypeHashLock);
    return typeInfo;
}

/*
 * add a new type to the SMIME type table
 */
static SECStatus
nss_cmstype_add(SECOidTag type, nsscmstypeInfo *typeinfo)
{
    PLHashEntry *entry;

    if (!nsscmstypeHash) {
        /* assert? this shouldn't happen */
        return SECFailure;
    }
    PR_Lock(nsscmstypeHashLock);
    /* this is really paranoia. If we really are racing nsscmstypeHash, we'll
     * also be racing nsscmstypeHashLock... */
    if (!nsscmstypeHash) {
        PR_Unlock(nsscmstypeHashLock);
        return SECFailure;
    }
    entry = PL_HashTableAdd(nsscmstypeHash, (void *)type, typeinfo);
    PR_Unlock(nsscmstypeHashLock);
    return entry ? SECSuccess : SECFailure;
}

/* helper functions to manage new content types
 */

PRBool
NSS_CMSType_IsWrapper(SECOidTag type)
{
    const nsscmstypeInfo *typeInfo = NULL;

    switch (type) {
        case SEC_OID_PKCS7_SIGNED_DATA:
        case SEC_OID_PKCS7_ENVELOPED_DATA:
        case SEC_OID_PKCS7_DIGESTED_DATA:
        case SEC_OID_PKCS7_ENCRYPTED_DATA:
            return PR_TRUE;
        default:
            typeInfo = nss_cmstype_lookup(type);
            if (typeInfo && !typeInfo->isData) {
                return PR_TRUE;
            }
    }
    return PR_FALSE;
}

PRBool
NSS_CMSType_IsData(SECOidTag type)
{
    const nsscmstypeInfo *typeInfo = NULL;

    switch (type) {
        case SEC_OID_PKCS7_DATA:
            return PR_TRUE;
        default:
            typeInfo = nss_cmstype_lookup(type);
            if (typeInfo && typeInfo->isData) {
                return PR_TRUE;
            }
    }
    return PR_FALSE;
}

const SEC_ASN1Template *
NSS_CMSType_GetTemplate(SECOidTag type)
{
    const nsscmstypeInfo *typeInfo = nss_cmstype_lookup(type);

    if (typeInfo && typeInfo->template) {
        return typeInfo->template;
    }
    return SEC_ASN1_GET(SEC_PointerToOctetStringTemplate);
}

size_t
NSS_CMSType_GetContentSize(SECOidTag type)
{
    const nsscmstypeInfo *typeInfo = nss_cmstype_lookup(type);

    if (typeInfo) {
        return typeInfo->size;
    }
    return sizeof(SECItem *);
}

void
NSS_CMSGenericWrapperData_Destroy(SECOidTag type, NSSCMSGenericWrapperData *gd)
{
    const nsscmstypeInfo *typeInfo = nss_cmstype_lookup(type);

    if (typeInfo && (typeInfo->destroy) && (gd != NULL)) {
        (*typeInfo->destroy)(gd);
    }
}

SECStatus
NSS_CMSGenericWrapperData_Decode_BeforeData(SECOidTag type,
                                            NSSCMSGenericWrapperData *gd)
{
    const nsscmstypeInfo *typeInfo;

    /* short cut common case */
    if (type == SEC_OID_PKCS7_DATA) {
        return SECSuccess;
    }

    typeInfo = nss_cmstype_lookup(type);
    if (typeInfo) {
        if (typeInfo->decode_before) {
            return (*typeInfo->decode_before)(gd);
        }
        /* decoder ops optional for data tags */
        if (typeInfo->isData) {
            return SECSuccess;
        }
    }
    /* expected a function, but none existed */
    return SECFailure;
}

SECStatus
NSS_CMSGenericWrapperData_Decode_AfterData(SECOidTag type,
                                           NSSCMSGenericWrapperData *gd)
{
    const nsscmstypeInfo *typeInfo;

    /* short cut common case */
    if (type == SEC_OID_PKCS7_DATA) {
        return SECSuccess;
    }

    typeInfo = nss_cmstype_lookup(type);
    if (typeInfo) {
        if (typeInfo->decode_after) {
            return (*typeInfo->decode_after)(gd);
        }
        /* decoder ops optional for data tags */
        if (typeInfo->isData) {
            return SECSuccess;
        }
    }
    /* expected a function, but none existed */
    return SECFailure;
}

SECStatus
NSS_CMSGenericWrapperData_Decode_AfterEnd(SECOidTag type,
                                          NSSCMSGenericWrapperData *gd)
{
    const nsscmstypeInfo *typeInfo;

    /* short cut common case */
    if (type == SEC_OID_PKCS7_DATA) {
        return SECSuccess;
    }

    typeInfo = nss_cmstype_lookup(type);
    if (typeInfo) {
        if (typeInfo->decode_end) {
            return (*typeInfo->decode_end)(gd);
        }
        /* decoder ops optional for data tags */
        if (typeInfo->isData) {
            return SECSuccess;
        }
    }
    /* expected a function, but none existed */
    return SECFailure;
}

SECStatus
NSS_CMSGenericWrapperData_Encode_BeforeStart(SECOidTag type,
                                             NSSCMSGenericWrapperData *gd)
{
    const nsscmstypeInfo *typeInfo;

    /* short cut common case */
    if (type == SEC_OID_PKCS7_DATA) {
        return SECSuccess;
    }

    typeInfo = nss_cmstype_lookup(type);
    if (typeInfo) {
        if (typeInfo->encode_start) {
            return (*typeInfo->encode_start)(gd);
        }
        /* decoder ops optional for data tags */
        if (typeInfo->isData) {
            return SECSuccess;
        }
    }
    /* expected a function, but none existed */
    return SECFailure;
}

SECStatus
NSS_CMSGenericWrapperData_Encode_BeforeData(SECOidTag type,
                                            NSSCMSGenericWrapperData *gd)
{
    const nsscmstypeInfo *typeInfo;

    /* short cut common case */
    if (type == SEC_OID_PKCS7_DATA) {
        return SECSuccess;
    }

    typeInfo = nss_cmstype_lookup(type);
    if (typeInfo) {
        if (typeInfo->encode_before) {
            return (*typeInfo->encode_before)(gd);
        }
        /* decoder ops optional for data tags */
        if (typeInfo->isData) {
            return SECSuccess;
        }
    }
    /* expected a function, but none existed */
    return SECFailure;
}

SECStatus
NSS_CMSGenericWrapperData_Encode_AfterData(SECOidTag type,
                                           NSSCMSGenericWrapperData *gd)
{
    const nsscmstypeInfo *typeInfo;

    /* short cut common case */
    if (type == SEC_OID_PKCS7_DATA) {
        return SECSuccess;
    }

    typeInfo = nss_cmstype_lookup(type);
    if (typeInfo) {
        if (typeInfo->encode_after) {
            return (*typeInfo->encode_after)(gd);
        }
        /* decoder ops optional for data tags */
        if (typeInfo->isData) {
            return SECSuccess;
        }
    }
    /* expected a function, but none existed */
    return SECFailure;
}

SECStatus
NSS_CMSType_RegisterContentType(SECOidTag type,
                                SEC_ASN1Template *asn1Template, size_t size,
                                NSSCMSGenericWrapperDataDestroy destroy,
                                NSSCMSGenericWrapperDataCallback decode_before,
                                NSSCMSGenericWrapperDataCallback decode_after,
                                NSSCMSGenericWrapperDataCallback decode_end,
                                NSSCMSGenericWrapperDataCallback encode_start,
                                NSSCMSGenericWrapperDataCallback encode_before,
                                NSSCMSGenericWrapperDataCallback encode_after,
                                PRBool isData)
{
    PRStatus rc;
    SECStatus rv;
    nsscmstypeInfo *typeInfo;
    const nsscmstypeInfo *exists;

    rc = PR_CallOnce(&nsscmstypeOnce, nss_cmstype_init);
    if (rc == PR_FAILURE) {
        return SECFailure;
    }
    PR_Lock(nsscmstypeAddLock);
    exists = nss_cmstype_lookup(type);
    if (exists) {
        PR_Unlock(nsscmstypeAddLock);
        /* already added */
        return SECSuccess;
    }
    typeInfo = PORT_ArenaNew(nsscmstypeArena, nsscmstypeInfo);
    typeInfo->type = type;
    typeInfo->size = size;
    typeInfo->isData = isData;
    typeInfo->template = asn1Template;
    typeInfo->destroy = destroy;
    typeInfo->decode_before = decode_before;
    typeInfo->decode_after = decode_after;
    typeInfo->decode_end = decode_end;
    typeInfo->encode_start = encode_start;
    typeInfo->encode_before = encode_before;
    typeInfo->encode_after = encode_after;
    rv = nss_cmstype_add(type, typeInfo);
    PR_Unlock(nsscmstypeAddLock);
    return rv;
}
