1 /* Unit test suite for wintrust asn functions
3 * Copyright 2007 Juan Lang
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.
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.
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
27 #include "wine/test.h"
29 static WCHAR url
[] = { 'h','t','t','p',':','/','/','w','i','n','e','h','q','.',
31 static const WCHAR nihongoURL
[] = { 'h','t','t','p',':','/','/',0x226f,
33 static const BYTE emptyURLSPCLink
[] = { 0x80,0x00 };
34 static const BYTE urlSPCLink
[] = {
35 0x80,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,
37 static const BYTE fileSPCLink
[] = {
38 0xa2,0x14,0x80,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,
39 0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
40 static const BYTE emptyMonikerSPCLink
[] = {
41 0xa1,0x14,0x04,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
42 0x00,0x00,0x00,0x00,0x00,0x04,0x00 };
43 static BYTE data
[] = { 0xba, 0xad, 0xf0, 0x0d };
44 static const BYTE monikerSPCLink
[] = {
45 0xa1,0x18,0x04,0x10,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,
46 0xea,0xea,0xea,0xea,0xea,0x04,0x04,0xba,0xad,0xf0,0x0d };
48 static void test_encodeSPCLink(void)
53 SPC_LINK link
= { 0 };
55 SetLastError(0xdeadbeef);
56 ret
= CryptEncodeObjectEx(X509_ASN_ENCODING
, SPC_LINK_STRUCT
, &link
,
57 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
58 ok(!ret
&& GetLastError() == E_INVALIDARG
,
59 "Expected E_INVALIDARG, got %08x\n", GetLastError());
60 link
.dwLinkChoice
= SPC_URL_LINK_CHOICE
;
61 ret
= CryptEncodeObjectEx(X509_ASN_ENCODING
, SPC_LINK_STRUCT
, &link
,
62 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
63 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
66 ok(size
== sizeof(emptyURLSPCLink
), "Unexpected size %d\n", size
);
67 ok(!memcmp(buf
, emptyURLSPCLink
, size
), "Unexpected value\n");
70 /* With an invalid char: */
71 U(link
).pwszUrl
= (LPWSTR
)nihongoURL
;
73 SetLastError(0xdeadbeef);
74 ret
= CryptEncodeObjectEx(X509_ASN_ENCODING
, SPC_LINK_STRUCT
, &link
,
75 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
76 ok(!ret
&& GetLastError() == CRYPT_E_INVALID_IA5_STRING
,
77 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
78 /* Unlike the crypt32 string encoding routines, size is not set to the
79 * index of the first invalid character.
81 ok(size
== 0, "Expected size 0, got %d\n", size
);
82 U(link
).pwszUrl
= url
;
83 ret
= CryptEncodeObjectEx(X509_ASN_ENCODING
, SPC_LINK_STRUCT
, &link
,
84 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
85 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
88 ok(size
== sizeof(urlSPCLink
), "Unexpected size %d\n", size
);
89 ok(!memcmp(buf
, urlSPCLink
, size
), "Unexpected value\n");
92 link
.dwLinkChoice
= SPC_FILE_LINK_CHOICE
;
93 U(link
).pwszFile
= (LPWSTR
)nihongoURL
;
94 ret
= CryptEncodeObjectEx(X509_ASN_ENCODING
, SPC_LINK_STRUCT
, &link
,
95 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
96 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
99 ok(size
== sizeof(fileSPCLink
), "Unexpected size %d\n", size
);
100 ok(!memcmp(buf
, fileSPCLink
, size
), "Unexpected value\n");
103 link
.dwLinkChoice
= SPC_MONIKER_LINK_CHOICE
;
104 memset(&U(link
).Moniker
, 0, sizeof(U(link
).Moniker
));
105 ret
= CryptEncodeObjectEx(X509_ASN_ENCODING
, SPC_LINK_STRUCT
, &link
,
106 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
107 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
110 ok(size
== sizeof(emptyMonikerSPCLink
), "Unexpected size %d\n", size
);
111 ok(!memcmp(buf
, emptyMonikerSPCLink
, size
), "Unexpected value\n");
114 memset(&U(link
).Moniker
.ClassId
, 0xea, sizeof(U(link
).Moniker
.ClassId
));
115 U(link
).Moniker
.SerializedData
.pbData
= data
;
116 U(link
).Moniker
.SerializedData
.cbData
= sizeof(data
);
117 ret
= CryptEncodeObjectEx(X509_ASN_ENCODING
, SPC_LINK_STRUCT
, &link
,
118 CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
119 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
122 ok(size
== sizeof(monikerSPCLink
), "Unexpected size %d\n", size
);
123 ok(!memcmp(buf
, monikerSPCLink
, size
), "Unexpected value\n");
128 static const BYTE badMonikerSPCLink
[] = {
129 0xa1,0x19,0x04,0x11,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,0xea,
130 0xea,0xea,0xea,0xea,0xea,0xea,0x04,0x04,0xba,0xad,0xf0,0x0d };
132 static void test_decodeSPCLink(void)
139 ret
= CryptDecodeObjectEx(X509_ASN_ENCODING
, SPC_LINK_STRUCT
,
140 emptyURLSPCLink
, sizeof(emptyURLSPCLink
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
141 (BYTE
*)&buf
, &size
);
142 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
145 link
= (SPC_LINK
*)buf
;
146 ok(link
->dwLinkChoice
== SPC_URL_LINK_CHOICE
,
147 "Expected SPC_URL_LINK_CHOICE, got %d\n", link
->dwLinkChoice
);
148 ok(lstrlenW(U(*link
).pwszUrl
) == 0, "Expected empty string\n");
151 ret
= CryptDecodeObjectEx(X509_ASN_ENCODING
, SPC_LINK_STRUCT
,
152 urlSPCLink
, sizeof(urlSPCLink
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
153 (BYTE
*)&buf
, &size
);
154 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
157 link
= (SPC_LINK
*)buf
;
158 ok(link
->dwLinkChoice
== SPC_URL_LINK_CHOICE
,
159 "Expected SPC_URL_LINK_CHOICE, got %d\n", link
->dwLinkChoice
);
160 ok(!lstrcmpW(U(*link
).pwszUrl
, url
), "Unexpected URL\n");
163 ret
= CryptDecodeObjectEx(X509_ASN_ENCODING
, SPC_LINK_STRUCT
,
164 fileSPCLink
, sizeof(fileSPCLink
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
165 (BYTE
*)&buf
, &size
);
166 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
169 link
= (SPC_LINK
*)buf
;
170 ok(link
->dwLinkChoice
== SPC_FILE_LINK_CHOICE
,
171 "Expected SPC_FILE_LINK_CHOICE, got %d\n", link
->dwLinkChoice
);
172 ok(!lstrcmpW(U(*link
).pwszFile
, nihongoURL
), "Unexpected file\n");
175 ret
= CryptDecodeObjectEx(X509_ASN_ENCODING
, SPC_LINK_STRUCT
,
176 emptyMonikerSPCLink
, sizeof(emptyMonikerSPCLink
), CRYPT_DECODE_ALLOC_FLAG
,
177 NULL
, (BYTE
*)&buf
, &size
);
178 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
181 SPC_SERIALIZED_OBJECT emptyMoniker
= { { 0 } };
183 link
= (SPC_LINK
*)buf
;
184 ok(link
->dwLinkChoice
== SPC_MONIKER_LINK_CHOICE
,
185 "Expected SPC_MONIKER_LINK_CHOICE, got %d\n", link
->dwLinkChoice
);
186 ok(!memcmp(&U(*link
).Moniker
.ClassId
, &emptyMoniker
.ClassId
,
187 sizeof(emptyMoniker
.ClassId
)), "Unexpected value\n");
188 ok(U(*link
).Moniker
.SerializedData
.cbData
== 0,
189 "Expected no serialized data\n");
192 ret
= CryptDecodeObjectEx(X509_ASN_ENCODING
, SPC_LINK_STRUCT
,
193 monikerSPCLink
, sizeof(monikerSPCLink
), CRYPT_DECODE_ALLOC_FLAG
, NULL
,
194 (BYTE
*)&buf
, &size
);
195 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
200 link
= (SPC_LINK
*)buf
;
201 ok(link
->dwLinkChoice
== SPC_MONIKER_LINK_CHOICE
,
202 "Expected SPC_MONIKER_LINK_CHOICE, got %d\n", link
->dwLinkChoice
);
203 memset(&id
, 0xea, sizeof(id
));
204 ok(!memcmp(&U(*link
).Moniker
.ClassId
, &id
, sizeof(id
)),
205 "Unexpected value\n");
206 ok(U(*link
).Moniker
.SerializedData
.cbData
== sizeof(data
),
207 "Unexpected data size %d\n", U(*link
).Moniker
.SerializedData
.cbData
);
208 ok(!memcmp(U(*link
).Moniker
.SerializedData
.pbData
, data
, sizeof(data
)),
209 "Unexpected value\n");
212 SetLastError(0xdeadbeef);
213 ret
= CryptDecodeObjectEx(X509_ASN_ENCODING
, SPC_LINK_STRUCT
,
214 badMonikerSPCLink
, sizeof(badMonikerSPCLink
), CRYPT_DECODE_ALLOC_FLAG
,
215 NULL
, (BYTE
*)&buf
, &size
);
216 ok(!ret
&& GetLastError() == CRYPT_E_BAD_ENCODE
,
217 "Expected CRYPT_E_BAD_ENCODE, got %08x\n", GetLastError());
220 static const BYTE emptySequence
[] = { 0x30,0x00 };
221 static BYTE flags
[] = { 1 };
222 static const BYTE onlyFlagsPEImage
[] = { 0x30,0x04,0x03,0x02,0x00,0x01 };
223 static const BYTE moreFlagsPEImage
[] = {
224 0x30,0x06,0x03,0x04,0x04,0xff,0x80,0x10 };
225 static const BYTE onlyEmptyFilePEImage
[] = {
226 0x30,0x06,0xa0,0x04,0xa2,0x02,0x80,0x00 };
227 static const BYTE flagsAndEmptyFilePEImage
[] = {
228 0x30,0x0a,0x03,0x02,0x00,0x01,0xa0,0x04,0xa2,0x02,0x80,0x00 };
229 static const BYTE flagsAndFilePEImage
[] = {
230 0x30,0x1c,0x03,0x02,0x00,0x01,0xa0,0x16,0xa2,0x14,0x80,0x12,0x00,0x68,0x00,
231 0x74,0x00,0x74,0x00,0x70,0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
233 static void test_encodeSPCPEImage(void)
238 SPC_PE_IMAGE_DATA imageData
= { { 0 } };
239 SPC_LINK link
= { 0 };
241 ret
= CryptEncodeObjectEx(X509_ASN_ENCODING
, SPC_PE_IMAGE_DATA_STRUCT
,
242 &imageData
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
243 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
246 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
247 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
248 "Unexpected value\n");
251 /* With an invalid link: */
252 imageData
.pFile
= &link
;
253 SetLastError(0xdeadbeef);
254 ret
= CryptEncodeObjectEx(X509_ASN_ENCODING
, SPC_PE_IMAGE_DATA_STRUCT
,
255 &imageData
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
256 ok(!ret
&& GetLastError () == E_INVALIDARG
,
257 "Expected E_INVALIDARG, got %08x\n", GetLastError());
258 /* With just unused bits field set: */
259 imageData
.pFile
= NULL
;
260 imageData
.Flags
.cUnusedBits
= 1;
261 ret
= CryptEncodeObjectEx(X509_ASN_ENCODING
, SPC_PE_IMAGE_DATA_STRUCT
,
262 &imageData
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
263 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
266 ok(size
== sizeof(emptySequence
), "Unexpected size %d\n", size
);
267 ok(!memcmp(buf
, emptySequence
, sizeof(emptySequence
)),
268 "Unexpected value\n");
271 /* With flags set: */
272 imageData
.Flags
.cUnusedBits
= 0;
273 imageData
.Flags
.pbData
= flags
;
274 imageData
.Flags
.cbData
= sizeof(flags
);
275 ret
= CryptEncodeObjectEx(X509_ASN_ENCODING
, SPC_PE_IMAGE_DATA_STRUCT
,
276 &imageData
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
277 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
280 ok(size
== sizeof(onlyFlagsPEImage
), "Unexpected size %d\n", size
);
281 ok(!memcmp(buf
, onlyFlagsPEImage
, sizeof(onlyFlagsPEImage
)),
282 "Unexpected value\n");
285 /* With just an empty file: */
286 imageData
.Flags
.cbData
= 0;
287 link
.dwLinkChoice
= SPC_FILE_LINK_CHOICE
;
288 imageData
.pFile
= &link
;
289 ret
= CryptEncodeObjectEx(X509_ASN_ENCODING
, SPC_PE_IMAGE_DATA_STRUCT
,
290 &imageData
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
291 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
294 ok(size
== sizeof(onlyEmptyFilePEImage
), "Unexpected size %d\n", size
);
295 ok(!memcmp(buf
, onlyEmptyFilePEImage
, sizeof(onlyEmptyFilePEImage
)),
296 "Unexpected value\n");
299 /* With flags and an empty file: */
300 imageData
.Flags
.pbData
= flags
;
301 imageData
.Flags
.cbData
= sizeof(flags
);
302 ret
= CryptEncodeObjectEx(X509_ASN_ENCODING
, SPC_PE_IMAGE_DATA_STRUCT
,
303 &imageData
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
304 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
307 ok(size
== sizeof(flagsAndEmptyFilePEImage
), "Unexpected size %d\n",
309 ok(!memcmp(buf
, flagsAndEmptyFilePEImage
,
310 sizeof(flagsAndEmptyFilePEImage
)), "Unexpected value\n");
313 /* Finally, a non-empty file: */
314 U(link
).pwszFile
= (LPWSTR
)nihongoURL
;
315 ret
= CryptEncodeObjectEx(X509_ASN_ENCODING
, SPC_PE_IMAGE_DATA_STRUCT
,
316 &imageData
, CRYPT_ENCODE_ALLOC_FLAG
, NULL
, &buf
, &size
);
317 ok(ret
, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
320 ok(size
== sizeof(flagsAndFilePEImage
), "Unexpected size %d\n", size
);
321 ok(!memcmp(buf
, flagsAndFilePEImage
, sizeof(flagsAndFilePEImage
)),
322 "Unexpected value\n");
327 static void test_decodeSPCPEImage(void)
329 static const WCHAR emptyString
[] = { 0 };
333 SPC_PE_IMAGE_DATA
*imageData
;
335 ret
= CryptDecodeObjectEx(X509_ASN_ENCODING
, SPC_PE_IMAGE_DATA_STRUCT
,
336 emptySequence
, sizeof(emptySequence
),
337 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
338 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
341 imageData
= (SPC_PE_IMAGE_DATA
*)buf
;
342 ok(imageData
->Flags
.cbData
== 0, "Expected empty flags, got %d\n",
343 imageData
->Flags
.cbData
);
344 ok(imageData
->pFile
== NULL
, "Expected no file\n");
347 ret
= CryptDecodeObjectEx(X509_ASN_ENCODING
, SPC_PE_IMAGE_DATA_STRUCT
,
348 onlyFlagsPEImage
, sizeof(onlyFlagsPEImage
),
349 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
350 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
353 imageData
= (SPC_PE_IMAGE_DATA
*)buf
;
354 ok(imageData
->Flags
.cbData
== sizeof(flags
),
355 "Unexpected flags size %d\n", imageData
->Flags
.cbData
);
356 if (imageData
->Flags
.cbData
)
357 ok(!memcmp(imageData
->Flags
.pbData
, flags
, sizeof(flags
)),
358 "Unexpected flags\n");
359 ok(imageData
->pFile
== NULL
, "Expected no file\n");
362 ret
= CryptDecodeObjectEx(X509_ASN_ENCODING
, SPC_PE_IMAGE_DATA_STRUCT
,
363 onlyEmptyFilePEImage
, sizeof(onlyEmptyFilePEImage
),
364 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
365 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
368 imageData
= (SPC_PE_IMAGE_DATA
*)buf
;
369 ok(imageData
->Flags
.cbData
== 0, "Expected empty flags, got %d\n",
370 imageData
->Flags
.cbData
);
371 ok(imageData
->pFile
!= NULL
, "Expected a file\n");
372 if (imageData
->pFile
)
374 ok(imageData
->pFile
->dwLinkChoice
== SPC_FILE_LINK_CHOICE
,
375 "Expected SPC_FILE_LINK_CHOICE, got %d\n",
376 imageData
->pFile
->dwLinkChoice
);
377 ok(!lstrcmpW(U(*imageData
->pFile
).pwszFile
, emptyString
),
378 "Unexpected file\n");
382 ret
= CryptDecodeObjectEx(X509_ASN_ENCODING
, SPC_PE_IMAGE_DATA_STRUCT
,
383 flagsAndEmptyFilePEImage
, sizeof(flagsAndEmptyFilePEImage
),
384 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
385 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
388 imageData
= (SPC_PE_IMAGE_DATA
*)buf
;
389 ok(imageData
->Flags
.cbData
== sizeof(flags
),
390 "Unexpected flags size %d\n", imageData
->Flags
.cbData
);
391 if (imageData
->Flags
.cbData
)
392 ok(!memcmp(imageData
->Flags
.pbData
, flags
, sizeof(flags
)),
393 "Unexpected flags\n");
394 ok(imageData
->pFile
!= NULL
, "Expected a file\n");
395 if (imageData
->pFile
)
397 ok(imageData
->pFile
->dwLinkChoice
== SPC_FILE_LINK_CHOICE
,
398 "Expected SPC_FILE_LINK_CHOICE, got %d\n",
399 imageData
->pFile
->dwLinkChoice
);
400 ok(!lstrcmpW(U(*imageData
->pFile
).pwszFile
, emptyString
),
401 "Unexpected file\n");
405 ret
= CryptDecodeObjectEx(X509_ASN_ENCODING
, SPC_PE_IMAGE_DATA_STRUCT
,
406 flagsAndFilePEImage
, sizeof(flagsAndFilePEImage
),
407 CRYPT_DECODE_ALLOC_FLAG
, NULL
, (BYTE
*)&buf
, &size
);
408 ok(ret
, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
411 imageData
= (SPC_PE_IMAGE_DATA
*)buf
;
412 ok(imageData
->Flags
.cbData
== sizeof(flags
),
413 "Unexpected flags size %d\n", imageData
->Flags
.cbData
);
414 if (imageData
->Flags
.cbData
)
415 ok(!memcmp(imageData
->Flags
.pbData
, flags
, sizeof(flags
)),
416 "Unexpected flags\n");
417 ok(imageData
->pFile
!= NULL
, "Expected a file\n");
418 if (imageData
->pFile
)
420 ok(imageData
->pFile
->dwLinkChoice
== SPC_FILE_LINK_CHOICE
,
421 "Expected SPC_FILE_LINK_CHOICE, got %d\n",
422 imageData
->pFile
->dwLinkChoice
);
423 ok(!lstrcmpW(U(*imageData
->pFile
).pwszFile
, nihongoURL
),
424 "Unexpected file\n");
432 test_encodeSPCLink();
433 test_decodeSPCLink();
434 test_encodeSPCPEImage();
435 test_decodeSPCPEImage();