Revert "winex11.drv: Optimise getting the bits of a DIB after calling SetDIBits."
[wine] / dlls / wintrust / tests / 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
33 static WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.',
34  'o','r','g',0 };
35 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
36  0x575b, 0 };
37 static const BYTE emptyURLSPCLink[] = { 0x80,0x00 };
38 static const BYTE urlSPCLink[] = {
39 0x80,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,
40 0x2e,0x6f,0x72,0x67};
41 static const BYTE fileSPCLink[] = {
42 0xa2,0x14,0x80,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
43 0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
44 static const BYTE emptyMonikerSPCLink[] = {
45 0xa1,0x14,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
46 0x00,0x00,0x00,0x00,0x00,0x04,0x00 };
47 static BYTE data[] = { 0xba, 0xad, 0xf0, 0x0d };
48 static const BYTE monikerSPCLink[] = {
49 0xa1,0x18,0x04,0x10,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,
50 0xea,0xea,0xea,0xea,0xea,0x04,0x04,0xba,0xad,0xf0,0x0d };
51
52 static void test_encodeSPCLink(void)
53 {
54     BOOL ret;
55     DWORD size = 0;
56     LPBYTE buf;
57     SPC_LINK link = { 0 };
58
59     if (!pCryptEncodeObjectEx)
60     {
61         skip("CryptEncodeObjectEx() is not available. Skipping the encodeSPCLink tests\n");
62         return;
63     }
64
65     SetLastError(0xdeadbeef);
66     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT, &link,
67      CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
68     ok(!ret && GetLastError() == E_INVALIDARG,
69      "Expected E_INVALIDARG, got %08x\n", GetLastError());
70     link.dwLinkChoice = SPC_URL_LINK_CHOICE;
71     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT, &link,
72      CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
73     ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
74     if (ret)
75     {
76         ok(size == sizeof(emptyURLSPCLink), "Unexpected size %d\n", size);
77         ok(!memcmp(buf, emptyURLSPCLink, size), "Unexpected value\n");
78         LocalFree(buf);
79     }
80     /* With an invalid char: */
81     U(link).pwszUrl = (LPWSTR)nihongoURL;
82     size = 1;
83     SetLastError(0xdeadbeef);
84     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT, &link,
85      CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
86     ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
87      "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
88     /* Unlike the crypt32 string encoding routines, size is not set to the
89      * index of the first invalid character.
90      */
91     ok(size == 0, "Expected size 0, got %d\n", size);
92     U(link).pwszUrl = url;
93     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT, &link,
94      CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
95     ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
96     if (ret)
97     {
98         ok(size == sizeof(urlSPCLink), "Unexpected size %d\n", size);
99         ok(!memcmp(buf, urlSPCLink, size), "Unexpected value\n");
100         LocalFree(buf);
101     }
102     link.dwLinkChoice = SPC_FILE_LINK_CHOICE;
103     U(link).pwszFile = (LPWSTR)nihongoURL;
104     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT, &link,
105      CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
106     ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
107     if (ret)
108     {
109         ok(size == sizeof(fileSPCLink), "Unexpected size %d\n", size);
110         ok(!memcmp(buf, fileSPCLink, size), "Unexpected value\n");
111         LocalFree(buf);
112     }
113     link.dwLinkChoice = SPC_MONIKER_LINK_CHOICE;
114     memset(&U(link).Moniker, 0, sizeof(U(link).Moniker));
115     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT, &link,
116      CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
117     ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
118     if (ret)
119     {
120         ok(size == sizeof(emptyMonikerSPCLink), "Unexpected size %d\n", size);
121         ok(!memcmp(buf, emptyMonikerSPCLink, size), "Unexpected value\n");
122         LocalFree(buf);
123     }
124     memset(&U(link).Moniker.ClassId, 0xea, sizeof(U(link).Moniker.ClassId));
125     U(link).Moniker.SerializedData.pbData = data;
126     U(link).Moniker.SerializedData.cbData = sizeof(data);
127     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT, &link,
128      CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
129     ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
130     if (ret)
131     {
132         ok(size == sizeof(monikerSPCLink), "Unexpected size %d\n", size);
133         ok(!memcmp(buf, monikerSPCLink, size), "Unexpected value\n");
134         LocalFree(buf);
135     }
136 }
137
138 static const BYTE badMonikerSPCLink[] = {
139 0xa1,0x19,0x04,0x11,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,
140 0xea,0xea,0xea,0xea,0xea,0xea,0x04,0x04,0xba,0xad,0xf0,0x0d };
141
142 static void test_decodeSPCLink(void)
143 {
144     BOOL ret;
145     LPBYTE buf = NULL;
146     DWORD size = 0;
147     SPC_LINK *link;
148
149     if (!pCryptDecodeObjectEx)
150     {
151         skip("CryptDecodeObjectEx() is not available. Skipping the decodeSPCLink tests\n");
152         return;
153     }
154
155     ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT,
156      emptyURLSPCLink, sizeof(emptyURLSPCLink), CRYPT_DECODE_ALLOC_FLAG, NULL,
157      (BYTE *)&buf, &size);
158     ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
159     if (ret)
160     {
161         link = (SPC_LINK *)buf;
162         ok(link->dwLinkChoice == SPC_URL_LINK_CHOICE,
163          "Expected SPC_URL_LINK_CHOICE, got %d\n", link->dwLinkChoice);
164         ok(lstrlenW(U(*link).pwszUrl) == 0, "Expected empty string\n");
165         LocalFree(buf);
166     }
167     ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT,
168      urlSPCLink, sizeof(urlSPCLink), CRYPT_DECODE_ALLOC_FLAG, NULL,
169      (BYTE *)&buf, &size);
170     ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
171     if (ret)
172     {
173         link = (SPC_LINK *)buf;
174         ok(link->dwLinkChoice == SPC_URL_LINK_CHOICE,
175          "Expected SPC_URL_LINK_CHOICE, got %d\n", link->dwLinkChoice);
176         ok(!lstrcmpW(U(*link).pwszUrl, url), "Unexpected URL\n");
177         LocalFree(buf);
178     }
179     ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT,
180      fileSPCLink, sizeof(fileSPCLink), CRYPT_DECODE_ALLOC_FLAG, NULL,
181      (BYTE *)&buf, &size);
182     ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
183     if (ret)
184     {
185         link = (SPC_LINK *)buf;
186         ok(link->dwLinkChoice == SPC_FILE_LINK_CHOICE,
187          "Expected SPC_FILE_LINK_CHOICE, got %d\n", link->dwLinkChoice);
188         ok(!lstrcmpW(U(*link).pwszFile, nihongoURL), "Unexpected file\n");
189         LocalFree(buf);
190     }
191     ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT,
192      emptyMonikerSPCLink, sizeof(emptyMonikerSPCLink), CRYPT_DECODE_ALLOC_FLAG,
193      NULL, (BYTE *)&buf, &size);
194     ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
195     if (ret)
196     {
197         SPC_SERIALIZED_OBJECT emptyMoniker = { { 0 } };
198
199         link = (SPC_LINK *)buf;
200         ok(link->dwLinkChoice == SPC_MONIKER_LINK_CHOICE,
201          "Expected SPC_MONIKER_LINK_CHOICE, got %d\n", link->dwLinkChoice);
202         ok(!memcmp(&U(*link).Moniker.ClassId, &emptyMoniker.ClassId,
203          sizeof(emptyMoniker.ClassId)), "Unexpected value\n");
204         ok(U(*link).Moniker.SerializedData.cbData == 0,
205          "Expected no serialized data\n");
206         LocalFree(buf);
207     }
208     ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT,
209      monikerSPCLink, sizeof(monikerSPCLink), CRYPT_DECODE_ALLOC_FLAG, NULL,
210      (BYTE *)&buf, &size);
211     ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
212     if (ret)
213     {
214         SPC_UUID id;
215
216         link = (SPC_LINK *)buf;
217         ok(link->dwLinkChoice == SPC_MONIKER_LINK_CHOICE,
218          "Expected SPC_MONIKER_LINK_CHOICE, got %d\n", link->dwLinkChoice);
219         memset(&id, 0xea, sizeof(id));
220         ok(!memcmp(&U(*link).Moniker.ClassId, &id, sizeof(id)),
221          "Unexpected value\n");
222         ok(U(*link).Moniker.SerializedData.cbData == sizeof(data),
223            "Unexpected data size %d\n", U(*link).Moniker.SerializedData.cbData);
224         ok(!memcmp(U(*link).Moniker.SerializedData.pbData, data, sizeof(data)),
225          "Unexpected value\n");
226         LocalFree(buf);
227     }
228     SetLastError(0xdeadbeef);
229     ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_LINK_STRUCT,
230      badMonikerSPCLink, sizeof(badMonikerSPCLink), CRYPT_DECODE_ALLOC_FLAG,
231      NULL, (BYTE *)&buf, &size);
232     ok(!ret && GetLastError() == CRYPT_E_BAD_ENCODE,
233      "Expected CRYPT_E_BAD_ENCODE, got %08x\n", GetLastError());
234 }
235
236 static const BYTE emptySequence[] = { 0x30,0x00 };
237 static BYTE flags[] = { 1 };
238 static const BYTE onlyFlagsPEImage[] = { 0x30,0x04,0x03,0x02,0x00,0x01 };
239 static const BYTE moreFlagsPEImage[] = {
240 0x30,0x06,0x03,0x04,0x04,0xff,0x80,0x10 };
241 static const BYTE onlyEmptyFilePEImage[] = {
242 0x30,0x06,0xa0,0x04,0xa2,0x02,0x80,0x00 };
243 static const BYTE flagsAndEmptyFilePEImage[] = {
244 0x30,0x0a,0x03,0x02,0x00,0x01,0xa0,0x04,0xa2,0x02,0x80,0x00 };
245 static const BYTE flagsAndFilePEImage[] = {
246 0x30,0x1c,0x03,0x02,0x00,0x01,0xa0,0x16,0xa2,0x14,0x80,0x12,0x00,0x68,0x00,
247 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
248
249 static void test_encodeSPCPEImage(void)
250 {
251     BOOL ret;
252     DWORD size = 0;
253     LPBYTE buf;
254     SPC_PE_IMAGE_DATA imageData = { { 0 } };
255     SPC_LINK link = { 0 };
256
257     if (!pCryptEncodeObjectEx)
258     {
259         skip("CryptEncodeObjectEx() is not available. Skipping the encodeSPCPEImage tests\n");
260         return;
261     }
262
263     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
264      &imageData, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
265     ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
266     if (ret)
267     {
268         ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
269         ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
270          "Unexpected value\n");
271         LocalFree(buf);
272     }
273     /* With an invalid link: */
274     imageData.pFile = &link;
275     SetLastError(0xdeadbeef);
276     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
277      &imageData, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
278     ok(!ret && GetLastError () == E_INVALIDARG,
279      "Expected E_INVALIDARG, got %08x\n", GetLastError());
280     /* With just unused bits field set: */
281     imageData.pFile = NULL;
282     imageData.Flags.cUnusedBits = 1;
283     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
284      &imageData, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
285     ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
286     if (ret)
287     {
288         ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
289         ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
290          "Unexpected value\n");
291         LocalFree(buf);
292     }
293     /* With flags set: */
294     imageData.Flags.cUnusedBits = 0;
295     imageData.Flags.pbData = flags;
296     imageData.Flags.cbData = sizeof(flags);
297     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
298      &imageData, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
299     ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
300     if (ret)
301     {
302         ok(size == sizeof(onlyFlagsPEImage), "Unexpected size %d\n", size);
303         ok(!memcmp(buf, onlyFlagsPEImage, sizeof(onlyFlagsPEImage)),
304          "Unexpected value\n");
305         LocalFree(buf);
306     }
307     /* With just an empty file: */
308     imageData.Flags.cbData = 0;
309     link.dwLinkChoice = SPC_FILE_LINK_CHOICE;
310     imageData.pFile = &link;
311     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
312      &imageData, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
313     ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
314     if (ret)
315     {
316         ok(size == sizeof(onlyEmptyFilePEImage), "Unexpected size %d\n", size);
317         ok(!memcmp(buf, onlyEmptyFilePEImage, sizeof(onlyEmptyFilePEImage)),
318          "Unexpected value\n");
319         LocalFree(buf);
320     }
321     /* With flags and an empty file: */
322     imageData.Flags.pbData = flags;
323     imageData.Flags.cbData = sizeof(flags);
324     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
325      &imageData, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
326     ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
327     if (ret)
328     {
329         ok(size == sizeof(flagsAndEmptyFilePEImage), "Unexpected size %d\n",
330          size);
331         ok(!memcmp(buf, flagsAndEmptyFilePEImage,
332          sizeof(flagsAndEmptyFilePEImage)), "Unexpected value\n");
333         LocalFree(buf);
334     }
335     /* Finally, a non-empty file: */
336     U(link).pwszFile = (LPWSTR)nihongoURL;
337     ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
338      &imageData, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
339     ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
340     if (ret)
341     {
342         ok(size == sizeof(flagsAndFilePEImage), "Unexpected size %d\n", size);
343         ok(!memcmp(buf, flagsAndFilePEImage, sizeof(flagsAndFilePEImage)),
344          "Unexpected value\n");
345         LocalFree(buf);
346     }
347 }
348
349 static void test_decodeSPCPEImage(void)
350 {
351     static const WCHAR emptyString[] = { 0 };
352     BOOL ret;
353     LPBYTE buf = NULL;
354     DWORD size = 0;
355     SPC_PE_IMAGE_DATA *imageData;
356
357     if (!pCryptDecodeObjectEx)
358     {
359         skip("CryptDecodeObjectEx() is not available. Skipping the decodeSPCPEImage tests\n");
360         return;
361     }
362
363     ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
364      emptySequence, sizeof(emptySequence),
365      CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
366     ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
367     if (ret)
368     {
369         imageData = (SPC_PE_IMAGE_DATA *)buf;
370         ok(imageData->Flags.cbData == 0, "Expected empty flags, got %d\n",
371          imageData->Flags.cbData);
372         ok(imageData->pFile == NULL, "Expected no file\n");
373         LocalFree(buf);
374     }
375     ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
376      onlyFlagsPEImage, sizeof(onlyFlagsPEImage),
377      CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
378     ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
379     if (ret)
380     {
381         imageData = (SPC_PE_IMAGE_DATA *)buf;
382         ok(imageData->Flags.cbData == sizeof(flags),
383          "Unexpected flags size %d\n", imageData->Flags.cbData);
384         if (imageData->Flags.cbData)
385             ok(!memcmp(imageData->Flags.pbData, flags, sizeof(flags)),
386              "Unexpected flags\n");
387         ok(imageData->pFile == NULL, "Expected no file\n");
388         LocalFree(buf);
389     }
390     ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
391      onlyEmptyFilePEImage, sizeof(onlyEmptyFilePEImage),
392      CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
393     ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
394     if (ret)
395     {
396         imageData = (SPC_PE_IMAGE_DATA *)buf;
397         ok(imageData->Flags.cbData == 0, "Expected empty flags, got %d\n",
398          imageData->Flags.cbData);
399         ok(imageData->pFile != NULL, "Expected a file\n");
400         if (imageData->pFile)
401         {
402             ok(imageData->pFile->dwLinkChoice == SPC_FILE_LINK_CHOICE,
403              "Expected SPC_FILE_LINK_CHOICE, got %d\n",
404              imageData->pFile->dwLinkChoice);
405             ok(!lstrcmpW(U(*imageData->pFile).pwszFile, emptyString),
406              "Unexpected file\n");
407         }
408         LocalFree(buf);
409     }
410     ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
411      flagsAndEmptyFilePEImage, sizeof(flagsAndEmptyFilePEImage),
412      CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
413     ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
414     if (ret)
415     {
416         imageData = (SPC_PE_IMAGE_DATA *)buf;
417         ok(imageData->Flags.cbData == sizeof(flags),
418          "Unexpected flags size %d\n", imageData->Flags.cbData);
419         if (imageData->Flags.cbData)
420             ok(!memcmp(imageData->Flags.pbData, flags, sizeof(flags)),
421              "Unexpected flags\n");
422         ok(imageData->pFile != NULL, "Expected a file\n");
423         if (imageData->pFile)
424         {
425             ok(imageData->pFile->dwLinkChoice == SPC_FILE_LINK_CHOICE,
426              "Expected SPC_FILE_LINK_CHOICE, got %d\n",
427              imageData->pFile->dwLinkChoice);
428             ok(!lstrcmpW(U(*imageData->pFile).pwszFile, emptyString),
429              "Unexpected file\n");
430         }
431         LocalFree(buf);
432     }
433     ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, SPC_PE_IMAGE_DATA_STRUCT,
434      flagsAndFilePEImage, sizeof(flagsAndFilePEImage),
435      CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
436     ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
437     if (ret)
438     {
439         imageData = (SPC_PE_IMAGE_DATA *)buf;
440         ok(imageData->Flags.cbData == sizeof(flags),
441          "Unexpected flags size %d\n", imageData->Flags.cbData);
442         if (imageData->Flags.cbData)
443             ok(!memcmp(imageData->Flags.pbData, flags, sizeof(flags)),
444              "Unexpected flags\n");
445         ok(imageData->pFile != NULL, "Expected a file\n");
446         if (imageData->pFile)
447         {
448             ok(imageData->pFile->dwLinkChoice == SPC_FILE_LINK_CHOICE,
449              "Expected SPC_FILE_LINK_CHOICE, got %d\n",
450              imageData->pFile->dwLinkChoice);
451             ok(!lstrcmpW(U(*imageData->pFile).pwszFile, nihongoURL),
452              "Unexpected file\n");
453         }
454         LocalFree(buf);
455     }
456 }
457
458 START_TEST(asn)
459 {
460     HMODULE hCrypt32 = LoadLibraryA("crypt32.dll");
461     pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
462     pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
463
464     test_encodeSPCLink();
465     test_decodeSPCLink();
466     test_encodeSPCPEImage();
467     test_decodeSPCPEImage();
468 }