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

/*
 * Certificate Extensions handling code
 *
 */

#include "cert.h"
#include "secitem.h"
#include "secoid.h"
#include "secder.h"
#include "secasn1.h"
#include "certxutl.h"
#include "secerr.h"

#ifdef OLD
#include "ocspti.h" /* XXX a better extensions interface would not
			 * require knowledge of data structures of callers */
#endif

static CERTCertExtension *
GetExtension(CERTCertExtension **extensions, SECItem *oid)
{
    CERTCertExtension **exts;
    CERTCertExtension *ext = NULL;
    SECComparison comp;

    exts = extensions;

    if (exts) {
        while (*exts) {
            ext = *exts;
            comp = SECITEM_CompareItem(oid, &ext->id);
            if (comp == SECEqual)
                break;

            exts++;
        }
        return (*exts ? ext : NULL);
    }
    return (NULL);
}

SECStatus
cert_FindExtensionByOID(CERTCertExtension **extensions, SECItem *oid,
                        SECItem *value)
{
    CERTCertExtension *ext;
    SECStatus rv = SECSuccess;

    ext = GetExtension(extensions, oid);
    if (ext == NULL) {
        PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
        return (SECFailure);
    }
    if (value)
        rv = SECITEM_CopyItem(NULL, value, &ext->value);
    return (rv);
}

SECStatus
CERT_GetExtenCriticality(CERTCertExtension **extensions, int tag,
                         PRBool *isCritical)
{
    CERTCertExtension *ext;
    SECOidData *oid;

    if (!isCritical)
        return (SECSuccess);

    /* find the extension in the extensions list */
    oid = SECOID_FindOIDByTag((SECOidTag)tag);
    if (!oid) {
        return (SECFailure);
    }
    ext = GetExtension(extensions, &oid->oid);
    if (ext == NULL) {
        PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
        return (SECFailure);
    }

    /* If the criticality is omitted, then it is false by default.
       ex->critical.data is NULL */
    if (ext->critical.data == NULL)
        *isCritical = PR_FALSE;
    else
        *isCritical = (ext->critical.data[0] == 0xff) ? PR_TRUE : PR_FALSE;
    return (SECSuccess);
}

SECStatus
cert_FindExtension(CERTCertExtension **extensions, int tag, SECItem *value)
{
    SECOidData *oid;

    oid = SECOID_FindOIDByTag((SECOidTag)tag);
    if (!oid) {
        return (SECFailure);
    }

    return (cert_FindExtensionByOID(extensions, &oid->oid, value));
}

typedef struct _extNode {
    struct _extNode *next;
    CERTCertExtension *ext;
} extNode;

typedef struct {
    void (*setExts)(void *object, CERTCertExtension **exts);
    void *object;
    PLArenaPool *ownerArena;
    PLArenaPool *arena;
    extNode *head;
    int count;
} extRec;

/*
 * cert_StartExtensions
 *
 * NOTE: This interface changed significantly to remove knowledge
 *   about callers data structures (owner objects)
 */
void *
cert_StartExtensions(void *owner, PLArenaPool *ownerArena,
                     void (*setExts)(void *object, CERTCertExtension **exts))
{
    PLArenaPool *arena;
    extRec *handle;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena) {
        return (0);
    }

    handle = (extRec *)PORT_ArenaAlloc(arena, sizeof(extRec));
    if (!handle) {
        PORT_FreeArena(arena, PR_FALSE);
        return (0);
    }

    handle->object = owner;
    handle->ownerArena = ownerArena;
    handle->setExts = setExts;

    handle->arena = arena;
    handle->head = 0;
    handle->count = 0;

    return (handle);
}

static unsigned char hextrue = 0xff;

/*
 * Note - assumes that data pointed to by oid->data will not move
 */
SECStatus
CERT_AddExtensionByOID(void *exthandle, SECItem *oid, SECItem *value,
                       PRBool critical, PRBool copyData)
{
    CERTCertExtension *ext;
    SECStatus rv;
    extNode *node;
    extRec *handle;

    handle = (extRec *)exthandle;

    /* allocate space for extension and list node */
    ext = (CERTCertExtension *)PORT_ArenaZAlloc(handle->ownerArena,
                                                sizeof(CERTCertExtension));
    if (!ext) {
        return (SECFailure);
    }

    node = (extNode *)PORT_ArenaAlloc(handle->arena, sizeof(extNode));
    if (!node) {
        return (SECFailure);
    }

    /* add to list */
    node->next = handle->head;
    handle->head = node;

    /* point to ext struct */
    node->ext = ext;

    /* the object ID of the extension */
    ext->id = *oid;

    /* set critical field */
    if (critical) {
        ext->critical.data = (unsigned char *)&hextrue;
        ext->critical.len = 1;
    }

    /* set the value */
    if (copyData) {
        rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value);
        if (rv) {
            return (SECFailure);
        }
    } else {
        ext->value = *value;
    }

    handle->count++;

    return (SECSuccess);
}

SECStatus
CERT_AddExtension(void *exthandle, int idtag, SECItem *value, PRBool critical,
                  PRBool copyData)
{
    SECOidData *oid;

    oid = SECOID_FindOIDByTag((SECOidTag)idtag);
    if (!oid) {
        return (SECFailure);
    }

    return (CERT_AddExtensionByOID(exthandle, &oid->oid, value, critical,
                                   copyData));
}

SECStatus
CERT_EncodeAndAddExtension(void *exthandle, int idtag, void *value,
                           PRBool critical, const SEC_ASN1Template *atemplate)
{
    extRec *handle;
    SECItem *encitem;

    handle = (extRec *)exthandle;

    encitem = SEC_ASN1EncodeItem(handle->ownerArena, NULL, value, atemplate);
    if (encitem == NULL) {
        return (SECFailure);
    }

    return CERT_AddExtension(exthandle, idtag, encitem, critical, PR_FALSE);
}

void
PrepareBitStringForEncoding(SECItem *bitsmap, SECItem *value)
{
    unsigned char onebyte;
    unsigned int i, len = 0;

    /* to prevent warning on some platform at compile time */
    onebyte = '\0';
    /* Get the position of the right-most turn-on bit */
    for (i = 0; i < (value->len) * 8; ++i) {
        if (i % 8 == 0)
            onebyte = value->data[i / 8];
        if (onebyte & 0x80)
            len = i;
        onebyte <<= 1;
    }
    bitsmap->data = value->data;
    /* Add one here since we work with base 1 */
    bitsmap->len = len + 1;
}

SECStatus
CERT_EncodeAndAddBitStrExtension(void *exthandle, int idtag, SECItem *value,
                                 PRBool critical)
{
    SECItem bitsmap;

    PrepareBitStringForEncoding(&bitsmap, value);
    return (CERT_EncodeAndAddExtension(exthandle, idtag, &bitsmap, critical,
                                       SEC_ASN1_GET(SEC_BitStringTemplate)));
}

SECStatus
CERT_FinishExtensions(void *exthandle)
{
    extRec *handle;
    extNode *node;
    CERTCertExtension **exts;
    SECStatus rv = SECFailure;

    handle = (extRec *)exthandle;

    /* allocate space for extensions array */
    exts = PORT_ArenaNewArray(handle->ownerArena, CERTCertExtension *,
                              handle->count + 1);
    if (exts == NULL) {
        goto loser;
    }

/* put extensions in owner object and update its version number */

#ifdef OLD
    switch (handle->type) {
        case CertificateExtensions:
            handle->owner.cert->extensions = exts;
            DER_SetUInteger(ownerArena, &(handle->owner.cert->version),
                            SEC_CERTIFICATE_VERSION_3);
            break;
        case CrlExtensions:
            handle->owner.crl->extensions = exts;
            DER_SetUInteger(ownerArena, &(handle->owner.crl->version),
                            SEC_CRL_VERSION_2);
            break;
        case OCSPRequestExtensions:
            handle->owner.request->tbsRequest->requestExtensions = exts;
            break;
        case OCSPSingleRequestExtensions:
            handle->owner.singleRequest->singleRequestExtensions = exts;
            break;
        case OCSPResponseSingleExtensions:
            handle->owner.singleResponse->singleExtensions = exts;
            break;
    }
#endif

    handle->setExts(handle->object, exts);

    /* update the version number */

    /* copy each extension pointer */
    node = handle->head;
    while (node) {
        *exts = node->ext;

        node = node->next;
        exts++;
    }

    /* terminate the array of extensions */
    *exts = 0;

    rv = SECSuccess;

loser:
    /* free working arena */
    PORT_FreeArena(handle->arena, PR_FALSE);
    return rv;
}

SECStatus
CERT_MergeExtensions(void *exthandle, CERTCertExtension **extensions)
{
    CERTCertExtension *ext;
    SECStatus rv = SECSuccess;
    SECOidTag tag;
    extNode *node;
    extRec *handle = exthandle;

    if (!exthandle || !extensions) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    while ((ext = *extensions++) != NULL) {
        tag = SECOID_FindOIDTag(&ext->id);
        for (node = handle->head; node != NULL; node = node->next) {
            if (tag == 0) {
                if (SECITEM_ItemsAreEqual(&ext->id, &node->ext->id))
                    break;
            } else {
                if (SECOID_FindOIDTag(&node->ext->id) == tag) {
                    break;
                }
            }
        }
        if (node == NULL) {
            PRBool critical = (ext->critical.len != 0 &&
                               ext->critical.data[ext->critical.len - 1] != 0);
            if (critical && tag == SEC_OID_UNKNOWN) {
                PORT_SetError(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
                rv = SECFailure;
                break;
            }
            /* add to list */
            rv = CERT_AddExtensionByOID(exthandle, &ext->id, &ext->value,
                                        critical, PR_TRUE);
            if (rv != SECSuccess)
                break;
        }
    }
    return rv;
}

/*
 * get the value of the Netscape Certificate Type Extension
 */
SECStatus
CERT_FindBitStringExtension(CERTCertExtension **extensions, int tag,
                            SECItem *retItem)
{
    SECItem wrapperItem, tmpItem = { siBuffer, 0 };
    SECStatus rv;
    PLArenaPool *arena = NULL;

    wrapperItem.data = NULL;
    tmpItem.data = NULL;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    if (!arena) {
        return (SECFailure);
    }

    rv = cert_FindExtension(extensions, tag, &wrapperItem);
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = SEC_QuickDERDecodeItem(
        arena, &tmpItem, SEC_ASN1_GET(SEC_BitStringTemplate), &wrapperItem);

    if (rv != SECSuccess) {
        goto loser;
    }

    retItem->data = (unsigned char *)PORT_Alloc((tmpItem.len + 7) >> 3);
    if (retItem->data == NULL) {
        goto loser;
    }

    PORT_Memcpy(retItem->data, tmpItem.data, (tmpItem.len + 7) >> 3);
    retItem->len = tmpItem.len;

    rv = SECSuccess;
    goto done;

loser:
    rv = SECFailure;

done:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    if (wrapperItem.data) {
        PORT_Free(wrapperItem.data);
    }

    return (rv);
}

PRBool
cert_HasCriticalExtension(CERTCertExtension **extensions)
{
    CERTCertExtension **exts;
    CERTCertExtension *ext = NULL;
    PRBool hasCriticalExten = PR_FALSE;

    exts = extensions;

    if (exts) {
        while (*exts) {
            ext = *exts;
            /* If the criticality is omitted, it's non-critical */
            if (ext->critical.data && ext->critical.data[0] == 0xff) {
                hasCriticalExten = PR_TRUE;
                break;
            }
            exts++;
        }
    }
    return (hasCriticalExten);
}

PRBool
cert_HasUnknownCriticalExten(CERTCertExtension **extensions)
{
    CERTCertExtension **exts;
    CERTCertExtension *ext = NULL;
    PRBool hasUnknownCriticalExten = PR_FALSE;

    exts = extensions;

    if (exts) {
        while (*exts) {
            ext = *exts;
            /* If the criticality is omitted, it's non-critical.
               If an extension is critical, make sure that we know
               how to process the extension.
             */
            if (ext->critical.data && ext->critical.data[0] == 0xff) {
                if (SECOID_KnownCertExtenOID(&ext->id) == PR_FALSE) {
                    hasUnknownCriticalExten = PR_TRUE;
                    break;
                }
            }
            exts++;
        }
    }
    return (hasUnknownCriticalExten);
}
