/* -*- 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 "cmmf.h"
#include "cmmfi.h"
#include "secitem.h"
#include "secder.h"

SECStatus
cmmf_DestroyPKIStatusInfo(CMMFPKIStatusInfo *info, PRBool freeit)
{
    if (info->status.data != NULL) {
        PORT_Free(info->status.data);
        info->status.data = NULL;
    }
    if (info->statusString.data != NULL) {
        PORT_Free(info->statusString.data);
        info->statusString.data = NULL;
    }
    if (info->failInfo.data != NULL) {
        PORT_Free(info->failInfo.data);
        info->failInfo.data = NULL;
    }
    if (freeit) {
        PORT_Free(info);
    }
    return SECSuccess;
}

SECStatus
CMMF_DestroyCertResponse(CMMFCertResponse *inCertResp)
{
    PORT_Assert(inCertResp != NULL);
    if (inCertResp != NULL) {
        if (inCertResp->certReqId.data != NULL) {
            PORT_Free(inCertResp->certReqId.data);
        }
        cmmf_DestroyPKIStatusInfo(&inCertResp->status, PR_FALSE);
        if (inCertResp->certifiedKeyPair != NULL) {
            CMMF_DestroyCertifiedKeyPair(inCertResp->certifiedKeyPair);
        }
        PORT_Free(inCertResp);
    }
    return SECSuccess;
}

SECStatus
CMMF_DestroyCertRepContent(CMMFCertRepContent *inCertRepContent)
{
    PORT_Assert(inCertRepContent != NULL);
    if (inCertRepContent != NULL) {
        CMMFCertResponse **pResponse = inCertRepContent->response;
        if (pResponse != NULL) {
            for (; *pResponse != NULL; pResponse++) {
                CMMFCertifiedKeyPair *certKeyPair = (*pResponse)->certifiedKeyPair;
                /* XXX Why not call CMMF_DestroyCertifiedKeyPair or
                 ** XXX cmmf_DestroyCertOrEncCert ?
                 */
                if (certKeyPair != NULL &&
                    certKeyPair->certOrEncCert.choice == cmmfCertificate &&
                    certKeyPair->certOrEncCert.cert.certificate != NULL) {
                    CERT_DestroyCertificate(certKeyPair->certOrEncCert.cert.certificate);
                    certKeyPair->certOrEncCert.cert.certificate = NULL;
                }
            }
        }
        if (inCertRepContent->caPubs) {
            CERTCertificate **caPubs = inCertRepContent->caPubs;
            for (; *caPubs; ++caPubs) {
                CERT_DestroyCertificate(*caPubs);
                *caPubs = NULL;
            }
        }
        if (inCertRepContent->poolp != NULL) {
            PORT_FreeArena(inCertRepContent->poolp, PR_TRUE);
        }
    }
    return SECSuccess;
}

SECStatus
CMMF_DestroyPOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyCont)
{
    PORT_Assert(inDecKeyCont != NULL);
    if (inDecKeyCont != NULL && inDecKeyCont->poolp) {
        PORT_FreeArena(inDecKeyCont->poolp, PR_FALSE);
    }
    return SECSuccess;
}

SECStatus
crmf_create_prtime(SECItem *src, PRTime **dest)
{
    *dest = PORT_ZNew(PRTime);
    return DER_DecodeTimeChoice(*dest, src);
}

CRMFCertExtension *
crmf_copy_cert_extension(PLArenaPool *poolp, CRMFCertExtension *inExtension)
{
    PRBool isCritical;
    SECOidTag id;
    SECItem *data;
    CRMFCertExtension *newExt;

    PORT_Assert(inExtension != NULL);
    if (inExtension == NULL) {
        return NULL;
    }
    id = CRMF_CertExtensionGetOidTag(inExtension);
    isCritical = CRMF_CertExtensionGetIsCritical(inExtension);
    data = CRMF_CertExtensionGetValue(inExtension);
    newExt = crmf_create_cert_extension(poolp, id,
                                        isCritical,
                                        data);
    SECITEM_FreeItem(data, PR_TRUE);
    return newExt;
}

static SECItem *
cmmf_encode_certificate(CERTCertificate *inCert)
{
    return SEC_ASN1EncodeItem(NULL, NULL, inCert,
                              SEC_ASN1_GET(SEC_SignedCertificateTemplate));
}

CERTCertList *
cmmf_MakeCertList(CERTCertificate **inCerts)
{
    CERTCertList *certList;
    CERTCertificate *currCert;
    SECItem *derCert, *freeCert = NULL;
    SECStatus rv;
    int i;

    certList = CERT_NewCertList();
    if (certList == NULL) {
        return NULL;
    }
    for (i = 0; inCerts[i] != NULL; i++) {
        derCert = &inCerts[i]->derCert;
        if (derCert->data == NULL) {
            derCert = freeCert = cmmf_encode_certificate(inCerts[i]);
        }
        currCert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
                                           derCert, NULL, PR_FALSE, PR_TRUE);
        if (freeCert != NULL) {
            SECITEM_FreeItem(freeCert, PR_TRUE);
            freeCert = NULL;
        }
        if (currCert == NULL) {
            goto loser;
        }
        rv = CERT_AddCertToListTail(certList, currCert);
        if (rv != SECSuccess) {
            goto loser;
        }
    }
    return certList;
loser:
    CERT_DestroyCertList(certList);
    return NULL;
}

CMMFPKIStatus
cmmf_PKIStatusInfoGetStatus(CMMFPKIStatusInfo *inStatus)
{
    long derVal;

    derVal = DER_GetInteger(&inStatus->status);
    if (derVal == -1 || derVal < cmmfGranted || derVal >= cmmfNumPKIStatus) {
        return cmmfNoPKIStatus;
    }
    return (CMMFPKIStatus)derVal;
}

int
CMMF_CertRepContentGetNumResponses(CMMFCertRepContent *inCertRepContent)
{
    int numResponses = 0;
    PORT_Assert(inCertRepContent != NULL);
    if (inCertRepContent != NULL && inCertRepContent->response != NULL) {
        while (inCertRepContent->response[numResponses] != NULL) {
            numResponses++;
        }
    }
    return numResponses;
}

SECStatus
cmmf_DestroyCertOrEncCert(CMMFCertOrEncCert *certOrEncCert, PRBool freeit)
{
    switch (certOrEncCert->choice) {
        case cmmfCertificate:
            CERT_DestroyCertificate(certOrEncCert->cert.certificate);
            certOrEncCert->cert.certificate = NULL;
            break;
        case cmmfEncryptedCert:
            crmf_destroy_encrypted_value(certOrEncCert->cert.encryptedCert,
                                         PR_TRUE);
            certOrEncCert->cert.encryptedCert = NULL;
            break;
        default:
            break;
    }
    if (freeit) {
        PORT_Free(certOrEncCert);
    }
    return SECSuccess;
}

SECStatus
cmmf_copy_secitem(PLArenaPool *poolp, SECItem *dest, SECItem *src)
{
    SECStatus rv;

    if (src->data != NULL) {
        rv = SECITEM_CopyItem(poolp, dest, src);
    } else {
        dest->data = NULL;
        dest->len = 0;
        rv = SECSuccess;
    }
    return rv;
}

SECStatus
CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair)
{
    PORT_Assert(inCertKeyPair != NULL);
    if (inCertKeyPair != NULL) {
        cmmf_DestroyCertOrEncCert(&inCertKeyPair->certOrEncCert, PR_FALSE);
        if (inCertKeyPair->privateKey) {
            crmf_destroy_encrypted_value(inCertKeyPair->privateKey, PR_TRUE);
        }
        if (inCertKeyPair->derPublicationInfo.data) {
            PORT_Free(inCertKeyPair->derPublicationInfo.data);
        }
        PORT_Free(inCertKeyPair);
    }
    return SECSuccess;
}

SECStatus
cmmf_CopyCertResponse(PLArenaPool *poolp,
                      CMMFCertResponse *dest,
                      CMMFCertResponse *src)
{
    SECStatus rv;

    if (src->certReqId.data != NULL) {
        rv = SECITEM_CopyItem(poolp, &dest->certReqId, &src->certReqId);
        if (rv != SECSuccess) {
            return rv;
        }
    }
    rv = cmmf_CopyPKIStatusInfo(poolp, &dest->status, &src->status);
    if (rv != SECSuccess) {
        return rv;
    }
    if (src->certifiedKeyPair != NULL) {
        CMMFCertifiedKeyPair *destKeyPair;

        destKeyPair = (poolp == NULL) ? PORT_ZNew(CMMFCertifiedKeyPair) : PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair);
        if (!destKeyPair) {
            return SECFailure;
        }
        rv = cmmf_CopyCertifiedKeyPair(poolp, destKeyPair,
                                       src->certifiedKeyPair);
        if (rv != SECSuccess) {
            if (!poolp) {
                CMMF_DestroyCertifiedKeyPair(destKeyPair);
            }
            return rv;
        }
        dest->certifiedKeyPair = destKeyPair;
    }
    return SECSuccess;
}

static SECStatus
cmmf_CopyCertOrEncCert(PLArenaPool *poolp, CMMFCertOrEncCert *dest,
                       CMMFCertOrEncCert *src)
{
    SECStatus rv = SECSuccess;
    CRMFEncryptedValue *encVal;

    dest->choice = src->choice;
    rv = cmmf_copy_secitem(poolp, &dest->derValue, &src->derValue);
    switch (src->choice) {
        case cmmfCertificate:
            dest->cert.certificate = CERT_DupCertificate(src->cert.certificate);
            break;
        case cmmfEncryptedCert:
            encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) : PORT_ArenaZNew(poolp, CRMFEncryptedValue);
            if (encVal == NULL) {
                return SECFailure;
            }
            rv = crmf_copy_encryptedvalue(poolp, src->cert.encryptedCert, encVal);
            if (rv != SECSuccess) {
                if (!poolp) {
                    crmf_destroy_encrypted_value(encVal, PR_TRUE);
                }
                return rv;
            }
            dest->cert.encryptedCert = encVal;
            break;
        default:
            rv = SECFailure;
    }
    return rv;
}

SECStatus
cmmf_CopyCertifiedKeyPair(PLArenaPool *poolp, CMMFCertifiedKeyPair *dest,
                          CMMFCertifiedKeyPair *src)
{
    SECStatus rv;

    rv = cmmf_CopyCertOrEncCert(poolp, &dest->certOrEncCert,
                                &src->certOrEncCert);
    if (rv != SECSuccess) {
        return rv;
    }

    if (src->privateKey != NULL) {
        CRMFEncryptedValue *encVal;

        encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) : PORT_ArenaZNew(poolp, CRMFEncryptedValue);
        if (encVal == NULL) {
            return SECFailure;
        }
        rv = crmf_copy_encryptedvalue(poolp, src->privateKey,
                                      encVal);
        if (rv != SECSuccess) {
            if (!poolp) {
                crmf_destroy_encrypted_value(encVal, PR_TRUE);
            }
            return rv;
        }
        dest->privateKey = encVal;
    }
    rv = cmmf_copy_secitem(poolp, &dest->derPublicationInfo,
                           &src->derPublicationInfo);
    return rv;
}

SECStatus
cmmf_CopyPKIStatusInfo(PLArenaPool *poolp, CMMFPKIStatusInfo *dest,
                       CMMFPKIStatusInfo *src)
{
    SECStatus rv;

    rv = cmmf_copy_secitem(poolp, &dest->status, &src->status);
    if (rv != SECSuccess) {
        return rv;
    }
    rv = cmmf_copy_secitem(poolp, &dest->statusString, &src->statusString);
    if (rv != SECSuccess) {
        return rv;
    }
    rv = cmmf_copy_secitem(poolp, &dest->failInfo, &src->failInfo);
    return rv;
}

CERTCertificate *
cmmf_CertOrEncCertGetCertificate(CMMFCertOrEncCert *certOrEncCert,
                                 CERTCertDBHandle *certdb)
{
    if (certOrEncCert->choice != cmmfCertificate ||
        certOrEncCert->cert.certificate == NULL) {
        return NULL;
    }
    return CERT_NewTempCertificate(certdb,
                                   &certOrEncCert->cert.certificate->derCert,
                                   NULL, PR_FALSE, PR_TRUE);
}

SECStatus
cmmf_PKIStatusInfoSetStatus(CMMFPKIStatusInfo *statusInfo,
                            PLArenaPool *poolp,
                            CMMFPKIStatus inStatus)
{
    SECItem *dummy;

    if (inStatus < cmmfGranted || inStatus >= cmmfNumPKIStatus) {
        return SECFailure;
    }

    dummy = SEC_ASN1EncodeInteger(poolp, &statusInfo->status, inStatus);
    PORT_Assert(dummy == &statusInfo->status);
    if (dummy != &statusInfo->status) {
        SECITEM_FreeItem(dummy, PR_TRUE);
        return SECFailure;
    }
    return SECSuccess;
}
