Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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);
        }
        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");
                }
            }
        }
        if (nameAttr)
            ret = CertRDNValueToStrW(nameAttr->dwValueType, &nameAttr->Value,
                                     pszNameString, cchNameString);
        else
            ret = 0;
        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;
}
Ejemplo n.º 3
0
Archivo: str.c Proyecto: wesgarner/wine
DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
 DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString)
{
    DWORD ret = 0;
    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_EMAIL_TYPE:
    {
        CERT_ALT_NAME_INFO *info;
        PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
         altNameOID, CERT_ALT_NAME_RFC822_NAME, &info);

        if (entry)
        {
            if (!pszNameString)
                ret = strlenW(entry->u.pwszRfc822Name) + 1;
            else if (cchNameString)
            {
                ret = min(strlenW(entry->u.pwszRfc822Name), cchNameString - 1);
                memcpy(pszNameString, entry->u.pwszRfc822Name,
                 ret * sizeof(WCHAR));
                pszNameString[ret++] = 0;
            }
        }
        if (info)
            LocalFree(info);
        if (!ret)
            ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType,
             name, szOID_RSA_emailAddr, pszNameString, cchNameString);
        break;
    }
    case CERT_NAME_RDN_TYPE:
        if (name->cbData)
            ret = CertNameToStrW(pCertContext->dwCertEncodingType, name,
             *(DWORD *)pvTypePara, pszNameString, cchNameString);
        else
        {
            CERT_ALT_NAME_INFO *info;
            PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
             altNameOID, CERT_ALT_NAME_DIRECTORY_NAME, &info);

            if (entry)
                ret = CertNameToStrW(pCertContext->dwCertEncodingType,
                 &entry->u.DirectoryName, *(DWORD *)pvTypePara, pszNameString,
                 cchNameString);
            if (info)
                LocalFree(info);
        }
        break;
    case CERT_NAME_ATTR_TYPE:
        ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType,
         name, pvTypePara, pszNameString, cchNameString);
        if (!ret)
        {
            CERT_ALT_NAME_INFO *altInfo;
            PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
             altNameOID, CERT_ALT_NAME_DIRECTORY_NAME, &altInfo);

            if (entry)
                ret = cert_name_to_str_with_indent(X509_ASN_ENCODING, 0,
                 &entry->u.DirectoryName, 0, pszNameString, cchNameString);
            if (altInfo)
                LocalFree(altInfo);
        }
        break;
    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 *nameInfo = NULL;
        DWORD bytes = 0, i;

        if (CryptDecodeObjectEx(pCertContext->dwCertEncodingType, X509_NAME,
         name->pbData, name->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &nameInfo,
         &bytes))
        {
            PCERT_RDN_ATTR nameAttr = NULL;

            for (i = 0; !nameAttr && i < sizeof(simpleAttributeOIDs) /
             sizeof(simpleAttributeOIDs[0]); i++)
                nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], nameInfo);
            if (nameAttr)
                ret = CertRDNValueToStrW(nameAttr->dwValueType,
                 &nameAttr->Value, pszNameString, cchNameString);
            LocalFree(nameInfo);
        }
        if (!ret)
        {
            CERT_ALT_NAME_INFO *altInfo;
            PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
             altNameOID, CERT_ALT_NAME_RFC822_NAME, &altInfo);

            if (altInfo)
            {
                if (!entry && altInfo->cAltEntry)
                    entry = &altInfo->rgAltEntry[0];
                if (entry)
                {
                    if (!pszNameString)
                        ret = strlenW(entry->u.pwszRfc822Name) + 1;
                    else if (cchNameString)
                    {
                        ret = min(strlenW(entry->u.pwszRfc822Name),
                         cchNameString - 1);
                        memcpy(pszNameString, entry->u.pwszRfc822Name,
                         ret * sizeof(WCHAR));
                        pszNameString[ret++] = 0;
                    }
                }
                LocalFree(altInfo);
            }
        }
        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;
    }
    case CERT_NAME_DNS_TYPE:
    {
        CERT_ALT_NAME_INFO *info;
        PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
         altNameOID, CERT_ALT_NAME_DNS_NAME, &info);

        if (entry)
        {
            if (!pszNameString)
                ret = strlenW(entry->u.pwszDNSName) + 1;
            else if (cchNameString)
            {
                ret = min(strlenW(entry->u.pwszDNSName), cchNameString - 1);
                memcpy(pszNameString, entry->u.pwszDNSName, ret * sizeof(WCHAR));
                pszNameString[ret++] = 0;
            }
        }
        if (info)
            LocalFree(info);
        if (!ret)
            ret = cert_get_name_from_rdn_attr(pCertContext->dwCertEncodingType,
             name, szOID_COMMON_NAME, pszNameString, cchNameString);
        break;
    }
    case CERT_NAME_URL_TYPE:
    {
        CERT_ALT_NAME_INFO *info;
        PCERT_ALT_NAME_ENTRY entry = cert_find_alt_name_entry(pCertContext,
         altNameOID, CERT_ALT_NAME_URL, &info);

        if (entry)
        {
            if (!pszNameString)
                ret = strlenW(entry->u.pwszURL) + 1;
            else if (cchNameString)
            {
                ret = min(strlenW(entry->u.pwszURL), cchNameString - 1);
                memcpy(pszNameString, entry->u.pwszURL, ret * sizeof(WCHAR));
                pszNameString[ret++] = 0;
            }
        }
        if (info)
            LocalFree(info);
        break;
    }
    default:
        FIXME("unimplemented for type %d\n", dwType);
        ret = 0;
    }
    if (!ret)
    {
        if (!pszNameString)
            ret = 1;
        else if (cchNameString)
        {
            pszNameString[0] = 0;
            ret = 1;
        }
    }
    return ret;
}