/*
 * Copyright 2004-2006 Juan Lang
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
#include "wine/debug.h"
#include "excpt.h"
#include "wine/exception.h"
#include "crypt32_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(crypt);

/* An extended certificate property in serialized form is prefixed by this
 * header.
 */
typedef struct _WINE_CERT_PROP_HEADER
{
    DWORD propID;
    DWORD unknown; /* always 1 */
    DWORD cb;
} WINE_CERT_PROP_HEADER, *PWINE_CERT_PROP_HEADER;

static BOOL CRYPT_SerializeStoreElement(const void *context,
 const BYTE *encodedContext, DWORD cbEncodedContext, DWORD contextPropID,
 PCWINE_CONTEXT_INTERFACE contextInterface, DWORD dwFlags, BOOL omitHashes,
 BYTE *pbElement, DWORD *pcbElement)
{
    BOOL ret;

    TRACE("(%p, %p, %08x, %d, %p, %p)\n", context, contextInterface, dwFlags,
     omitHashes, pbElement, pcbElement);

    if (context)
    {
        DWORD bytesNeeded = sizeof(WINE_CERT_PROP_HEADER) + cbEncodedContext;
        DWORD prop = 0;

        ret = TRUE;
        do {
            prop = contextInterface->enumProps(context, prop);
            if (prop && (!omitHashes || !IS_CERT_HASH_PROP_ID(prop)))
            {
                DWORD propSize = 0;

                ret = contextInterface->getProp(context, prop, NULL, &propSize);
                if (ret)
                    bytesNeeded += sizeof(WINE_CERT_PROP_HEADER) + propSize;
            }
        } while (ret && prop != 0);

        if (!pbElement)
        {
            *pcbElement = bytesNeeded;
            ret = TRUE;
        }
        else if (*pcbElement < bytesNeeded)
        {
            *pcbElement = bytesNeeded;
            SetLastError(ERROR_MORE_DATA);
            ret = FALSE;
        }
        else
        {
            PWINE_CERT_PROP_HEADER hdr;
            DWORD bufSize = 0;
            LPBYTE buf = NULL;

            prop = 0;
            do {
                prop = contextInterface->enumProps(context, prop);
                if (prop && (!omitHashes || !IS_CERT_HASH_PROP_ID(prop)))
                {
                    DWORD propSize = 0;

                    ret = contextInterface->getProp(context, prop, NULL,
                     &propSize);
                    if (ret)
                    {
                        if (bufSize < propSize)
                        {
                            if (buf)
                                buf = CryptMemRealloc(buf, propSize);
                            else
                                buf = CryptMemAlloc(propSize);
                            bufSize = propSize;
                        }
                        if (buf)
                        {
                            ret = contextInterface->getProp(context, prop, buf,
                             &propSize);
                            if (ret)
                            {
                                hdr = (PWINE_CERT_PROP_HEADER)pbElement;
                                hdr->propID = prop;
                                hdr->unknown = 1;
                                hdr->cb = propSize;
                                pbElement += sizeof(WINE_CERT_PROP_HEADER);
                                if (propSize)
                                {
                                    memcpy(pbElement, buf, propSize);
                                    pbElement += propSize;
                                }
                            }
                        }
                        else
                            ret = FALSE;
                    }
                }
            } while (ret && prop != 0);
            CryptMemFree(buf);

            hdr = (PWINE_CERT_PROP_HEADER)pbElement;
            hdr->propID = contextPropID;
            hdr->unknown = 1;
            hdr->cb = cbEncodedContext;
            memcpy(pbElement + sizeof(WINE_CERT_PROP_HEADER),
             encodedContext, cbEncodedContext);
        }
    }
    else
        ret = FALSE;
    return ret;
}

BOOL WINAPI CertSerializeCertificateStoreElement(PCCERT_CONTEXT pCertContext,
 DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement)
{
    return CRYPT_SerializeStoreElement(pCertContext,
     pCertContext->pbCertEncoded, pCertContext->cbCertEncoded,
     CERT_CERT_PROP_ID, pCertInterface, dwFlags, FALSE, pbElement, pcbElement);
}

BOOL WINAPI CertSerializeCRLStoreElement(PCCRL_CONTEXT pCrlContext,
 DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement)
{
    return CRYPT_SerializeStoreElement(pCrlContext,
     pCrlContext->pbCrlEncoded, pCrlContext->cbCrlEncoded,
     CERT_CRL_PROP_ID, pCRLInterface, dwFlags, FALSE, pbElement, pcbElement);
}

BOOL WINAPI CertSerializeCTLStoreElement(PCCTL_CONTEXT pCtlContext,
 DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement)
{
    return CRYPT_SerializeStoreElement(pCtlContext,
     pCtlContext->pbCtlEncoded, pCtlContext->cbCtlEncoded,
     CERT_CTL_PROP_ID, pCTLInterface, dwFlags, FALSE, pbElement, pcbElement);
}

/* Looks for the property with ID propID in the buffer buf.  Returns a pointer
 * to its header if a valid header is found, NULL if not.  Valid means the
 * length of thte property won't overrun buf, and the unknown field is 1.
 */
static const WINE_CERT_PROP_HEADER *CRYPT_findPropID(const BYTE *buf,
 DWORD size, DWORD propID)
{
    const WINE_CERT_PROP_HEADER *ret = NULL;
    BOOL done = FALSE;

    while (size && !ret && !done)
    {
        if (size < sizeof(WINE_CERT_PROP_HEADER))
        {
            SetLastError(CRYPT_E_FILE_ERROR);
            done = TRUE;
        }
        else
        {
            const WINE_CERT_PROP_HEADER *hdr =
             (const WINE_CERT_PROP_HEADER *)buf;

            size -= sizeof(WINE_CERT_PROP_HEADER);
            buf += sizeof(WINE_CERT_PROP_HEADER);
            if (size < hdr->cb)
            {
                SetLastError(E_INVALIDARG);
                done = TRUE;
            }
            else if (!hdr->propID)
            {
                /* assume a zero prop ID means the data are uninitialized, so
                 * stop looking.
                 */
                done = TRUE;
            }
            else if (hdr->unknown != 1)
            {
                SetLastError(ERROR_FILE_NOT_FOUND);
                done = TRUE;
            }
            else if (hdr->propID == propID)
                ret = hdr;
            else
            {
                buf += hdr->cb;
                size -= hdr->cb;
            }
        }
    }
    return ret;
}

static BOOL CRYPT_ReadContextProp(
 const WINE_CONTEXT_INTERFACE *contextInterface, const void *context,
 const WINE_CERT_PROP_HEADER *hdr, const BYTE *pbElement, DWORD cbElement)
{
    BOOL ret;

    if (cbElement < hdr->cb)
    {
        SetLastError(E_INVALIDARG);
        ret = FALSE;
    }
    else if (hdr->unknown != 1)
    {
        SetLastError(ERROR_FILE_NOT_FOUND);
        ret = FALSE;
    }
    else if (hdr->propID != CERT_CERT_PROP_ID &&
     hdr->propID != CERT_CRL_PROP_ID && hdr->propID != CERT_CTL_PROP_ID)
    {
        /* Have to create a blob for most types, but not
         * for all.. arghh.
         */
        switch (hdr->propID)
        {
        case CERT_AUTO_ENROLL_PROP_ID:
        case CERT_CTL_USAGE_PROP_ID:
        case CERT_DESCRIPTION_PROP_ID:
        case CERT_FRIENDLY_NAME_PROP_ID:
        case CERT_HASH_PROP_ID:
        case CERT_KEY_IDENTIFIER_PROP_ID:
        case CERT_MD5_HASH_PROP_ID:
        case CERT_NEXT_UPDATE_LOCATION_PROP_ID:
        case CERT_PUBKEY_ALG_PARA_PROP_ID:
        case CERT_PVK_FILE_PROP_ID:
        case CERT_SIGNATURE_HASH_PROP_ID:
        case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID:
        case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
        case CERT_ENROLLMENT_PROP_ID:
        case CERT_CROSS_CERT_DIST_POINTS_PROP_ID:
        case CERT_RENEWAL_PROP_ID:
        {
            CRYPT_DATA_BLOB blob = { hdr->cb,
             (LPBYTE)pbElement };

            ret = contextInterface->setProp(context,
             hdr->propID, 0, &blob);
            break;
        }
        case CERT_DATE_STAMP_PROP_ID:
            ret = contextInterface->setProp(context,
             hdr->propID, 0, pbElement);
            break;
        case CERT_KEY_PROV_INFO_PROP_ID:
        {
            PCRYPT_KEY_PROV_INFO info =
             (PCRYPT_KEY_PROV_INFO)pbElement;

            CRYPT_FixKeyProvInfoPointers(info);
            ret = contextInterface->setProp(context,
             hdr->propID, 0, pbElement);
            break;
        }
        default:
            ret = FALSE;
        }
    }
    else
    {
        /* ignore the context itself */
        ret = TRUE;
    }
    return ret;
}

const void *CRYPT_ReadSerializedElement(const BYTE *pbElement, DWORD cbElement,
 DWORD dwContextTypeFlags, DWORD *pdwContentType)
{
    const void *context;

    TRACE("(%p, %d, %08x, %p)\n", pbElement, cbElement, dwContextTypeFlags,
     pdwContentType);

    if (!cbElement)
    {
        SetLastError(ERROR_END_OF_MEDIA);
        return NULL;
    }

    __TRY
    {
        const WINE_CONTEXT_INTERFACE *contextInterface = NULL;
        const WINE_CERT_PROP_HEADER *hdr = NULL;
        DWORD type = 0;
        BOOL ret;

        ret = TRUE;
        context = NULL;
        if (dwContextTypeFlags == CERT_STORE_ALL_CONTEXT_FLAG)
        {
            hdr = CRYPT_findPropID(pbElement, cbElement, CERT_CERT_PROP_ID);
            if (hdr)
                type = CERT_STORE_CERTIFICATE_CONTEXT;
            else
            {
                hdr = CRYPT_findPropID(pbElement, cbElement, CERT_CRL_PROP_ID);
                if (hdr)
                    type = CERT_STORE_CRL_CONTEXT;
                else
                {
                    hdr = CRYPT_findPropID(pbElement, cbElement,
                     CERT_CTL_PROP_ID);
                    if (hdr)
                        type = CERT_STORE_CTL_CONTEXT;
                }
            }
        }
        else if (dwContextTypeFlags & CERT_STORE_CERTIFICATE_CONTEXT_FLAG)
        {
            hdr = CRYPT_findPropID(pbElement, cbElement, CERT_CERT_PROP_ID);
            type = CERT_STORE_CERTIFICATE_CONTEXT;
        }
        else if (dwContextTypeFlags & CERT_STORE_CRL_CONTEXT_FLAG)
        {
            hdr = CRYPT_findPropID(pbElement, cbElement, CERT_CRL_PROP_ID);
            type = CERT_STORE_CRL_CONTEXT;
        }
        else if (dwContextTypeFlags & CERT_STORE_CTL_CONTEXT_FLAG)
        {
            hdr = CRYPT_findPropID(pbElement, cbElement, CERT_CTL_PROP_ID);
            type = CERT_STORE_CTL_CONTEXT;
        }

        switch (type)
        {
        case CERT_STORE_CERTIFICATE_CONTEXT:
            contextInterface = pCertInterface;
            break;
        case CERT_STORE_CRL_CONTEXT:
            contextInterface = pCRLInterface;
            break;
        case CERT_STORE_CTL_CONTEXT:
            contextInterface = pCTLInterface;
            break;
        default:
            SetLastError(E_INVALIDARG);
            ret = FALSE;
        }
        if (!hdr)
            ret = FALSE;

        if (ret)
            context = contextInterface->create(X509_ASN_ENCODING,
             (BYTE *)hdr + sizeof(WINE_CERT_PROP_HEADER), hdr->cb);
        if (ret && context)
        {
            BOOL noMoreProps = FALSE;

            while (!noMoreProps && ret)
            {
                if (cbElement < sizeof(WINE_CERT_PROP_HEADER))
                    ret = FALSE;
                else
                {
                    const WINE_CERT_PROP_HEADER *hdr =
                     (const WINE_CERT_PROP_HEADER *)pbElement;

                    TRACE("prop is %d\n", hdr->propID);
                    cbElement -= sizeof(WINE_CERT_PROP_HEADER);
                    pbElement += sizeof(WINE_CERT_PROP_HEADER);
                    if (!hdr->propID)
                    {
                        /* Like in CRYPT_findPropID, stop if the propID is zero
                         */
                        noMoreProps = TRUE;
                    }
                    else
                        ret = CRYPT_ReadContextProp(contextInterface, context,
                         hdr, pbElement, cbElement);
                    pbElement += hdr->cb;
                    cbElement -= hdr->cb;
                    if (!cbElement)
                        noMoreProps = TRUE;
                }
            }
            if (ret)
            {
                if (pdwContentType)
                    *pdwContentType = type;
            }
            else
            {
                contextInterface->free(context);
                context = NULL;
            }
        }
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError(STATUS_ACCESS_VIOLATION);
        context = NULL;
    }
    __ENDTRY
    return context;
}

static const BYTE fileHeader[] = { 0, 0, 0, 0, 'C','E','R','T' };

BOOL CRYPT_ReadSerializedFile(HANDLE file, HCERTSTORE store)
{
    BYTE fileHeaderBuf[sizeof(fileHeader)];
    DWORD read;
    BOOL ret;

    /* Failure reading is non-critical, we'll leave the store empty */
    ret = ReadFile(file, fileHeaderBuf, sizeof(fileHeaderBuf), &read, NULL);
    if (ret)
    {
        if (!memcmp(fileHeaderBuf, fileHeader, read))
        {
            WINE_CERT_PROP_HEADER propHdr;
            const void *context = NULL;
            const WINE_CONTEXT_INTERFACE *contextInterface = NULL;
            LPBYTE buf = NULL;
            DWORD bufSize = 0;

            do {
                ret = ReadFile(file, &propHdr, sizeof(propHdr), &read, NULL);
                if (ret && read == sizeof(propHdr))
                {
                    if (contextInterface && context &&
                     (propHdr.propID == CERT_CERT_PROP_ID ||
                     propHdr.propID == CERT_CRL_PROP_ID ||
                     propHdr.propID == CERT_CTL_PROP_ID))
                    {
                        /* We have a new context, so free the existing one */
                        contextInterface->free(context);
                    }
                    if (propHdr.cb > bufSize)
                    {
                        /* Not reusing realloc, because the old data aren't
                         * needed any longer.
                         */
                        CryptMemFree(buf);
                        buf = CryptMemAlloc(propHdr.cb);
                        bufSize = propHdr.cb;
                    }
                    if (buf)
                    {
                        ret = ReadFile(file, buf, propHdr.cb, &read, NULL);
                        if (ret && read == propHdr.cb)
                        {
                            if (propHdr.propID == CERT_CERT_PROP_ID)
                            {
                                contextInterface = pCertInterface;
                                ret = contextInterface->addEncodedToStore(store,
                                 X509_ASN_ENCODING, buf, read,
                                 CERT_STORE_ADD_NEW, &context);
                            }
                            else if (propHdr.propID == CERT_CRL_PROP_ID)
                            {
                                contextInterface = pCRLInterface;
                                ret = contextInterface->addEncodedToStore(store,
                                 X509_ASN_ENCODING, buf, read,
                                 CERT_STORE_ADD_NEW, &context);
                            }
                            else if (propHdr.propID == CERT_CTL_PROP_ID)
                            {
                                contextInterface = pCTLInterface;
                                ret = contextInterface->addEncodedToStore(store,
                                 X509_ASN_ENCODING, buf, read,
                                 CERT_STORE_ADD_NEW, &context);
                            }
                            else
                                ret = CRYPT_ReadContextProp(contextInterface,
                                 context, &propHdr, buf, read);
                        }
                    }
                    else
                        ret = FALSE;
                }
            } while (ret && read > 0);
            if (contextInterface && context)
            {
                /* Free the last context added */
                contextInterface->free(context);
            }
            CryptMemFree(buf);
            ret = TRUE;
        }
    }
    else
        ret = TRUE;
    return ret;
}

static BOOL WINAPI CRYPT_SerializeCertNoHash(PCCERT_CONTEXT pCertContext,
 DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement)
{
    return CRYPT_SerializeStoreElement(pCertContext,
     pCertContext->pbCertEncoded, pCertContext->cbCertEncoded,
     CERT_CERT_PROP_ID, pCertInterface, dwFlags, TRUE, pbElement, pcbElement);
}

static BOOL WINAPI CRYPT_SerializeCRLNoHash(PCCRL_CONTEXT pCrlContext,
 DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement)
{
    return CRYPT_SerializeStoreElement(pCrlContext,
     pCrlContext->pbCrlEncoded, pCrlContext->cbCrlEncoded,
     CERT_CRL_PROP_ID, pCRLInterface, dwFlags, TRUE, pbElement, pcbElement);
}

static BOOL WINAPI CRYPT_SerializeCTLNoHash(PCCTL_CONTEXT pCtlContext,
 DWORD dwFlags, BYTE *pbElement, DWORD *pcbElement)
{
    return CRYPT_SerializeStoreElement(pCtlContext,
     pCtlContext->pbCtlEncoded, pCtlContext->cbCtlEncoded,
     CERT_CTL_PROP_ID, pCTLInterface, dwFlags, TRUE, pbElement, pcbElement);
}

static BOOL CRYPT_SerializeContextsToFile(HANDLE file,
 const WINE_CONTEXT_INTERFACE *contextInterface, HCERTSTORE store)
{
    const void *context = NULL;
    BOOL ret;

    do {
        context = contextInterface->enumContextsInStore(store, context);
        if (context)
        {
            DWORD size = 0;
            LPBYTE buf = NULL;

            ret = contextInterface->serialize(context, 0, NULL, &size);
            if (size)
                buf = CryptMemAlloc(size);
            if (buf)
            {
                ret = contextInterface->serialize(context, 0, buf, &size);
                if (ret)
                    ret = WriteFile(file, buf, size, &size, NULL);
            }
            CryptMemFree(buf);
        }
        else
            ret = TRUE;
    } while (ret && context != NULL);
    if (context)
        contextInterface->free(context);
    return ret;
}

BOOL CRYPT_WriteSerializedFile(HANDLE file, HCERTSTORE store)
{
    static const BYTE fileTrailer[12] = { 0 };
    WINE_CONTEXT_INTERFACE interface;
    BOOL ret;
    DWORD size;

    SetFilePointer(file, 0, NULL, FILE_BEGIN);
    ret = WriteFile(file, fileHeader, sizeof(fileHeader), &size, NULL);
    if (ret)
    {
        memcpy(&interface, pCertInterface, sizeof(interface));
        interface.serialize = (SerializeElementFunc)CRYPT_SerializeCertNoHash;
        ret = CRYPT_SerializeContextsToFile(file, &interface, store);
    }
    if (ret)
    {
        memcpy(&interface, pCRLInterface, sizeof(interface));
        interface.serialize = (SerializeElementFunc)CRYPT_SerializeCRLNoHash;
        ret = CRYPT_SerializeContextsToFile(file, &interface, store);
    }
    if (ret)
    {
        memcpy(&interface, pCTLInterface, sizeof(interface));
        interface.serialize = (SerializeElementFunc)CRYPT_SerializeCTLNoHash;
        ret = CRYPT_SerializeContextsToFile(file, &interface, store);
    }
    if (ret)
        ret = WriteFile(file, fileTrailer, sizeof(fileTrailer), &size, NULL);
    return ret;
}

BOOL WINAPI CertAddSerializedElementToStore(HCERTSTORE hCertStore,
 const BYTE *pbElement, DWORD cbElement, DWORD dwAddDisposition, DWORD dwFlags,
 DWORD dwContextTypeFlags, DWORD *pdwContentType, const void **ppvContext)
{
    const void *context;
    DWORD type;
    BOOL ret;

    TRACE("(%p, %p, %d, %08x, %08x, %08x, %p, %p)\n", hCertStore,
     pbElement, cbElement, dwAddDisposition, dwFlags, dwContextTypeFlags,
     pdwContentType, ppvContext);

    /* Call the internal function, then delete the hashes.  Tests show this
     * function uses real hash values, not whatever's stored in the hash
     * property.
     */
    context = CRYPT_ReadSerializedElement(pbElement, cbElement,
     dwContextTypeFlags, &type);
    if (context)
    {
        const WINE_CONTEXT_INTERFACE *contextInterface = NULL;

        switch (type)
        {
        case CERT_STORE_CERTIFICATE_CONTEXT:
            contextInterface = pCertInterface;
            break;
        case CERT_STORE_CRL_CONTEXT:
            contextInterface = pCRLInterface;
            break;
        case CERT_STORE_CTL_CONTEXT:
            contextInterface = pCTLInterface;
            break;
        default:
            SetLastError(E_INVALIDARG);
        }
        if (contextInterface)
        {
            contextInterface->setProp(context, CERT_HASH_PROP_ID, 0, NULL);
            contextInterface->setProp(context, CERT_MD5_HASH_PROP_ID, 0, NULL);
            contextInterface->setProp(context, CERT_SIGNATURE_HASH_PROP_ID, 0,
             NULL);
            if (pdwContentType)
                *pdwContentType = type;
            ret = contextInterface->addContextToStore(hCertStore, context,
             dwAddDisposition, ppvContext);
            contextInterface->free(context);
        }
        else
            ret = FALSE;
    }
    else
        ret = FALSE;
    return ret;
}
