[WINTRUST_WINETEST]
[reactos.git] / rostests / winetests / wintrust / asn.c
1 /* Unit test suite for wintrust asn functions
2 *
3 * Copyright 2007 Juan Lang
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 *
19 */
20 #include <stdarg.h>
21 #include "windef.h"
22 #include "winbase.h"
23 #include "winerror.h"
24 #include "wincrypt.h"
25 #include "wintrust.h"
26
27 #include "wine/test.h"
28
29 static BOOL (WINAPI *pCryptDecodeObjectEx)(DWORD,LPCSTR,const BYTE*,DWORD,DWORD,PCRYPT_DECODE_PARA,void*,DWORD*);
30 static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*);
31
32 static const BYTE falseCriteria[] = { 0x30,0x06,0x01,0x01,0x00,0x01,0x01,0x00 };
33 static const BYTE trueCriteria[] = { 0x30,0x06,0x01,0x01,0xff,0x01,0x01,0xff };
34
35 static void test_encodeSPCFinancialCriteria(void)
36 {
37 BOOL ret;
38 DWORD size = 0;
39 LPBYTE buf;
40 SPC_FINANCIAL_CRITERIA criteria = { FALSE, FALSE };
41
42 if (!pCryptEncodeObjectEx)
43 {
44 win_skip("CryptEncodeObjectEx() is not available. Skipping the encodeFinancialCriteria tests\n");
45 return;
46 }
47 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_FINANCIAL_CRITERIA_STRUCT,
48 &criteria, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
49 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
50 if (ret)
51 {
52 ok(size == sizeof(falseCriteria), "Unexpected size %d\n", size);
53 ok(!memcmp(buf, falseCriteria, size), "Unexpected value\n");
54 LocalFree(buf);
55 }
56 criteria.fFinancialInfoAvailable = criteria.fMeetsCriteria = TRUE;
57 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_FINANCIAL_CRITERIA_STRUCT,
58 &criteria, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
59 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
60 if (ret)
61 {
62 ok(size == sizeof(trueCriteria), "Unexpected size %d\n", size);
63 ok(!memcmp(buf, trueCriteria, size), "Unexpected value\n");
64 LocalFree(buf);
65 }
66 }
67
68 static void test_decodeSPCFinancialCriteria(void)
69 {
70 BOOL ret;
71 SPC_FINANCIAL_CRITERIA criteria;
72 DWORD size = sizeof(criteria);
73
74 if (!pCryptDecodeObjectEx)
75 {
76 win_skip("CryptDecodeObjectEx() is not available. Skipping the decodeSPCFinancialCriteria tests\n");
77 return;
78 }
79
80 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_FINANCIAL_CRITERIA_STRUCT,
81 falseCriteria, sizeof(falseCriteria), 0, NULL, &criteria, &size);
82 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
83 if (ret)
84 {
85 ok(!criteria.fFinancialInfoAvailable, "expected FALSE\n");
86 ok(!criteria.fMeetsCriteria, "expected FALSE\n");
87 }
88 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_FINANCIAL_CRITERIA_STRUCT,
89 trueCriteria, sizeof(trueCriteria), 0, NULL, &criteria, &size);
90 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
91 if (ret)
92 {
93 ok(criteria.fFinancialInfoAvailable, "expected TRUE\n");
94 ok(criteria.fMeetsCriteria, "expected TRUE\n");
95 }
96 }
97
98 static WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.',
99 'o','r','g',0 };
100 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
101 0x575b, 0 };
102 static const BYTE emptyURLSPCLink[] = { 0x80,0x00 };
103 static const BYTE urlSPCLink[] = {
104 0x80,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,
105 0x2e,0x6f,0x72,0x67};
106 static const BYTE fileSPCLink[] = {
107 0xa2,0x14,0x80,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
108 0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
109 static const BYTE emptyMonikerSPCLink[] = {
110 0xa1,0x14,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
111 0x00,0x00,0x00,0x00,0x00,0x04,0x00 };
112 static BYTE data[] = { 0xba, 0xad, 0xf0, 0x0d };
113 static const BYTE monikerSPCLink[] = {
114 0xa1,0x18,0x04,0x10,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,
115 0xea,0xea,0xea,0xea,0xea,0x04,0x04,0xba,0xad,0xf0,0x0d };
116
117 static void test_encodeSPCLink(void)
118 {
119 BOOL ret;
120 DWORD size = 0;
121 LPBYTE buf;
122 SPC_LINK link = { 0 };
123
124 if (!pCryptEncodeObjectEx)
125 {
126 win_skip("CryptEncodeObjectEx() is not available. Skipping the encodeSPCLink tests\n");
127 return;
128 }
129
130 SetLastError(0xdeadbeef);
131 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT, &link,
132 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
133 ok(!ret && GetLastError() == E_INVALIDARG,
134 "Expected E_INVALIDARG, got %08x\n", GetLastError());
135 link.dwLinkChoice = SPC_URL_LINK_CHOICE;
136 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT, &link,
137 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
138 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
139 if (ret)
140 {
141 ok(size == sizeof(emptyURLSPCLink), "Unexpected size %d\n", size);
142 ok(!memcmp(buf, emptyURLSPCLink, size), "Unexpected value\n");
143 LocalFree(buf);
144 }
145 /* With an invalid char: */
146 U(link).pwszUrl = (LPWSTR)nihongoURL;
147 size = 1;
148 SetLastError(0xdeadbeef);
149 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT, &link,
150 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
151 ok(!ret &&
152 (GetLastError() == CRYPT_E_INVALID_IA5_STRING ||
153 GetLastError() == OSS_BAD_PTR /* WinNT */),
154 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
155 /* Unlike the crypt32 string encoding routines, size is not set to the
156 * index of the first invalid character.
157 */
158 ok(size == 0, "Expected size 0, got %d\n", size);
159 U(link).pwszUrl = url;
160 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT, &link,
161 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
162 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
163 if (ret)
164 {
165 ok(size == sizeof(urlSPCLink), "Unexpected size %d\n", size);
166 ok(!memcmp(buf, urlSPCLink, size), "Unexpected value\n");
167 LocalFree(buf);
168 }
169 link.dwLinkChoice = SPC_FILE_LINK_CHOICE;
170 U(link).pwszFile = (LPWSTR)nihongoURL;
171 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT, &link,
172 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
173 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
174 if (ret)
175 {
176 ok(size == sizeof(fileSPCLink), "Unexpected size %d\n", size);
177 ok(!memcmp(buf, fileSPCLink, size), "Unexpected value\n");
178 LocalFree(buf);
179 }
180 link.dwLinkChoice = SPC_MONIKER_LINK_CHOICE;
181 memset(&U(link).Moniker, 0, sizeof(U(link).Moniker));
182 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT, &link,
183 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
184 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
185 if (ret)
186 {
187 ok(size == sizeof(emptyMonikerSPCLink), "Unexpected size %d\n", size);
188 ok(!memcmp(buf, emptyMonikerSPCLink, size), "Unexpected value\n");
189 LocalFree(buf);
190 }
191 memset(&U(link).Moniker.ClassId, 0xea, sizeof(U(link).Moniker.ClassId));
192 U(link).Moniker.SerializedData.pbData = data;
193 U(link).Moniker.SerializedData.cbData = sizeof(data);
194 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT, &link,
195 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
196 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
197 if (ret)
198 {
199 ok(size == sizeof(monikerSPCLink), "Unexpected size %d\n", size);
200 ok(!memcmp(buf, monikerSPCLink, size), "Unexpected value\n");
201 LocalFree(buf);
202 }
203 }
204
205 static const BYTE badMonikerSPCLink[] = {
206 0xa1,0x19,0x04,0x11,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,
207 0xea,0xea,0xea,0xea,0xea,0xea,0x04,0x04,0xba,0xad,0xf0,0x0d };
208
209 static void test_decodeSPCLink(void)
210 {
211 BOOL ret;
212 LPBYTE buf = NULL;
213 DWORD size = 0;
214 SPC_LINK *link;
215
216 if (!pCryptDecodeObjectEx)
217 {
218 win_skip("CryptDecodeObjectEx() is not available. Skipping the decodeSPCLink tests\n");
219 return;
220 }
221
222 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT,
223 emptyURLSPCLink, sizeof(emptyURLSPCLink), CRYPT_DECODE_ALLOC_FLAG, NULL,
224 &buf, &size);
225 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
226 if (ret)
227 {
228 link = (SPC_LINK *)buf;
229 ok(link->dwLinkChoice == SPC_URL_LINK_CHOICE,
230 "Expected SPC_URL_LINK_CHOICE, got %d\n", link->dwLinkChoice);
231 ok(lstrlenW(U(*link).pwszUrl) == 0, "Expected empty string\n");
232 LocalFree(buf);
233 }
234 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT,
235 urlSPCLink, sizeof(urlSPCLink), CRYPT_DECODE_ALLOC_FLAG, NULL,
236 &buf, &size);
237 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
238 if (ret)
239 {
240 link = (SPC_LINK *)buf;
241 ok(link->dwLinkChoice == SPC_URL_LINK_CHOICE,
242 "Expected SPC_URL_LINK_CHOICE, got %d\n", link->dwLinkChoice);
243 ok(!lstrcmpW(U(*link).pwszUrl, url), "Unexpected URL\n");
244 LocalFree(buf);
245 }
246 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT,
247 fileSPCLink, sizeof(fileSPCLink), CRYPT_DECODE_ALLOC_FLAG, NULL,
248 &buf, &size);
249 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
250 if (ret)
251 {
252 link = (SPC_LINK *)buf;
253 ok(link->dwLinkChoice == SPC_FILE_LINK_CHOICE,
254 "Expected SPC_FILE_LINK_CHOICE, got %d\n", link->dwLinkChoice);
255 ok(!lstrcmpW(U(*link).pwszFile, nihongoURL), "Unexpected file\n");
256 LocalFree(buf);
257 }
258 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT,
259 emptyMonikerSPCLink, sizeof(emptyMonikerSPCLink), CRYPT_DECODE_ALLOC_FLAG,
260 NULL, &buf, &size);
261 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
262 if (ret)
263 {
264 SPC_SERIALIZED_OBJECT emptyMoniker = { { 0 } };
265
266 link = (SPC_LINK *)buf;
267 ok(link->dwLinkChoice == SPC_MONIKER_LINK_CHOICE,
268 "Expected SPC_MONIKER_LINK_CHOICE, got %d\n", link->dwLinkChoice);
269 ok(!memcmp(&U(*link).Moniker.ClassId, &emptyMoniker.ClassId,
270 sizeof(emptyMoniker.ClassId)), "Unexpected value\n");
271 ok(U(*link).Moniker.SerializedData.cbData == 0,
272 "Expected no serialized data\n");
273 LocalFree(buf);
274 }
275 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT,
276 monikerSPCLink, sizeof(monikerSPCLink), CRYPT_DECODE_ALLOC_FLAG, NULL,
277 &buf, &size);
278 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
279 if (ret)
280 {
281 SPC_UUID id;
282
283 link = (SPC_LINK *)buf;
284 ok(link->dwLinkChoice == SPC_MONIKER_LINK_CHOICE,
285 "Expected SPC_MONIKER_LINK_CHOICE, got %d\n", link->dwLinkChoice);
286 memset(&id, 0xea, sizeof(id));
287 ok(!memcmp(&U(*link).Moniker.ClassId, &id, sizeof(id)),
288 "Unexpected value\n");
289 ok(U(*link).Moniker.SerializedData.cbData == sizeof(data),
290 "Unexpected data size %d\n", U(*link).Moniker.SerializedData.cbData);
291 ok(!memcmp(U(*link).Moniker.SerializedData.pbData, data, sizeof(data)),
292 "Unexpected value\n");
293 LocalFree(buf);
294 }
295 SetLastError(0xdeadbeef);
296 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT,
297 badMonikerSPCLink, sizeof(badMonikerSPCLink), CRYPT_DECODE_ALLOC_FLAG,
298 NULL, &buf, &size);
299 ok(!ret &&
300 (GetLastError() == CRYPT_E_BAD_ENCODE ||
301 GetLastError() == OSS_DATA_ERROR /* WinNT */),
302 "Expected CRYPT_E_BAD_ENCODE, got %08x\n", GetLastError());
303 }
304
305 static const BYTE emptySequence[] = { 0x30,0x00 };
306 static BYTE flags[] = { 1 };
307 static const BYTE onlyFlagsPEImage[] = { 0x30,0x04,0x03,0x02,0x00,0x01 };
308 static const BYTE moreFlagsPEImage[] = {
309 0x30,0x06,0x03,0x04,0x04,0xff,0x80,0x10 };
310 static const BYTE onlyEmptyFilePEImage[] = {
311 0x30,0x06,0xa0,0x04,0xa2,0x02,0x80,0x00 };
312 static const BYTE flagsAndEmptyFilePEImage[] = {
313 0x30,0x0a,0x03,0x02,0x00,0x01,0xa0,0x04,0xa2,0x02,0x80,0x00 };
314 static const BYTE flagsAndFilePEImage[] = {
315 0x30,0x1c,0x03,0x02,0x00,0x01,0xa0,0x16,0xa2,0x14,0x80,0x12,0x00,0x68,0x00,
316 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
317
318 static void test_encodeSPCPEImage(void)
319 {
320 BOOL ret;
321 DWORD size = 0;
322 LPBYTE buf;
323 SPC_PE_IMAGE_DATA imageData = { { 0 } };
324 SPC_LINK link = { 0 };
325
326 if (!pCryptEncodeObjectEx)
327 {
328 win_skip("CryptEncodeObjectEx() is not available. Skipping the encodeSPCPEImage tests\n");
329 return;
330 }
331
332 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
333 &imageData, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
334 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
335 if (ret)
336 {
337 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
338 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
339 "Unexpected value\n");
340 LocalFree(buf);
341 }
342 /* With an invalid link: */
343 imageData.pFile = &link;
344 SetLastError(0xdeadbeef);
345 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
346 &imageData, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
347 ok(!ret && GetLastError () == E_INVALIDARG,
348 "Expected E_INVALIDARG, got %08x\n", GetLastError());
349 /* With just unused bits field set: */
350 imageData.pFile = NULL;
351 imageData.Flags.cUnusedBits = 1;
352 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
353 &imageData, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
354 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
355 if (ret)
356 {
357 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
358 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
359 "Unexpected value\n");
360 LocalFree(buf);
361 }
362 /* With flags set: */
363 imageData.Flags.cUnusedBits = 0;
364 imageData.Flags.pbData = flags;
365 imageData.Flags.cbData = sizeof(flags);
366 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
367 &imageData, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
368 if (!ret && GetLastError() == OSS_TOO_LONG)
369 {
370 skip("SPC_PE_IMAGE_DATA_STRUCT not supported\n");
371 return;
372 }
373 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
374 if (ret)
375 {
376 ok(size == sizeof(onlyFlagsPEImage), "Unexpected size %d\n", size);
377 ok(!memcmp(buf, onlyFlagsPEImage, sizeof(onlyFlagsPEImage)),
378 "Unexpected value\n");
379 LocalFree(buf);
380 }
381 /* With just an empty file: */
382 imageData.Flags.cbData = 0;
383 link.dwLinkChoice = SPC_FILE_LINK_CHOICE;
384 imageData.pFile = &link;
385 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
386 &imageData, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
387 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
388 if (ret)
389 {
390 ok(size == sizeof(onlyEmptyFilePEImage), "Unexpected size %d\n", size);
391 ok(!memcmp(buf, onlyEmptyFilePEImage, sizeof(onlyEmptyFilePEImage)),
392 "Unexpected value\n");
393 LocalFree(buf);
394 }
395 /* With flags and an empty file: */
396 imageData.Flags.pbData = flags;
397 imageData.Flags.cbData = sizeof(flags);
398 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
399 &imageData, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
400 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
401 if (ret)
402 {
403 ok(size == sizeof(flagsAndEmptyFilePEImage), "Unexpected size %d\n",
404 size);
405 ok(!memcmp(buf, flagsAndEmptyFilePEImage,
406 sizeof(flagsAndEmptyFilePEImage)), "Unexpected value\n");
407 LocalFree(buf);
408 }
409 /* Finally, a non-empty file: */
410 U(link).pwszFile = (LPWSTR)nihongoURL;
411 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
412 &imageData, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
413 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
414 if (ret)
415 {
416 ok(size == sizeof(flagsAndFilePEImage), "Unexpected size %d\n", size);
417 ok(!memcmp(buf, flagsAndFilePEImage, sizeof(flagsAndFilePEImage)),
418 "Unexpected value\n");
419 LocalFree(buf);
420 }
421 }
422
423 static void test_decodeSPCPEImage(void)
424 {
425 static const WCHAR emptyString[] = { 0 };
426 BOOL ret;
427 LPBYTE buf = NULL;
428 DWORD size = 0;
429 SPC_PE_IMAGE_DATA *imageData;
430
431 if (!pCryptDecodeObjectEx)
432 {
433 win_skip("CryptDecodeObjectEx() is not available. Skipping the decodeSPCPEImage tests\n");
434 return;
435 }
436
437 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
438 emptySequence, sizeof(emptySequence),
439 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
440 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
441 if (ret)
442 {
443 imageData = (SPC_PE_IMAGE_DATA *)buf;
444 ok(imageData->Flags.cbData == 0, "Expected empty flags, got %d\n",
445 imageData->Flags.cbData);
446 ok(imageData->pFile == NULL, "Expected no file\n");
447 LocalFree(buf);
448 }
449 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
450 onlyFlagsPEImage, sizeof(onlyFlagsPEImage),
451 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
452 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
453 if (ret)
454 {
455 imageData = (SPC_PE_IMAGE_DATA *)buf;
456 ok(imageData->Flags.cbData == sizeof(flags),
457 "Unexpected flags size %d\n", imageData->Flags.cbData);
458 if (imageData->Flags.cbData)
459 ok(!memcmp(imageData->Flags.pbData, flags, sizeof(flags)),
460 "Unexpected flags\n");
461 ok(imageData->pFile == NULL, "Expected no file\n");
462 LocalFree(buf);
463 }
464 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
465 onlyEmptyFilePEImage, sizeof(onlyEmptyFilePEImage),
466 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
467 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
468 if (ret)
469 {
470 imageData = (SPC_PE_IMAGE_DATA *)buf;
471 ok(imageData->Flags.cbData == 0, "Expected empty flags, got %d\n",
472 imageData->Flags.cbData);
473 ok(imageData->pFile != NULL, "Expected a file\n");
474 if (imageData->pFile)
475 {
476 ok(imageData->pFile->dwLinkChoice == SPC_FILE_LINK_CHOICE,
477 "Expected SPC_FILE_LINK_CHOICE, got %d\n",
478 imageData->pFile->dwLinkChoice);
479 ok(!lstrcmpW(U(*imageData->pFile).pwszFile, emptyString),
480 "Unexpected file\n");
481 }
482 LocalFree(buf);
483 }
484 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
485 flagsAndEmptyFilePEImage, sizeof(flagsAndEmptyFilePEImage),
486 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
487 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
488 if (ret)
489 {
490 imageData = (SPC_PE_IMAGE_DATA *)buf;
491 ok(imageData->Flags.cbData == sizeof(flags),
492 "Unexpected flags size %d\n", imageData->Flags.cbData);
493 if (imageData->Flags.cbData)
494 ok(!memcmp(imageData->Flags.pbData, flags, sizeof(flags)),
495 "Unexpected flags\n");
496 ok(imageData->pFile != NULL, "Expected a file\n");
497 if (imageData->pFile)
498 {
499 ok(imageData->pFile->dwLinkChoice == SPC_FILE_LINK_CHOICE,
500 "Expected SPC_FILE_LINK_CHOICE, got %d\n",
501 imageData->pFile->dwLinkChoice);
502 ok(!lstrcmpW(U(*imageData->pFile).pwszFile, emptyString),
503 "Unexpected file\n");
504 }
505 LocalFree(buf);
506 }
507 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
508 flagsAndFilePEImage, sizeof(flagsAndFilePEImage),
509 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
510 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
511 if (ret)
512 {
513 imageData = (SPC_PE_IMAGE_DATA *)buf;
514 ok(imageData->Flags.cbData == sizeof(flags),
515 "Unexpected flags size %d\n", imageData->Flags.cbData);
516 if (imageData->Flags.cbData)
517 ok(!memcmp(imageData->Flags.pbData, flags, sizeof(flags)),
518 "Unexpected flags\n");
519 ok(imageData->pFile != NULL, "Expected a file\n");
520 if (imageData->pFile)
521 {
522 ok(imageData->pFile->dwLinkChoice == SPC_FILE_LINK_CHOICE,
523 "Expected SPC_FILE_LINK_CHOICE, got %d\n",
524 imageData->pFile->dwLinkChoice);
525 ok(!lstrcmpW(U(*imageData->pFile).pwszFile, nihongoURL),
526 "Unexpected file\n");
527 }
528 LocalFree(buf);
529 }
530 }
531
532 static WCHAR foo[] = { 'f','o','o',0 };
533 static WCHAR guidStr[] = { '{','8','b','c','9','6','b','0','0','-',
534 '8','d','a','1','-','1','1','c','f','-','8','7','3','6','-','0','0',
535 'a','a','0','0','a','4','8','5','e','b','}',0 };
536
537 static const BYTE emptyCatMemberInfo[] = { 0x30,0x05,0x1e,0x00,0x02,0x01,0x00 };
538 static const BYTE catMemberInfoWithSillyGuid[] = {
539 0x30,0x0b,0x1e,0x06,0x00,0x66,0x00,0x6f,0x00,0x6f,0x02,0x01,0x00 };
540 static const BYTE catMemberInfoWithGuid[] = {
541 0x30,0x51,0x1e,0x4c,0x00,0x7b,0x00,0x38,0x00,0x62,0x00,0x63,0x00,0x39,0x00,0x36,
542 0x00,0x62,0x00,0x30,0x00,0x30,0x00,0x2d,0x00,0x38,0x00,0x64,0x00,0x61,0x00,0x31,
543 0x00,0x2d,0x00,0x31,0x00,0x31,0x00,0x63,0x00,0x66,0x00,0x2d,0x00,0x38,0x00,0x37,
544 0x00,0x33,0x00,0x36,0x00,0x2d,0x00,0x30,0x00,0x30,0x00,0x61,0x00,0x61,0x00,0x30,
545 0x00,0x30,0x00,0x61,0x00,0x34,0x00,0x38,0x00,0x35,0x00,0x65,0x00,0x62,0x00,0x7d,
546 0x02,0x01,0x00 };
547
548 static void test_encodeCatMemberInfo(void)
549 {
550 CAT_MEMBERINFO info;
551 BOOL ret;
552 DWORD size = 0;
553 LPBYTE buf;
554
555 memset(&info, 0, sizeof(info));
556
557 if (!pCryptEncodeObjectEx)
558 {
559 win_skip("CryptEncodeObjectEx() is not available. Skipping the encodeCatMemberInfo tests\n");
560 return;
561 }
562
563 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, CAT_MEMBERINFO_STRUCT,
564 &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
565 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
566 if (ret)
567 {
568 ok(size == sizeof(emptyCatMemberInfo), "Unexpected size %d\n", size);
569 ok(!memcmp(buf, emptyCatMemberInfo, sizeof(emptyCatMemberInfo)),
570 "Unexpected value\n");
571 LocalFree(buf);
572 }
573 info.pwszSubjGuid = foo;
574 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, CAT_MEMBERINFO_STRUCT,
575 &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
576 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
577 if (ret)
578 {
579 ok(size == sizeof(catMemberInfoWithSillyGuid), "Unexpected size %d\n",
580 size);
581 ok(!memcmp(buf, catMemberInfoWithSillyGuid,
582 sizeof(catMemberInfoWithSillyGuid)), "Unexpected value\n");
583 LocalFree(buf);
584 }
585 info.pwszSubjGuid = guidStr;
586 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, CAT_MEMBERINFO_STRUCT,
587 &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
588 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
589 if (ret)
590 {
591 ok(size == sizeof(catMemberInfoWithGuid), "Unexpected size %d\n",
592 size);
593 ok(!memcmp(buf, catMemberInfoWithGuid, sizeof(catMemberInfoWithGuid)),
594 "Unexpected value\n");
595 LocalFree(buf);
596 }
597 }
598
599 static void test_decodeCatMemberInfo(void)
600 {
601 BOOL ret;
602 LPBYTE buf;
603 DWORD size;
604 CAT_MEMBERINFO *info;
605
606 if (!pCryptDecodeObjectEx)
607 {
608 win_skip("CryptDecodeObjectEx() is not available. Skipping the decodeCatMemberInfo tests\n");
609 return;
610 }
611
612 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, CAT_MEMBERINFO_STRUCT,
613 emptyCatMemberInfo, sizeof(emptyCatMemberInfo),
614 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
615 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
616 if (ret)
617 {
618 info = (CAT_MEMBERINFO *)buf;
619 ok(!info->pwszSubjGuid || !info->pwszSubjGuid[0],
620 "expected empty pwszSubjGuid\n");
621 ok(info->dwCertVersion == 0, "expected dwCertVersion == 0, got %d\n",
622 info->dwCertVersion);
623 LocalFree(buf);
624 }
625 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, CAT_MEMBERINFO_STRUCT,
626 catMemberInfoWithSillyGuid, sizeof(catMemberInfoWithSillyGuid),
627 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
628 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
629 if (ret)
630 {
631 info = (CAT_MEMBERINFO *)buf;
632 ok(info->pwszSubjGuid && !lstrcmpW(info->pwszSubjGuid, foo),
633 "unexpected pwszSubjGuid\n");
634 ok(info->dwCertVersion == 0, "expected dwCertVersion == 0, got %d\n",
635 info->dwCertVersion);
636 LocalFree(buf);
637 }
638 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, CAT_MEMBERINFO_STRUCT,
639 catMemberInfoWithGuid, sizeof(catMemberInfoWithGuid),
640 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
641 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
642 if (ret)
643 {
644 info = (CAT_MEMBERINFO *)buf;
645 ok(info->pwszSubjGuid && !lstrcmpW(info->pwszSubjGuid, guidStr),
646 "unexpected pwszSubjGuid\n");
647 ok(info->dwCertVersion == 0, "expected dwCertVersion == 0, got %d\n",
648 info->dwCertVersion);
649 LocalFree(buf);
650 }
651 }
652
653 static const BYTE emptyCatNameValue[] = {
654 0x30,0x07,0x1e,0x00,0x02,0x01,0x00,0x04,0x00 };
655 static const BYTE catNameValueWithTag[] = {
656 0x30,0x0d,0x1e,0x06,0x00,0x66,0x00,0x6f,0x00,0x6f,0x02,0x01,0x00,0x04,0x00 };
657 static const BYTE catNameValueWithFlags[] = {
658 0x30,0x0a,0x1e,0x00,0x02,0x04,0xf0,0x0d,0xd0,0x0d,0x04,0x00 };
659 static const BYTE catNameValueWithValue[] = {
660 0x30,0x0b,0x1e,0x00,0x02,0x01,0x00,0x04,0x04,0x01,0x02,0x03,0x04 };
661
662 static BYTE aVal[] = { 1,2,3,4 };
663
664 static void test_encodeCatNameValue(void)
665 {
666 static WCHAR foo[] = { 'f','o','o',0 };
667 BOOL ret;
668 LPBYTE buf;
669 DWORD size;
670 CAT_NAMEVALUE value;
671
672 memset(&value, 0, sizeof(value));
673 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, CAT_NAMEVALUE_STRUCT,
674 &value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
675 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
676 if (ret)
677 {
678 ok(size == sizeof(emptyCatNameValue), "Unexpected size %d\n", size);
679 ok(!memcmp(buf, emptyCatNameValue, sizeof(emptyCatNameValue)),
680 "Unexpected value\n");
681 LocalFree(buf);
682 }
683 value.pwszTag = foo;
684 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, CAT_NAMEVALUE_STRUCT,
685 &value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
686 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
687 if (ret)
688 {
689 ok(size == sizeof(catNameValueWithTag), "Unexpected size %d\n", size);
690 ok(!memcmp(buf, catNameValueWithTag, sizeof(catNameValueWithTag)),
691 "Unexpected value\n");
692 LocalFree(buf);
693 }
694 value.pwszTag = NULL;
695 value.fdwFlags = 0xf00dd00d;
696 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, CAT_NAMEVALUE_STRUCT,
697 &value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
698 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
699 if (ret)
700 {
701 ok(size == sizeof(catNameValueWithFlags), "Unexpected size %d\n", size);
702 ok(!memcmp(buf, catNameValueWithFlags, sizeof(catNameValueWithFlags)),
703 "Unexpected value\n");
704 LocalFree(buf);
705 }
706 value.fdwFlags = 0;
707 value.Value.cbData = sizeof(aVal);
708 value.Value.pbData = aVal;
709 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, CAT_NAMEVALUE_STRUCT,
710 &value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
711 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
712 if (ret)
713 {
714 ok(size == sizeof(catNameValueWithValue), "Unexpected size %d\n", size);
715 ok(!memcmp(buf, catNameValueWithValue, sizeof(catNameValueWithValue)),
716 "Unexpected value\n");
717 LocalFree(buf);
718 }
719 }
720
721 static void test_decodeCatNameValue(void)
722 {
723 BOOL ret;
724 LPBYTE buf;
725 DWORD size;
726 CAT_NAMEVALUE *value;
727
728 buf = NULL;
729 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, CAT_NAMEVALUE_STRUCT,
730 emptyCatNameValue, sizeof(emptyCatNameValue),
731 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
732 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
733 if (ret)
734 {
735 value = (CAT_NAMEVALUE *)buf;
736 ok(!value->pwszTag || !value->pwszTag[0], "expected empty pwszTag\n");
737 ok(value->fdwFlags == 0, "expected fdwFlags == 0, got %08x\n",
738 value->fdwFlags);
739 ok(value->Value.cbData == 0, "expected 0-length value, got %d\n",
740 value->Value.cbData);
741 LocalFree(buf);
742 }
743 buf = NULL;
744 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, CAT_NAMEVALUE_STRUCT,
745 catNameValueWithTag, sizeof(catNameValueWithTag),
746 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
747 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
748 if (ret)
749 {
750 value = (CAT_NAMEVALUE *)buf;
751 ok(value->pwszTag && !lstrcmpW(value->pwszTag, foo),
752 "unexpected pwszTag\n");
753 ok(value->fdwFlags == 0, "expected fdwFlags == 0, got %08x\n",
754 value->fdwFlags);
755 ok(value->Value.cbData == 0, "expected 0-length value, got %d\n",
756 value->Value.cbData);
757 LocalFree(buf);
758 }
759 buf = NULL;
760 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, CAT_NAMEVALUE_STRUCT,
761 catNameValueWithFlags, sizeof(catNameValueWithFlags),
762 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
763 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
764 if (ret)
765 {
766 value = (CAT_NAMEVALUE *)buf;
767 ok(!value->pwszTag || !value->pwszTag[0], "expected empty pwszTag\n");
768 ok(value->fdwFlags == 0xf00dd00d,
769 "expected fdwFlags == 0xf00dd00d, got %08x\n", value->fdwFlags);
770 ok(value->Value.cbData == 0, "expected 0-length value, got %d\n",
771 value->Value.cbData);
772 LocalFree(buf);
773 }
774 buf = NULL;
775 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, CAT_NAMEVALUE_STRUCT,
776 catNameValueWithValue, sizeof(catNameValueWithValue),
777 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
778 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
779 if (ret)
780 {
781 value = (CAT_NAMEVALUE *)buf;
782 ok(!value->pwszTag || !value->pwszTag[0], "expected empty pwszTag\n");
783 ok(value->fdwFlags == 0, "expected fdwFlags == 0, got %08x\n",
784 value->fdwFlags);
785 ok(value->Value.cbData == sizeof(aVal), "unexpected size %d\n",
786 value->Value.cbData);
787 ok(!memcmp(value->Value.pbData, aVal, value->Value.cbData),
788 "unexpected value\n");
789 LocalFree(buf);
790 }
791 }
792
793 static const WCHAR progName[] = { 'A',' ','p','r','o','g','r','a','m',0 };
794 static const BYTE spOpusInfoWithProgramName[] = {
795 0x30,0x16,0xa0,0x14,0x80,0x12,0x00,0x41,0x00,0x20,0x00,0x70,0x00,0x72,0x00,0x6f,
796 0x00,0x67,0x00,0x72,0x00,0x61,0x00,0x6d };
797 static WCHAR winehq[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q',
798 '.','o','r','g','/',0 };
799 static const BYTE spOpusInfoWithMoreInfo[] = {
800 0x30,0x16,0xa1,0x14,0x80,0x12,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,
801 0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x2f };
802 static const BYTE spOpusInfoWithPublisherInfo[] = {
803 0x30,0x16,0xa2,0x14,0x80,0x12,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,
804 0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x2f };
805
806 static void test_encodeSpOpusInfo(void)
807 {
808 BOOL ret;
809 LPBYTE buf;
810 DWORD size;
811 SPC_SP_OPUS_INFO info;
812 SPC_LINK moreInfo;
813
814 memset(&info, 0, sizeof(info));
815 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_SP_OPUS_INFO_STRUCT,
816 &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
817 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
818 if (ret)
819 {
820 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
821 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
822 LocalFree(buf);
823 }
824 info.pwszProgramName = progName;
825 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_SP_OPUS_INFO_STRUCT,
826 &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
827 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
828 if (ret)
829 {
830 ok(size == sizeof(spOpusInfoWithProgramName), "unexpected size %d\n",
831 size);
832 ok(!memcmp(buf, spOpusInfoWithProgramName, size),
833 "unexpected value\n");
834 LocalFree(buf);
835 }
836 info.pwszProgramName = NULL;
837 memset(&moreInfo, 0, sizeof(moreInfo));
838 info.pMoreInfo = &moreInfo;
839 SetLastError(0xdeadbeef);
840 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_SP_OPUS_INFO_STRUCT,
841 &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
842 ok(!ret && GetLastError() == E_INVALIDARG,
843 "expected E_INVALIDARG, got %08x\n", GetLastError());
844 moreInfo.dwLinkChoice = SPC_URL_LINK_CHOICE;
845 U(moreInfo).pwszUrl = winehq;
846 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_SP_OPUS_INFO_STRUCT,
847 &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
848 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
849 if (ret)
850 {
851 ok(size == sizeof(spOpusInfoWithMoreInfo),
852 "unexpected size %d\n", size);
853 ok(!memcmp(buf, spOpusInfoWithMoreInfo, size),
854 "unexpected value\n");
855 LocalFree(buf);
856 }
857 info.pMoreInfo = NULL;
858 info.pPublisherInfo = &moreInfo;
859 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_SP_OPUS_INFO_STRUCT,
860 &info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
861 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
862 if (ret)
863 {
864 ok(size == sizeof(spOpusInfoWithPublisherInfo),
865 "unexpected size %d\n", size);
866 ok(!memcmp(buf, spOpusInfoWithPublisherInfo, size),
867 "unexpected value\n");
868 LocalFree(buf);
869 }
870 }
871
872 static void test_decodeSpOpusInfo(void)
873 {
874 BOOL ret;
875 DWORD size;
876 SPC_SP_OPUS_INFO *info;
877
878 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_SP_OPUS_INFO_STRUCT,
879 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
880 &info, &size);
881 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
882 if (ret)
883 {
884 ok(!info->pwszProgramName, "expected NULL\n");
885 ok(!info->pMoreInfo, "expected NULL\n");
886 ok(!info->pPublisherInfo, "expected NULL\n");
887 LocalFree(info);
888 }
889 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_SP_OPUS_INFO_STRUCT,
890 spOpusInfoWithProgramName, sizeof(spOpusInfoWithProgramName),
891 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
892 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
893 if (ret)
894 {
895 ok(info->pwszProgramName && !lstrcmpW(info->pwszProgramName,
896 progName), "unexpected program name\n");
897 ok(!info->pMoreInfo, "expected NULL\n");
898 ok(!info->pPublisherInfo, "expected NULL\n");
899 LocalFree(info);
900 }
901 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_SP_OPUS_INFO_STRUCT,
902 spOpusInfoWithMoreInfo, sizeof(spOpusInfoWithMoreInfo),
903 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
904 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
905 if (ret)
906 {
907 ok(!info->pwszProgramName, "expected NULL\n");
908 ok(info->pMoreInfo != NULL, "expected a value for pMoreInfo\n");
909 if (info->pMoreInfo)
910 {
911 ok(info->pMoreInfo->dwLinkChoice == SPC_URL_LINK_CHOICE,
912 "unexpected link choice %d\n", info->pMoreInfo->dwLinkChoice);
913 ok(!lstrcmpW(U(*info->pMoreInfo).pwszUrl, winehq),
914 "unexpected link value\n");
915 }
916 ok(!info->pPublisherInfo, "expected NULL\n");
917 LocalFree(info);
918 }
919 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_SP_OPUS_INFO_STRUCT,
920 spOpusInfoWithPublisherInfo, sizeof(spOpusInfoWithPublisherInfo),
921 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
922 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
923 if (ret)
924 {
925 ok(!info->pwszProgramName, "expected NULL\n");
926 ok(!info->pMoreInfo, "expected NULL\n");
927 ok(info->pPublisherInfo != NULL,
928 "expected a value for pPublisherInfo\n");
929 if (info->pPublisherInfo)
930 {
931 ok(info->pPublisherInfo->dwLinkChoice == SPC_URL_LINK_CHOICE,
932 "unexpected link choice %d\n",
933 info->pPublisherInfo->dwLinkChoice);
934 ok(!lstrcmpW(U(*info->pPublisherInfo).pwszUrl, winehq),
935 "unexpected link value\n");
936 }
937 LocalFree(info);
938 }
939 }
940
941 START_TEST(asn)
942 {
943 HMODULE hCrypt32 = LoadLibraryA("crypt32.dll");
944 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
945 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
946
947 test_encodeSPCFinancialCriteria();
948 test_decodeSPCFinancialCriteria();
949 test_encodeSPCLink();
950 test_decodeSPCLink();
951 test_encodeSPCPEImage();
952 test_decodeSPCPEImage();
953 test_encodeCatMemberInfo();
954 test_decodeCatMemberInfo();
955 test_encodeCatNameValue();
956 test_decodeCatNameValue();
957 test_encodeSpOpusInfo();
958 test_decodeSpOpusInfo();
959
960 FreeLibrary(hCrypt32);
961 }