/*
 * Copyright 2006 Juan Lang for CodeWeavers
 *
 * 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 "winnls.h"
#include "winuser.h"
#include "wincrypt.h"
#include "wine/debug.h"
#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(crypt);

DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
 LPSTR psz, DWORD csz)
{
    DWORD ret = 0;

    TRACE("(%d, %p, %p, %d)\n", dwValueType, pValue, psz, csz);

    switch (dwValueType)
    {
    case CERT_RDN_ANY_TYPE:
        break;
    case CERT_RDN_NUMERIC_STRING:
    case CERT_RDN_PRINTABLE_STRING:
    case CERT_RDN_TELETEX_STRING:
    case CERT_RDN_VIDEOTEX_STRING:
    case CERT_RDN_IA5_STRING:
    case CERT_RDN_GRAPHIC_STRING:
    case CERT_RDN_VISIBLE_STRING:
    case CERT_RDN_GENERAL_STRING:
        if (!psz || !csz)
            ret = pValue->cbData;
        else
        {
            DWORD chars = min(pValue->cbData, csz - 1);

            if (chars)
            {
                memcpy(psz, pValue->pbData, chars);
                ret += chars;
                csz -= chars;
            }
        }
        break;
    default:
        FIXME("string type %d unimplemented\n", dwValueType);
    }
    if (psz && csz)
    {
        *(psz + ret) = '\0';
        csz--;
        ret++;
    }
    else
        ret++;
    TRACE("returning %d (%s)\n", ret, debugstr_a(psz));
    return ret;
}

DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
 LPWSTR psz, DWORD csz)
{
    DWORD ret = 0;

    TRACE("(%d, %p, %p, %d)\n", dwValueType, pValue, psz, csz);

    switch (dwValueType)
    {
    case CERT_RDN_ANY_TYPE:
        break;
    case CERT_RDN_NUMERIC_STRING:
    case CERT_RDN_PRINTABLE_STRING:
    case CERT_RDN_TELETEX_STRING:
    case CERT_RDN_VIDEOTEX_STRING:
    case CERT_RDN_IA5_STRING:
    case CERT_RDN_GRAPHIC_STRING:
    case CERT_RDN_VISIBLE_STRING:
    case CERT_RDN_GENERAL_STRING:
        if (!psz || !csz)
            ret = pValue->cbData;
        else
        {
            DWORD chars = min(pValue->cbData, csz - 1);

            if (chars)
            {
                DWORD i;

                for (i = 0; i < chars; i++)
                    psz[i] = pValue->pbData[i];
                ret += chars;
                csz -= chars;
            }
        }
        break;
    default:
        FIXME("string type %d unimplemented\n", dwValueType);
    }
    if (psz && csz)
    {
        *(psz + ret) = '\0';
        csz--;
        ret++;
    }
    else
        ret++;
    TRACE("returning %d (%s)\n", ret, debugstr_w(psz));
    return ret;
}

/* Adds the prefix prefix to the string pointed to by psz, followed by the
 * character '='.  Copies no more than csz characters.  Returns the number of
 * characters copied.  If psz is NULL, returns the number of characters that
 * would be copied.
 */
static DWORD CRYPT_AddPrefixA(LPCSTR prefix, LPSTR psz, DWORD csz)
{
    DWORD chars;

    TRACE("(%s, %p, %d)\n", debugstr_a(prefix), psz, csz);

    if (psz)
    {
        chars = min(lstrlenA(prefix), csz);
        memcpy(psz, prefix, chars);
        csz -= chars;
        *(psz + chars) = '=';
        chars++;
        csz--;
    }
    else
        chars = lstrlenA(prefix) + 1;
    return chars;
}

DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
 DWORD dwStrType, LPSTR psz, DWORD csz)
{
    static const DWORD unsupportedFlags = CERT_NAME_STR_NO_QUOTING_FLAG |
     CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG;
    static const char commaSep[] = ", ";
    static const char semiSep[] = "; ";
    static const char crlfSep[] = "\r\n";
    static const char plusSep[] = " + ";
    static const char spaceSep[] = " ";
    DWORD ret = 0, bytes = 0;
    BOOL bRet;
    CERT_NAME_INFO *info;

    TRACE("(%d, %p, %08x, %p, %d)\n", dwCertEncodingType, pName, dwStrType,
     psz, csz);
    if (dwStrType & unsupportedFlags)
        FIXME("unsupported flags: %08x\n", dwStrType & unsupportedFlags);

    bRet = CryptDecodeObjectEx(dwCertEncodingType, X509_NAME, pName->pbData,
     pName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &bytes);
    if (bRet)
    {
        DWORD i, j, sepLen, rdnSepLen;
        LPCSTR sep, rdnSep;

        if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG)
            sep = semiSep;
        else if (dwStrType & CERT_NAME_STR_CRLF_FLAG)
            sep = crlfSep;
        else
            sep = commaSep;
        sepLen = strlen(sep);
        if (dwStrType & CERT_NAME_STR_NO_PLUS_FLAG)
            rdnSep = spaceSep;
        else
            rdnSep = plusSep;
        rdnSepLen = strlen(rdnSep);
        for (i = 0; (!psz || ret < csz) && i < info->cRDN; i++)
        {
            for (j = 0; (!psz || ret < csz) && j < info->rgRDN[i].cRDNAttr; j++)
            {
                DWORD chars;
                char prefixBuf[10]; /* big enough for GivenName */
                LPCSTR prefix = NULL;

                if ((dwStrType & 0x000000ff) == CERT_OID_NAME_STR)
                    prefix = info->rgRDN[i].rgRDNAttr[j].pszObjId;
                else if ((dwStrType & 0x000000ff) == CERT_X500_NAME_STR)
                {
                    PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(
                     CRYPT_OID_INFO_OID_KEY,
                     info->rgRDN[i].rgRDNAttr[j].pszObjId,
                     CRYPT_RDN_ATTR_OID_GROUP_ID);

                    if (oidInfo)
                    {
                        WideCharToMultiByte(CP_ACP, 0, oidInfo->pwszName, -1,
                         prefixBuf, sizeof(prefixBuf), NULL, NULL);
                        prefix = prefixBuf;
                    }
                    else
                        prefix = info->rgRDN[i].rgRDNAttr[j].pszObjId;
                }
                if (prefix)
                {
                    /* - 1 is needed to account for the NULL terminator. */
                    chars = CRYPT_AddPrefixA(prefix,
                     psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0);
                    ret += chars;
                    csz -= chars;
                }
                /* FIXME: handle quoting */
                chars = CertRDNValueToStrA(
                 info->rgRDN[i].rgRDNAttr[j].dwValueType, 
                 &info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL,
                 psz ? csz - ret : 0);
                if (chars)
                    ret += chars - 1;
                if (j < info->rgRDN[i].cRDNAttr - 1)
                {
                    if (psz && ret < csz - rdnSepLen - 1)
                        memcpy(psz + ret, rdnSep, rdnSepLen);
                    ret += rdnSepLen;
                }
            }
            if (i < info->cRDN - 1)
            {
                if (psz && ret < csz - sepLen - 1)
                    memcpy(psz + ret, sep, sepLen);
                ret += sepLen;
            }
        }
        LocalFree(info);
    }
    if (psz && csz)
    {
        *(psz + ret) = '\0';
        csz--;
        ret++;
    }
    else
        ret++;
    TRACE("Returning %s\n", debugstr_a(psz));
    return ret;
}

/* Adds the prefix prefix to the wide-character string pointed to by psz,
 * followed by the character '='.  Copies no more than csz characters.  Returns
 * the number of characters copied.  If psz is NULL, returns the number of
 * characters that would be copied.
 * Assumes the characters in prefix are ASCII (not multibyte characters.)
 */
static DWORD CRYPT_AddPrefixAToW(LPCSTR prefix, LPWSTR psz, DWORD csz)
{
    DWORD chars;

    TRACE("(%s, %p, %d)\n", debugstr_a(prefix), psz, csz);

    if (psz)
    {
        DWORD i;

        chars = min(lstrlenA(prefix), csz);
        for (i = 0; i < chars; i++)
            *(psz + i) = prefix[i];
        csz -= chars;
        *(psz + chars) = '=';
        chars++;
        csz--;
    }
    else
        chars = lstrlenA(prefix) + 1;
    return chars;
}

/* Adds the prefix prefix to the string pointed to by psz, followed by the
 * character '='.  Copies no more than csz characters.  Returns the number of
 * characters copied.  If psz is NULL, returns the number of characters that
 * would be copied.
 */
static DWORD CRYPT_AddPrefixW(LPCWSTR prefix, LPWSTR psz, DWORD csz)
{
    DWORD chars;

    TRACE("(%s, %p, %d)\n", debugstr_w(prefix), psz, csz);

    if (psz)
    {
        chars = min(lstrlenW(prefix), csz);
        memcpy(psz, prefix, chars * sizeof(WCHAR));
        csz -= chars;
        *(psz + chars) = '=';
        chars++;
        csz--;
    }
    else
        chars = lstrlenW(prefix) + 1;
    return chars;
}

DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
 DWORD dwStrType, LPWSTR psz, DWORD csz)
{
    static const DWORD unsupportedFlags = CERT_NAME_STR_NO_QUOTING_FLAG |
     CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG;
    static const WCHAR commaSep[] = { ',',' ',0 };
    static const WCHAR semiSep[] = { ';',' ',0 };
    static const WCHAR crlfSep[] = { '\r','\n',0 };
    static const WCHAR plusSep[] = { ' ','+',' ',0 };
    static const WCHAR spaceSep[] = { ' ',0 };
    DWORD ret = 0, bytes = 0;
    BOOL bRet;
    CERT_NAME_INFO *info;

    TRACE("(%d, %p, %08x, %p, %d)\n", dwCertEncodingType, pName, dwStrType,
     psz, csz);
    if (dwStrType & unsupportedFlags)
        FIXME("unsupported flags: %08x\n", dwStrType & unsupportedFlags);

    bRet = CryptDecodeObjectEx(dwCertEncodingType, X509_NAME, pName->pbData,
     pName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &bytes);
    if (bRet)
    {
        DWORD i, j, sepLen, rdnSepLen;
        LPCWSTR sep, rdnSep;

        if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG)
            sep = semiSep;
        else if (dwStrType & CERT_NAME_STR_CRLF_FLAG)
            sep = crlfSep;
        else
            sep = commaSep;
        sepLen = lstrlenW(sep);
        if (dwStrType & CERT_NAME_STR_NO_PLUS_FLAG)
            rdnSep = spaceSep;
        else
            rdnSep = plusSep;
        rdnSepLen = lstrlenW(rdnSep);
        for (i = 0; (!psz || ret < csz) && i < info->cRDN; i++)
        {
            for (j = 0; (!psz || ret < csz) && j < info->rgRDN[i].cRDNAttr; j++)
            {
                DWORD chars;
                LPCSTR prefixA = NULL;
                LPCWSTR prefixW = NULL;

                if ((dwStrType & 0x000000ff) == CERT_OID_NAME_STR)
                    prefixA = info->rgRDN[i].rgRDNAttr[j].pszObjId;
                else if ((dwStrType & 0x000000ff) == CERT_X500_NAME_STR)
                {
                    PCCRYPT_OID_INFO oidInfo = CryptFindOIDInfo(
                     CRYPT_OID_INFO_OID_KEY,
                     info->rgRDN[i].rgRDNAttr[j].pszObjId,
                     CRYPT_RDN_ATTR_OID_GROUP_ID);

                    if (oidInfo)
                        prefixW = oidInfo->pwszName;
                    else
                        prefixA = info->rgRDN[i].rgRDNAttr[j].pszObjId;
                }
                if (prefixW)
                {
                    /* - 1 is needed to account for the NULL terminator. */
                    chars = CRYPT_AddPrefixW(prefixW,
                     psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0);
                    ret += chars;
                    csz -= chars;
                }
                else if (prefixA)
                {
                    /* - 1 is needed to account for the NULL terminator. */
                    chars = CRYPT_AddPrefixAToW(prefixA,
                     psz ? psz + ret : NULL, psz ? csz - ret - 1 : 0);
                    ret += chars;
                    csz -= chars;
                }
                /* FIXME: handle quoting */
                chars = CertRDNValueToStrW(
                 info->rgRDN[i].rgRDNAttr[j].dwValueType, 
                 &info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL,
                 psz ? csz - ret : 0);
                if (chars)
                    ret += chars - 1;
                if (j < info->rgRDN[i].cRDNAttr - 1)
                {
                    if (psz && ret < csz - rdnSepLen - 1)
                        memcpy(psz + ret, rdnSep, rdnSepLen * sizeof(WCHAR));
                    ret += rdnSepLen;
                }
            }
            if (i < info->cRDN - 1)
            {
                if (psz && ret < csz - sepLen - 1)
                    memcpy(psz + ret, sep, sepLen * sizeof(WCHAR));
                ret += sepLen;
            }
        }
        LocalFree(info);
    }
    if (psz && csz)
    {
        *(psz + ret) = '\0';
        csz--;
        ret++;
    }
    else
        ret++;
    TRACE("Returning %s\n", debugstr_w(psz));
    return ret;
}

BOOL WINAPI CertStrToNameA(DWORD dwCertEncodingType, LPCSTR pszX500,
 DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded,
 LPCSTR *ppszError)
{
    LPWSTR x500, errorStr;
    BOOL ret;
    int len;

    TRACE("(%08x, %s, %08x, %p, %p, %p, %p)\n", dwCertEncodingType,
     debugstr_a(pszX500), dwStrType, pvReserved, pbEncoded, pcbEncoded,
     ppszError);

    len = MultiByteToWideChar(CP_ACP, 0, pszX500, -1, NULL, 0);
    x500 = CryptMemAlloc(len * sizeof(WCHAR));
    if (x500)
    {
        MultiByteToWideChar(CP_ACP, 0, pszX500, -1, x500, len);
        ret = CertStrToNameW(dwCertEncodingType, x500, dwStrType, pvReserved,
         pbEncoded, pcbEncoded, ppszError ? (LPCWSTR *)&errorStr : NULL);
        if (ppszError)
        {
            DWORD i;

            *ppszError = pszX500;
            for (i = 0; i < errorStr - x500; i++)
                CharNextA(*ppszError);
        }
        CryptMemFree(x500);
    }
    else
        ret = FALSE;
    return ret;
}

struct KeynameKeeper
{
    WCHAR  buf[10]; /* big enough for L"GivenName" */
    LPWSTR keyName; /* usually = buf, but may be allocated */
    DWORD  keyLen;
};

static void CRYPT_InitializeKeynameKeeper(struct KeynameKeeper *keeper)
{
    keeper->keyName = keeper->buf;
    keeper->keyLen = sizeof(keeper->buf) / sizeof(keeper->buf[0]);
}

static void CRYPT_FreeKeynameKeeper(struct KeynameKeeper *keeper)
{
    if (keeper->keyName != keeper->buf)
        CryptMemFree(keeper->keyName);
}

struct X500TokenW
{
    LPCWSTR start;
    LPCWSTR end;
};

static void CRYPT_KeynameKeeperFromTokenW(struct KeynameKeeper *keeper,
 struct X500TokenW *key)
{
    DWORD len = key->end - key->start;

    if (len > keeper->keyLen)
    {
        if (keeper->keyName == keeper->buf)
            keeper->keyName = CryptMemAlloc(len * sizeof(WCHAR));
        else
            keeper->keyName = CryptMemRealloc(keeper->keyName,
             len * sizeof(WCHAR));
        keeper->keyLen = len;
    }
    memcpy(keeper->keyName, key->start, (key->end - key->start) *
     sizeof(WCHAR));
    keeper->keyName[len] = '\0';
    TRACE("Keyname is %s\n", debugstr_w(keeper->keyName));
}

static DWORD CRYPT_GetNextKeyW(LPCWSTR str, struct X500TokenW *token,
 LPCWSTR *ppszError)
{
    DWORD ret = ERROR_SUCCESS;

    while (*str && isspaceW(*str))
        str++;
    if (*str)
    {
        token->start = str;
        while (*str && *str != '=' && !isspaceW(*str))
            str++;
        if (*str && (*str == '=' || isspaceW(*str)))
            token->end = str;
        else
        {
            TRACE("missing equals char at %s\n", debugstr_w(token->start));
            if (ppszError)
                *ppszError = token->start;
            ret = CRYPT_E_INVALID_X500_STRING;
        }
    }
    else
        token->start = NULL;
    return ret;
}

/* Assumes separators are characters in the 0-255 range */
static DWORD CRYPT_GetNextValueW(LPCWSTR str, DWORD dwFlags, LPCWSTR separators,
 struct X500TokenW *token, LPCWSTR *ppszError)
{
    DWORD ret = ERROR_SUCCESS;

    TRACE("(%s, %s, %p, %p)\n", debugstr_w(str), debugstr_w(separators), token,
     ppszError);

    while (*str && isspaceW(*str))
        str++;
    if (*str)
    {
        token->start = str;
        if (!(dwFlags & CERT_NAME_STR_NO_QUOTING_FLAG) && *str == '"')
        {
            token->end = NULL;
            str++;
            while (!token->end && !ret)
            {
                while (*str && *str != '"')
                    str++;
                if (*str == '"')
                {
                    if (*(str + 1) != '"')
                        token->end = str + 1;
                    else
                        str += 2;
                }
                else
                {
                    TRACE("unterminated quote at %s\n", debugstr_w(str));
                    if (ppszError)
                        *ppszError = str;
                    ret = CRYPT_E_INVALID_X500_STRING;
                }
            }
        }
        else
        {
            WCHAR map[256] = { 0 };

            while (*separators)
                map[*separators++] = 1;
            while (*str && (*str >= 0xff || !map[*(const unsigned short *)str]))
                str++;
            token->end = str;
        }
    }
    else
    {
        TRACE("missing value at %s\n", debugstr_w(str));
        if (ppszError)
            *ppszError = str;
        ret = CRYPT_E_INVALID_X500_STRING;
    }
    return ret;
}

/* Encodes the string represented by value as the string type type into the
 * CERT_NAME_BLOB output.  If there is an error and ppszError is not NULL,
 * *ppszError is set to the first failing character.  If there is no error,
 * output's pbData must be freed with LocalFree.
 */
static BOOL CRYPT_EncodeValueWithType(DWORD dwCertEncodingType,
 struct X500TokenW *value, PCERT_NAME_BLOB output, DWORD type,
 LPCWSTR *ppszError)
{
    CERT_NAME_VALUE nameValue = { type, { 0, NULL } };
    BOOL ret = FALSE;

    nameValue.Value.pbData = CryptMemAlloc((value->end - value->start) *
     sizeof(WCHAR));
    if (nameValue.Value.pbData)
    {
        DWORD i;
        LPWSTR ptr = (LPWSTR)nameValue.Value.pbData;

        for (i = 0; i < value->end - value->start; i++)
        {
            *ptr++ = value->start[i];
            if (value->start[i] == '"')
                i++;
        }
        nameValue.Value.cbData = (LPBYTE)ptr - nameValue.Value.pbData;
        ret = CryptEncodeObjectEx(dwCertEncodingType, X509_UNICODE_NAME_VALUE,
         &nameValue, CRYPT_ENCODE_ALLOC_FLAG, NULL, &output->pbData,
         &output->cbData);
        if (!ret && ppszError)
        {
            if (type == CERT_RDN_NUMERIC_STRING &&
             GetLastError() == CRYPT_E_INVALID_NUMERIC_STRING)
                *ppszError = value->start + output->cbData;
            else if (type == CERT_RDN_PRINTABLE_STRING &&
             GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING)
                *ppszError = value->start + output->cbData;
            else if (type == CERT_RDN_IA5_STRING &&
             GetLastError() == CRYPT_E_INVALID_IA5_STRING)
                *ppszError = value->start + output->cbData;
        }
        CryptMemFree(nameValue.Value.pbData);
    }
    return ret;
}

static BOOL CRYPT_EncodeValue(DWORD dwCertEncodingType,
 struct X500TokenW *value, PCERT_NAME_BLOB output, const DWORD *types,
 LPCWSTR *ppszError)
{
    DWORD i;
    BOOL ret;

    ret = FALSE;
    for (i = 0; !ret && types[i]; i++)
        ret = CRYPT_EncodeValueWithType(dwCertEncodingType, value, output,
         types[i], ppszError);
    return ret;
}

static BOOL CRYPT_ValueToRDN(DWORD dwCertEncodingType, PCERT_NAME_INFO info,
 PCCRYPT_OID_INFO keyOID, struct X500TokenW *value, LPCWSTR *ppszError)
{
    BOOL ret = FALSE;

    TRACE("OID %s, value %s\n", debugstr_a(keyOID->pszOID),
     debugstr_wn(value->start, value->end - value->start));

    if (!info->rgRDN)
        info->rgRDN = CryptMemAlloc(sizeof(CERT_RDN));
    else
        info->rgRDN = CryptMemRealloc(info->rgRDN,
         (info->cRDN + 1) * sizeof(CERT_RDN));
    if (info->rgRDN)
    {
        /* FIXME: support multiple RDN attrs */
        info->rgRDN[info->cRDN].rgRDNAttr =
         CryptMemAlloc(sizeof(CERT_RDN_ATTR));
        if (info->rgRDN[info->cRDN].rgRDNAttr)
        {
            static const DWORD defaultTypes[] = { CERT_RDN_PRINTABLE_STRING,
             CERT_RDN_BMP_STRING, 0 };
            const DWORD *types;

            info->rgRDN[info->cRDN].cRDNAttr = 1;
            info->rgRDN[info->cRDN].rgRDNAttr[0].pszObjId =
             (LPSTR)keyOID->pszOID;
            info->rgRDN[info->cRDN].rgRDNAttr[0].dwValueType =
             CERT_RDN_ENCODED_BLOB;
            if (keyOID->ExtraInfo.cbData)
                types = (const DWORD *)keyOID->ExtraInfo.pbData;
            else
                types = defaultTypes;

            /* Remove surrounding quotes */
            if (value->start[0] == '"')
            {
                value->start++;
                value->end--;
            }
            ret = CRYPT_EncodeValue(dwCertEncodingType, value,
             &info->rgRDN[info->cRDN].rgRDNAttr[0].Value, types, ppszError);
        }
    }
    if (ret)
        info->cRDN++;
    return ret;
}

BOOL WINAPI CertStrToNameW(DWORD dwCertEncodingType, LPCWSTR pszX500,
 DWORD dwStrType, void *pvReserved, BYTE *pbEncoded, DWORD *pcbEncoded,
 LPCWSTR *ppszError)
{
    CERT_NAME_INFO info = { 0, NULL };
    LPCWSTR str;
    struct KeynameKeeper keeper;
    DWORD i, error = ERROR_SUCCESS;
    BOOL ret = TRUE;

    TRACE("(%08x, %s, %08x, %p, %p, %p, %p)\n", dwCertEncodingType,
     debugstr_w(pszX500), dwStrType, pvReserved, pbEncoded, pcbEncoded,
     ppszError);

    CRYPT_InitializeKeynameKeeper(&keeper);
    str = pszX500;
    while (str && *str && !error && ret)
    {
        struct X500TokenW token;

        error = CRYPT_GetNextKeyW(str, &token, ppszError);
        if (!error && token.start)
        {
            PCCRYPT_OID_INFO keyOID;

            CRYPT_KeynameKeeperFromTokenW(&keeper, &token);
            keyOID = CryptFindOIDInfo(CRYPT_OID_INFO_NAME_KEY, keeper.keyName,
             CRYPT_RDN_ATTR_OID_GROUP_ID);
            if (!keyOID)
            {
                if (ppszError)
                    *ppszError = token.start;
                error = CRYPT_E_INVALID_X500_STRING;
            }
            else
            {
                str = token.end;
                while (isspace(*str))
                    str++;
                if (*str != '=')
                {
                    if (ppszError)
                        *ppszError = str;
                    error = CRYPT_E_INVALID_X500_STRING;
                }
                else
                {
                    static const WCHAR commaSep[] = { ',',0 };
                    static const WCHAR semiSep[] = { ';',0 };
                    static const WCHAR crlfSep[] = { '\r','\n',0 };
                    static const WCHAR allSeps[] = { ',',';','\r','\n',0 };
                    LPCWSTR sep;

                    str++;
                    if (dwStrType & CERT_NAME_STR_COMMA_FLAG)
                        sep = commaSep;
                    else if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG)
                        sep = semiSep;
                    else if (dwStrType & CERT_NAME_STR_CRLF_FLAG)
                        sep = crlfSep;
                    else
                        sep = allSeps;
                    error = CRYPT_GetNextValueW(str, dwStrType, sep, &token,
                     ppszError);
                    if (!error)
                    {
                        str = token.end;
                        ret = CRYPT_ValueToRDN(dwCertEncodingType, &info,
                         keyOID, &token, ppszError);
                    }
                }
            }
        }
    }
    CRYPT_FreeKeynameKeeper(&keeper);
    if (!error)
    {
        ret = CryptEncodeObjectEx(dwCertEncodingType, X509_NAME, &info,
         0, NULL, pbEncoded, pcbEncoded);
        for (i = 0; i < info.cRDN; i++)
        {
            DWORD j;

            for (j = 0; j < info.rgRDN[i].cRDNAttr; j++)
                LocalFree(info.rgRDN[i].rgRDNAttr[j].Value.pbData);
            CryptMemFree(info.rgRDN[i].rgRDNAttr);
        }
        CryptMemFree(info.rgRDN);
    }
    else
    {
        SetLastError(error);
        ret = FALSE;
    }
    return ret;
}

DWORD WINAPI CertGetNameStringA(PCCERT_CONTEXT pCertContext, DWORD dwType,
 DWORD dwFlags, void *pvTypePara, LPSTR pszNameString, DWORD cchNameString)
{
    DWORD ret;

    TRACE("(%p, %d, %08x, %p, %p, %d)\n", pCertContext, dwType, dwFlags,
     pvTypePara, pszNameString, cchNameString);

    if (pszNameString)
    {
        LPWSTR wideName;
        DWORD nameLen;

        nameLen = CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara,
         NULL, 0);
        wideName = CryptMemAlloc(nameLen * sizeof(WCHAR));
        if (wideName)
        {
            CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara,
             wideName, nameLen);
            nameLen = WideCharToMultiByte(CP_ACP, 0, wideName, nameLen,
             pszNameString, cchNameString, NULL, NULL);
            if (nameLen <= cchNameString)
                ret = nameLen;
            else
            {
                pszNameString[cchNameString - 1] = '\0';
                ret = cchNameString;
            }
            CryptMemFree(wideName);
        }
        else
        {
            *pszNameString = '\0';
            ret = 1;
        }
    }
    else
        ret = CertGetNameStringW(pCertContext, dwType, dwFlags, pvTypePara,
         NULL, 0);
    return ret;
}

DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
 DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString)
{
    DWORD ret;
    PCERT_NAME_BLOB name;
    LPCSTR altNameOID;

    TRACE("(%p, %d, %08x, %p, %p, %d)\n", pCertContext, dwType,
     dwFlags, pvTypePara, pszNameString, cchNameString);

    if (dwFlags & CERT_NAME_ISSUER_FLAG)
    {
        name = &pCertContext->pCertInfo->Issuer;
        altNameOID = szOID_ISSUER_ALT_NAME;
    }
    else
    {
        name = &pCertContext->pCertInfo->Subject;
        altNameOID = szOID_SUBJECT_ALT_NAME;
    }

    switch (dwType)
    {
    case CERT_NAME_SIMPLE_DISPLAY_TYPE:
    {
        static const LPCSTR simpleAttributeOIDs[] = { szOID_COMMON_NAME,
         szOID_ORGANIZATIONAL_UNIT_NAME, szOID_ORGANIZATION_NAME,
         szOID_RSA_emailAddr };
        CERT_NAME_INFO *info = NULL;
        PCERT_RDN_ATTR nameAttr = NULL;
        DWORD bytes = 0, i;

        if (CryptDecodeObjectEx(pCertContext->dwCertEncodingType, X509_NAME,
         name->pbData, name->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info,
         &bytes))
        {
            for (i = 0; !nameAttr && i < sizeof(simpleAttributeOIDs) /
             sizeof(simpleAttributeOIDs[0]); i++)
                nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], info);
        }
        else
            ret = 0;
        if (!nameAttr)
        {
            PCERT_EXTENSION ext = CertFindExtension(altNameOID,
             pCertContext->pCertInfo->cExtension,
             pCertContext->pCertInfo->rgExtension);

            if (ext)
            {
                for (i = 0; !nameAttr && i < sizeof(simpleAttributeOIDs) /
                 sizeof(simpleAttributeOIDs[0]); i++)
                    nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], info);
                if (!nameAttr)
                {
                    /* FIXME: gotta then look for a rfc822Name choice in ext.
                     * Failing that, look for the first attribute.
                     */
                    FIXME("CERT_NAME_SIMPLE_DISPLAY_TYPE: stub\n");
                    ret = 0;
                }
            }
        }
        ret = CertRDNValueToStrW(nameAttr->dwValueType, &nameAttr->Value,
         pszNameString, cchNameString);
        if (info)
            LocalFree(info);
        break;
    }
    case CERT_NAME_FRIENDLY_DISPLAY_TYPE:
    {
        DWORD cch = cchNameString;

        if (CertGetCertificateContextProperty(pCertContext,
         CERT_FRIENDLY_NAME_PROP_ID, pszNameString, &cch))
            ret = cch;
        else
            ret = CertGetNameStringW(pCertContext,
             CERT_NAME_SIMPLE_DISPLAY_TYPE, dwFlags, pvTypePara, pszNameString,
             cchNameString);
        break;
    }
    default:
        FIXME("unimplemented for type %d\n", dwType);
        ret = 0;
    }
    return ret;
}
