static const char *get_cert_common_name(PCCERT_CONTEXT cert) { static char buf[1024]; const char *name = NULL; CERT_NAME_INFO *nameInfo; DWORD size; BOOL ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, cert->pCertInfo->Subject.pbData, cert->pCertInfo->Subject.cbData, CRYPT_DECODE_NOCOPY_FLAG | CRYPT_DECODE_ALLOC_FLAG, NULL, &nameInfo, &size); if (ret) { PCERT_RDN_ATTR commonName = CertFindRDNAttr(szOID_COMMON_NAME, nameInfo); if (commonName) { CertRDNValueToStrA(commonName->dwValueType, &commonName->Value, buf, sizeof(buf)); name = buf; } LocalFree(nameInfo); } return name; }
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("(%ld, %p, %08lx, %p, %ld)\n", dwCertEncodingType, pName, dwStrType, psz, csz); if (dwStrType & unsupportedFlags) FIXME("unsupported flags: %08lx\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; }