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

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

    /* set object ID of the extension and its value */
    if (copyData) {
        rv = SECITEM_CopyItem(handle->ownerArena, &ext->id, oid);
        if (rv) {
            return (SECFailure);
        }

        rv = SECITEM_CopyItem(handle->ownerArena, &ext->value, value);
        if (rv) {
            return (SECFailure);
        }
    } else {
        ext->id = *oid;
        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;
    PORTCheapArenaPool tmpArena;

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

    PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);

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

    rv = SEC_QuickDERDecodeItem(&tmpArena.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:
    PORT_DestroyCheapArena(&tmpArena);

    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);
}
