/* -*- Mode: C; tab-width: 8 -*-*/
/* 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/. */

#include "crmf.h"
#include "crmfi.h"
#include "keyhi.h"
#include "secder.h"

/*
 * Macro that returns PR_TRUE if the pointer is not NULL.
 * If the pointer is NULL, then the macro will return PR_FALSE.
 */
#define IS_NOT_NULL(ptr) ((ptr) == NULL) ? PR_FALSE : PR_TRUE

const unsigned char hexTrue = 0xff;
const unsigned char hexFalse = 0x00;

SECStatus
crmf_encode_integer(PLArenaPool *poolp, SECItem *dest, long value)
{
    SECItem *dummy;

    dummy = SEC_ASN1EncodeInteger(poolp, dest, value);
    PORT_Assert(dummy == dest);
    if (dummy == NULL) {
        return SECFailure;
    }
    return SECSuccess;
}

SECStatus
crmf_encode_unsigned_integer(PLArenaPool *poolp, SECItem *dest,
                             unsigned long value)
{
    SECItem *dummy;

    dummy = SEC_ASN1EncodeUnsignedInteger(poolp, dest, value);
    PORT_Assert(dummy == dest);
    if (dummy != dest) {
        return SECFailure;
    }
    return SECSuccess;
}

static SECStatus
crmf_copy_secitem(PLArenaPool *poolp, SECItem *dest, SECItem *src)
{
    return SECITEM_CopyItem(poolp, dest, src);
}

PRBool
CRMF_DoesRequestHaveField(CRMFCertRequest *inCertReq,
                          CRMFCertTemplateField inField)
{

    PORT_Assert(inCertReq != NULL);
    if (inCertReq == NULL) {
        return PR_FALSE;
    }
    switch (inField) {
        case crmfVersion:
            return inCertReq->certTemplate.version.data != NULL;
        case crmfSerialNumber:
            return inCertReq->certTemplate.serialNumber.data != NULL;
        case crmfSigningAlg:
            return inCertReq->certTemplate.signingAlg != NULL;
        case crmfIssuer:
            return inCertReq->certTemplate.issuer != NULL;
        case crmfValidity:
            return inCertReq->certTemplate.validity != NULL;
        case crmfSubject:
            return inCertReq->certTemplate.subject != NULL;
        case crmfPublicKey:
            return inCertReq->certTemplate.publicKey != NULL;
        case crmfIssuerUID:
            return inCertReq->certTemplate.issuerUID.data != NULL;
        case crmfSubjectUID:
            return inCertReq->certTemplate.subjectUID.data != NULL;
        case crmfExtension:
            return CRMF_CertRequestGetNumberOfExtensions(inCertReq) != 0;
    }
    return PR_FALSE;
}

CRMFCertRequest *
CRMF_CreateCertRequest(PRUint32 inRequestID)
{
    PLArenaPool *poolp;
    CRMFCertRequest *certReq;
    SECStatus rv;

    poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
    if (poolp == NULL) {
        goto loser;
    }

    certReq = PORT_ArenaZNew(poolp, CRMFCertRequest);
    if (certReq == NULL) {
        goto loser;
    }

    certReq->poolp = poolp;
    certReq->requestID = inRequestID;

    rv = crmf_encode_unsigned_integer(poolp, &(certReq->certReqId),
                                      inRequestID);
    if (rv != SECSuccess) {
        goto loser;
    }

    return certReq;
loser:
    if (poolp) {
        PORT_FreeArena(poolp, PR_FALSE);
    }
    return NULL;
}

SECStatus
CRMF_DestroyCertRequest(CRMFCertRequest *inCertReq)
{
    PORT_Assert(inCertReq != NULL);
    if (inCertReq != NULL) {
        if (inCertReq->certTemplate.extensions) {
            PORT_Free(inCertReq->certTemplate.extensions);
        }
        if (inCertReq->controls) {
            /* Right now we don't support EnveloppedData option,
             * so we won't go through and delete each occurrence of
             * an EnveloppedData in the control.
             */
            PORT_Free(inCertReq->controls);
        }
        if (inCertReq->poolp) {
            PORT_FreeArena(inCertReq->poolp, PR_TRUE);
        }
    }
    return SECSuccess;
}

static SECStatus
crmf_template_add_version(PLArenaPool *poolp, SECItem *dest, long version)
{
    return (crmf_encode_integer(poolp, dest, version));
}

static SECStatus
crmf_template_add_serialnumber(PLArenaPool *poolp, SECItem *dest, long serial)
{
    return (crmf_encode_integer(poolp, dest, serial));
}

SECStatus
crmf_template_copy_secalg(PLArenaPool *poolp, SECAlgorithmID **dest,
                          SECAlgorithmID *src)
{
    SECStatus rv;
    void *mark = NULL;
    SECAlgorithmID *mySecAlg;

    if (!poolp) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    mark = PORT_ArenaMark(poolp);
    *dest = mySecAlg = PORT_ArenaZNew(poolp, SECAlgorithmID);
    if (mySecAlg == NULL) {
        goto loser;
    }
    rv = SECOID_CopyAlgorithmID(poolp, mySecAlg, src);
    if (rv != SECSuccess) {
        goto loser;
    }
    if (mark) {
        PORT_ArenaUnmark(poolp, mark);
    }
    return SECSuccess;

loser:
    *dest = NULL;
    if (mark) {
        PORT_ArenaRelease(poolp, mark);
    }
    return SECFailure;
}

SECStatus
crmf_copy_cert_name(PLArenaPool *poolp, CERTName **dest,
                    CERTName *src)
{
    CERTName *newName;
    SECStatus rv;
    void *mark;

    mark = PORT_ArenaMark(poolp);
    *dest = newName = PORT_ArenaZNew(poolp, CERTName);
    if (newName == NULL) {
        goto loser;
    }

    rv = CERT_CopyName(poolp, newName, src);
    if (rv != SECSuccess) {
        goto loser;
    }
    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;
loser:
    PORT_ArenaRelease(poolp, mark);
    *dest = NULL;
    return SECFailure;
}

static SECStatus
crmf_template_add_issuer(PLArenaPool *poolp, CERTName **dest,
                         CERTName *issuerName)
{
    return crmf_copy_cert_name(poolp, dest, issuerName);
}

static SECStatus
crmf_template_add_validity(PLArenaPool *poolp, CRMFOptionalValidity **dest,
                           CRMFValidityCreationInfo *info)
{
    SECStatus rv;
    void *mark;
    CRMFOptionalValidity *myValidity;

    /*First off, let's make sure at least one of the two fields is present*/
    if (!info || (!info->notBefore && !info->notAfter)) {
        return SECFailure;
    }
    mark = PORT_ArenaMark(poolp);
    *dest = myValidity = PORT_ArenaZNew(poolp, CRMFOptionalValidity);
    if (myValidity == NULL) {
        goto loser;
    }

    if (info->notBefore) {
        rv = DER_EncodeTimeChoice(poolp, &myValidity->notBefore,
                                  *info->notBefore);
        if (rv != SECSuccess) {
            goto loser;
        }
    }
    if (info->notAfter) {
        rv = DER_EncodeTimeChoice(poolp, &myValidity->notAfter,
                                  *info->notAfter);
        if (rv != SECSuccess) {
            goto loser;
        }
    }
    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;
loser:
    PORT_ArenaRelease(poolp, mark);
    *dest = NULL;
    return SECFailure;
}

static SECStatus
crmf_template_add_subject(PLArenaPool *poolp, CERTName **dest,
                          CERTName *subject)
{
    return crmf_copy_cert_name(poolp, dest, subject);
}

SECStatus
crmf_template_add_public_key(PLArenaPool *poolp,
                             CERTSubjectPublicKeyInfo **dest,
                             CERTSubjectPublicKeyInfo *pubKey)
{
    CERTSubjectPublicKeyInfo *spki;
    SECStatus rv;

    *dest = spki = (poolp == NULL) ? PORT_ZNew(CERTSubjectPublicKeyInfo) : PORT_ArenaZNew(poolp, CERTSubjectPublicKeyInfo);
    if (spki == NULL) {
        goto loser;
    }
    rv = SECKEY_CopySubjectPublicKeyInfo(poolp, spki, pubKey);
    if (rv != SECSuccess) {
        goto loser;
    }
    return SECSuccess;
loser:
    if (poolp == NULL && spki != NULL) {
        SECKEY_DestroySubjectPublicKeyInfo(spki);
    }
    *dest = NULL;
    return SECFailure;
}

static SECStatus
crmf_copy_bitstring(PLArenaPool *poolp, SECItem *dest, const SECItem *src)
{
    SECStatus rv;
    SECItem byteSrc;

    byteSrc = *src;
    byteSrc.len = CRMF_BITS_TO_BYTES(byteSrc.len);
    rv = crmf_copy_secitem(poolp, dest, &byteSrc);
    dest->len = src->len;
    return rv;
}

static SECStatus
crmf_template_add_issuer_uid(PLArenaPool *poolp, SECItem *dest,
                             const SECItem *issuerUID)
{
    return crmf_copy_bitstring(poolp, dest, issuerUID);
}

static SECStatus
crmf_template_add_subject_uid(PLArenaPool *poolp, SECItem *dest,
                              const SECItem *subjectUID)
{
    return crmf_copy_bitstring(poolp, dest, subjectUID);
}

static void
crmf_zeroize_new_extensions(CRMFCertExtension **extensions,
                            int numToZeroize)
{
    PORT_Memset((void *)extensions, 0, sizeof(CERTCertExtension *) * numToZeroize);
}

/*
 * The strategy for adding templates will differ from all the other
 * attributes in the template.  First, we want to allow the client
 * of this API to set extensions more than just once.  So we will
 * need the ability grow the array of extensions.  Since arenas don't
 * give us the realloc function, we'll use the generic PORT_* functions
 * to allocate the array of pointers *ONLY*.  Then we will allocate each
 * individual extension from the arena that comes along with the certReq
 * structure that owns this template.
 */
static SECStatus
crmf_template_add_extensions(PLArenaPool *poolp, CRMFCertTemplate *inTemplate,
                             CRMFCertExtCreationInfo *extensions)
{
    void *mark;
    int newSize, oldSize, i;
    SECStatus rv;
    CRMFCertExtension **extArray;
    CRMFCertExtension *newExt, *currExt;

    mark = PORT_ArenaMark(poolp);
    if (inTemplate->extensions == NULL) {
        newSize = extensions->numExtensions;
        extArray = PORT_ZNewArray(CRMFCertExtension *, newSize + 1);
    } else {
        newSize = inTemplate->numExtensions + extensions->numExtensions;
        extArray = PORT_Realloc(inTemplate->extensions,
                                sizeof(CRMFCertExtension *) * (newSize + 1));
    }
    if (extArray == NULL) {
        goto loser;
    }
    oldSize = inTemplate->numExtensions;
    inTemplate->extensions = extArray;
    inTemplate->numExtensions = newSize;
    for (i = oldSize; i < newSize; i++) {
        newExt = PORT_ArenaZNew(poolp, CRMFCertExtension);
        if (newExt == NULL) {
            goto loser2;
        }
        currExt = extensions->extensions[i - oldSize];
        rv = crmf_copy_secitem(poolp, &(newExt->id), &(currExt->id));
        if (rv != SECSuccess) {
            goto loser2;
        }
        rv = crmf_copy_secitem(poolp, &(newExt->critical),
                               &(currExt->critical));
        if (rv != SECSuccess) {
            goto loser2;
        }
        rv = crmf_copy_secitem(poolp, &(newExt->value), &(currExt->value));
        if (rv != SECSuccess) {
            goto loser2;
        }
        extArray[i] = newExt;
    }
    extArray[newSize] = NULL;
    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;
loser2:
    crmf_zeroize_new_extensions(&(inTemplate->extensions[oldSize]),
                                extensions->numExtensions);
    inTemplate->numExtensions = oldSize;
loser:
    PORT_ArenaRelease(poolp, mark);
    return SECFailure;
}

SECStatus
CRMF_CertRequestSetTemplateField(CRMFCertRequest *inCertReq,
                                 CRMFCertTemplateField inTemplateField,
                                 void *data)
{
    CRMFCertTemplate *certTemplate;
    PLArenaPool *poolp;
    SECStatus rv = SECFailure;
    void *mark;

    if (inCertReq == NULL) {
        return SECFailure;
    }

    certTemplate = &(inCertReq->certTemplate);

    poolp = inCertReq->poolp;
    mark = PORT_ArenaMark(poolp);
    switch (inTemplateField) {
        case crmfVersion:
            rv = crmf_template_add_version(poolp, &(certTemplate->version),
                                           *(long *)data);
            break;
        case crmfSerialNumber:
            rv = crmf_template_add_serialnumber(poolp,
                                                &(certTemplate->serialNumber),
                                                *(long *)data);
            break;
        case crmfSigningAlg:
            rv = crmf_template_copy_secalg(poolp, &(certTemplate->signingAlg),
                                           (SECAlgorithmID *)data);
            break;
        case crmfIssuer:
            rv = crmf_template_add_issuer(poolp, &(certTemplate->issuer),
                                          (CERTName *)data);
            break;
        case crmfValidity:
            rv = crmf_template_add_validity(poolp, &(certTemplate->validity),
                                            (CRMFValidityCreationInfo *)data);
            break;
        case crmfSubject:
            rv = crmf_template_add_subject(poolp, &(certTemplate->subject),
                                           (CERTName *)data);
            break;
        case crmfPublicKey:
            rv = crmf_template_add_public_key(poolp, &(certTemplate->publicKey),
                                              (CERTSubjectPublicKeyInfo *)data);
            break;
        case crmfIssuerUID:
            rv = crmf_template_add_issuer_uid(poolp, &(certTemplate->issuerUID),
                                              (SECItem *)data);
            break;
        case crmfSubjectUID:
            rv = crmf_template_add_subject_uid(poolp, &(certTemplate->subjectUID),
                                               (SECItem *)data);
            break;
        case crmfExtension:
            rv = crmf_template_add_extensions(poolp, certTemplate,
                                              (CRMFCertExtCreationInfo *)data);
            break;
    }
    if (rv != SECSuccess) {
        PORT_ArenaRelease(poolp, mark);
    } else {
        PORT_ArenaUnmark(poolp, mark);
    }
    return rv;
}

SECStatus
CRMF_CertReqMsgSetCertRequest(CRMFCertReqMsg *inCertReqMsg,
                              CRMFCertRequest *inCertReq)
{
    PORT_Assert(inCertReqMsg != NULL && inCertReq != NULL);
    if (inCertReqMsg == NULL || inCertReq == NULL) {
        return SECFailure;
    }
    inCertReqMsg->certReq = crmf_copy_cert_request(inCertReqMsg->poolp,
                                                   inCertReq);
    return (inCertReqMsg->certReq == NULL) ? SECFailure : SECSuccess;
}

CRMFCertReqMsg *
CRMF_CreateCertReqMsg(void)
{
    PLArenaPool *poolp;
    CRMFCertReqMsg *reqMsg;

    poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
    if (poolp == NULL) {
        goto loser;
    }
    reqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg);
    if (reqMsg == NULL) {
        goto loser;
    }
    reqMsg->poolp = poolp;
    return reqMsg;

loser:
    if (poolp) {
        PORT_FreeArena(poolp, PR_FALSE);
    }
    return NULL;
}

SECStatus
CRMF_DestroyCertReqMsg(CRMFCertReqMsg *inCertReqMsg)
{
    PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->poolp != NULL);
    if (!inCertReqMsg->isDecoded) {
        if (inCertReqMsg->certReq->certTemplate.extensions != NULL) {
            PORT_Free(inCertReqMsg->certReq->certTemplate.extensions);
        }
        if (inCertReqMsg->certReq->controls != NULL) {
            PORT_Free(inCertReqMsg->certReq->controls);
        }
    }
    PORT_FreeArena(inCertReqMsg->poolp, PR_TRUE);
    return SECSuccess;
}

CRMFCertExtension *
crmf_create_cert_extension(PLArenaPool *poolp,
                           SECOidTag id,
                           PRBool isCritical,
                           SECItem *data)
{
    CRMFCertExtension *newExt;
    SECOidData *oidData;
    SECStatus rv;

    newExt = (poolp == NULL) ? PORT_ZNew(CRMFCertExtension) : PORT_ArenaZNew(poolp, CRMFCertExtension);
    if (newExt == NULL) {
        goto loser;
    }
    oidData = SECOID_FindOIDByTag(id);
    if (oidData == NULL ||
        oidData->supportedExtension != SUPPORTED_CERT_EXTENSION) {
        goto loser;
    }

    rv = SECITEM_CopyItem(poolp, &(newExt->id), &(oidData->oid));
    if (rv != SECSuccess) {
        goto loser;
    }

    rv = SECITEM_CopyItem(poolp, &(newExt->value), data);
    if (rv != SECSuccess) {
        goto loser;
    }

    if (isCritical) {
        newExt->critical.data = (poolp == NULL) ? PORT_New(unsigned char)
                                                : PORT_ArenaNew(poolp, unsigned char);
        if (newExt->critical.data == NULL) {
            goto loser;
        }
        newExt->critical.data[0] = hexTrue;
        newExt->critical.len = 1;
    }
    return newExt;
loser:
    if (newExt != NULL && poolp == NULL) {
        CRMF_DestroyCertExtension(newExt);
    }
    return NULL;
}

CRMFCertExtension *
CRMF_CreateCertExtension(SECOidTag id,
                         PRBool isCritical,
                         SECItem *data)
{
    return crmf_create_cert_extension(NULL, id, isCritical, data);
}

static SECStatus
crmf_destroy_cert_extension(CRMFCertExtension *inExtension, PRBool freeit)
{
    if (inExtension != NULL) {
        SECITEM_FreeItem(&(inExtension->id), PR_FALSE);
        SECITEM_FreeItem(&(inExtension->value), PR_FALSE);
        SECITEM_FreeItem(&(inExtension->critical), PR_FALSE);
        if (freeit) {
            PORT_Free(inExtension);
        }
    }
    return SECSuccess;
}

SECStatus
CRMF_DestroyCertExtension(CRMFCertExtension *inExtension)
{
    return crmf_destroy_cert_extension(inExtension, PR_TRUE);
}

SECStatus
CRMF_DestroyCertReqMessages(CRMFCertReqMessages *inCertReqMsgs)
{
    PORT_Assert(inCertReqMsgs != NULL);
    if (inCertReqMsgs != NULL) {
        PORT_FreeArena(inCertReqMsgs->poolp, PR_TRUE);
    }
    return SECSuccess;
}

static PRBool
crmf_item_has_data(SECItem *item)
{
    if (item != NULL && item->data != NULL) {
        return PR_TRUE;
    }
    return PR_FALSE;
}

PRBool
CRMF_CertRequestIsFieldPresent(CRMFCertRequest *inCertReq,
                               CRMFCertTemplateField inTemplateField)
{
    PRBool retVal;
    CRMFCertTemplate *certTemplate;

    PORT_Assert(inCertReq != NULL);
    if (inCertReq == NULL) {
        /* This is probably some kind of error, but this is
         * the safest return value for this function.
         */
        return PR_FALSE;
    }
    certTemplate = &inCertReq->certTemplate;
    switch (inTemplateField) {
        case crmfVersion:
            retVal = crmf_item_has_data(&certTemplate->version);
            break;
        case crmfSerialNumber:
            retVal = crmf_item_has_data(&certTemplate->serialNumber);
            break;
        case crmfSigningAlg:
            retVal = IS_NOT_NULL(certTemplate->signingAlg);
            break;
        case crmfIssuer:
            retVal = IS_NOT_NULL(certTemplate->issuer);
            break;
        case crmfValidity:
            retVal = IS_NOT_NULL(certTemplate->validity);
            break;
        case crmfSubject:
            retVal = IS_NOT_NULL(certTemplate->subject);
            break;
        case crmfPublicKey:
            retVal = IS_NOT_NULL(certTemplate->publicKey);
            break;
        case crmfIssuerUID:
            retVal = crmf_item_has_data(&certTemplate->issuerUID);
            break;
        case crmfSubjectUID:
            retVal = crmf_item_has_data(&certTemplate->subjectUID);
            break;
        case crmfExtension:
            retVal = IS_NOT_NULL(certTemplate->extensions);
            break;
        default:
            retVal = PR_FALSE;
    }
    return retVal;
}
