2 * Copyright 2006 Juan Lang for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "wine/debug.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
26 DWORD WINAPI CertRDNValueToStrA(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
31 TRACE("(%ld, %p, %p, %ld)\n", dwValueType, pValue, psz, csz);
35 case CERT_RDN_ANY_TYPE:
37 case CERT_RDN_PRINTABLE_STRING:
38 case CERT_RDN_IA5_STRING:
43 DWORD chars = min(pValue->cbData, csz - 1);
47 memcpy(psz, pValue->pbData, chars);
54 FIXME("string type %ld unimplemented\n", dwValueType);
67 DWORD WINAPI CertRDNValueToStrW(DWORD dwValueType, PCERT_RDN_VALUE_BLOB pValue,
68 LPWSTR psz, DWORD csz)
72 TRACE("(%ld, %p, %p, %ld)\n", dwValueType, pValue, psz, csz);
76 case CERT_RDN_ANY_TYPE:
78 case CERT_RDN_PRINTABLE_STRING:
79 case CERT_RDN_IA5_STRING:
84 DWORD chars = min(pValue->cbData, csz - 1);
90 for (i = 0; i < chars; i++)
91 psz[i] = pValue->pbData[i];
98 FIXME("string type %ld unimplemented\n", dwValueType);
112 DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
113 DWORD dwStrType, LPSTR psz, DWORD csz)
115 static const DWORD unsupportedFlags = CERT_NAME_STR_NO_QUOTING_FLAG |
116 CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG;
117 static const char commaSep[] = ", ";
118 static const char semiSep[] = "; ";
119 static const char crlfSep[] = "\r\n";
120 static const char plusSep[] = " + ";
121 static const char spaceSep[] = " ";
122 DWORD ret = 0, bytes = 0;
124 CERT_NAME_INFO *info;
126 TRACE("(%ld, %p, %p, %ld)\n", dwCertEncodingType, pName, psz, csz);
127 if (dwStrType & unsupportedFlags)
128 FIXME("unsupported flags: %08lx\n", dwStrType & unsupportedFlags);
130 bRet = CryptDecodeObjectEx(dwCertEncodingType, X509_NAME, pName->pbData,
131 pName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &bytes);
134 DWORD i, j, sepLen, rdnSepLen;
137 if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG)
139 else if (dwStrType & CERT_NAME_STR_CRLF_FLAG)
143 sepLen = strlen(sep);
144 if (dwStrType & CERT_NAME_STR_NO_PLUS_FLAG)
148 rdnSepLen = strlen(rdnSep);
149 for (i = 0; ret < csz && i < info->cRDN; i++)
151 for (j = 0; ret < csz && j < info->rgRDN[i].cRDNAttr; j++)
155 if ((dwStrType & 0x000000ff) == CERT_OID_NAME_STR)
157 /* - 1 is needed to account for the NULL terminator. */
159 lstrlenA(info->rgRDN[i].rgRDNAttr[j].pszObjId),
162 memcpy(psz + ret, info->rgRDN[i].rgRDNAttr[j].pszObjId,
174 /* FIXME: handle quoting */
175 chars = CertRDNValueToStrA(
176 info->rgRDN[i].rgRDNAttr[j].dwValueType,
177 &info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL,
181 if (j < info->rgRDN[i].cRDNAttr - 1)
183 if (psz && ret < csz - rdnSepLen - 1)
184 memcpy(psz + ret, rdnSep, rdnSepLen);
188 if (i < info->cRDN - 1)
190 if (psz && ret < csz - sepLen - 1)
191 memcpy(psz + ret, sep, sepLen);
208 DWORD WINAPI CertNameToStrW(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName,
209 DWORD dwStrType, LPWSTR psz, DWORD csz)
211 static const DWORD unsupportedFlags = CERT_NAME_STR_NO_QUOTING_FLAG |
212 CERT_NAME_STR_REVERSE_FLAG | CERT_NAME_STR_ENABLE_T61_UNICODE_FLAG;
213 static const WCHAR commaSep[] = { ',',' ',0 };
214 static const WCHAR semiSep[] = { ';',' ',0 };
215 static const WCHAR crlfSep[] = { '\r','\n',0 };
216 static const WCHAR plusSep[] = { ' ','+',' ',0 };
217 static const WCHAR spaceSep[] = { ' ',0 };
218 DWORD ret = 0, bytes = 0;
220 CERT_NAME_INFO *info;
222 TRACE("(%ld, %p, %p, %ld)\n", dwCertEncodingType, pName, psz, csz);
223 if (dwStrType & unsupportedFlags)
224 FIXME("unsupported flags: %08lx\n", dwStrType & unsupportedFlags);
226 bRet = CryptDecodeObjectEx(dwCertEncodingType, X509_NAME, pName->pbData,
227 pName->cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &bytes);
230 DWORD i, j, sepLen, rdnSepLen;
233 if (dwStrType & CERT_NAME_STR_SEMICOLON_FLAG)
235 else if (dwStrType & CERT_NAME_STR_CRLF_FLAG)
239 sepLen = lstrlenW(sep);
240 if (dwStrType & CERT_NAME_STR_NO_PLUS_FLAG)
244 rdnSepLen = lstrlenW(rdnSep);
245 for (i = 0; ret < csz && i < info->cRDN; i++)
247 for (j = 0; ret < csz && j < info->rgRDN[i].cRDNAttr; j++)
251 if ((dwStrType & 0x000000ff) == CERT_OID_NAME_STR)
253 /* - 1 is needed to account for the NULL terminator. */
255 lstrlenA(info->rgRDN[i].rgRDNAttr[j].pszObjId),
261 for (k = 0; k < chars; k++)
263 info->rgRDN[i].rgRDNAttr[j].pszObjId[k];
275 /* FIXME: handle quoting */
276 chars = CertRDNValueToStrW(
277 info->rgRDN[i].rgRDNAttr[j].dwValueType,
278 &info->rgRDN[i].rgRDNAttr[j].Value, psz ? psz + ret : NULL,
282 if (j < info->rgRDN[i].cRDNAttr - 1)
284 if (psz && ret < csz - rdnSepLen - 1)
285 memcpy(psz + ret, rdnSep, rdnSepLen * sizeof(WCHAR));
289 if (i < info->cRDN - 1)
291 if (psz && ret < csz - sepLen - 1)
292 memcpy(psz + ret, sep, sepLen * sizeof(WCHAR));