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
));