From 8e7f30ef1115c5940268be3bda49d827e8701455 Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Thu, 16 Feb 2006 12:08:19 +0100 Subject: [PATCH] crypt32: Partially implement CertGetNameString. --- dlls/crypt32/crypt32.spec | 2 + dlls/crypt32/str.c | 133 ++++++++++++++++++++++++++++++++++++++ include/wincrypt.h | 18 ++++++ 3 files changed, 153 insertions(+) diff --git a/dlls/crypt32/crypt32.spec b/dlls/crypt32/crypt32.spec index 6a0b2d6a453..e13c9e62411 100644 --- a/dlls/crypt32/crypt32.spec +++ b/dlls/crypt32/crypt32.spec @@ -52,6 +52,8 @@ @ stub CertGetEnhancedKeyUsage @ stub CertGetIntendedKeyUsage @ stub CertGetIssuerCertificateFromStore +@ stdcall CertGetNameStringA(ptr long long ptr ptr long) +@ stdcall CertGetNameStringW(ptr long long ptr ptr long) @ stub CertGetPublicKeyLength @ stub CertGetSubjectCertificateFromStore @ stub CertIsRDNAttrsInCertificateName diff --git a/dlls/crypt32/str.c b/dlls/crypt32/str.c index d34c9da8dcb..cf56c479fb9 100644 --- a/dlls/crypt32/str.c +++ b/dlls/crypt32/str.c @@ -18,6 +18,7 @@ #include #include "windef.h" #include "winbase.h" +#include "winnls.h" #include "wincrypt.h" #include "wine/debug.h" @@ -306,3 +307,135 @@ DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, ret++; return ret; } + +DWORD WINAPI CertGetNameStringA(PCCERT_CONTEXT pCertContext, DWORD dwType, + DWORD dwFlags, void *pvTypePara, LPSTR pszNameString, DWORD cchNameString) +{ + DWORD ret; + + TRACE("(%p, %ld, %08lx, %p, %p, %ld)\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, %ld, %08lx, %p, %p, %ld)\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 %ld\n", dwType); + ret = 0; + } + return ret; +} diff --git a/include/wincrypt.h b/include/wincrypt.h index dc3a44d02ab..aa3240b5f6d 100644 --- a/include/wincrypt.h +++ b/include/wincrypt.h @@ -2283,6 +2283,18 @@ static const WCHAR CERT_PHYSICAL_STORE_AUTH_ROOT_NAME[] = #define CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG 0x00020000 #define CERT_NAME_STR_DISABLE_IE4_UTF8_FLAG 0x00010000 +#define CERT_NAME_EMAIL_TYPE 1 +#define CERT_NAME_RDN_TYPE 2 +#define CERT_NAME_ATTR_TYPE 3 +#define CERT_NAME_SIMPLE_DISPLAY_TYPE 4 +#define CERT_NAME_FRIENDLY_DISPLAY_TYPE 5 +#define CERT_NAME_DNS_TYPE 6 +#define CERT_NAME_URL_TYPE 7 +#define CERT_NAME_UPN_TYPE 8 + +#define CERT_NAME_ISSUER_FLAG 0x00000001 +#define CERT_NAME_DISABLE_IE4_UTF8_FLAG 0x00010000 + /* function declarations */ /* advapi32.dll */ BOOL WINAPI CryptAcquireContextA(HCRYPTPROV *phProv, LPCSTR pszContainer, @@ -2642,6 +2654,12 @@ BOOL WINAPI CryptUnprotectData( DATA_BLOB* pDataIn, LPWSTR* ppszDataDescr, DATA_BLOB* pOptionalEntropy, PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, DWORD dwFlags, DATA_BLOB* pDataOut ); +DWORD WINAPI CertGetNameStringA(PCCERT_CONTEXT pCertContext, DWORD dwType, + DWORD dwFlags, void *pvTypePara, LPSTR pszNameString, DWORD cchNameString); +DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType, + DWORD dwFlags, void *pvTypePara, LPWSTR pszNameString, DWORD cchNameString); +#define CertGetNameString WINELIB_NAME_AW(CertGetNameString) + DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue, LPSTR psz, DWORD csz); DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,