From 8d8520975fa0b1a6b9ec5198ae6b3524f77ef1c8 Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Mon, 17 Jul 2006 11:50:20 -0700 Subject: [PATCH] crypt32: Output x.500 strings from CertNameToStrA/W. --- dlls/crypt32/str.c | 155 +++++++++++++++++++++++++++++++-------- dlls/crypt32/tests/str.c | 3 + 2 files changed, 127 insertions(+), 31 deletions(-) diff --git a/dlls/crypt32/str.c b/dlls/crypt32/str.c index a80301e4110..ef67a9a4952 100644 --- a/dlls/crypt32/str.c +++ b/dlls/crypt32/str.c @@ -109,6 +109,30 @@ DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, 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 = min(lstrlenA(prefix), csz); + + TRACE("(%s, %p, %ld)\n", debugstr_a(prefix), psz, csz); + + if (psz && chars) + memcpy(psz, prefix, chars); + csz -= chars; + if (csz > 1) + { + if (psz) + *(psz + chars) = '='; + chars++; + csz--; + } + return chars; +} + DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, DWORD dwStrType, LPSTR psz, DWORD csz) { @@ -152,25 +176,33 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, for (j = 0; 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 = min( - lstrlenA(info->rgRDN[i].rgRDNAttr[j].pszObjId), - csz - ret - 1); - if (psz && chars) - memcpy(psz + ret, info->rgRDN[i].rgRDNAttr[j].pszObjId, - chars); + chars = CRYPT_AddPrefixA(prefix, psz + ret, csz - ret - 1); ret += chars; csz -= chars; - if (csz > 1) - { - if (psz) - *(psz + ret) = '='; - ret++; - csz--; - } } /* FIXME: handle quoting */ chars = CertRDNValueToStrA( @@ -206,6 +238,60 @@ DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, 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 = min(lstrlenA(prefix), csz); + + TRACE("(%s, %p, %ld)\n", debugstr_a(prefix), psz, csz); + + if (psz && chars) + { + DWORD i; + + for (i = 0; i < chars; i++) + *(psz + i) = prefix[i]; + } + csz -= chars; + if (csz > 1) + { + if (psz) + *(psz + chars) = '='; + chars++; + csz--; + } + 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 = min(lstrlenW(prefix), csz); + + TRACE("(%s, %p, %ld)\n", debugstr_w(prefix), psz, csz); + + if (psz && chars) + memcpy(psz, prefix, chars * sizeof(WCHAR)); + csz -= chars; + if (csz > 1) + { + if (psz) + *(psz + chars) = '='; + chars++; + csz--; + } + return chars; +} + DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, DWORD dwStrType, LPWSTR psz, DWORD csz) { @@ -249,30 +335,37 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, for (j = 0; 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 = min( - lstrlenA(info->rgRDN[i].rgRDNAttr[j].pszObjId), - csz - ret - 1); - if (psz && chars) - { - DWORD k; - - for (k = 0; k < chars; k++) - *(psz + ret + k) = - info->rgRDN[i].rgRDNAttr[j].pszObjId[k]; - } + chars = CRYPT_AddPrefixW(prefixW, psz + ret, csz - ret - 1); + ret += chars; + csz -= chars; + } + else if (prefixA) + { + /* - 1 is needed to account for the NULL terminator. */ + chars = CRYPT_AddPrefixAToW(prefixA, psz + ret, + csz - ret - 1); ret += chars; csz -= chars; - if (csz > 1) - { - if (psz) - *(psz + ret) = '='; - ret++; - csz--; - } } /* FIXME: handle quoting */ chars = CertRDNValueToStrW( diff --git a/dlls/crypt32/tests/str.c b/dlls/crypt32/tests/str.c index c7c2e97f3ae..abece9ccb3c 100644 --- a/dlls/crypt32/tests/str.c +++ b/dlls/crypt32/tests/str.c @@ -118,6 +118,7 @@ static char subjectStrSemicolon[] = "2.5.4.6=US; 2.5.4.8=Minnesota; 2.5.4.7=Minneapolis; 2.5.4.10=CodeWeavers; 2.5.4.11=Wine Development; 2.5.4.3=localhost; 1.2.840.113549.1.9.1=aric@codeweavers.com"; static char subjectStrCRLF[] = "2.5.4.6=US\r\n2.5.4.8=Minnesota\r\n2.5.4.7=Minneapolis\r\n2.5.4.10=CodeWeavers\r\n2.5.4.11=Wine Development\r\n2.5.4.3=localhost\r\n1.2.840.113549.1.9.1=aric@codeweavers.com"; +static char x500SubjectStr[] = "C=US, S=Minnesota, L=Minneapolis, O=CodeWeavers, OU=Wine Development, CN=localhost, E=aric@codeweavers.com"; static WCHAR issuerStrW[] = { 'U','S',',',' ','M','i','n','n','e','s','o','t','a',',',' ','M','i','n','n', 'e','a','p','o','l','i','s',',',' ','C','o','d','e','W','e','a','v','e','r', @@ -349,6 +350,8 @@ static void test_CertNameToStrA(void) test_NameToStrConversionA(&context->pCertInfo->Subject, CERT_OID_NAME_STR | CERT_NAME_STR_CRLF_FLAG, subjectStrCRLF); + test_NameToStrConversionA(&context->pCertInfo->Subject, + CERT_X500_NAME_STR, x500SubjectStr); CertFreeCertificateContext(context); }