push 6b90daee4ad260d418fbcb69f08db2ce800b82e2
[wine/hacks.git] / dlls / crypt32 / tests / encode.c
blob0b164882688b0c9e516796878e35e95026b9dc0c
1 /*
2 * Unit test suite for crypt32.dll's CryptEncodeObjectEx/CryptDecodeObjectEx
4 * Copyright 2005 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <windef.h>
23 #include <winbase.h>
24 #include <winerror.h>
25 #include <wincrypt.h>
27 #include "wine/test.h"
30 static BOOL (WINAPI *pCryptDecodeObjectEx)(DWORD,LPCSTR,const BYTE*,DWORD,DWORD,PCRYPT_DECODE_PARA,void*,DWORD*);
31 static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*);
33 struct encodedInt
35 int val;
36 const BYTE *encoded;
39 static const BYTE bin1[] = {0x02,0x01,0x01};
40 static const BYTE bin2[] = {0x02,0x01,0x7f};
41 static const BYTE bin3[] = {0x02,0x02,0x00,0x80};
42 static const BYTE bin4[] = {0x02,0x02,0x01,0x00};
43 static const BYTE bin5[] = {0x02,0x01,0x80};
44 static const BYTE bin6[] = {0x02,0x02,0xff,0x7f};
45 static const BYTE bin7[] = {0x02,0x04,0xba,0xdd,0xf0,0x0d};
47 static const struct encodedInt ints[] = {
48 { 1, bin1 },
49 { 127, bin2 },
50 { 128, bin3 },
51 { 256, bin4 },
52 { -128, bin5 },
53 { -129, bin6 },
54 { 0xbaddf00d, bin7 },
57 struct encodedBigInt
59 const BYTE *val;
60 const BYTE *encoded;
61 const BYTE *decoded;
64 static const BYTE bin8[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
65 static const BYTE bin9[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
66 static const BYTE bin10[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
68 static const BYTE bin11[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
69 static const BYTE bin12[] = {0x02,0x09,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
70 static const BYTE bin13[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0};
72 static const struct encodedBigInt bigInts[] = {
73 { bin8, bin9, bin10 },
74 { bin11, bin12, bin13 },
77 static const BYTE bin14[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
78 static const BYTE bin15[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
79 static const BYTE bin16[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
80 static const BYTE bin17[] = {0x02,0x0c,0x00,0xff,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
82 /* Decoded is the same as original, so don't bother storing a separate copy */
83 static const struct encodedBigInt bigUInts[] = {
84 { bin14, bin15, NULL },
85 { bin16, bin17, NULL },
88 static void test_encodeInt(DWORD dwEncoding)
90 DWORD bufSize = 0;
91 int i;
92 BOOL ret;
93 CRYPT_INTEGER_BLOB blob;
94 BYTE *buf = NULL;
96 /* CryptEncodeObjectEx with NULL bufSize crashes..
97 ret = pCryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
98 NULL);
100 /* check bogus encoding */
101 ret = pCryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
102 &bufSize);
103 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
104 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
105 if (0)
107 /* check with NULL integer buffer. Windows XP incorrectly returns an
108 * NTSTATUS (crashes on win9x).
110 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, NULL, NULL,
111 &bufSize);
112 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
113 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
115 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
117 /* encode as normal integer */
118 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 0,
119 NULL, NULL, &bufSize);
120 ok(ret, "Expected success, got %d\n", GetLastError());
121 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val,
122 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
123 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
124 if (buf)
126 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
127 buf[0]);
128 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
129 buf[1], ints[i].encoded[1]);
130 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
131 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
132 LocalFree(buf);
134 /* encode as multibyte integer */
135 blob.cbData = sizeof(ints[i].val);
136 blob.pbData = (BYTE *)&ints[i].val;
137 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
138 0, NULL, NULL, &bufSize);
139 ok(ret, "Expected success, got %d\n", GetLastError());
140 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
141 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
142 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
143 if (buf)
145 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
146 buf[0]);
147 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
148 buf[1], ints[i].encoded[1]);
149 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
150 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
151 LocalFree(buf);
154 /* encode a couple bigger ints, just to show it's little-endian and leading
155 * sign bytes are dropped
157 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
159 blob.cbData = strlen((const char*)bigInts[i].val);
160 blob.pbData = (BYTE *)bigInts[i].val;
161 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
162 0, NULL, NULL, &bufSize);
163 ok(ret, "Expected success, got %d\n", GetLastError());
164 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
165 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
166 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
167 if (buf)
169 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
170 buf[0]);
171 ok(buf[1] == bigInts[i].encoded[1], "Got length %d, expected %d\n",
172 buf[1], bigInts[i].encoded[1]);
173 ok(!memcmp(buf + 1, bigInts[i].encoded + 1,
174 bigInts[i].encoded[1] + 1),
175 "Encoded value didn't match expected\n");
176 LocalFree(buf);
179 /* and, encode some uints */
180 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
182 blob.cbData = strlen((const char*)bigUInts[i].val);
183 blob.pbData = (BYTE*)bigUInts[i].val;
184 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
185 0, NULL, NULL, &bufSize);
186 ok(ret, "Expected success, got %d\n", GetLastError());
187 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
188 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
189 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
190 if (buf)
192 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
193 buf[0]);
194 ok(buf[1] == bigUInts[i].encoded[1], "Got length %d, expected %d\n",
195 buf[1], bigUInts[i].encoded[1]);
196 ok(!memcmp(buf + 1, bigUInts[i].encoded + 1,
197 bigUInts[i].encoded[1] + 1),
198 "Encoded value didn't match expected\n");
199 LocalFree(buf);
204 static void test_decodeInt(DWORD dwEncoding)
206 static const BYTE bigInt[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff };
207 static const BYTE testStr[] = { 0x16, 4, 't', 'e', 's', 't' };
208 static const BYTE longForm[] = { 2, 0x81, 0x01, 0x01 };
209 static const BYTE bigBogus[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 };
210 static const BYTE extraBytes[] = { 2, 1, 1, 0, 0, 0, 0 };
211 BYTE *buf = NULL;
212 DWORD bufSize = 0;
213 int i;
214 BOOL ret;
216 /* CryptDecodeObjectEx with NULL bufSize crashes..
217 ret = pCryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded,
218 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
220 /* check bogus encoding */
221 ret = pCryptDecodeObjectEx(3, X509_INTEGER, (BYTE *)&ints[0].encoded,
222 ints[0].encoded[1] + 2, 0, NULL, NULL, &bufSize);
223 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
224 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
225 /* check with NULL integer buffer */
226 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, 0, NULL, NULL,
227 &bufSize);
228 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
229 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
230 /* check with a valid, but too large, integer */
231 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, bigInt, bigInt[1] + 2,
232 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
233 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
234 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
235 /* check with a DER-encoded string */
236 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, testStr, testStr[1] + 2,
237 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
238 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
239 "Expected CRYPT_E_ASN1_BADTAG, got %d\n", GetLastError());
240 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
242 /* When the output buffer is NULL, this always succeeds */
243 SetLastError(0xdeadbeef);
244 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
245 ints[i].encoded, ints[i].encoded[1] + 2, 0, NULL, NULL,
246 &bufSize);
247 ok(ret && GetLastError() == NOERROR,
248 "Expected success and NOERROR, got %d\n", GetLastError());
249 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
250 ints[i].encoded, ints[i].encoded[1] + 2,
251 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
252 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
253 ok(bufSize == sizeof(int), "Wrong size %d\n", bufSize);
254 ok(buf != NULL, "Expected allocated buffer\n");
255 if (buf)
257 ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n",
258 ints[i].val, *(int *)buf);
259 LocalFree(buf);
262 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
264 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
265 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 0, NULL, NULL,
266 &bufSize);
267 ok(ret && GetLastError() == NOERROR,
268 "Expected success and NOERROR, got %d\n", GetLastError());
269 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
270 bigInts[i].encoded, bigInts[i].encoded[1] + 2,
271 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
272 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
273 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
274 ok(buf != NULL, "Expected allocated buffer\n");
275 if (buf)
277 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
279 ok(blob->cbData == strlen((const char*)bigInts[i].decoded),
280 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts[i].decoded),
281 blob->cbData);
282 ok(!memcmp(blob->pbData, bigInts[i].decoded, blob->cbData),
283 "Unexpected value\n");
284 LocalFree(buf);
287 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
289 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
290 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 0, NULL, NULL,
291 &bufSize);
292 ok(ret && GetLastError() == NOERROR,
293 "Expected success and NOERROR, got %d\n", GetLastError());
294 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
295 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2,
296 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
297 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
298 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
299 ok(buf != NULL, "Expected allocated buffer\n");
300 if (buf)
302 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
304 ok(blob->cbData == strlen((const char*)bigUInts[i].val),
305 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts[i].val),
306 blob->cbData);
307 ok(!memcmp(blob->pbData, bigUInts[i].val, blob->cbData),
308 "Unexpected value\n");
309 LocalFree(buf);
312 /* Decode the value 1 with long-form length */
313 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, longForm,
314 sizeof(longForm), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
315 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
316 if (buf)
318 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
319 LocalFree(buf);
321 /* check with extra bytes at the end */
322 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, extraBytes,
323 sizeof(extraBytes), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
324 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
325 if (buf)
327 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
328 LocalFree(buf);
330 /* Try to decode some bogus large items */
331 /* The buffer size is smaller than the encoded length, so this should fail
332 * with CRYPT_E_ASN1_EOD if it's being decoded.
333 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit
334 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes.
335 * So this test unfortunately isn't useful.
336 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig,
337 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
338 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
339 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
341 /* This will try to decode the buffer and overflow it, check that it's
342 * caught.
344 if (0)
346 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
347 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, bigBogus,
348 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
349 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
350 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
354 static const BYTE bin18[] = {0x0a,0x01,0x01};
355 static const BYTE bin19[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
357 /* These are always encoded unsigned, and aren't constrained to be any
358 * particular value
360 static const struct encodedInt enums[] = {
361 { 1, bin18 },
362 { -128, bin19 },
365 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
366 * X509_ENUMERATED.
368 static const LPCSTR enumeratedTypes[] = { X509_ENUMERATED,
369 szOID_CRL_REASON_CODE };
371 static void test_encodeEnumerated(DWORD dwEncoding)
373 DWORD i, j;
375 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
377 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
379 BOOL ret;
380 BYTE *buf = NULL;
381 DWORD bufSize = 0;
383 ret = pCryptEncodeObjectEx(dwEncoding, enumeratedTypes[i],
384 &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
385 &bufSize);
386 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
387 if (buf)
389 ok(buf[0] == 0xa,
390 "Got unexpected type %d for enumerated (expected 0xa)\n",
391 buf[0]);
392 ok(buf[1] == enums[j].encoded[1],
393 "Got length %d, expected %d\n", buf[1], enums[j].encoded[1]);
394 ok(!memcmp(buf + 1, enums[j].encoded + 1,
395 enums[j].encoded[1] + 1),
396 "Encoded value of 0x%08x didn't match expected\n",
397 enums[j].val);
398 LocalFree(buf);
404 static void test_decodeEnumerated(DWORD dwEncoding)
406 DWORD i, j;
408 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
410 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
412 BOOL ret;
413 DWORD bufSize = sizeof(int);
414 int val;
416 ret = pCryptDecodeObjectEx(dwEncoding, enumeratedTypes[i],
417 enums[j].encoded, enums[j].encoded[1] + 2, 0, NULL,
418 (BYTE *)&val, &bufSize);
419 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
420 ok(bufSize == sizeof(int),
421 "Got unexpected size %d for enumerated\n", bufSize);
422 ok(val == enums[j].val, "Unexpected value %d, expected %d\n",
423 val, enums[j].val);
428 struct encodedFiletime
430 SYSTEMTIME sysTime;
431 const BYTE *encodedTime;
434 static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType,
435 const struct encodedFiletime *time)
437 FILETIME ft = { 0 };
438 BYTE *buf = NULL;
439 DWORD bufSize = 0;
440 BOOL ret;
442 ret = SystemTimeToFileTime(&time->sysTime, &ft);
443 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
444 ret = pCryptEncodeObjectEx(dwEncoding, structType, &ft,
445 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
446 /* years other than 1950-2050 are not allowed for encodings other than
447 * X509_CHOICE_OF_TIME.
449 if (structType == X509_CHOICE_OF_TIME ||
450 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
452 ok(ret, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
453 GetLastError());
454 ok(buf != NULL, "Expected an allocated buffer\n");
455 if (buf)
457 ok(buf[0] == time->encodedTime[0],
458 "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0],
459 buf[0]);
460 ok(buf[1] == time->encodedTime[1], "Expected %d bytes, got %d\n",
461 time->encodedTime[1], bufSize);
462 ok(!memcmp(time->encodedTime + 2, buf + 2, time->encodedTime[1]),
463 "Got unexpected value for time encoding\n");
464 LocalFree(buf);
467 else
468 ok(!ret && GetLastError() == CRYPT_E_BAD_ENCODE,
469 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
472 static const char *printSystemTime(const SYSTEMTIME *st)
474 static char buf[25];
476 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay,
477 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
478 return buf;
481 static const char *printFileTime(const FILETIME *ft)
483 static char buf[25];
484 SYSTEMTIME st;
486 FileTimeToSystemTime(ft, &st);
487 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay,
488 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
489 return buf;
492 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got)
494 SYSTEMTIME st;
496 FileTimeToSystemTime(got, &st);
497 ok(expected->wYear == st.wYear &&
498 expected->wMonth == st.wMonth &&
499 expected->wDay == st.wDay &&
500 expected->wHour == st.wHour &&
501 expected->wMinute == st.wMinute &&
502 expected->wSecond == st.wSecond &&
503 abs(expected->wMilliseconds - st.wMilliseconds) <= 1,
504 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
505 printSystemTime(expected), printFileTime(got));
508 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
509 const struct encodedFiletime *time)
511 FILETIME ft = { 0 };
512 DWORD size = sizeof(ft);
513 BOOL ret;
515 ret = pCryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
516 time->encodedTime[1] + 2, 0, NULL, &ft, &size);
517 /* years other than 1950-2050 are not allowed for encodings other than
518 * X509_CHOICE_OF_TIME.
520 if (structType == X509_CHOICE_OF_TIME ||
521 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
523 ok(ret, "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
524 GetLastError());
525 compareTime(&time->sysTime, &ft);
527 else
528 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
529 "Expected CRYPT_E_ASN1_BADTAG, got 0x%08x\n", GetLastError());
532 static const BYTE bin20[] = {
533 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
534 static const BYTE bin21[] = {
535 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
536 static const BYTE bin22[] = {
537 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
539 static const struct encodedFiletime times[] = {
540 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
541 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
542 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
545 static void test_encodeFiletime(DWORD dwEncoding)
547 DWORD i;
549 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
551 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
552 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
553 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
557 static const BYTE bin23[] = {
558 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
559 static const BYTE bin24[] = {
560 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
561 static const BYTE bin25[] = {
562 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
563 static const BYTE bin26[] = {
564 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
565 static const BYTE bin27[] = {
566 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
567 static const BYTE bin28[] = {
568 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
569 static const BYTE bin29[] = {
570 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
571 static const BYTE bin30[] = {
572 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
573 static const BYTE bin31[] = {
574 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
575 static const BYTE bin32[] = {
576 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
577 static const BYTE bin33[] = {
578 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
579 static const BYTE bin34[] = {
580 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
581 static const BYTE bin35[] = {
582 0x17,0x08, '4','5','0','6','0','6','1','6'};
583 static const BYTE bin36[] = {
584 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
585 static const BYTE bin37[] = {
586 0x18,0x04, '2','1','4','5'};
587 static const BYTE bin38[] = {
588 0x18,0x08, '2','1','4','5','0','6','0','6'};
590 static void test_decodeFiletime(DWORD dwEncoding)
592 static const struct encodedFiletime otherTimes[] = {
593 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
594 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
595 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
596 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
597 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
598 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
599 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
600 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
601 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
602 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
603 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
604 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
606 /* An oddball case that succeeds in Windows, but doesn't seem correct
607 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
609 static const unsigned char *bogusTimes[] = {
610 /* oddly, this succeeds on Windows, with year 2765
611 "\x18" "\x0f" "21r50606161000Z",
613 bin35,
614 bin36,
615 bin37,
616 bin38,
618 DWORD i, size;
619 FILETIME ft1 = { 0 }, ft2 = { 0 };
620 BOOL ret;
622 /* Check bogus length with non-NULL buffer */
623 ret = SystemTimeToFileTime(&times[0].sysTime, &ft1);
624 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
625 size = 1;
626 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
627 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
628 ok(!ret && GetLastError() == ERROR_MORE_DATA,
629 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
630 /* Normal tests */
631 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
633 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
634 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
635 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
637 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
639 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
640 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
641 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
643 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
645 size = sizeof(ft1);
646 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
647 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
648 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
649 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
653 static const char commonName[] = "Juan Lang";
654 static const char surName[] = "Lang";
656 static const BYTE emptySequence[] = { 0x30, 0 };
657 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
658 static const BYTE twoRDNs[] = {
659 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
660 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
661 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
662 static const BYTE encodedTwoRDNs[] = {
663 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
664 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
665 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
666 0x6e,0x67,0x00,
669 static const BYTE us[] = { 0x55, 0x53 };
670 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
671 0x74, 0x61 };
672 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
673 0x6f, 0x6c, 0x69, 0x73 };
674 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
675 0x76, 0x65, 0x72, 0x73 };
676 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
677 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
678 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
679 0x73, 0x74 };
680 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
681 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
683 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
684 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
686 static CHAR oid_us[] = "2.5.4.6",
687 oid_minnesota[] = "2.5.4.8",
688 oid_minneapolis[] = "2.5.4.7",
689 oid_codeweavers[] = "2.5.4.10",
690 oid_wine[] = "2.5.4.11",
691 oid_localhostAttr[] = "2.5.4.3",
692 oid_aric[] = "1.2.840.113549.1.9.1";
693 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
694 { RDNA(minnesota) },
695 { RDNA(minneapolis) },
696 { RDNA(codeweavers) },
697 { RDNA(wine) },
698 { RDNA(localhostAttr) },
699 { RDNIA5(aric) } };
700 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
701 { RDNA(localhostAttr) },
702 { RDNA(minnesota) },
703 { RDNA(minneapolis) },
704 { RDNA(codeweavers) },
705 { RDNA(wine) },
706 { RDNIA5(aric) } };
708 #undef RDNIA5
709 #undef RDNA
711 static const BYTE encodedRDNAttrs[] = {
712 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
713 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
714 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
715 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
716 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
717 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
718 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
719 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
720 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
721 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
724 static void test_encodeName(DWORD dwEncoding)
726 CERT_RDN_ATTR attrs[2];
727 CERT_RDN rdn;
728 CERT_NAME_INFO info;
729 static CHAR oid_common_name[] = szOID_COMMON_NAME,
730 oid_sur_name[] = szOID_SUR_NAME;
731 BYTE *buf = NULL;
732 DWORD size = 0;
733 BOOL ret;
735 if (0)
737 /* Test with NULL pvStructInfo (crashes on win9x) */
738 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
739 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
740 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
741 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
743 /* Test with empty CERT_NAME_INFO */
744 info.cRDN = 0;
745 info.rgRDN = NULL;
746 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
747 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
748 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
749 if (buf)
751 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
752 "Got unexpected encoding for empty name\n");
753 LocalFree(buf);
755 if (0)
757 /* Test with bogus CERT_RDN (crashes on win9x) */
758 info.cRDN = 1;
759 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
760 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
761 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
762 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
764 /* Test with empty CERT_RDN */
765 rdn.cRDNAttr = 0;
766 rdn.rgRDNAttr = NULL;
767 info.cRDN = 1;
768 info.rgRDN = &rdn;
769 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
770 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
771 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
772 if (buf)
774 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
775 "Got unexpected encoding for empty RDN array\n");
776 LocalFree(buf);
778 if (0)
780 /* Test with bogus attr array (crashes on win9x) */
781 rdn.cRDNAttr = 1;
782 rdn.rgRDNAttr = NULL;
783 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
784 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
785 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
786 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
788 /* oddly, a bogus OID is accepted by Windows XP; not testing.
789 attrs[0].pszObjId = "bogus";
790 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
791 attrs[0].Value.cbData = sizeof(commonName);
792 attrs[0].Value.pbData = (BYTE *)commonName;
793 rdn.cRDNAttr = 1;
794 rdn.rgRDNAttr = attrs;
795 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
796 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
797 ok(!ret, "Expected failure, got success\n");
799 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
800 * the encoded attributes to be swapped.
802 attrs[0].pszObjId = oid_common_name;
803 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
804 attrs[0].Value.cbData = sizeof(commonName);
805 attrs[0].Value.pbData = (BYTE *)commonName;
806 attrs[1].pszObjId = oid_sur_name;
807 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
808 attrs[1].Value.cbData = sizeof(surName);
809 attrs[1].Value.pbData = (BYTE *)surName;
810 rdn.cRDNAttr = 2;
811 rdn.rgRDNAttr = attrs;
812 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
813 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
814 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
815 if (buf)
817 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
818 "Got unexpected encoding for two RDN array\n");
819 LocalFree(buf);
821 /* A name can be "encoded" with previously encoded RDN attrs. */
822 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
823 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
824 attrs[0].Value.cbData = sizeof(twoRDNs);
825 rdn.cRDNAttr = 1;
826 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
827 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
828 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
829 if (buf)
831 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
832 ok(!memcmp(buf, encodedTwoRDNs, size),
833 "Unexpected value for re-endoded two RDN array\n");
834 LocalFree(buf);
836 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
837 rdn.cRDNAttr = 1;
838 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
839 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
840 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
841 ok(!ret && GetLastError() == E_INVALIDARG,
842 "Expected E_INVALIDARG, got %08x\n", GetLastError());
843 /* Test a more complex name */
844 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
845 rdn.rgRDNAttr = (PCERT_RDN_ATTR)rdnAttrs;
846 info.cRDN = 1;
847 info.rgRDN = &rdn;
848 buf = NULL;
849 size = 0;
850 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
851 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
852 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
853 if (ret)
855 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
856 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
857 LocalFree(buf);
861 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
862 static WCHAR surNameW[] = { 'L','a','n','g',0 };
864 static const BYTE twoRDNsNoNull[] = {
865 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
866 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
867 0x20,0x4c,0x61,0x6e,0x67 };
868 static const BYTE anyType[] = {
869 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
870 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
871 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
872 0x61,0x4c,0x67,0x6e };
874 static void test_encodeUnicodeName(DWORD dwEncoding)
876 CERT_RDN_ATTR attrs[2];
877 CERT_RDN rdn;
878 CERT_NAME_INFO info;
879 static CHAR oid_common_name[] = szOID_COMMON_NAME,
880 oid_sur_name[] = szOID_SUR_NAME;
881 BYTE *buf = NULL;
882 DWORD size = 0;
883 BOOL ret;
885 if (0)
887 /* Test with NULL pvStructInfo (crashes on win9x) */
888 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
889 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
890 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
891 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
893 /* Test with empty CERT_NAME_INFO */
894 info.cRDN = 0;
895 info.rgRDN = NULL;
896 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
897 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
898 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
899 if (buf)
901 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
902 "Got unexpected encoding for empty name\n");
903 LocalFree(buf);
905 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
906 * encoding (the NULL).
908 attrs[0].pszObjId = oid_common_name;
909 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
910 attrs[0].Value.cbData = sizeof(commonNameW);
911 attrs[0].Value.pbData = (BYTE *)commonNameW;
912 rdn.cRDNAttr = 1;
913 rdn.rgRDNAttr = attrs;
914 info.cRDN = 1;
915 info.rgRDN = &rdn;
916 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
917 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
918 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
919 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
920 ok(size == 9, "Unexpected error index %08x\n", size);
921 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
922 * forces the order of the encoded attributes to be swapped.
924 attrs[0].pszObjId = oid_common_name;
925 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
926 attrs[0].Value.cbData = 0;
927 attrs[0].Value.pbData = (BYTE *)commonNameW;
928 attrs[1].pszObjId = oid_sur_name;
929 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
930 attrs[1].Value.cbData = 0;
931 attrs[1].Value.pbData = (BYTE *)surNameW;
932 rdn.cRDNAttr = 2;
933 rdn.rgRDNAttr = attrs;
934 info.cRDN = 1;
935 info.rgRDN = &rdn;
936 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
937 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
938 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
939 if (buf)
941 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
942 "Got unexpected encoding for two RDN array\n");
943 LocalFree(buf);
945 /* A name can be "encoded" with previously encoded RDN attrs. */
946 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
947 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
948 attrs[0].Value.cbData = sizeof(twoRDNs);
949 rdn.cRDNAttr = 1;
950 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
951 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
952 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
953 if (buf)
955 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
956 ok(!memcmp(buf, encodedTwoRDNs, size),
957 "Unexpected value for re-endoded two RDN array\n");
958 LocalFree(buf);
960 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
961 rdn.cRDNAttr = 1;
962 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
963 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
964 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
965 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
966 if (buf)
968 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
969 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
970 LocalFree(buf);
974 static void compareNameValues(const CERT_NAME_VALUE *expected,
975 const CERT_NAME_VALUE *got)
977 ok(got->dwValueType == expected->dwValueType,
978 "Expected string type %d, got %d\n", expected->dwValueType,
979 got->dwValueType);
980 ok(got->Value.cbData == expected->Value.cbData,
981 "String type %d: unexpected data size, got %d, expected %d\n",
982 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
983 if (got->Value.cbData && got->Value.pbData)
984 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
985 min(got->Value.cbData, expected->Value.cbData)),
986 "String type %d: unexpected value\n", expected->dwValueType);
989 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
990 const CERT_RDN_ATTR *got)
992 if (expected->pszObjId && strlen(expected->pszObjId))
994 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
995 expected->pszObjId);
996 if (got->pszObjId)
998 ok(!strcmp(got->pszObjId, expected->pszObjId),
999 "Got unexpected OID %s, expected %s\n", got->pszObjId,
1000 expected->pszObjId);
1003 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
1004 (const CERT_NAME_VALUE *)&got->dwValueType);
1007 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
1009 ok(got->cRDNAttr == expected->cRDNAttr,
1010 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
1011 if (got->cRDNAttr)
1013 DWORD i;
1015 for (i = 0; i < got->cRDNAttr; i++)
1016 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1020 static void compareNames(const CERT_NAME_INFO *expected,
1021 const CERT_NAME_INFO *got)
1023 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
1024 expected->cRDN, got->cRDN);
1025 if (got->cRDN)
1027 DWORD i;
1029 for (i = 0; i < got->cRDN; i++)
1030 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1034 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1035 static const BYTE twoRDNsExtraBytes[] = {
1036 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1037 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1038 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1040 static void test_decodeName(DWORD dwEncoding)
1042 BYTE *buf = NULL;
1043 DWORD bufSize = 0;
1044 BOOL ret;
1045 CERT_RDN rdn;
1046 CERT_NAME_INFO info = { 1, &rdn };
1048 /* test empty name */
1049 bufSize = 0;
1050 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1051 emptySequence[1] + 2,
1052 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1053 (BYTE *)&buf, &bufSize);
1054 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1055 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1056 * decoder works the same way, so only test the count.
1058 if (buf)
1060 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1061 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1062 "Expected 0 RDNs in empty info, got %d\n",
1063 ((CERT_NAME_INFO *)buf)->cRDN);
1064 LocalFree(buf);
1066 /* test empty name with indefinite-length encoding */
1067 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1068 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1069 (BYTE *)&buf, &bufSize);
1070 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1071 if (ret)
1073 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1074 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1075 "Expected 0 RDNs in empty info, got %d\n",
1076 ((CERT_NAME_INFO *)buf)->cRDN);
1077 LocalFree(buf);
1079 /* test empty RDN */
1080 bufSize = 0;
1081 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1082 emptyRDNs[1] + 2,
1083 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1084 (BYTE *)&buf, &bufSize);
1085 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1086 if (buf)
1088 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1090 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1091 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1092 "Got unexpected value for empty RDN\n");
1093 LocalFree(buf);
1095 /* test two RDN attrs */
1096 bufSize = 0;
1097 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1098 twoRDNs[1] + 2,
1099 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1100 (BYTE *)&buf, &bufSize);
1101 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1102 if (buf)
1104 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1105 oid_common_name[] = szOID_COMMON_NAME;
1107 CERT_RDN_ATTR attrs[] = {
1108 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1109 (BYTE *)surName } },
1110 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1111 (BYTE *)commonName } },
1114 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1115 rdn.rgRDNAttr = attrs;
1116 compareNames(&info, (CERT_NAME_INFO *)buf);
1117 LocalFree(buf);
1119 /* test that two RDN attrs with extra bytes succeeds */
1120 bufSize = 0;
1121 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1122 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1123 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1124 /* And, a slightly more complicated name */
1125 buf = NULL;
1126 bufSize = 0;
1127 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1128 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1129 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1130 if (ret)
1132 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1133 rdn.rgRDNAttr = (PCERT_RDN_ATTR)decodedRdnAttrs;
1134 compareNames(&info, (CERT_NAME_INFO *)buf);
1135 LocalFree(buf);
1139 static void test_decodeUnicodeName(DWORD dwEncoding)
1141 BYTE *buf = NULL;
1142 DWORD bufSize = 0;
1143 BOOL ret;
1144 CERT_RDN rdn;
1145 CERT_NAME_INFO info = { 1, &rdn };
1147 /* test empty name */
1148 bufSize = 0;
1149 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1150 emptySequence[1] + 2,
1151 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1152 (BYTE *)&buf, &bufSize);
1153 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1154 if (buf)
1156 ok(bufSize == sizeof(CERT_NAME_INFO),
1157 "Got wrong bufSize %d\n", bufSize);
1158 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1159 "Expected 0 RDNs in empty info, got %d\n",
1160 ((CERT_NAME_INFO *)buf)->cRDN);
1161 LocalFree(buf);
1163 /* test empty RDN */
1164 bufSize = 0;
1165 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1166 emptyRDNs[1] + 2,
1167 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1168 (BYTE *)&buf, &bufSize);
1169 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1170 if (buf)
1172 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1174 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1175 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1176 "Got unexpected value for empty RDN\n");
1177 LocalFree(buf);
1179 /* test two RDN attrs */
1180 bufSize = 0;
1181 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1182 sizeof(twoRDNsNoNull),
1183 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1184 (BYTE *)&buf, &bufSize);
1185 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1186 if (buf)
1188 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1189 oid_common_name[] = szOID_COMMON_NAME;
1191 CERT_RDN_ATTR attrs[] = {
1192 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1193 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1194 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1195 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1198 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1199 rdn.rgRDNAttr = attrs;
1200 compareNames(&info, (CERT_NAME_INFO *)buf);
1201 LocalFree(buf);
1205 struct EncodedNameValue
1207 CERT_NAME_VALUE value;
1208 const BYTE *encoded;
1209 DWORD encodedSize;
1212 static const char bogusIA5[] = "\x80";
1213 static const char bogusPrintable[] = "~";
1214 static const char bogusNumeric[] = "A";
1215 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1216 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1217 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1218 static BYTE octetCommonNameValue[] = {
1219 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1220 static BYTE numericCommonNameValue[] = {
1221 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1222 static BYTE printableCommonNameValue[] = {
1223 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1224 static BYTE t61CommonNameValue[] = {
1225 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1226 static BYTE videotexCommonNameValue[] = {
1227 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1228 static BYTE ia5CommonNameValue[] = {
1229 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1230 static BYTE graphicCommonNameValue[] = {
1231 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1232 static BYTE visibleCommonNameValue[] = {
1233 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1234 static BYTE generalCommonNameValue[] = {
1235 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1236 static BYTE bmpCommonNameValue[] = {
1237 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1238 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1239 static BYTE utf8CommonNameValue[] = {
1240 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1242 static struct EncodedNameValue nameValues[] = {
1243 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1244 octetCommonNameValue, sizeof(octetCommonNameValue) },
1245 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1246 numericCommonNameValue, sizeof(numericCommonNameValue) },
1247 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1248 printableCommonNameValue, sizeof(printableCommonNameValue) },
1249 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1250 t61CommonNameValue, sizeof(t61CommonNameValue) },
1251 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1252 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1253 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1254 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1255 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1256 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1257 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1258 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1259 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1260 generalCommonNameValue, sizeof(generalCommonNameValue) },
1261 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1262 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1263 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1264 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1265 /* The following tests succeed under Windows, but really should fail,
1266 * they contain characters that are illegal for the encoding. I'm
1267 * including them to justify my lazy encoding.
1269 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1270 sizeof(bin42) },
1271 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1272 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1273 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1274 bin44, sizeof(bin44) },
1277 static void test_encodeNameValue(DWORD dwEncoding)
1279 BYTE *buf = NULL;
1280 DWORD size = 0, i;
1281 BOOL ret;
1282 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1284 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1285 value.Value.pbData = printableCommonNameValue;
1286 value.Value.cbData = sizeof(printableCommonNameValue);
1287 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1288 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1289 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1290 if (buf)
1292 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1293 size);
1294 ok(!memcmp(buf, printableCommonNameValue, size),
1295 "Unexpected encoding\n");
1296 LocalFree(buf);
1298 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1300 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1301 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1302 &size);
1303 ok(ret, "Type %d: CryptEncodeObjectEx failed: %08x\n",
1304 nameValues[i].value.dwValueType, GetLastError());
1305 if (buf)
1307 ok(size == nameValues[i].encodedSize,
1308 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1309 ok(!memcmp(buf, nameValues[i].encoded, size),
1310 "Got unexpected encoding\n");
1311 LocalFree(buf);
1316 static void test_decodeNameValue(DWORD dwEncoding)
1318 int i;
1319 BYTE *buf = NULL;
1320 DWORD bufSize = 0;
1321 BOOL ret;
1323 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1325 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1326 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1327 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1328 (BYTE *)&buf, &bufSize);
1329 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1330 nameValues[i].value.dwValueType, GetLastError());
1331 if (buf)
1333 compareNameValues(&nameValues[i].value,
1334 (const CERT_NAME_VALUE *)buf);
1335 LocalFree(buf);
1340 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1341 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1342 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1343 'h','q','.','o','r','g',0 };
1344 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1345 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1346 0x6f, 0x72, 0x67 };
1347 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1348 0x575b, 0 };
1349 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1350 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1351 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1352 static const BYTE localhost[] = { 127, 0, 0, 1 };
1353 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1354 0x01 };
1355 static const unsigned char encodedCommonName[] = {
1356 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1357 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1358 static const BYTE encodedDirectoryName[] = {
1359 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1360 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1362 static void test_encodeAltName(DWORD dwEncoding)
1364 CERT_ALT_NAME_INFO info = { 0 };
1365 CERT_ALT_NAME_ENTRY entry = { 0 };
1366 BYTE *buf = NULL;
1367 DWORD size = 0;
1368 BOOL ret;
1369 char oid[] = "1.2.3";
1371 /* Test with empty info */
1372 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1373 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1374 if (buf)
1376 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1377 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1378 LocalFree(buf);
1380 /* Test with an empty entry */
1381 info.cAltEntry = 1;
1382 info.rgAltEntry = &entry;
1383 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1384 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1385 ok(!ret && GetLastError() == E_INVALIDARG,
1386 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1387 /* Test with an empty pointer */
1388 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1389 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1390 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1391 if (buf)
1393 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1394 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1395 LocalFree(buf);
1397 /* Test with a real URL */
1398 U(entry).pwszURL = (LPWSTR)url;
1399 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1400 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1401 if (buf)
1403 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1404 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1405 LocalFree(buf);
1407 /* Now with the URL containing an invalid IA5 char */
1408 U(entry).pwszURL = (LPWSTR)nihongoURL;
1409 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1410 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1411 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1412 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1413 /* The first invalid character is at index 7 */
1414 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1415 "Expected invalid char at index 7, got %d\n",
1416 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1417 /* Now with the URL missing a scheme */
1418 U(entry).pwszURL = (LPWSTR)dnsName;
1419 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1420 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1421 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1422 if (buf)
1424 /* This succeeds, but it shouldn't, so don't worry about conforming */
1425 LocalFree(buf);
1427 /* Now with a DNS name */
1428 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1429 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1430 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1431 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1432 if (buf)
1434 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1435 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1436 LocalFree(buf);
1438 /* Test with an IP address */
1439 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1440 U(entry).IPAddress.cbData = sizeof(localhost);
1441 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1442 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1443 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1444 if (buf)
1446 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1447 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1448 LocalFree(buf);
1450 /* Test with OID */
1451 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1452 U(entry).pszRegisteredID = oid;
1453 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1454 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1455 if (buf)
1457 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1458 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1459 LocalFree(buf);
1461 /* Test with directory name */
1462 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1463 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1464 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1465 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1466 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1467 if (buf)
1469 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1470 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1471 LocalFree(buf);
1475 static void test_decodeAltName(DWORD dwEncoding)
1477 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1478 0x00, 0x00, 0x01 };
1479 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1480 0x01 };
1481 BOOL ret;
1482 BYTE *buf = NULL;
1483 DWORD bufSize = 0;
1484 CERT_ALT_NAME_INFO *info;
1486 /* Test some bogus ones first */
1487 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1488 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1489 NULL, (BYTE *)&buf, &bufSize);
1490 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1491 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
1492 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1493 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1494 &bufSize);
1495 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
1496 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
1497 /* Now expected cases */
1498 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1499 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1500 &bufSize);
1501 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1502 if (buf)
1504 info = (CERT_ALT_NAME_INFO *)buf;
1506 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1507 info->cAltEntry);
1508 LocalFree(buf);
1510 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1511 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1512 &bufSize);
1513 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1514 if (buf)
1516 info = (CERT_ALT_NAME_INFO *)buf;
1518 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1519 info->cAltEntry);
1520 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1521 "Expected CERT_ALT_NAME_URL, got %d\n",
1522 info->rgAltEntry[0].dwAltNameChoice);
1523 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1524 "Expected empty URL\n");
1525 LocalFree(buf);
1527 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1528 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1529 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1530 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1531 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1532 &bufSize);
1533 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1534 if (buf)
1536 info = (CERT_ALT_NAME_INFO *)buf;
1538 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1539 info->cAltEntry);
1540 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1541 "Expected CERT_ALT_NAME_URL, got %d\n",
1542 info->rgAltEntry[0].dwAltNameChoice);
1543 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1544 LocalFree(buf);
1546 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1547 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1548 &bufSize);
1549 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1550 if (buf)
1552 info = (CERT_ALT_NAME_INFO *)buf;
1554 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1555 info->cAltEntry);
1556 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1557 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1558 info->rgAltEntry[0].dwAltNameChoice);
1559 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1560 "Unexpected DNS name\n");
1561 LocalFree(buf);
1563 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1564 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1565 &bufSize);
1566 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1567 if (buf)
1569 info = (CERT_ALT_NAME_INFO *)buf;
1571 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1572 info->cAltEntry);
1573 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1574 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1575 info->rgAltEntry[0].dwAltNameChoice);
1576 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1577 "Unexpected IP address length %d\n",
1578 U(info->rgAltEntry[0]).IPAddress.cbData);
1579 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1580 sizeof(localhost)), "Unexpected IP address value\n");
1581 LocalFree(buf);
1583 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1584 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1585 &bufSize);
1586 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1587 if (buf)
1589 info = (CERT_ALT_NAME_INFO *)buf;
1591 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1592 info->cAltEntry);
1593 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1594 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1595 info->rgAltEntry[0].dwAltNameChoice);
1596 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1597 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1598 LocalFree(buf);
1600 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1601 encodedDirectoryName, sizeof(encodedDirectoryName),
1602 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1603 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1604 if (buf)
1606 info = (CERT_ALT_NAME_INFO *)buf;
1608 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1609 info->cAltEntry);
1610 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1611 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1612 info->rgAltEntry[0].dwAltNameChoice);
1613 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1614 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1615 U(info->rgAltEntry[0]).DirectoryName.cbData);
1616 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1617 encodedCommonName, sizeof(encodedCommonName)),
1618 "Unexpected directory name value\n");
1619 LocalFree(buf);
1623 struct UnicodeExpectedError
1625 DWORD valueType;
1626 LPCWSTR str;
1627 DWORD errorIndex;
1628 DWORD error;
1631 static const WCHAR oneW[] = { '1',0 };
1632 static const WCHAR aW[] = { 'a',0 };
1633 static const WCHAR quoteW[] = { '"', 0 };
1635 static struct UnicodeExpectedError unicodeErrors[] = {
1636 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1637 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1638 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1639 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1640 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1641 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1644 struct UnicodeExpectedResult
1646 DWORD valueType;
1647 LPCWSTR str;
1648 CRYPT_DATA_BLOB encoded;
1651 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1652 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1653 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1654 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1655 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1656 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1657 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1658 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1659 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1660 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1661 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1662 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1663 0x5b };
1664 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1665 0x6f,0x5b };
1666 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1667 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1668 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1669 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1671 static struct UnicodeExpectedResult unicodeResults[] = {
1672 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1673 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1674 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1675 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1676 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1677 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1678 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1679 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1680 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1681 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1682 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1683 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1684 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1687 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1688 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1689 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1692 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1694 BYTE *buf = NULL;
1695 DWORD size = 0, i;
1696 BOOL ret;
1697 CERT_NAME_VALUE value;
1699 if (0)
1701 /* Crashes on win9x */
1702 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1703 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1704 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1705 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1707 /* Have to have a string of some sort */
1708 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1709 value.Value.pbData = NULL;
1710 value.Value.cbData = 0;
1711 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1712 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1713 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1714 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1715 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1716 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1717 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1718 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1719 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1720 value.dwValueType = CERT_RDN_ANY_TYPE;
1721 value.Value.pbData = (LPBYTE)oneW;
1722 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1723 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1724 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1725 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1726 value.Value.cbData = sizeof(oneW);
1727 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1728 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1729 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1730 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1731 /* An encoded string with specified length isn't good enough either */
1732 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1733 value.Value.pbData = oneUniversal;
1734 value.Value.cbData = sizeof(oneUniversal);
1735 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1736 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1737 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1738 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1739 /* More failure checking */
1740 value.Value.cbData = 0;
1741 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1743 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1744 value.dwValueType = unicodeErrors[i].valueType;
1745 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1746 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1747 ok(!ret && GetLastError() == unicodeErrors[i].error,
1748 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1749 unicodeErrors[i].error, GetLastError());
1750 ok(size == unicodeErrors[i].errorIndex,
1751 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1752 size);
1754 /* cbData can be zero if the string is NULL-terminated */
1755 value.Value.cbData = 0;
1756 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1758 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1759 value.dwValueType = unicodeResults[i].valueType;
1760 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1761 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1762 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1763 if (buf)
1765 ok(size == unicodeResults[i].encoded.cbData,
1766 "Value type %d: expected size %d, got %d\n",
1767 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1768 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1769 "Value type %d: unexpected value\n", value.dwValueType);
1770 LocalFree(buf);
1773 /* These "encode," but they do so by truncating each unicode character
1774 * rather than properly encoding it. Kept separate from the proper results,
1775 * because the encoded forms won't decode to their original strings.
1777 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1779 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1780 value.dwValueType = unicodeWeirdness[i].valueType;
1781 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1782 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1783 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1784 if (buf)
1786 ok(size == unicodeWeirdness[i].encoded.cbData,
1787 "Value type %d: expected size %d, got %d\n",
1788 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1789 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1790 "Value type %d: unexpected value\n", value.dwValueType);
1791 LocalFree(buf);
1796 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1798 if (n <= 0) return 0;
1799 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1800 return *str1 - *str2;
1803 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1805 DWORD i;
1807 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1809 BYTE *buf = NULL;
1810 BOOL ret;
1811 DWORD size = 0;
1813 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1814 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1815 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1816 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1817 if (ret && buf)
1819 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1821 ok(value->dwValueType == unicodeResults[i].valueType,
1822 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1823 value->dwValueType);
1824 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1825 value->Value.cbData / sizeof(WCHAR)),
1826 "Unexpected decoded value for index %d (value type %d)\n", i,
1827 unicodeResults[i].valueType);
1828 LocalFree(buf);
1833 struct encodedOctets
1835 const BYTE *val;
1836 const BYTE *encoded;
1839 static const unsigned char bin46[] = { 'h','i',0 };
1840 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1841 static const unsigned char bin48[] = {
1842 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1843 static const unsigned char bin49[] = {
1844 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1845 static const unsigned char bin50[] = { 0 };
1846 static const unsigned char bin51[] = { 0x04,0x00,0 };
1848 static const struct encodedOctets octets[] = {
1849 { bin46, bin47 },
1850 { bin48, bin49 },
1851 { bin50, bin51 },
1854 static void test_encodeOctets(DWORD dwEncoding)
1856 CRYPT_DATA_BLOB blob;
1857 DWORD i;
1859 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1861 BYTE *buf = NULL;
1862 BOOL ret;
1863 DWORD bufSize = 0;
1865 blob.cbData = strlen((const char*)octets[i].val);
1866 blob.pbData = (BYTE*)octets[i].val;
1867 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1868 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1869 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1870 if (buf)
1872 ok(buf[0] == 4,
1873 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1874 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1875 buf[1], octets[i].encoded[1]);
1876 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1877 octets[i].encoded[1] + 1), "Got unexpected value\n");
1878 LocalFree(buf);
1883 static void test_decodeOctets(DWORD dwEncoding)
1885 DWORD i;
1887 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1889 BYTE *buf = NULL;
1890 BOOL ret;
1891 DWORD bufSize = 0;
1893 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1894 (BYTE *)octets[i].encoded, octets[i].encoded[1] + 2,
1895 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1896 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1897 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1898 "Expected size >= %d, got %d\n",
1899 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1900 ok(buf != NULL, "Expected allocated buffer\n");
1901 if (buf)
1903 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
1905 if (blob->cbData)
1906 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
1907 "Unexpected value\n");
1908 LocalFree(buf);
1913 static const BYTE bytesToEncode[] = { 0xff, 0xff };
1915 struct encodedBits
1917 DWORD cUnusedBits;
1918 const BYTE *encoded;
1919 DWORD cbDecoded;
1920 const BYTE *decoded;
1923 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
1924 static const unsigned char bin53[] = { 0xff,0xff };
1925 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
1926 static const unsigned char bin55[] = { 0xff,0xfe };
1927 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
1928 static const unsigned char bin57[] = { 0xfe };
1929 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
1931 static const struct encodedBits bits[] = {
1932 /* normal test cases */
1933 { 0, bin52, 2, bin53 },
1934 { 1, bin54, 2, bin55 },
1935 /* strange test case, showing cUnusedBits >= 8 is allowed */
1936 { 9, bin56, 1, bin57 },
1937 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1938 { 17, bin58, 0, NULL },
1941 static void test_encodeBits(DWORD dwEncoding)
1943 DWORD i;
1945 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1947 CRYPT_BIT_BLOB blob;
1948 BOOL ret;
1949 BYTE *buf = NULL;
1950 DWORD bufSize = 0;
1952 blob.cbData = sizeof(bytesToEncode);
1953 blob.pbData = (BYTE *)bytesToEncode;
1954 blob.cUnusedBits = bits[i].cUnusedBits;
1955 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
1956 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1957 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1958 if (buf)
1960 ok(bufSize == bits[i].encoded[1] + 2,
1961 "Got unexpected size %d, expected %d\n", bufSize,
1962 bits[i].encoded[1] + 2);
1963 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
1964 "Unexpected value\n");
1965 LocalFree(buf);
1970 static void test_decodeBits(DWORD dwEncoding)
1972 static const BYTE ber[] = "\x03\x02\x01\xff";
1973 static const BYTE berDecoded = 0xfe;
1974 DWORD i;
1975 BOOL ret;
1976 BYTE *buf = NULL;
1977 DWORD bufSize = 0;
1979 /* normal cases */
1980 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1982 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
1983 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1984 &bufSize);
1985 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1986 if (buf)
1988 CRYPT_BIT_BLOB *blob;
1990 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
1991 "Got unexpected size %d\n", bufSize);
1992 blob = (CRYPT_BIT_BLOB *)buf;
1993 ok(blob->cbData == bits[i].cbDecoded,
1994 "Got unexpected length %d, expected %d\n", blob->cbData,
1995 bits[i].cbDecoded);
1996 if (blob->cbData && bits[i].cbDecoded)
1997 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
1998 "Unexpected value\n");
1999 LocalFree(buf);
2002 /* special case: check that something that's valid in BER but not in DER
2003 * decodes successfully
2005 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2006 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2007 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2008 if (buf)
2010 CRYPT_BIT_BLOB *blob;
2012 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2013 "Got unexpected size %d\n", bufSize);
2014 blob = (CRYPT_BIT_BLOB *)buf;
2015 ok(blob->cbData == sizeof(berDecoded),
2016 "Got unexpected length %d\n", blob->cbData);
2017 if (blob->cbData)
2018 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2019 LocalFree(buf);
2023 struct Constraints2
2025 CERT_BASIC_CONSTRAINTS2_INFO info;
2026 const BYTE *encoded;
2029 static const unsigned char bin59[] = { 0x30,0x00 };
2030 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2031 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2032 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2033 static const struct Constraints2 constraints2[] = {
2034 /* empty constraints */
2035 { { FALSE, FALSE, 0}, bin59 },
2036 /* can be a CA */
2037 { { TRUE, FALSE, 0}, bin60 },
2038 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2039 * but that's not the case
2041 { { FALSE, TRUE, 0}, bin61 },
2042 /* can be a CA and has path length constraints set */
2043 { { TRUE, TRUE, 1}, bin62 },
2046 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2047 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2048 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2049 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2050 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2051 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2052 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2053 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2054 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2055 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2057 static void test_encodeBasicConstraints(DWORD dwEncoding)
2059 DWORD i, bufSize = 0;
2060 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2061 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2062 (LPBYTE)encodedDomainName };
2063 BOOL ret;
2064 BYTE *buf = NULL;
2066 /* First test with the simpler info2 */
2067 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2069 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2070 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2071 &bufSize);
2072 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2073 if (buf)
2075 ok(bufSize == constraints2[i].encoded[1] + 2,
2076 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2077 bufSize);
2078 ok(!memcmp(buf, constraints2[i].encoded,
2079 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2080 LocalFree(buf);
2083 /* Now test with more complex basic constraints */
2084 info.SubjectType.cbData = 0;
2085 info.fPathLenConstraint = FALSE;
2086 info.cSubtreesConstraint = 0;
2087 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2088 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2089 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2090 if (buf)
2092 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2093 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2094 "Unexpected value\n");
2095 LocalFree(buf);
2097 /* None of the certs I examined had any subtree constraint, but I test one
2098 * anyway just in case.
2100 info.cSubtreesConstraint = 1;
2101 info.rgSubtreesConstraint = &nameBlob;
2102 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2103 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2104 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2105 if (buf)
2107 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2108 ok(!memcmp(buf, constraintWithDomainName,
2109 sizeof(constraintWithDomainName)), "Unexpected value\n");
2110 LocalFree(buf);
2112 /* FIXME: test encoding with subject type. */
2115 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2117 static void test_decodeBasicConstraints(DWORD dwEncoding)
2119 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2120 0xff };
2121 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2122 DWORD i;
2123 BOOL ret;
2124 BYTE *buf = NULL;
2125 DWORD bufSize = 0;
2127 /* First test with simpler info2 */
2128 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2130 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2131 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2132 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2133 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2134 GetLastError());
2135 if (buf)
2137 CERT_BASIC_CONSTRAINTS2_INFO *info =
2138 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2140 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2141 "Unexpected value for item %d\n", i);
2142 LocalFree(buf);
2145 /* Check with the order of encoded elements inverted */
2146 buf = (PBYTE)1;
2147 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2148 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2149 &bufSize);
2150 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2151 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2152 ok(!buf, "Expected buf to be set to NULL\n");
2153 /* Check with a non-DER bool */
2154 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2155 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2156 (BYTE *)&buf, &bufSize);
2157 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2158 if (buf)
2160 CERT_BASIC_CONSTRAINTS2_INFO *info =
2161 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2163 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2164 LocalFree(buf);
2166 /* Check with a non-basic constraints value */
2167 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2168 (LPBYTE)encodedCommonName, encodedCommonName[1] + 2,
2169 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2170 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2171 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2172 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2173 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2174 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2175 (BYTE *)&buf, &bufSize);
2176 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2177 if (buf)
2179 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2181 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2182 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2183 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2184 LocalFree(buf);
2186 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2187 constraintWithDomainName, sizeof(constraintWithDomainName),
2188 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2189 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2190 if (buf)
2192 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2194 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2195 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2196 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2197 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2199 ok(info->rgSubtreesConstraint[0].cbData ==
2200 sizeof(encodedDomainName), "Wrong size %d\n",
2201 info->rgSubtreesConstraint[0].cbData);
2202 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2203 sizeof(encodedDomainName)), "Unexpected value\n");
2205 LocalFree(buf);
2209 /* These are terrible public keys of course, I'm just testing encoding */
2210 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2211 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2212 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2213 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2214 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2215 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2216 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2217 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2219 struct EncodedRSAPubKey
2221 const BYTE *modulus;
2222 size_t modulusLen;
2223 const BYTE *encoded;
2224 size_t decodedModulusLen;
2227 struct EncodedRSAPubKey rsaPubKeys[] = {
2228 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2229 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2230 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2231 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2234 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2236 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2237 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2238 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2239 BOOL ret;
2240 BYTE *buf = NULL;
2241 DWORD bufSize = 0, i;
2243 /* Try with a bogus blob type */
2244 hdr->bType = 2;
2245 hdr->bVersion = CUR_BLOB_VERSION;
2246 hdr->reserved = 0;
2247 hdr->aiKeyAlg = CALG_RSA_KEYX;
2248 rsaPubKey->magic = 0x31415352;
2249 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2250 rsaPubKey->pubexp = 65537;
2251 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2252 sizeof(modulus1));
2254 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2255 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2256 &bufSize);
2257 ok(!ret && GetLastError() == E_INVALIDARG,
2258 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2259 /* Now with a bogus reserved field */
2260 hdr->bType = PUBLICKEYBLOB;
2261 hdr->reserved = 1;
2262 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2263 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2264 &bufSize);
2265 if (buf)
2267 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2268 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2269 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2270 LocalFree(buf);
2272 /* Now with a bogus blob version */
2273 hdr->reserved = 0;
2274 hdr->bVersion = 0;
2275 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2276 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2277 &bufSize);
2278 if (buf)
2280 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2281 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2282 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2283 LocalFree(buf);
2285 /* And with a bogus alg ID */
2286 hdr->bVersion = CUR_BLOB_VERSION;
2287 hdr->aiKeyAlg = CALG_DES;
2288 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2289 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2290 &bufSize);
2291 if (buf)
2293 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2294 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2295 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2296 LocalFree(buf);
2298 /* Check a couple of RSA-related OIDs */
2299 hdr->aiKeyAlg = CALG_RSA_KEYX;
2300 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2301 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2302 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2303 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2304 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2305 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2306 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2307 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2308 /* Finally, all valid */
2309 hdr->aiKeyAlg = CALG_RSA_KEYX;
2310 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2312 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2313 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2314 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2315 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2316 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2317 if (buf)
2319 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2320 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2321 bufSize);
2322 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2323 "Unexpected value\n");
2324 LocalFree(buf);
2329 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2331 DWORD i;
2332 LPBYTE buf = NULL;
2333 DWORD bufSize = 0;
2334 BOOL ret;
2336 /* Try with a bad length */
2337 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2338 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2339 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2340 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2341 "Expected CRYPT_E_ASN1_EOD, got %08x\n", CRYPT_E_ASN1_EOD);
2342 /* Try with a couple of RSA-related OIDs */
2343 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2344 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2345 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2346 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2347 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2348 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2349 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2350 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2351 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2352 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2353 /* Now try success cases */
2354 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2356 bufSize = 0;
2357 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2358 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2359 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2360 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2361 if (buf)
2363 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2364 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2366 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2367 rsaPubKeys[i].decodedModulusLen,
2368 "Wrong size %d\n", bufSize);
2369 ok(hdr->bType == PUBLICKEYBLOB,
2370 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2371 hdr->bType);
2372 ok(hdr->bVersion == CUR_BLOB_VERSION,
2373 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2374 CUR_BLOB_VERSION, hdr->bVersion);
2375 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2376 hdr->reserved);
2377 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2378 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2379 ok(rsaPubKey->magic == 0x31415352,
2380 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2381 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2382 "Wrong bit len %d\n", rsaPubKey->bitlen);
2383 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2384 rsaPubKey->pubexp);
2385 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2386 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2387 "Unexpected modulus\n");
2388 LocalFree(buf);
2393 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2394 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2395 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2397 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2398 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2399 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2400 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2402 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2404 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2405 CRYPT_SEQUENCE_OF_ANY seq;
2406 DWORD i;
2407 BOOL ret;
2408 BYTE *buf = NULL;
2409 DWORD bufSize = 0;
2411 /* Encode a homogeneous sequence */
2412 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2414 blobs[i].cbData = ints[i].encoded[1] + 2;
2415 blobs[i].pbData = (BYTE *)ints[i].encoded;
2417 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2418 seq.rgValue = blobs;
2420 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2421 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2422 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2423 if (buf)
2425 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2426 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2427 LocalFree(buf);
2429 /* Change the type of the first element in the sequence, and give it
2430 * another go
2432 blobs[0].cbData = times[0].encodedTime[1] + 2;
2433 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2434 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2435 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2436 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2437 if (buf)
2439 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2440 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2441 "Unexpected value\n");
2442 LocalFree(buf);
2446 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2448 BOOL ret;
2449 BYTE *buf = NULL;
2450 DWORD bufSize = 0;
2452 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2453 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2454 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2455 if (buf)
2457 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2458 DWORD i;
2460 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2461 "Wrong elements %d\n", seq->cValue);
2462 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2464 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2465 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2466 seq->rgValue[i].cbData);
2467 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2468 ints[i].encoded[1] + 2), "Unexpected value\n");
2470 LocalFree(buf);
2472 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2473 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2474 &bufSize);
2475 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2476 if (buf)
2478 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2480 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2481 "Wrong elements %d\n", seq->cValue);
2482 /* Just check the first element since it's all that changed */
2483 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2484 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2485 seq->rgValue[0].cbData);
2486 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2487 times[0].encodedTime[1] + 2), "Unexpected value\n");
2488 LocalFree(buf);
2492 struct encodedExtensions
2494 CERT_EXTENSIONS exts;
2495 const BYTE *encoded;
2498 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2499 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2500 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2501 static CERT_EXTENSION criticalExt =
2502 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2503 static CERT_EXTENSION nonCriticalExt =
2504 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2506 static const BYTE ext0[] = { 0x30,0x00 };
2507 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2508 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2509 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2510 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2512 static const struct encodedExtensions exts[] = {
2513 { { 0, NULL }, ext0 },
2514 { { 1, &criticalExt }, ext1 },
2515 { { 1, &nonCriticalExt }, ext2 },
2518 static void test_encodeExtensions(DWORD dwEncoding)
2520 DWORD i;
2522 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2524 BOOL ret;
2525 BYTE *buf = NULL;
2526 DWORD bufSize = 0;
2528 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2529 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2530 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2531 if (buf)
2533 ok(bufSize == exts[i].encoded[1] + 2,
2534 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2535 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2536 "Unexpected value\n");
2537 LocalFree(buf);
2542 static void test_decodeExtensions(DWORD dwEncoding)
2544 DWORD i;
2546 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2548 BOOL ret;
2549 BYTE *buf = NULL;
2550 DWORD bufSize = 0;
2552 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2553 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2554 NULL, (BYTE *)&buf, &bufSize);
2555 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2556 if (buf)
2558 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2559 DWORD j;
2561 ok(ext->cExtension == exts[i].exts.cExtension,
2562 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2563 ext->cExtension);
2564 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2566 ok(!strcmp(ext->rgExtension[j].pszObjId,
2567 exts[i].exts.rgExtension[j].pszObjId),
2568 "Expected OID %s, got %s\n",
2569 exts[i].exts.rgExtension[j].pszObjId,
2570 ext->rgExtension[j].pszObjId);
2571 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2572 exts[i].exts.rgExtension[j].Value.pbData,
2573 exts[i].exts.rgExtension[j].Value.cbData),
2574 "Unexpected value\n");
2576 LocalFree(buf);
2581 /* MS encodes public key info with a NULL if the algorithm identifier's
2582 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2583 * it encodes them by omitting the algorithm parameters. This latter approach
2584 * seems more correct, so accept either form.
2586 struct encodedPublicKey
2588 CERT_PUBLIC_KEY_INFO info;
2589 const BYTE *encoded;
2590 const BYTE *encodedNoNull;
2591 CERT_PUBLIC_KEY_INFO decoded;
2594 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2595 0xe, 0xf };
2596 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2598 static const unsigned char bin64[] = {
2599 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2600 static const unsigned char bin65[] = {
2601 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2602 static const unsigned char bin66[] = {
2603 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2604 static const unsigned char bin67[] = {
2605 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2606 static const unsigned char bin68[] = {
2607 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2608 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2609 static const unsigned char bin69[] = {
2610 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2611 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2612 static const unsigned char bin70[] = {
2613 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2614 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2615 0x0f};
2616 static const unsigned char bin71[] = {
2617 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2618 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2619 0x0f};
2620 static unsigned char bin72[] = { 0x05,0x00};
2622 static CHAR oid_bogus[] = "1.2.3",
2623 oid_rsa[] = szOID_RSA;
2625 static const struct encodedPublicKey pubKeys[] = {
2626 /* with a bogus OID */
2627 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2628 bin64, bin65,
2629 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2630 /* some normal keys */
2631 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2632 bin66, bin67,
2633 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2634 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2635 bin68, bin69,
2636 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2637 /* with add'l parameters--note they must be DER-encoded */
2638 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2639 (BYTE *)aKey, 0 } },
2640 bin70, bin71,
2641 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2642 (BYTE *)aKey, 0 } } },
2645 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2647 DWORD i;
2649 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2651 BOOL ret;
2652 BYTE *buf = NULL;
2653 DWORD bufSize = 0;
2655 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2656 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2657 &bufSize);
2658 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2659 if (buf)
2661 ok(bufSize == pubKeys[i].encoded[1] + 2 ||
2662 bufSize == pubKeys[i].encodedNoNull[1] + 2,
2663 "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
2664 pubKeys[i].encodedNoNull[1] + 2, bufSize);
2665 if (bufSize == pubKeys[i].encoded[1] + 2)
2666 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2667 "Unexpected value\n");
2668 else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
2669 ok(!memcmp(buf, pubKeys[i].encodedNoNull,
2670 pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
2671 LocalFree(buf);
2676 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2677 const CERT_PUBLIC_KEY_INFO *got)
2679 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2680 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2681 got->Algorithm.pszObjId);
2682 ok(expected->Algorithm.Parameters.cbData ==
2683 got->Algorithm.Parameters.cbData,
2684 "Expected parameters of %d bytes, got %d\n",
2685 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2686 if (expected->Algorithm.Parameters.cbData)
2687 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2688 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2689 "Unexpected algorithm parameters\n");
2690 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2691 "Expected public key of %d bytes, got %d\n",
2692 expected->PublicKey.cbData, got->PublicKey.cbData);
2693 if (expected->PublicKey.cbData)
2694 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2695 got->PublicKey.cbData), "Unexpected public key value\n");
2698 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2700 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2701 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2702 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2703 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2704 DWORD i;
2705 BOOL ret;
2706 BYTE *buf = NULL;
2707 DWORD bufSize = 0;
2709 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2711 /* The NULL form decodes to the decoded member */
2712 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2713 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2714 NULL, (BYTE *)&buf, &bufSize);
2715 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2716 if (buf)
2718 comparePublicKeyInfo(&pubKeys[i].decoded,
2719 (CERT_PUBLIC_KEY_INFO *)buf);
2720 LocalFree(buf);
2722 /* The non-NULL form decodes to the original */
2723 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2724 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2725 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2726 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2727 if (buf)
2729 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2730 LocalFree(buf);
2733 /* Test with bogus (not valid DER) parameters */
2734 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2735 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2736 NULL, (BYTE *)&buf, &bufSize);
2737 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2738 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2741 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2742 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2743 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2744 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2745 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2746 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2747 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2748 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2749 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2750 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2751 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2752 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2753 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2754 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2755 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2756 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2757 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2758 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2759 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2760 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2761 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2762 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2763 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2764 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2765 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2766 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2767 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2768 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2769 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2770 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2771 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2772 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2773 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2774 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2775 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2776 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2777 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2778 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2779 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2780 static const BYTE v1CertWithPubKey[] = {
2781 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2782 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2783 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2784 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2785 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2786 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2787 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2788 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2789 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2790 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2791 0x01,0x01 };
2792 static const BYTE v1CertWithPubKeyNoNull[] = {
2793 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2794 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2795 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2796 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2797 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2798 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2799 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2800 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2801 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2802 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2803 static const BYTE v1CertWithSubjectKeyId[] = {
2804 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2805 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2806 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2807 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2808 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2809 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2810 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2811 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2812 0x4c,0x61,0x6e,0x67,0x00 };
2814 static const BYTE serialNum[] = { 0x01 };
2816 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2818 BOOL ret;
2819 BYTE *buf = NULL;
2820 DWORD size = 0;
2821 CERT_INFO info = { 0 };
2822 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2823 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2824 CERT_EXTENSION ext;
2826 if (0)
2828 /* Test with NULL pvStructInfo (crashes on win9x) */
2829 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2830 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2831 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2832 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2834 /* Test with a V1 cert */
2835 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2836 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2837 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2838 if (buf)
2840 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2841 v1Cert[1] + 2, size);
2842 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2843 LocalFree(buf);
2845 /* Test v2 cert */
2846 info.dwVersion = CERT_V2;
2847 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2848 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2849 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2850 if (buf)
2852 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2853 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2854 LocalFree(buf);
2856 /* Test v3 cert */
2857 info.dwVersion = CERT_V3;
2858 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2859 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2860 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2861 if (buf)
2863 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2864 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2865 LocalFree(buf);
2867 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2868 * API doesn't prevent it)
2870 info.dwVersion = CERT_V1;
2871 info.cExtension = 1;
2872 info.rgExtension = &criticalExt;
2873 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2874 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2875 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2876 if (buf)
2878 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2879 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2880 LocalFree(buf);
2882 /* test v1 cert with a serial number */
2883 info.SerialNumber.cbData = sizeof(serialNum);
2884 info.SerialNumber.pbData = (BYTE *)serialNum;
2885 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2886 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2887 if (buf)
2889 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2890 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2891 LocalFree(buf);
2893 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2894 info.Issuer.cbData = sizeof(encodedCommonName);
2895 info.Issuer.pbData = (BYTE *)encodedCommonName;
2896 info.Subject.cbData = sizeof(encodedCommonName);
2897 info.Subject.pbData = (BYTE *)encodedCommonName;
2898 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2899 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2900 if (buf)
2902 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
2903 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
2904 LocalFree(buf);
2906 /* Add a public key */
2907 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2908 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2909 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
2910 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2911 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2912 if (buf)
2914 ok(size == sizeof(v1CertWithPubKey) ||
2915 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
2916 if (size == sizeof(v1CertWithPubKey))
2917 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
2918 else if (size == sizeof(v1CertWithPubKeyNoNull))
2919 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
2920 "Got unexpected value\n");
2921 LocalFree(buf);
2923 /* Remove the public key, and add a subject key identifier extension */
2924 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2925 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
2926 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
2927 ext.pszObjId = oid_subject_key_identifier;
2928 ext.fCritical = FALSE;
2929 ext.Value.cbData = sizeof(octetCommonNameValue);
2930 ext.Value.pbData = (BYTE *)octetCommonNameValue;
2931 info.cExtension = 1;
2932 info.rgExtension = &ext;
2933 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2934 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2935 if (buf)
2937 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
2938 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
2939 LocalFree(buf);
2943 static void test_decodeCertToBeSigned(DWORD dwEncoding)
2945 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
2946 v1CertWithConstraints, v1CertWithSerial };
2947 BOOL ret;
2948 BYTE *buf = NULL;
2949 DWORD size = 0, i;
2951 /* Test with NULL pbEncoded */
2952 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
2953 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2954 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2955 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2956 if (0)
2958 /* Crashes on win9x */
2959 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
2960 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2961 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2962 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2964 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
2965 * minimum a cert must have a non-zero serial number, an issuer, and a
2966 * subject.
2968 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
2970 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
2971 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2972 (BYTE *)&buf, &size);
2973 ok(!ret, "Expected failure\n");
2975 /* Now check with serial number, subject and issuer specified */
2976 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
2977 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2978 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2979 if (buf)
2981 CERT_INFO *info = (CERT_INFO *)buf;
2983 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
2984 ok(info->SerialNumber.cbData == 1,
2985 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
2986 ok(*info->SerialNumber.pbData == *serialNum,
2987 "Expected serial number %d, got %d\n", *serialNum,
2988 *info->SerialNumber.pbData);
2989 ok(info->Issuer.cbData == sizeof(encodedCommonName),
2990 "Wrong size %d\n", info->Issuer.cbData);
2991 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
2992 "Unexpected issuer\n");
2993 ok(info->Subject.cbData == sizeof(encodedCommonName),
2994 "Wrong size %d\n", info->Subject.cbData);
2995 ok(!memcmp(info->Subject.pbData, encodedCommonName,
2996 info->Subject.cbData), "Unexpected subject\n");
2997 LocalFree(buf);
2999 /* Check again with pub key specified */
3000 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3001 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3002 (BYTE *)&buf, &size);
3003 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3004 if (buf)
3006 CERT_INFO *info = (CERT_INFO *)buf;
3008 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3009 ok(info->SerialNumber.cbData == 1,
3010 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3011 ok(*info->SerialNumber.pbData == *serialNum,
3012 "Expected serial number %d, got %d\n", *serialNum,
3013 *info->SerialNumber.pbData);
3014 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3015 "Wrong size %d\n", info->Issuer.cbData);
3016 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3017 "Unexpected issuer\n");
3018 ok(info->Subject.cbData == sizeof(encodedCommonName),
3019 "Wrong size %d\n", info->Subject.cbData);
3020 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3021 info->Subject.cbData), "Unexpected subject\n");
3022 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3023 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3024 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3025 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3026 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3027 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3028 sizeof(aKey)), "Unexpected public key\n");
3029 LocalFree(buf);
3033 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3034 0xe, 0xf };
3036 static const BYTE signedBigCert[] = {
3037 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3038 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3039 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3040 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3041 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3042 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3043 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3044 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3045 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3046 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3047 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3048 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3050 static void test_encodeCert(DWORD dwEncoding)
3052 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3053 * also that bigCert is a NULL-terminated string, so don't count its
3054 * last byte (otherwise the signed cert won't decode.)
3056 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3057 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3058 BOOL ret;
3059 BYTE *buf = NULL;
3060 DWORD bufSize = 0;
3062 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3063 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
3064 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3065 if (buf)
3067 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3068 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3069 LocalFree(buf);
3073 static void test_decodeCert(DWORD dwEncoding)
3075 BOOL ret;
3076 BYTE *buf = NULL;
3077 DWORD size = 0;
3079 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3080 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3081 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3082 if (buf)
3084 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3086 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3087 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3088 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3089 "Unexpected cert\n");
3090 ok(info->Signature.cbData == sizeof(hash),
3091 "Wrong signature size %d\n", info->Signature.cbData);
3092 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3093 "Unexpected signature\n");
3094 LocalFree(buf);
3096 /* A signed cert decodes as a CERT_INFO too */
3097 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3098 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3099 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3100 if (buf)
3102 CERT_INFO *info = (CERT_INFO *)buf;
3104 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3105 ok(info->SerialNumber.cbData == 1,
3106 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3107 ok(*info->SerialNumber.pbData == *serialNum,
3108 "Expected serial number %d, got %d\n", *serialNum,
3109 *info->SerialNumber.pbData);
3110 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3111 "Wrong size %d\n", info->Issuer.cbData);
3112 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3113 "Unexpected issuer\n");
3114 ok(info->Subject.cbData == sizeof(encodedCommonName),
3115 "Wrong size %d\n", info->Subject.cbData);
3116 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3117 info->Subject.cbData), "Unexpected subject\n");
3118 LocalFree(buf);
3122 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3123 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3124 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3125 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3126 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3127 0x00, 0x03 };
3128 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3129 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3130 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3131 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3132 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3133 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3134 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3135 0x2e, 0x6f, 0x72, 0x67 };
3136 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3137 CRL_REASON_AFFILIATION_CHANGED;
3139 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3141 CRL_DIST_POINTS_INFO info = { 0 };
3142 CRL_DIST_POINT point = { { 0 } };
3143 CERT_ALT_NAME_ENTRY entry = { 0 };
3144 BOOL ret;
3145 BYTE *buf = NULL;
3146 DWORD size = 0;
3148 /* Test with an empty info */
3149 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3150 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3151 ok(!ret && GetLastError() == E_INVALIDARG,
3152 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3153 /* Test with one empty dist point */
3154 info.cDistPoint = 1;
3155 info.rgDistPoint = &point;
3156 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3157 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3158 if (buf)
3160 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3161 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3162 LocalFree(buf);
3164 /* A dist point with an invalid name */
3165 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3166 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3167 U(entry).pwszURL = (LPWSTR)nihongoURL;
3168 U(point.DistPointName).FullName.cAltEntry = 1;
3169 U(point.DistPointName).FullName.rgAltEntry = &entry;
3170 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3171 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3172 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3173 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3174 /* The first invalid character is at index 7 */
3175 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3176 "Expected invalid char at index 7, got %d\n",
3177 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3178 /* A dist point with (just) a valid name */
3179 U(entry).pwszURL = (LPWSTR)url;
3180 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3181 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3182 if (buf)
3184 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3185 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3186 LocalFree(buf);
3188 /* A dist point with (just) reason flags */
3189 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3190 point.ReasonFlags.cbData = sizeof(crlReason);
3191 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3192 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3193 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3194 if (buf)
3196 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3197 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3198 LocalFree(buf);
3200 /* A dist point with just an issuer */
3201 point.ReasonFlags.cbData = 0;
3202 point.CRLIssuer.cAltEntry = 1;
3203 point.CRLIssuer.rgAltEntry = &entry;
3204 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3205 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3206 if (buf)
3208 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3209 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3210 LocalFree(buf);
3212 /* A dist point with both a name and an issuer */
3213 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3214 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3215 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3216 if (buf)
3218 ok(size == sizeof(distPointWithUrlAndIssuer),
3219 "Wrong size %d\n", size);
3220 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3221 LocalFree(buf);
3225 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3227 BOOL ret;
3228 BYTE *buf = NULL;
3229 DWORD size = 0;
3230 PCRL_DIST_POINTS_INFO info;
3231 PCRL_DIST_POINT point;
3232 PCERT_ALT_NAME_ENTRY entry;
3234 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3235 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3236 (BYTE *)&buf, &size);
3237 if (ret)
3239 info = (PCRL_DIST_POINTS_INFO)buf;
3240 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3241 "Wrong size %d\n", size);
3242 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3243 info->cDistPoint);
3244 point = info->rgDistPoint;
3245 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3246 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3247 point->DistPointName.dwDistPointNameChoice);
3248 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3249 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3250 LocalFree(buf);
3252 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3253 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3254 (BYTE *)&buf, &size);
3255 if (ret)
3257 info = (PCRL_DIST_POINTS_INFO)buf;
3258 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3259 "Wrong size %d\n", size);
3260 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3261 info->cDistPoint);
3262 point = info->rgDistPoint;
3263 ok(point->DistPointName.dwDistPointNameChoice ==
3264 CRL_DIST_POINT_FULL_NAME,
3265 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3266 point->DistPointName.dwDistPointNameChoice);
3267 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3268 "Expected 1 name entry, got %d\n",
3269 U(point->DistPointName).FullName.cAltEntry);
3270 entry = U(point->DistPointName).FullName.rgAltEntry;
3271 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3272 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3273 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3274 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3275 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3276 LocalFree(buf);
3278 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3279 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3280 NULL, (BYTE *)&buf, &size);
3281 if (ret)
3283 info = (PCRL_DIST_POINTS_INFO)buf;
3284 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3285 "Wrong size %d\n", size);
3286 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3287 info->cDistPoint);
3288 point = info->rgDistPoint;
3289 ok(point->DistPointName.dwDistPointNameChoice ==
3290 CRL_DIST_POINT_NO_NAME,
3291 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3292 point->DistPointName.dwDistPointNameChoice);
3293 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3294 "Expected reason length\n");
3295 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3296 "Unexpected reason\n");
3297 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3298 LocalFree(buf);
3300 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3301 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3302 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3303 if (ret)
3305 info = (PCRL_DIST_POINTS_INFO)buf;
3306 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3307 "Wrong size %d\n", size);
3308 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3309 info->cDistPoint);
3310 point = info->rgDistPoint;
3311 ok(point->DistPointName.dwDistPointNameChoice ==
3312 CRL_DIST_POINT_FULL_NAME,
3313 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3314 point->DistPointName.dwDistPointNameChoice);
3315 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3316 "Expected 1 name entry, got %d\n",
3317 U(point->DistPointName).FullName.cAltEntry);
3318 entry = U(point->DistPointName).FullName.rgAltEntry;
3319 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3320 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3321 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3322 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3323 ok(point->CRLIssuer.cAltEntry == 1,
3324 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3325 entry = point->CRLIssuer.rgAltEntry;
3326 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3327 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3328 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3329 LocalFree(buf);
3333 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3334 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3335 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3336 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3337 0x67 };
3339 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3341 BOOL ret;
3342 BYTE *buf = NULL;
3343 DWORD size = 0;
3344 CRL_ISSUING_DIST_POINT point = { { 0 } };
3345 CERT_ALT_NAME_ENTRY entry;
3347 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3348 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3349 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3351 skip("no X509_ISSUING_DIST_POINT encode support\n");
3352 return;
3354 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3355 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3356 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3357 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3358 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3359 if (buf)
3361 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3362 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3363 LocalFree(buf);
3365 /* nonsensical flags */
3366 point.fOnlyContainsUserCerts = TRUE;
3367 point.fOnlyContainsCACerts = TRUE;
3368 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3369 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3370 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3371 if (buf)
3373 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3374 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3375 LocalFree(buf);
3377 /* unimplemented name type */
3378 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3379 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3380 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3381 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3382 ok(!ret && GetLastError() == E_INVALIDARG,
3383 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3384 /* empty name */
3385 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3386 U(point.DistPointName).FullName.cAltEntry = 0;
3387 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3388 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3389 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3390 if (buf)
3392 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3393 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3394 LocalFree(buf);
3396 /* name with URL entry */
3397 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3398 U(entry).pwszURL = (LPWSTR)url;
3399 U(point.DistPointName).FullName.cAltEntry = 1;
3400 U(point.DistPointName).FullName.rgAltEntry = &entry;
3401 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3402 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3403 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3404 if (buf)
3406 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3407 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3408 LocalFree(buf);
3412 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3413 const CERT_ALT_NAME_ENTRY *got)
3415 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3416 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3417 got->dwAltNameChoice);
3418 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3420 switch (got->dwAltNameChoice)
3422 case CERT_ALT_NAME_RFC822_NAME:
3423 case CERT_ALT_NAME_DNS_NAME:
3424 case CERT_ALT_NAME_EDI_PARTY_NAME:
3425 case CERT_ALT_NAME_URL:
3426 case CERT_ALT_NAME_REGISTERED_ID:
3427 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3428 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3429 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3430 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3431 "Unexpected name\n");
3432 break;
3433 case CERT_ALT_NAME_X400_ADDRESS:
3434 case CERT_ALT_NAME_DIRECTORY_NAME:
3435 case CERT_ALT_NAME_IP_ADDRESS:
3436 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3437 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3438 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3439 U(*got).IPAddress.cbData), "Unexpected value\n");
3440 break;
3445 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3446 const CERT_ALT_NAME_INFO *got)
3448 DWORD i;
3450 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3451 expected->cAltEntry, got->cAltEntry);
3452 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3453 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3456 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3457 const CRL_DIST_POINT_NAME *got)
3459 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3460 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3461 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3462 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3465 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3466 const CRL_ISSUING_DIST_POINT *got)
3468 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3469 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3470 "Unexpected fOnlyContainsUserCerts\n");
3471 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3472 "Unexpected fOnlyContainsCACerts\n");
3473 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3474 "Unexpected reason flags\n");
3475 ok(got->fIndirectCRL == expected->fIndirectCRL,
3476 "Unexpected fIndirectCRL\n");
3479 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3481 BOOL ret;
3482 BYTE *buf = NULL;
3483 DWORD size = 0;
3484 CRL_ISSUING_DIST_POINT point = { { 0 } };
3486 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3487 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3488 (BYTE *)&buf, &size);
3489 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3491 skip("no X509_ISSUING_DIST_POINT decode support\n");
3492 return;
3494 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3495 if (ret)
3497 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3498 LocalFree(buf);
3500 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3501 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3502 (BYTE *)&buf, &size);
3503 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3504 if (ret)
3506 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3507 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3508 LocalFree(buf);
3510 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3511 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3512 (BYTE *)&buf, &size);
3513 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3514 if (ret)
3516 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3517 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3518 U(point.DistPointName).FullName.cAltEntry = 0;
3519 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3520 LocalFree(buf);
3522 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3523 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3524 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3525 if (ret)
3527 CERT_ALT_NAME_ENTRY entry;
3529 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3530 U(entry).pwszURL = (LPWSTR)url;
3531 U(point.DistPointName).FullName.cAltEntry = 1;
3532 U(point.DistPointName).FullName.rgAltEntry = &entry;
3533 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3534 LocalFree(buf);
3538 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3539 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3540 0x30, 0x5a };
3541 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3542 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3543 0x30, 0x30, 0x30, 0x30, 0x5a };
3544 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3545 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3546 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3547 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3548 0x5a };
3549 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3550 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3551 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3552 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3553 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3554 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3555 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3556 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3557 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3558 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3559 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3560 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3561 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3562 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3563 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3564 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3565 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3566 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3567 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3568 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3569 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3570 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3571 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3572 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3573 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3574 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3575 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3576 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3577 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3578 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3579 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3580 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3581 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3582 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3583 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3584 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3585 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3586 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3587 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3588 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3590 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3592 BOOL ret;
3593 BYTE *buf = NULL;
3594 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3595 DWORD size = 0;
3596 CRL_INFO info = { 0 };
3597 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3598 CERT_EXTENSION ext;
3600 /* Test with a V1 CRL */
3601 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3602 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3603 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3604 if (buf)
3606 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3607 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3608 LocalFree(buf);
3610 /* Test v2 CRL */
3611 info.dwVersion = CRL_V2;
3612 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3613 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3614 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3615 if (buf)
3617 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3618 v2CRL[1] + 2, size);
3619 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3620 LocalFree(buf);
3622 /* v1 CRL with a name */
3623 info.dwVersion = CRL_V1;
3624 info.Issuer.cbData = sizeof(encodedCommonName);
3625 info.Issuer.pbData = (BYTE *)encodedCommonName;
3626 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3627 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3628 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3629 if (buf)
3631 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3632 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3633 LocalFree(buf);
3635 if (0)
3637 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3638 info.cCRLEntry = 1;
3639 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3640 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3641 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3642 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3644 /* now set an empty entry */
3645 info.cCRLEntry = 1;
3646 info.rgCRLEntry = &entry;
3647 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3648 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3649 if (buf)
3651 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3652 "Wrong size %d\n", size);
3653 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3654 "Got unexpected value\n");
3655 LocalFree(buf);
3657 /* an entry with a serial number */
3658 entry.SerialNumber.cbData = sizeof(serialNum);
3659 entry.SerialNumber.pbData = (BYTE *)serialNum;
3660 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3661 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3662 if (buf)
3664 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3665 "Wrong size %d\n", size);
3666 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3667 "Got unexpected value\n");
3668 LocalFree(buf);
3670 /* an entry with an extension */
3671 entry.cExtension = 1;
3672 entry.rgExtension = &criticalExt;
3673 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3674 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3675 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3676 if (buf)
3678 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3679 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3680 LocalFree(buf);
3682 /* a CRL with an extension */
3683 entry.cExtension = 0;
3684 info.cExtension = 1;
3685 info.rgExtension = &criticalExt;
3686 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3687 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3688 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3689 if (buf)
3691 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3692 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3693 LocalFree(buf);
3695 /* a v2 CRL with an extension, this time non-critical */
3696 info.dwVersion = CRL_V2;
3697 info.rgExtension = &nonCriticalExt;
3698 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3699 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3700 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3701 if (buf)
3703 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3704 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3705 LocalFree(buf);
3707 /* a v2 CRL with an issuing dist point extension */
3708 ext.pszObjId = oid_issuing_dist_point;
3709 ext.fCritical = TRUE;
3710 ext.Value.cbData = sizeof(urlIDP);
3711 ext.Value.pbData = (LPBYTE)urlIDP;
3712 entry.rgExtension = &ext;
3713 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3714 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3715 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3716 if (buf)
3718 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3719 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3720 LocalFree(buf);
3724 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3725 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3726 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3727 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3728 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3729 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3730 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3731 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3732 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3733 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3734 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3735 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3736 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3737 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3738 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3739 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3740 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3741 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3742 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3743 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3744 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3745 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3746 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3747 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3748 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3749 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3750 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3751 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3752 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3753 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3754 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3755 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3756 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3757 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3758 0xcd };
3759 static const BYTE verisignCRLWithLotsOfEntries[] = {
3760 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3761 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3762 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3763 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3764 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3765 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3766 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3767 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3768 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3769 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3770 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3771 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3772 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3773 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3774 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3775 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3776 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3777 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3778 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3779 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3780 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3781 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3782 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3783 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3784 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3785 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3786 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3787 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3788 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3789 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3790 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3791 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3792 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3793 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3794 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3795 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3796 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3797 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3798 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3799 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3800 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3801 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3802 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3803 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3804 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3805 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3806 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3807 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3808 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3809 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3810 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3811 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3812 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3813 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3814 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3815 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3816 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3817 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3818 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3819 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3820 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3821 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3822 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3823 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3824 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3825 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3826 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3827 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3828 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3829 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3830 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3831 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3832 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3833 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3834 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3835 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3836 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3837 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3838 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3839 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3840 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3841 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3842 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3843 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3844 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3845 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3846 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3847 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3848 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3849 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3850 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3851 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3852 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3853 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3854 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3855 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3856 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3857 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3858 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3859 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3860 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3861 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3862 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3863 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3864 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3865 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3866 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3867 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3868 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3869 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3870 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3871 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3872 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3873 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3874 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3875 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3876 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3877 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3878 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3879 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3880 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3881 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3882 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3883 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3884 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3885 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3886 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3887 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3888 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3889 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3890 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3891 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3892 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3893 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3894 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3895 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3896 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3897 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3898 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3899 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3900 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3901 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3902 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3903 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3904 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3905 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3906 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3907 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3908 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3909 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3910 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3911 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3912 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3913 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3914 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3915 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3916 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3917 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3918 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3919 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3920 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3921 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3922 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3923 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3924 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3925 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3926 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3927 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3928 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3929 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3930 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3931 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3932 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3933 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3934 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3935 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3936 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3937 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3938 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3939 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3940 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3941 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
3942 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
3943 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
3944 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
3945 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
3946 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
3947 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
3948 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
3949 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
3950 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
3951 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
3952 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
3953 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
3954 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
3955 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
3956 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
3957 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
3958 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
3959 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
3960 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
3961 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
3962 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
3963 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
3964 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
3965 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
3966 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
3967 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
3968 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
3969 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
3970 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
3971 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
3972 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
3973 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
3974 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
3975 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
3976 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
3977 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
3978 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
3979 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
3980 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
3981 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
3982 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
3983 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
3984 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
3985 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
3986 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
3987 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
3988 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
3989 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
3990 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
3991 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
3992 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
3993 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
3994 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
3995 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
3996 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
3997 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
3998 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
3999 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4000 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4001 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4002 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4003 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4004 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4005 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4006 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4007 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4008 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4009 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4010 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4011 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4012 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4013 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4014 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4015 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4016 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4017 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4018 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4019 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4020 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4021 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4022 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4023 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4024 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4025 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4026 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4027 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4028 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4029 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4030 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4031 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4032 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4033 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4034 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4035 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4036 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4037 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4038 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4039 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4040 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4041 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4042 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4043 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4044 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4045 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4046 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4047 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4048 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4049 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4050 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4051 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4052 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4053 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4054 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4055 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4056 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4057 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4058 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4059 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4060 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4061 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4062 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4063 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4064 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4065 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4066 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4067 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4068 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4069 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4070 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4071 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4072 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4073 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4074 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4075 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4076 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4077 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4078 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4079 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4080 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4081 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4082 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4083 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4084 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4085 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4086 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4087 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4088 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4089 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4090 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4091 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4092 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4093 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4094 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4095 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4096 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4097 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4098 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4099 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4100 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4101 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4102 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4103 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4104 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4105 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4106 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4107 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4108 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4109 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4110 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4111 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4112 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4113 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4114 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4115 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4116 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4117 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4118 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4119 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4120 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4121 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4122 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4123 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4124 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4125 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4126 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4127 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4128 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4129 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4130 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4131 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4132 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4133 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4134 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4135 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4136 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4137 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4138 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4139 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4140 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4141 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4142 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4143 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4144 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4145 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4146 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4147 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4148 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4149 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4150 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4151 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4152 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4153 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4154 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4155 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4156 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4157 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4158 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4159 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4160 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4161 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4162 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4163 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4164 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4165 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4166 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4167 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4168 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4169 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4170 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4171 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4172 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4173 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4174 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4175 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4176 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4177 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4178 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4179 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4180 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4181 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4182 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4183 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4184 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4185 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4186 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4187 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4188 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4189 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4190 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4191 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4192 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4193 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4194 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4195 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4196 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4197 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4198 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4199 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4200 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4201 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4202 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4203 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4204 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4205 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4206 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4207 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4208 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4209 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4210 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4211 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4212 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4213 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4214 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4215 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4216 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4217 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4218 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4219 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4220 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4221 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4222 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4223 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4224 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4225 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4226 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4227 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4228 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4229 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4230 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4231 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4232 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4233 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4234 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4235 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4236 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4237 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4238 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4239 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4240 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4241 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4242 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4243 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4244 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4245 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4246 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4247 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4248 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4249 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4250 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4251 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4252 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4253 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4254 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4255 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4256 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4257 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4258 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4259 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4260 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4261 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4262 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4263 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4264 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4265 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4266 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4267 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4269 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4271 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4272 BOOL ret;
4273 BYTE *buf = NULL;
4274 DWORD size = 0, i;
4276 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4278 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4279 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4280 (BYTE *)&buf, &size);
4281 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT),
4282 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4284 /* at a minimum, a CRL must contain an issuer: */
4285 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4286 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4287 (BYTE *)&buf, &size);
4288 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4289 if (buf)
4291 CRL_INFO *info = (CRL_INFO *)buf;
4293 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4294 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4295 info->cCRLEntry);
4296 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4297 "Wrong issuer size %d\n", info->Issuer.cbData);
4298 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4299 "Unexpected issuer\n");
4300 LocalFree(buf);
4302 /* check decoding with an empty CRL entry */
4303 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4304 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4305 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4306 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
4307 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4308 /* with a real CRL entry */
4309 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4310 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4311 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4312 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4313 if (buf)
4315 CRL_INFO *info = (CRL_INFO *)buf;
4316 CRL_ENTRY *entry;
4318 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4319 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4320 info->cCRLEntry);
4321 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4322 entry = info->rgCRLEntry;
4323 ok(entry->SerialNumber.cbData == 1,
4324 "Expected serial number size 1, got %d\n",
4325 entry->SerialNumber.cbData);
4326 ok(*entry->SerialNumber.pbData == *serialNum,
4327 "Expected serial number %d, got %d\n", *serialNum,
4328 *entry->SerialNumber.pbData);
4329 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4330 "Wrong issuer size %d\n", info->Issuer.cbData);
4331 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4332 "Unexpected issuer\n");
4333 LocalFree(buf);
4335 /* a real CRL from verisign that has extensions */
4336 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4337 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4338 NULL, (BYTE *)&buf, &size);
4339 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4340 if (buf)
4342 CRL_INFO *info = (CRL_INFO *)buf;
4343 CRL_ENTRY *entry;
4345 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4346 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4347 info->cCRLEntry);
4348 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4349 entry = info->rgCRLEntry;
4350 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4351 info->cExtension);
4352 LocalFree(buf);
4354 /* another real CRL from verisign that has lots of entries */
4355 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4356 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4357 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4358 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4359 if (buf)
4361 CRL_INFO *info = (CRL_INFO *)buf;
4363 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4364 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4365 info->cCRLEntry);
4366 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4367 info->cExtension);
4368 LocalFree(buf);
4370 /* and finally, with an extension */
4371 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4372 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4373 NULL, (BYTE *)&buf, &size);
4374 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4375 if (buf)
4377 CRL_INFO *info = (CRL_INFO *)buf;
4378 CRL_ENTRY *entry;
4380 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4381 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4382 info->cCRLEntry);
4383 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4384 entry = info->rgCRLEntry;
4385 ok(entry->SerialNumber.cbData == 1,
4386 "Expected serial number size 1, got %d\n",
4387 entry->SerialNumber.cbData);
4388 ok(*entry->SerialNumber.pbData == *serialNum,
4389 "Expected serial number %d, got %d\n", *serialNum,
4390 *entry->SerialNumber.pbData);
4391 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4392 "Wrong issuer size %d\n", info->Issuer.cbData);
4393 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4394 "Unexpected issuer\n");
4395 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4396 info->cExtension);
4397 LocalFree(buf);
4399 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4400 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4401 NULL, (BYTE *)&buf, &size);
4402 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4403 if (buf)
4405 CRL_INFO *info = (CRL_INFO *)buf;
4407 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4408 info->cExtension);
4409 LocalFree(buf);
4411 /* And again, with an issuing dist point */
4412 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4413 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4414 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4415 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4416 if (buf)
4418 CRL_INFO *info = (CRL_INFO *)buf;
4420 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4421 info->cExtension);
4422 LocalFree(buf);
4426 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4427 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4428 static const BYTE encodedUsage[] = {
4429 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4430 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4431 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4433 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4435 BOOL ret;
4436 BYTE *buf = NULL;
4437 DWORD size = 0;
4438 CERT_ENHKEY_USAGE usage;
4440 /* Test with empty usage */
4441 usage.cUsageIdentifier = 0;
4442 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4443 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4444 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4445 if (buf)
4447 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4448 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4449 LocalFree(buf);
4451 /* Test with a few usages */
4452 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4453 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4454 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4455 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4456 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4457 if (buf)
4459 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4460 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4461 LocalFree(buf);
4465 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4467 BOOL ret;
4468 LPBYTE buf = NULL;
4469 DWORD size = 0;
4471 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4472 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4473 (BYTE *)&buf, &size);
4474 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4475 if (buf)
4477 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4479 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4480 "Wrong size %d\n", size);
4481 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4482 usage->cUsageIdentifier);
4483 LocalFree(buf);
4485 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4486 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4487 (BYTE *)&buf, &size);
4488 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4489 if (buf)
4491 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4492 DWORD i;
4494 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4495 "Wrong size %d\n", size);
4496 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4497 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4498 for (i = 0; i < usage->cUsageIdentifier; i++)
4499 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4500 "Expected OID %s, got %s\n", keyUsages[i],
4501 usage->rgpszUsageIdentifier[i]);
4502 LocalFree(buf);
4506 static BYTE keyId[] = { 1,2,3,4 };
4507 static const BYTE authorityKeyIdWithId[] = {
4508 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4509 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4510 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4511 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4512 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4514 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4516 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4517 BOOL ret;
4518 BYTE *buf = NULL;
4519 DWORD size = 0;
4521 /* Test with empty id */
4522 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4523 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4524 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4525 if (buf)
4527 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4528 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4529 LocalFree(buf);
4531 /* With just a key id */
4532 info.KeyId.cbData = sizeof(keyId);
4533 info.KeyId.pbData = keyId;
4534 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4535 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4536 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4537 if (buf)
4539 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4540 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4541 LocalFree(buf);
4543 /* With just an issuer */
4544 info.KeyId.cbData = 0;
4545 info.CertIssuer.cbData = sizeof(encodedCommonName);
4546 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4547 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4548 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4549 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4550 if (buf)
4552 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4553 size);
4554 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4555 LocalFree(buf);
4557 /* With just a serial number */
4558 info.CertIssuer.cbData = 0;
4559 info.CertSerialNumber.cbData = sizeof(serialNum);
4560 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4561 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4562 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4563 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4564 if (buf)
4566 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4567 size);
4568 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4569 LocalFree(buf);
4573 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4575 BOOL ret;
4576 LPBYTE buf = NULL;
4577 DWORD size = 0;
4579 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4580 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4581 (BYTE *)&buf, &size);
4582 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4583 if (buf)
4585 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4587 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4588 size);
4589 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4590 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4591 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4592 LocalFree(buf);
4594 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4595 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4596 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4597 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4598 if (buf)
4600 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4602 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4603 size);
4604 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4605 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4606 "Unexpected key id\n");
4607 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4608 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4609 LocalFree(buf);
4611 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4612 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4613 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4614 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4615 if (buf)
4617 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4619 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4620 size);
4621 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4622 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4623 "Unexpected issuer len\n");
4624 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4625 sizeof(encodedCommonName)), "Unexpected issuer\n");
4626 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4627 LocalFree(buf);
4629 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4630 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4631 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4632 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4633 if (buf)
4635 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4637 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4638 size);
4639 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4640 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4641 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4642 "Unexpected serial number len\n");
4643 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4644 "Unexpected serial number\n");
4645 LocalFree(buf);
4649 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4650 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4651 0x6f,0x72,0x67 };
4653 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4655 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4656 CERT_ALT_NAME_ENTRY entry = { 0 };
4657 BOOL ret;
4658 BYTE *buf = NULL;
4659 DWORD size = 0;
4661 /* Test with empty id */
4662 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4663 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4664 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4665 if (buf)
4667 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4668 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4669 LocalFree(buf);
4671 /* With just a key id */
4672 info.KeyId.cbData = sizeof(keyId);
4673 info.KeyId.pbData = keyId;
4674 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4675 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4676 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4677 if (buf)
4679 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4680 size);
4681 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4682 LocalFree(buf);
4684 /* With a bogus issuer name */
4685 info.KeyId.cbData = 0;
4686 info.AuthorityCertIssuer.cAltEntry = 1;
4687 info.AuthorityCertIssuer.rgAltEntry = &entry;
4688 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4689 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4690 ok(!ret && GetLastError() == E_INVALIDARG,
4691 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4692 /* With an issuer name */
4693 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4694 U(entry).pwszURL = (LPWSTR)url;
4695 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4696 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4697 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4698 if (buf)
4700 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4701 size);
4702 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4703 "Unexpected value\n");
4704 LocalFree(buf);
4706 /* With just a serial number */
4707 info.AuthorityCertIssuer.cAltEntry = 0;
4708 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4709 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4710 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4711 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4712 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4713 if (buf)
4715 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4716 size);
4717 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4718 LocalFree(buf);
4722 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4724 BOOL ret;
4725 LPBYTE buf = NULL;
4726 DWORD size = 0;
4728 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4729 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4730 (BYTE *)&buf, &size);
4731 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4732 if (buf)
4734 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4736 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4737 size);
4738 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4739 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4740 "Expected no issuer name entries\n");
4741 ok(info->AuthorityCertSerialNumber.cbData == 0,
4742 "Expected no serial number\n");
4743 LocalFree(buf);
4745 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4746 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4747 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4748 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4749 if (buf)
4751 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4753 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4754 size);
4755 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4756 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4757 "Unexpected key id\n");
4758 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4759 "Expected no issuer name entries\n");
4760 ok(info->AuthorityCertSerialNumber.cbData == 0,
4761 "Expected no serial number\n");
4762 LocalFree(buf);
4764 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4765 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4766 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4767 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4768 if (buf)
4770 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4772 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4773 size);
4774 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4775 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4776 "Expected 1 issuer entry, got %d\n",
4777 info->AuthorityCertIssuer.cAltEntry);
4778 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4779 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4780 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4781 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4782 url), "Unexpected URL\n");
4783 ok(info->AuthorityCertSerialNumber.cbData == 0,
4784 "Expected no serial number\n");
4785 LocalFree(buf);
4787 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4788 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4789 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4790 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4791 if (buf)
4793 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4795 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4796 size);
4797 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4798 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4799 "Expected no issuer name entries\n");
4800 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4801 "Unexpected serial number len\n");
4802 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4803 sizeof(serialNum)), "Unexpected serial number\n");
4804 LocalFree(buf);
4808 static const BYTE authorityInfoAccessWithUrl[] = {
4809 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4810 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
4811 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
4812 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4813 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
4814 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
4816 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
4818 static char oid1[] = "1.2.3";
4819 static char oid2[] = "1.5.6";
4820 BOOL ret;
4821 BYTE *buf = NULL;
4822 DWORD size = 0;
4823 CERT_ACCESS_DESCRIPTION accessDescription[2];
4824 CERT_AUTHORITY_INFO_ACCESS aia;
4826 memset(accessDescription, 0, sizeof(accessDescription));
4827 aia.cAccDescr = 0;
4828 aia.rgAccDescr = NULL;
4829 /* Having no access descriptions is allowed */
4830 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4831 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4832 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4833 if (buf)
4835 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
4836 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
4837 LocalFree(buf);
4838 buf = NULL;
4840 /* It can't have an empty access method */
4841 aia.cAccDescr = 1;
4842 aia.rgAccDescr = accessDescription;
4843 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4844 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4845 ok(!ret && GetLastError() == E_INVALIDARG,
4846 "expected E_INVALIDARG, got %08x\n", GetLastError());
4847 /* It can't have an empty location */
4848 accessDescription[0].pszAccessMethod = oid1;
4849 SetLastError(0xdeadbeef);
4850 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4851 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4852 ok(!ret && GetLastError() == E_INVALIDARG,
4853 "expected E_INVALIDARG, got %08x\n", GetLastError());
4854 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4855 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
4856 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4857 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4858 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4859 if (buf)
4861 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
4862 size);
4863 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
4864 "unexpected value\n");
4865 LocalFree(buf);
4866 buf = NULL;
4868 accessDescription[1].pszAccessMethod = oid2;
4869 accessDescription[1].AccessLocation.dwAltNameChoice =
4870 CERT_ALT_NAME_IP_ADDRESS;
4871 U(accessDescription[1].AccessLocation).IPAddress.cbData =
4872 sizeof(encodedIPAddr);
4873 U(accessDescription[1].AccessLocation).IPAddress.pbData =
4874 (LPBYTE)encodedIPAddr;
4875 aia.cAccDescr = 2;
4876 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4877 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4878 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4879 if (buf)
4881 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
4882 "unexpected size %d\n", size);
4883 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
4884 "unexpected value\n");
4885 LocalFree(buf);
4886 buf = NULL;
4890 static void compareAuthorityInfoAccess(LPCSTR header,
4891 const CERT_AUTHORITY_INFO_ACCESS *expected,
4892 const CERT_AUTHORITY_INFO_ACCESS *got)
4894 DWORD i;
4896 ok(expected->cAccDescr == got->cAccDescr,
4897 "%s: expected %d access descriptions, got %d\n", header,
4898 expected->cAccDescr, got->cAccDescr);
4899 for (i = 0; i < expected->cAccDescr; i++)
4901 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
4902 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
4903 header, i, expected->rgAccDescr[i].pszAccessMethod,
4904 got->rgAccDescr[i].pszAccessMethod);
4905 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
4906 &got->rgAccDescr[i].AccessLocation);
4910 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
4912 static char oid1[] = "1.2.3";
4913 static char oid2[] = "1.5.6";
4914 BOOL ret;
4915 LPBYTE buf = NULL;
4916 DWORD size = 0;
4918 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4919 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4920 (BYTE *)&buf, &size);
4921 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4922 if (buf)
4924 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
4926 compareAuthorityInfoAccess("empty AIA", &aia,
4927 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4928 LocalFree(buf);
4929 buf = NULL;
4931 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4932 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
4933 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4934 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4935 if (buf)
4937 CERT_ACCESS_DESCRIPTION accessDescription;
4938 CERT_AUTHORITY_INFO_ACCESS aia;
4940 accessDescription.pszAccessMethod = oid1;
4941 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4942 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
4943 aia.cAccDescr = 1;
4944 aia.rgAccDescr = &accessDescription;
4945 compareAuthorityInfoAccess("AIA with URL", &aia,
4946 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4947 LocalFree(buf);
4948 buf = NULL;
4950 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4951 authorityInfoAccessWithUrlAndIPAddr,
4952 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
4953 NULL, (BYTE *)&buf, &size);
4954 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4955 if (buf)
4957 CERT_ACCESS_DESCRIPTION accessDescription[2];
4958 CERT_AUTHORITY_INFO_ACCESS aia;
4960 accessDescription[0].pszAccessMethod = oid1;
4961 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4962 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
4963 accessDescription[1].pszAccessMethod = oid2;
4964 accessDescription[1].AccessLocation.dwAltNameChoice =
4965 CERT_ALT_NAME_IP_ADDRESS;
4966 U(accessDescription[1].AccessLocation).IPAddress.cbData =
4967 sizeof(encodedIPAddr);
4968 U(accessDescription[1].AccessLocation).IPAddress.pbData =
4969 (LPBYTE)encodedIPAddr;
4970 aia.cAccDescr = 2;
4971 aia.rgAccDescr = accessDescription;
4972 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
4973 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4974 LocalFree(buf);
4975 buf = NULL;
4979 static const BYTE emptyCTL[] = {
4980 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
4981 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
4982 static const BYTE emptyCTLWithVersion1[] = {
4983 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
4984 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
4985 static const BYTE ctlWithUsageIdentifier[] = {
4986 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
4987 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
4988 static const BYTE ctlWithListIdentifier[] = {
4989 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
4990 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
4991 static const BYTE ctlWithSequenceNumber[] = {
4992 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
4993 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
4994 static const BYTE ctlWithThisUpdate[] = {
4995 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
4996 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
4997 static const BYTE ctlWithThisAndNextUpdate[] = {
4998 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
4999 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5000 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5001 static const BYTE ctlWithAlgId[] = {
5002 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5003 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5004 static const BYTE ctlWithBogusEntry[] = {
5005 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5006 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5007 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5008 static const BYTE ctlWithOneEntry[] = {
5009 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5010 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5011 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5012 static const BYTE ctlWithTwoEntries[] = {
5013 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5014 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5015 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5016 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5017 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5019 static void test_encodeCTL(DWORD dwEncoding)
5021 static char oid1[] = "1.2.3";
5022 static char oid2[] = "1.5.6";
5023 char *pOid1 = oid1;
5024 BOOL ret;
5025 BYTE *buf = NULL;
5026 DWORD size = 0;
5027 CTL_INFO info;
5028 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5029 CTL_ENTRY ctlEntry[2];
5030 CRYPT_ATTRIBUTE attr1, attr2;
5031 CRYPT_ATTR_BLOB value1, value2;
5033 memset(&info, 0, sizeof(info));
5034 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5035 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5036 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5037 if (buf)
5039 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5040 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5041 LocalFree(buf);
5042 buf = NULL;
5044 info.dwVersion = 1;
5045 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5046 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5047 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5048 if (buf)
5050 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5051 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5052 LocalFree(buf);
5053 buf = NULL;
5055 info.dwVersion = 0;
5056 info.SubjectUsage.cUsageIdentifier = 1;
5057 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5058 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5059 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5060 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5061 if (buf)
5063 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5064 size);
5065 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5066 LocalFree(buf);
5067 buf = NULL;
5069 info.SubjectUsage.cUsageIdentifier = 0;
5070 info.ListIdentifier.cbData = sizeof(serialNum);
5071 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5072 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5073 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5074 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5075 if (buf)
5077 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5078 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5079 LocalFree(buf);
5080 buf = NULL;
5082 info.ListIdentifier.cbData = 0;
5083 info.SequenceNumber.cbData = sizeof(serialNum);
5084 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5085 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5086 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5087 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5088 if (buf)
5090 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5091 size);
5092 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5093 LocalFree(buf);
5094 buf = NULL;
5096 info.SequenceNumber.cbData = 0;
5097 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5098 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5099 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5100 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5101 if (buf)
5103 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5104 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5105 LocalFree(buf);
5106 buf = NULL;
5108 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5109 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5110 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5111 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5112 if (buf)
5114 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5115 size);
5116 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5117 LocalFree(buf);
5118 buf = NULL;
5120 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5121 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5122 info.SubjectAlgorithm.pszObjId = oid2;
5123 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5124 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5125 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5126 if (buf)
5128 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5129 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5130 LocalFree(buf);
5131 buf = NULL;
5133 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5134 * (see tests below) but it'll encode fine.
5136 info.SubjectAlgorithm.pszObjId = NULL;
5137 value1.cbData = sizeof(serialNum);
5138 value1.pbData = (LPBYTE)serialNum;
5139 attr1.pszObjId = oid1;
5140 attr1.cValue = 1;
5141 attr1.rgValue = &value1;
5142 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5143 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5144 ctlEntry[0].cAttribute = 1;
5145 ctlEntry[0].rgAttribute = &attr1;
5146 info.cCTLEntry = 1;
5147 info.rgCTLEntry = ctlEntry;
5148 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5149 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5150 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5151 if (buf)
5153 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5154 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5155 LocalFree(buf);
5156 buf = NULL;
5158 value1.cbData = sizeof(emptySequence);
5159 value1.pbData = (LPBYTE)emptySequence;
5160 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5161 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5162 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5163 if (buf)
5165 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5166 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5167 LocalFree(buf);
5168 buf = NULL;
5170 value2.cbData = sizeof(encodedIPAddr);
5171 value2.pbData = (LPBYTE)encodedIPAddr;
5172 attr2.pszObjId = oid2;
5173 attr2.cValue = 1;
5174 attr2.rgValue = &value2;
5175 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5176 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5177 ctlEntry[1].cAttribute = 1;
5178 ctlEntry[1].rgAttribute = &attr2;
5179 info.cCTLEntry = 2;
5180 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5181 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5182 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5183 if (buf)
5185 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5186 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5187 LocalFree(buf);
5188 buf = NULL;
5192 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5193 const CTL_INFO *got)
5195 DWORD i, j, k;
5197 ok(expected->dwVersion == got->dwVersion,
5198 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5199 got->dwVersion);
5200 ok(expected->SubjectUsage.cUsageIdentifier ==
5201 got->SubjectUsage.cUsageIdentifier,
5202 "%s: expected %d usage identifiers, got %d\n", header,
5203 expected->SubjectUsage.cUsageIdentifier,
5204 got->SubjectUsage.cUsageIdentifier);
5205 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5206 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5207 got->SubjectUsage.rgpszUsageIdentifier[i]),
5208 "%s[%d]: expected %s, got %s\n", header, i,
5209 expected->SubjectUsage.rgpszUsageIdentifier[i],
5210 got->SubjectUsage.rgpszUsageIdentifier[i]);
5211 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5212 "%s: expected list identifier of %d bytes, got %d\n", header,
5213 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5214 if (expected->ListIdentifier.cbData)
5215 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5216 expected->ListIdentifier.cbData),
5217 "%s: unexpected list identifier value\n", header);
5218 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5219 "%s: expected sequence number of %d bytes, got %d\n", header,
5220 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5221 if (expected->SequenceNumber.cbData)
5222 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5223 expected->SequenceNumber.cbData),
5224 "%s: unexpected sequence number value\n", header);
5225 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5226 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5227 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5228 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5229 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5230 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5231 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5232 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5233 if (expected->SubjectAlgorithm.pszObjId &&
5234 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5235 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5236 expected->SubjectAlgorithm.pszObjId);
5237 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5238 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5239 got->SubjectAlgorithm.pszObjId),
5240 "%s: expected subject algorithm %s, got %s\n", header,
5241 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5242 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5243 got->SubjectAlgorithm.Parameters.cbData,
5244 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5245 expected->SubjectAlgorithm.Parameters.cbData,
5246 got->SubjectAlgorithm.Parameters.cbData);
5247 if (expected->SubjectAlgorithm.Parameters.cbData)
5248 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5249 got->SubjectAlgorithm.Parameters.pbData,
5250 expected->SubjectAlgorithm.Parameters.cbData),
5251 "%s: unexpected subject algorithm parameter value\n", header);
5252 ok(expected->cCTLEntry == got->cCTLEntry,
5253 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5254 got->cCTLEntry);
5255 for (i = 0; i < expected->cCTLEntry; i++)
5257 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5258 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5259 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5260 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5261 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5262 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5263 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5264 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5265 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5266 "%s[%d]: unexpected subject identifier value\n",
5267 header, i);
5268 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5270 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5271 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5272 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5273 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5274 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5275 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5277 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5278 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5279 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5280 header, i, j, k,
5281 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5282 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5283 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5284 ok(!memcmp(
5285 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5286 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5287 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5288 "%s[%d][%d][%d]: unexpected value\n",
5289 header, i, j, k);
5293 ok(expected->cExtension == got->cExtension,
5294 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5295 got->cExtension);
5296 for (i = 0; i < expected->cExtension; i++)
5298 ok(!strcmp(expected->rgExtension[i].pszObjId,
5299 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5300 header, i, expected->rgExtension[i].pszObjId,
5301 got->rgExtension[i].pszObjId);
5302 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5303 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5304 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5305 ok(expected->rgExtension[i].Value.cbData ==
5306 got->rgExtension[i].Value.cbData,
5307 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5308 header, i, expected->rgExtension[i].Value.cbData,
5309 got->rgExtension[i].Value.cbData);
5310 if (expected->rgExtension[i].Value.cbData)
5311 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5312 got->rgExtension[i].Value.pbData,
5313 expected->rgExtension[i].Value.cbData),
5314 "%s[%d]: unexpected extension value\n", header, i);
5318 static const BYTE signedCTL[] = {
5319 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5320 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5321 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5322 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5323 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5324 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5325 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5326 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5327 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5328 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5329 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5330 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5331 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5332 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5333 static const BYTE signedCTLWithCTLInnerContent[] = {
5334 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5335 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5336 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5337 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5338 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5339 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5340 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5341 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5342 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5343 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5344 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5345 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5346 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5347 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5348 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5349 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5350 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5351 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5352 0x57,0x6c,0x0b,0x47,0xb8 };
5354 static void test_decodeCTL(DWORD dwEncoding)
5356 static char oid1[] = "1.2.3";
5357 static char oid2[] = "1.5.6";
5358 static BYTE nullData[] = { 5,0 };
5359 char *pOid1 = oid1;
5360 BOOL ret;
5361 BYTE *buf = NULL;
5362 DWORD size = 0;
5363 CTL_INFO info;
5364 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5365 CTL_ENTRY ctlEntry[2];
5366 CRYPT_ATTRIBUTE attr1, attr2;
5367 CRYPT_ATTR_BLOB value1, value2;
5369 memset(&info, 0, sizeof(info));
5370 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5371 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5372 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5373 if (buf)
5375 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5376 LocalFree(buf);
5377 buf = NULL;
5379 info.dwVersion = 1;
5380 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5381 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
5382 &size);
5383 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5384 if (buf)
5386 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5387 LocalFree(buf);
5388 buf = NULL;
5390 info.dwVersion = 0;
5391 info.SubjectUsage.cUsageIdentifier = 1;
5392 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5393 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5394 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5395 (BYTE *)&buf, &size);
5396 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5397 if (buf)
5399 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5400 LocalFree(buf);
5401 buf = NULL;
5403 info.SubjectUsage.cUsageIdentifier = 0;
5404 info.ListIdentifier.cbData = sizeof(serialNum);
5405 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5406 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5407 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5408 (BYTE *)&buf, &size);
5409 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5410 if (buf)
5412 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5413 LocalFree(buf);
5414 buf = NULL;
5416 info.ListIdentifier.cbData = 0;
5417 info.SequenceNumber.cbData = sizeof(serialNum);
5418 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5419 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5420 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL,
5421 (BYTE *)&buf, &size);
5422 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5423 if (buf)
5425 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5426 LocalFree(buf);
5427 buf = NULL;
5429 info.SequenceNumber.cbData = 0;
5430 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5431 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5432 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5433 (BYTE *)&buf, &size);
5434 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5435 if (buf)
5437 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5438 LocalFree(buf);
5439 buf = NULL;
5441 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5442 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5443 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5444 (BYTE *)&buf, &size);
5445 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5446 if (buf)
5448 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5449 LocalFree(buf);
5450 buf = NULL;
5452 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5453 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5454 info.SubjectAlgorithm.pszObjId = oid2;
5455 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5456 info.SubjectAlgorithm.Parameters.pbData = nullData;
5457 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5458 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL,
5459 (BYTE *)&buf, &size);
5460 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5461 if (buf)
5463 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5464 LocalFree(buf);
5465 buf = NULL;
5467 SetLastError(0xdeadbeef);
5468 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5469 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5470 (BYTE *)&buf, &size);
5471 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || CRYPT_E_ASN1_CORRUPT),
5472 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5473 GetLastError());
5474 info.SubjectAlgorithm.Parameters.cbData = 0;
5475 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5476 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5477 info.SubjectAlgorithm.pszObjId = oid2;
5478 info.SubjectAlgorithm.pszObjId = NULL;
5479 value1.cbData = sizeof(emptySequence);
5480 value1.pbData = (LPBYTE)emptySequence;
5481 attr1.pszObjId = oid1;
5482 attr1.cValue = 1;
5483 attr1.rgValue = &value1;
5484 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5485 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5486 ctlEntry[0].cAttribute = 1;
5487 ctlEntry[0].rgAttribute = &attr1;
5488 info.cCTLEntry = 1;
5489 info.rgCTLEntry = ctlEntry;
5490 SetLastError(0xdeadbeef);
5491 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5492 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5493 (BYTE *)&buf, &size);
5494 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5495 if (buf)
5497 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5498 LocalFree(buf);
5499 buf = NULL;
5501 value2.cbData = sizeof(encodedIPAddr);
5502 value2.pbData = (LPBYTE)encodedIPAddr;
5503 attr2.pszObjId = oid2;
5504 attr2.cValue = 1;
5505 attr2.rgValue = &value2;
5506 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5507 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5508 ctlEntry[1].cAttribute = 1;
5509 ctlEntry[1].rgAttribute = &attr2;
5510 info.cCTLEntry = 2;
5511 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5512 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL,
5513 (BYTE *)&buf, &size);
5514 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5515 if (buf)
5517 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5518 LocalFree(buf);
5519 buf = NULL;
5521 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5522 SetLastError(0xdeadbeef);
5523 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5524 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5525 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
5526 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
5527 SetLastError(0xdeadbeef);
5528 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5529 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5530 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5531 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
5532 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
5535 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5536 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5537 0x03,0,0,0,0,0,0 };
5538 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5539 0xa0,0x01,0x01 };
5540 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5541 0x03,0x02,0x01,0x01 };
5542 static BYTE bogusDER[] = { 1 };
5544 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5546 BOOL ret;
5547 BYTE *buf = NULL;
5548 DWORD size = 0;
5549 CRYPT_CONTENT_INFO info = { 0 };
5550 char oid1[] = "1.2.3";
5552 if (0)
5554 /* Crashes on win9x */
5555 SetLastError(0xdeadbeef);
5556 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5557 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5558 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5559 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5561 SetLastError(0xdeadbeef);
5562 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5563 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5564 ok(!ret && GetLastError() == E_INVALIDARG,
5565 "Expected E_INVALIDARG, got %x\n", GetLastError());
5566 info.pszObjId = oid1;
5567 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5568 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5569 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5570 if (buf)
5572 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5573 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5574 LocalFree(buf);
5576 info.Content.pbData = bogusDER;
5577 info.Content.cbData = sizeof(bogusDER);
5578 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5579 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5580 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5581 if (buf)
5583 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5584 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5585 LocalFree(buf);
5587 info.Content.pbData = (BYTE *)ints[0].encoded;
5588 info.Content.cbData = ints[0].encoded[1] + 2;
5589 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5590 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5591 if (buf)
5593 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5594 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5595 LocalFree(buf);
5599 static const BYTE indefiniteSignedPKCSContent[] = {
5600 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5601 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5602 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5603 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5604 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5605 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5606 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5607 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5608 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5609 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5610 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5611 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5612 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5613 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5614 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5615 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5616 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5617 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5618 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5619 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5620 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5621 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5622 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5623 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5624 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5625 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5626 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5627 0x00,0x00,0x00,0x00,0x00,0x00 };
5629 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5631 BOOL ret;
5632 LPBYTE buf = NULL;
5633 DWORD size = 0;
5634 CRYPT_CONTENT_INFO *info;
5636 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5637 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5638 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5639 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5640 if (buf)
5642 info = (CRYPT_CONTENT_INFO *)buf;
5644 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5645 info->pszObjId);
5646 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5647 info->Content.cbData);
5648 LocalFree(buf);
5650 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5651 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5652 0, NULL, NULL, &size);
5653 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5654 SetLastError(0xdeadbeef);
5655 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5656 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5657 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5658 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5659 * I doubt an app depends on that.
5661 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5662 GetLastError() == CRYPT_E_ASN1_CORRUPT),
5663 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5664 GetLastError());
5665 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5666 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5667 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5668 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5669 if (buf)
5671 info = (CRYPT_CONTENT_INFO *)buf;
5673 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5674 info->pszObjId);
5675 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5676 "Unexpected size %d\n", info->Content.cbData);
5677 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5678 info->Content.cbData), "Unexpected value\n");
5679 LocalFree(buf);
5681 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5682 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5683 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5684 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5685 if (buf)
5687 info = (CRYPT_CONTENT_INFO *)buf;
5689 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5690 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5691 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5692 info->Content.cbData);
5693 LocalFree(buf);
5697 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5698 0x00 };
5699 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5700 0x01 };
5701 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5702 0x02,0x01,0x01 };
5704 static void test_encodePKCSAttribute(DWORD dwEncoding)
5706 CRYPT_ATTRIBUTE attr = { 0 };
5707 BOOL ret;
5708 LPBYTE buf = NULL;
5709 DWORD size = 0;
5710 CRYPT_ATTR_BLOB blob;
5711 char oid[] = "1.2.3";
5713 if (0)
5715 /* Crashes on win9x */
5716 SetLastError(0xdeadbeef);
5717 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5718 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5719 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5720 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5722 SetLastError(0xdeadbeef);
5723 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5724 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5725 ok(!ret && GetLastError() == E_INVALIDARG,
5726 "Expected E_INVALIDARG, got %x\n", GetLastError());
5727 attr.pszObjId = oid;
5728 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5729 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5730 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5731 if (buf)
5733 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5734 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5735 LocalFree(buf);
5737 blob.cbData = sizeof(bogusDER);
5738 blob.pbData = bogusDER;
5739 attr.cValue = 1;
5740 attr.rgValue = &blob;
5741 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5742 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5743 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5744 if (buf)
5746 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
5747 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
5748 LocalFree(buf);
5750 blob.pbData = (BYTE *)ints[0].encoded;
5751 blob.cbData = ints[0].encoded[1] + 2;
5752 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5753 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5754 if (buf)
5756 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
5757 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
5758 LocalFree(buf);
5762 static void test_decodePKCSAttribute(DWORD dwEncoding)
5764 BOOL ret;
5765 LPBYTE buf = NULL;
5766 DWORD size = 0;
5767 CRYPT_ATTRIBUTE *attr;
5769 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5770 emptyPKCSAttr, sizeof(emptyPKCSAttr),
5771 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5772 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5773 if (buf)
5775 attr = (CRYPT_ATTRIBUTE *)buf;
5777 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5778 attr->pszObjId);
5779 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5780 LocalFree(buf);
5782 SetLastError(0xdeadbeef);
5783 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5784 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5785 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5786 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5787 * I doubt an app depends on that.
5789 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5790 GetLastError() == CRYPT_E_ASN1_CORRUPT),
5791 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5792 GetLastError());
5793 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5794 intPKCSAttr, sizeof(intPKCSAttr),
5795 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5796 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5797 if (buf)
5799 attr = (CRYPT_ATTRIBUTE *)buf;
5801 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5802 attr->pszObjId);
5803 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5804 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5805 "Unexpected size %d\n", attr->rgValue[0].cbData);
5806 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5807 attr->rgValue[0].cbData), "Unexpected value\n");
5808 LocalFree(buf);
5812 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5813 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5814 0x2a,0x03,0x31,0x00 };
5815 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5816 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5818 static void test_encodePKCSAttributes(DWORD dwEncoding)
5820 CRYPT_ATTRIBUTES attributes = { 0 };
5821 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5822 CRYPT_ATTR_BLOB blob;
5823 BOOL ret;
5824 LPBYTE buf = NULL;
5825 DWORD size = 0;
5826 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5828 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5829 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5830 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5831 if (buf)
5833 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5834 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5835 LocalFree(buf);
5837 attributes.cAttr = 1;
5838 attributes.rgAttr = attr;
5839 SetLastError(0xdeadbeef);
5840 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5841 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5842 ok(!ret && GetLastError() == E_INVALIDARG,
5843 "Expected E_INVALIDARG, got %x\n", GetLastError());
5844 attr[0].pszObjId = oid1;
5845 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5846 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5847 if (buf)
5849 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5850 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5851 LocalFree(buf);
5853 attr[1].pszObjId = oid2;
5854 attr[1].cValue = 1;
5855 attr[1].rgValue = &blob;
5856 blob.pbData = (BYTE *)ints[0].encoded;
5857 blob.cbData = ints[0].encoded[1] + 2;
5858 attributes.cAttr = 2;
5859 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5860 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5861 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5862 if (buf)
5864 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5865 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5866 LocalFree(buf);
5870 static void test_decodePKCSAttributes(DWORD dwEncoding)
5872 BOOL ret;
5873 LPBYTE buf = NULL;
5874 DWORD size = 0;
5875 CRYPT_ATTRIBUTES *attributes;
5877 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5878 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5879 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5880 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5881 if (buf)
5883 attributes = (CRYPT_ATTRIBUTES *)buf;
5884 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5885 attributes->cAttr);
5886 LocalFree(buf);
5888 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5889 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5890 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5891 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5892 if (buf)
5894 attributes = (CRYPT_ATTRIBUTES *)buf;
5895 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5896 attributes->cAttr);
5897 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5898 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5899 ok(attributes->rgAttr[0].cValue == 0,
5900 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5901 LocalFree(buf);
5903 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5904 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5905 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5906 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5907 if (buf)
5909 attributes = (CRYPT_ATTRIBUTES *)buf;
5910 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5911 attributes->cAttr);
5912 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5913 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5914 ok(attributes->rgAttr[0].cValue == 0,
5915 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5916 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5917 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5918 ok(attributes->rgAttr[1].cValue == 1,
5919 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5920 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5921 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5922 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5923 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5924 LocalFree(buf);
5928 static const BYTE singleCapability[] = {
5929 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
5930 static const BYTE twoCapabilities[] = {
5931 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
5932 static const BYTE singleCapabilitywithNULL[] = {
5933 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5935 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
5937 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
5938 BOOL ret;
5939 LPBYTE buf = NULL;
5940 DWORD size = 0;
5941 CRYPT_SMIME_CAPABILITY capability[2];
5942 CRYPT_SMIME_CAPABILITIES capabilities;
5944 /* An empty capabilities is allowed */
5945 capabilities.cCapability = 0;
5946 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5947 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5948 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5949 if (buf)
5951 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
5952 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5953 LocalFree(buf);
5955 /* A non-empty capabilities with an empty capability (lacking an OID) is
5956 * not allowed
5958 capability[0].pszObjId = NULL;
5959 capability[0].Parameters.cbData = 0;
5960 capabilities.cCapability = 1;
5961 capabilities.rgCapability = capability;
5962 SetLastError(0xdeadbeef);
5963 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5964 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5965 ok(!ret && GetLastError() == E_INVALIDARG,
5966 "expected E_INVALIDARG, got %08x\n", GetLastError());
5967 capability[0].pszObjId = oid1;
5968 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5969 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5970 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5971 if (buf)
5973 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
5974 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
5975 LocalFree(buf);
5977 capability[1].pszObjId = oid2;
5978 capability[1].Parameters.cbData = 0;
5979 capabilities.cCapability = 2;
5980 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5981 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5982 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5983 if (buf)
5985 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
5986 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
5987 LocalFree(buf);
5991 static void compareSMimeCapabilities(LPCSTR header,
5992 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
5994 DWORD i;
5996 ok(got->cCapability == expected->cCapability,
5997 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
5998 got->cCapability);
5999 for (i = 0; i < expected->cCapability; i++)
6001 ok(!strcmp(expected->rgCapability[i].pszObjId,
6002 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6003 header, i, expected->rgCapability[i].pszObjId,
6004 got->rgCapability[i].pszObjId);
6005 ok(expected->rgCapability[i].Parameters.cbData ==
6006 got->rgCapability[i].Parameters.cbData,
6007 "%s[%d]: expected %d bytes, got %d\n", header, i,
6008 expected->rgCapability[i].Parameters.cbData,
6009 got->rgCapability[i].Parameters.cbData);
6010 if (expected->rgCapability[i].Parameters.cbData)
6011 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6012 got->rgCapability[i].Parameters.pbData,
6013 expected->rgCapability[i].Parameters.cbData),
6014 "%s[%d]: unexpected value\n", header, i);
6018 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6020 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6021 BOOL ret;
6022 DWORD size = 0;
6023 CRYPT_SMIME_CAPABILITY capability[2];
6024 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6026 SetLastError(0xdeadbeef);
6027 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6028 emptySequence, sizeof(emptySequence),
6029 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6030 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6031 if (ret)
6033 capabilities.cCapability = 0;
6034 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6035 LocalFree(ptr);
6037 SetLastError(0xdeadbeef);
6038 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6039 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6040 (BYTE *)&ptr, &size);
6041 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6042 if (ret)
6044 capability[0].pszObjId = oid1;
6045 capability[0].Parameters.cbData = 0;
6046 capabilities.cCapability = 1;
6047 capabilities.rgCapability = capability;
6048 compareSMimeCapabilities("single capability", &capabilities, ptr);
6049 LocalFree(ptr);
6051 SetLastError(0xdeadbeef);
6052 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6053 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6054 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6055 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6056 if (ret)
6058 BYTE NULLparam[] = {0x05, 0x00};
6059 capability[0].pszObjId = oid1;
6060 capability[0].Parameters.cbData = 2;
6061 capability[0].Parameters.pbData = NULLparam;
6062 capabilities.cCapability = 1;
6063 capabilities.rgCapability = capability;
6064 compareSMimeCapabilities("single capability with NULL", &capabilities,
6065 ptr);
6066 LocalFree(ptr);
6068 SetLastError(0xdeadbeef);
6069 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6070 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6071 (BYTE *)&ptr, &size);
6072 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6073 if (ret)
6075 capability[0].Parameters.cbData = 0;
6076 capability[1].pszObjId = oid2;
6077 capability[1].Parameters.cbData = 0;
6078 capabilities.cCapability = 2;
6079 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6080 LocalFree(ptr);
6084 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6085 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6086 0x67 };
6087 static const BYTE minimalPKCSSigner[] = {
6088 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6089 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6090 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6091 static const BYTE PKCSSignerWithSerial[] = {
6092 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6093 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6094 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6095 0x00 };
6096 static const BYTE PKCSSignerWithHashAlgo[] = {
6097 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6098 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6099 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6100 0x00,0x04,0x00 };
6101 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6102 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6103 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6104 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6105 0x06,0x05,0x00,0x04,0x00 };
6106 static const BYTE PKCSSignerWithHash[] = {
6107 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6108 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6109 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6110 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6111 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6112 static const BYTE PKCSSignerWithAuthAttr[] = {
6113 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6114 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6115 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6116 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6117 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6118 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6119 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6121 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6123 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6124 BOOL ret;
6125 LPBYTE buf = NULL;
6126 DWORD size = 0;
6127 CMSG_SIGNER_INFO info = { 0 };
6128 char oid_common_name[] = szOID_COMMON_NAME;
6129 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6130 (LPBYTE)encodedCommonName };
6131 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6133 SetLastError(0xdeadbeef);
6134 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6135 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6136 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6138 skip("no PKCS7_SIGNER_INFO encode support\n");
6139 return;
6141 ok(!ret && GetLastError() == E_INVALIDARG,
6142 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6143 /* To be encoded, a signer must have an issuer at least, and the encoding
6144 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6145 * see decoding tests.)
6147 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6148 info.Issuer.pbData = encodedCommonNameNoNull;
6149 SetLastError(0xdeadbeef);
6150 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6151 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6152 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6153 ok(!ret && GetLastError() == E_INVALIDARG,
6154 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6155 else
6157 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6158 if (buf)
6160 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6161 if (size == sizeof(minimalPKCSSigner))
6162 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6163 else
6164 ok(0, "Unexpected value\n");
6165 LocalFree(buf);
6168 info.SerialNumber.cbData = sizeof(serialNum);
6169 info.SerialNumber.pbData = (BYTE *)serialNum;
6170 SetLastError(0xdeadbeef);
6171 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6172 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6173 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6174 ok(!ret && GetLastError() == E_INVALIDARG,
6175 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6176 else
6178 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6179 if (buf)
6181 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6182 size);
6183 if (size == sizeof(PKCSSignerWithSerial))
6184 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6185 "Unexpected value\n");
6186 else
6187 ok(0, "Unexpected value\n");
6188 LocalFree(buf);
6191 info.HashAlgorithm.pszObjId = oid1;
6192 SetLastError(0xdeadbeef);
6193 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6194 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6195 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6196 ok(!ret && GetLastError() == E_INVALIDARG,
6197 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6198 else
6200 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6201 if (buf)
6203 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6204 size);
6205 if (size == sizeof(PKCSSignerWithHashAlgo))
6206 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6207 "Unexpected value\n");
6208 else
6209 ok(0, "Unexpected value\n");
6210 LocalFree(buf);
6213 info.HashEncryptionAlgorithm.pszObjId = oid2;
6214 SetLastError(0xdeadbeef);
6215 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6216 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6217 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6218 ok(!ret && GetLastError() == E_INVALIDARG,
6219 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6220 else
6222 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6223 if (buf)
6225 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6226 "Unexpected size %d\n", size);
6227 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6228 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6229 "Unexpected value\n");
6230 else
6231 ok(0, "Unexpected value\n");
6232 LocalFree(buf);
6235 info.EncryptedHash.cbData = sizeof(hash);
6236 info.EncryptedHash.pbData = (BYTE *)hash;
6237 SetLastError(0xdeadbeef);
6238 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6239 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6240 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6241 ok(!ret && GetLastError() == E_INVALIDARG,
6242 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6243 else
6245 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6246 if (buf)
6248 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6249 size);
6250 if (size == sizeof(PKCSSignerWithHash))
6251 ok(!memcmp(buf, PKCSSignerWithHash, size),
6252 "Unexpected value\n");
6253 else
6254 ok(0, "Unexpected value\n");
6255 LocalFree(buf);
6258 info.AuthAttrs.cAttr = 1;
6259 info.AuthAttrs.rgAttr = &attr;
6260 SetLastError(0xdeadbeef);
6261 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6262 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6263 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6264 ok(!ret && GetLastError() == E_INVALIDARG,
6265 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6266 else
6268 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6269 if (buf)
6271 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6272 size);
6273 if (size == sizeof(PKCSSignerWithAuthAttr))
6274 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6275 "Unexpected value\n");
6276 else
6277 ok(0, "Unexpected value\n");
6278 LocalFree(buf);
6283 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6285 BOOL ret;
6286 LPBYTE buf = NULL;
6287 DWORD size = 0;
6288 CMSG_SIGNER_INFO *info;
6290 /* A PKCS signer can't be decoded without a serial number. */
6291 SetLastError(0xdeadbeef);
6292 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6293 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6294 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6295 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
6296 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6297 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6298 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6299 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6300 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6301 if (buf)
6303 info = (CMSG_SIGNER_INFO *)buf;
6304 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6305 info->dwVersion);
6306 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6307 "Unexpected size %d\n", info->Issuer.cbData);
6308 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6309 info->Issuer.cbData), "Unexpected value\n");
6310 ok(info->SerialNumber.cbData == sizeof(serialNum),
6311 "Unexpected size %d\n", info->SerialNumber.cbData);
6312 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6313 "Unexpected value\n");
6314 LocalFree(buf);
6316 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6317 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6318 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6319 if (buf)
6321 info = (CMSG_SIGNER_INFO *)buf;
6322 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6323 info->dwVersion);
6324 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6325 "Unexpected size %d\n", info->Issuer.cbData);
6326 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6327 info->Issuer.cbData), "Unexpected value\n");
6328 ok(info->SerialNumber.cbData == sizeof(serialNum),
6329 "Unexpected size %d\n", info->SerialNumber.cbData);
6330 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6331 "Unexpected value\n");
6332 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6333 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6334 LocalFree(buf);
6336 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6337 PKCSSignerWithHashAndEncryptionAlgo,
6338 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6339 NULL, (BYTE *)&buf, &size);
6340 if (buf)
6342 info = (CMSG_SIGNER_INFO *)buf;
6343 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6344 info->dwVersion);
6345 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6346 "Unexpected size %d\n", info->Issuer.cbData);
6347 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6348 info->Issuer.cbData), "Unexpected value\n");
6349 ok(info->SerialNumber.cbData == sizeof(serialNum),
6350 "Unexpected size %d\n", info->SerialNumber.cbData);
6351 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6352 "Unexpected value\n");
6353 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6354 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6355 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6356 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6357 LocalFree(buf);
6359 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6360 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6361 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6362 if (buf)
6364 info = (CMSG_SIGNER_INFO *)buf;
6365 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6366 info->dwVersion);
6367 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6368 "Unexpected size %d\n", info->Issuer.cbData);
6369 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6370 info->Issuer.cbData), "Unexpected value\n");
6371 ok(info->SerialNumber.cbData == sizeof(serialNum),
6372 "Unexpected size %d\n", info->SerialNumber.cbData);
6373 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6374 "Unexpected value\n");
6375 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6376 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6377 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6378 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6379 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6380 info->EncryptedHash.cbData);
6381 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6382 "Unexpected value\n");
6383 LocalFree(buf);
6385 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6386 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6387 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6388 if (buf)
6390 info = (CMSG_SIGNER_INFO *)buf;
6391 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6392 info->AuthAttrs.cAttr);
6393 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6394 "Expected %s, got %s\n", szOID_COMMON_NAME,
6395 info->AuthAttrs.rgAttr[0].pszObjId);
6396 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6397 info->AuthAttrs.rgAttr[0].cValue);
6398 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6399 sizeof(encodedCommonName), "Unexpected size %d\n",
6400 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6401 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6402 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6403 LocalFree(buf);
6407 static const BYTE CMSSignerWithKeyId[] = {
6408 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6409 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6411 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6413 BOOL ret;
6414 LPBYTE buf = NULL;
6415 DWORD size = 0;
6416 CMSG_CMS_SIGNER_INFO info = { 0 };
6417 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6419 SetLastError(0xdeadbeef);
6420 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6421 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6422 ok(!ret && GetLastError() == E_INVALIDARG,
6423 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6424 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6425 SetLastError(0xdeadbeef);
6426 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6427 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6428 ok(!ret, "Expected failure, got %d\n", ret);
6429 ok(GetLastError() == E_INVALIDARG,
6430 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6431 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6432 * be a key id or a issuer serial number with at least the issuer set, and
6433 * the encoding must include PKCS_7_ASN_ENCODING.
6434 * (That isn't enough to be decoded, see decoding tests.)
6436 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6437 sizeof(encodedCommonNameNoNull);
6438 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6439 SetLastError(0xdeadbeef);
6440 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6441 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6442 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6443 ok(!ret && GetLastError() == E_INVALIDARG,
6444 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6445 else
6447 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6448 if (buf)
6450 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6451 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6452 LocalFree(buf);
6455 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6456 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6457 SetLastError(0xdeadbeef);
6458 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6459 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6460 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6461 ok(!ret && GetLastError() == E_INVALIDARG,
6462 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6463 else
6465 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6466 if (buf)
6468 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6469 size);
6470 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6471 LocalFree(buf);
6474 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6475 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6476 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6477 SetLastError(0xdeadbeef);
6478 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6479 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6480 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6481 ok(!ret && GetLastError() == E_INVALIDARG,
6482 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6483 else
6485 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6486 if (buf)
6488 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6489 size);
6490 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6491 LocalFree(buf);
6494 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6495 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6496 * (see RFC 3852, section 5.3.)
6498 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6499 U(info.SignerId).HashId.cbData = sizeof(hash);
6500 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6501 SetLastError(0xdeadbeef);
6502 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6503 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6504 ok(!ret && GetLastError() == E_INVALIDARG,
6505 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6506 /* Now with a hash algo */
6507 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6508 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6509 sizeof(encodedCommonNameNoNull);
6510 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6511 info.HashAlgorithm.pszObjId = oid1;
6512 SetLastError(0xdeadbeef);
6513 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6514 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6515 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6516 ok(!ret && GetLastError() == E_INVALIDARG,
6517 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6518 else
6520 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6521 if (buf)
6523 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6524 size);
6525 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6526 "Unexpected value\n");
6527 LocalFree(buf);
6530 info.HashEncryptionAlgorithm.pszObjId = oid2;
6531 SetLastError(0xdeadbeef);
6532 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6533 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6534 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6535 ok(!ret && GetLastError() == E_INVALIDARG,
6536 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6537 else
6539 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6540 if (buf)
6542 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6543 "Unexpected size %d\n", size);
6544 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6545 "Unexpected value\n");
6546 LocalFree(buf);
6549 info.EncryptedHash.cbData = sizeof(hash);
6550 info.EncryptedHash.pbData = (BYTE *)hash;
6551 SetLastError(0xdeadbeef);
6552 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6553 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6554 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6555 ok(!ret && GetLastError() == E_INVALIDARG,
6556 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6557 else
6559 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6560 if (buf)
6562 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6563 size);
6564 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6565 LocalFree(buf);
6570 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6572 BOOL ret;
6573 LPBYTE buf = NULL;
6574 DWORD size = 0;
6575 CMSG_CMS_SIGNER_INFO *info;
6576 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6578 /* A CMS signer can't be decoded without a serial number. */
6579 SetLastError(0xdeadbeef);
6580 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6581 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6582 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6583 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
6584 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6585 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6586 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6587 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6588 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6589 if (buf)
6591 info = (CMSG_CMS_SIGNER_INFO *)buf;
6592 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6593 info->dwVersion);
6594 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6595 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6596 info->SignerId.dwIdChoice);
6597 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6598 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6599 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6600 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6601 encodedCommonNameNoNull,
6602 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6603 "Unexpected value\n");
6604 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6605 sizeof(serialNum), "Unexpected size %d\n",
6606 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6607 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6608 serialNum, sizeof(serialNum)), "Unexpected value\n");
6609 LocalFree(buf);
6611 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6612 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6613 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6614 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6615 if (buf)
6617 info = (CMSG_CMS_SIGNER_INFO *)buf;
6618 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6619 info->dwVersion);
6620 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6621 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6622 info->SignerId.dwIdChoice);
6623 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6624 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6625 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6626 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6627 encodedCommonNameNoNull,
6628 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6629 "Unexpected value\n");
6630 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6631 sizeof(serialNum), "Unexpected size %d\n",
6632 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6633 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6634 serialNum, sizeof(serialNum)), "Unexpected value\n");
6635 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6636 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6637 LocalFree(buf);
6639 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6640 PKCSSignerWithHashAndEncryptionAlgo,
6641 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6642 NULL, (BYTE *)&buf, &size);
6643 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6644 if (buf)
6646 info = (CMSG_CMS_SIGNER_INFO *)buf;
6647 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6648 info->dwVersion);
6649 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6650 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6651 info->SignerId.dwIdChoice);
6652 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6653 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6654 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6655 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6656 encodedCommonNameNoNull,
6657 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6658 "Unexpected value\n");
6659 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6660 sizeof(serialNum), "Unexpected size %d\n",
6661 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6662 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6663 serialNum, sizeof(serialNum)), "Unexpected value\n");
6664 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6665 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6666 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6667 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6668 LocalFree(buf);
6670 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6671 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6672 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6673 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6674 if (buf)
6676 info = (CMSG_CMS_SIGNER_INFO *)buf;
6677 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6678 info->dwVersion);
6679 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6680 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6681 info->SignerId.dwIdChoice);
6682 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6683 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6684 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6685 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6686 encodedCommonNameNoNull,
6687 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6688 "Unexpected value\n");
6689 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6690 sizeof(serialNum), "Unexpected size %d\n",
6691 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6692 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6693 serialNum, sizeof(serialNum)), "Unexpected value\n");
6694 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6695 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6696 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6697 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6698 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6699 info->EncryptedHash.cbData);
6700 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6701 "Unexpected value\n");
6702 LocalFree(buf);
6704 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6705 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6706 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6707 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6708 if (buf)
6710 info = (CMSG_CMS_SIGNER_INFO *)buf;
6711 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6712 info->dwVersion);
6713 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6714 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6715 info->SignerId.dwIdChoice);
6716 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6717 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6718 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
6719 "Unexpected value\n");
6720 LocalFree(buf);
6724 static BYTE emptyDNSPermittedConstraints[] = {
6725 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6726 static BYTE emptyDNSExcludedConstraints[] = {
6727 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6728 static BYTE DNSExcludedConstraints[] = {
6729 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
6730 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6731 static BYTE permittedAndExcludedConstraints[] = {
6732 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6733 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
6734 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6735 static BYTE permittedAndExcludedWithMinConstraints[] = {
6736 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6737 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
6738 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6739 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
6740 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6741 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
6742 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6744 static void test_encodeNameConstraints(DWORD dwEncoding)
6746 BOOL ret;
6747 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
6748 CERT_GENERAL_SUBTREE permitted = { { 0 } };
6749 CERT_GENERAL_SUBTREE excluded = { { 0 } };
6750 LPBYTE buf;
6751 DWORD size;
6753 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6754 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6755 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6757 skip("no X509_NAME_CONSTRAINTS encode support\n");
6758 return;
6760 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6761 if (ret)
6763 ok(size == sizeof(emptySequence), "Unexpected size\n");
6764 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
6765 LocalFree(buf);
6767 constraints.cPermittedSubtree = 1;
6768 constraints.rgPermittedSubtree = &permitted;
6769 SetLastError(0xdeadbeef);
6770 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6771 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6772 ok(!ret && GetLastError() == E_INVALIDARG,
6773 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6774 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6775 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6776 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6777 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6778 if (ret)
6780 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
6781 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
6782 "Unexpected value\n");
6783 LocalFree(buf);
6785 constraints.cPermittedSubtree = 0;
6786 constraints.cExcludedSubtree = 1;
6787 constraints.rgExcludedSubtree = &excluded;
6788 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6789 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6790 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6791 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6792 if (ret)
6794 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
6795 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
6796 "Unexpected value\n");
6797 LocalFree(buf);
6799 U(excluded.Base).pwszURL = (LPWSTR)url;
6800 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6801 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6802 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6803 if (ret)
6805 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
6806 ok(!memcmp(buf, DNSExcludedConstraints, size),
6807 "Unexpected value\n");
6808 LocalFree(buf);
6810 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
6811 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6812 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6813 constraints.cPermittedSubtree = 1;
6814 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6815 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6816 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6817 if (ret)
6819 ok(size == sizeof(permittedAndExcludedConstraints),
6820 "Unexpected size\n");
6821 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
6822 "Unexpected value\n");
6823 LocalFree(buf);
6825 permitted.dwMinimum = 5;
6826 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6827 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6828 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6829 if (ret)
6831 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
6832 "Unexpected size\n");
6833 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
6834 "Unexpected value\n");
6835 LocalFree(buf);
6837 permitted.fMaximum = TRUE;
6838 permitted.dwMaximum = 3;
6839 SetLastError(0xdeadbeef);
6840 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6841 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6842 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6843 if (ret)
6845 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
6846 "Unexpected size\n");
6847 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
6848 "Unexpected value\n");
6849 LocalFree(buf);
6853 struct EncodedNameConstraints
6855 CRYPT_DATA_BLOB encoded;
6856 CERT_NAME_CONSTRAINTS_INFO constraints;
6859 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
6860 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6861 static CERT_GENERAL_SUBTREE DNSSubtree = {
6862 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6863 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
6864 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
6865 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
6866 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
6867 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
6868 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
6870 struct EncodedNameConstraints encodedNameConstraints[] = {
6871 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
6872 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
6873 { 1, &emptyDNSSubtree, 0, NULL } },
6874 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
6875 { 0, NULL, 1, &emptyDNSSubtree } },
6876 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
6877 { 0, NULL, 1, &DNSSubtree } },
6878 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
6879 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
6880 { { sizeof(permittedAndExcludedWithMinConstraints),
6881 permittedAndExcludedWithMinConstraints },
6882 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
6883 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
6884 permittedAndExcludedWithMinMaxConstraints },
6885 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
6888 static void test_decodeNameConstraints(DWORD dwEncoding)
6890 BOOL ret;
6891 DWORD i;
6892 CERT_NAME_CONSTRAINTS_INFO *constraints;
6894 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
6895 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6896 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6897 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6898 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6899 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6900 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6901 for (i = 0;
6902 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
6903 i++)
6905 DWORD size;
6907 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
6908 encodedNameConstraints[i].encoded.pbData,
6909 encodedNameConstraints[i].encoded.cbData,
6910 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
6911 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6913 skip("no X509_NAME_CONSTRAINTS decode support\n");
6914 return;
6916 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
6917 if (ret)
6919 DWORD j;
6921 if (constraints->cPermittedSubtree !=
6922 encodedNameConstraints[i].constraints.cPermittedSubtree)
6923 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
6924 encodedNameConstraints[i].constraints.cPermittedSubtree,
6925 constraints->cPermittedSubtree);
6926 if (constraints->cPermittedSubtree ==
6927 encodedNameConstraints[i].constraints.cPermittedSubtree)
6929 for (j = 0; j < constraints->cPermittedSubtree; j++)
6931 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
6932 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
6935 if (constraints->cExcludedSubtree !=
6936 encodedNameConstraints[i].constraints.cExcludedSubtree)
6937 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
6938 encodedNameConstraints[i].constraints.cExcludedSubtree,
6939 constraints->cExcludedSubtree);
6940 if (constraints->cExcludedSubtree ==
6941 encodedNameConstraints[i].constraints.cExcludedSubtree)
6943 for (j = 0; j < constraints->cExcludedSubtree; j++)
6945 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
6946 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
6949 LocalFree(constraints);
6954 /* Free *pInfo with HeapFree */
6955 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
6957 BOOL ret;
6958 DWORD size = 0;
6959 HCRYPTKEY key;
6961 /* This crashes
6962 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
6964 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
6965 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6966 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6967 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
6968 &size);
6969 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6970 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6971 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
6972 NULL, &size);
6973 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6974 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6975 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
6976 0, NULL, NULL, &size);
6977 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6978 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6979 /* Test with no key */
6980 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
6981 0, NULL, NULL, &size);
6982 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
6983 GetLastError());
6984 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
6985 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
6986 if (ret)
6988 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
6989 NULL, 0, NULL, NULL, &size);
6990 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
6991 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
6992 if (*pInfo)
6994 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
6995 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
6996 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
6997 GetLastError());
6998 if (ret)
7000 /* By default (we passed NULL as the OID) the OID is
7001 * szOID_RSA_RSA.
7003 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7004 "Expected %s, got %s\n", szOID_RSA_RSA,
7005 (*pInfo)->Algorithm.pszObjId);
7009 CryptDestroyKey(key);
7012 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7013 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7014 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7015 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7016 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7017 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7018 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7019 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7020 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7021 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7022 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7023 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7024 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7025 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7026 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7027 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7028 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7029 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7030 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7031 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7032 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7033 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7034 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7035 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7036 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7038 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7040 BOOL ret;
7041 HCRYPTKEY key;
7042 PCCERT_CONTEXT context;
7043 DWORD dwSize;
7044 ALG_ID ai;
7046 /* These crash
7047 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7048 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7049 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7050 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7051 NULL);
7053 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7054 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7055 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7056 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7057 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7058 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7059 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7060 &key);
7061 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7062 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7064 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7065 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7066 &key);
7067 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7069 dwSize = sizeof(ai);
7070 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7071 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7072 if(ret)
7074 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7075 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7078 CryptDestroyKey(key);
7080 /* Repeat with forced algorithm */
7081 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7082 &key);
7083 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7085 dwSize = sizeof(ai);
7086 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7087 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7088 if(ret)
7090 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7091 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7094 CryptDestroyKey(key);
7096 /* Test importing a public key from a certificate context */
7097 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7098 sizeof(expiredCert));
7099 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7100 GetLastError());
7101 if (context)
7103 ok(!strcmp(szOID_RSA_RSA,
7104 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7105 "Expected %s, got %s\n", szOID_RSA_RSA,
7106 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7107 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7108 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7109 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7110 CryptDestroyKey(key);
7111 CertFreeCertificateContext(context);
7115 static const char cspName[] = "WineCryptTemp";
7117 static void testPortPublicKeyInfo(void)
7119 HCRYPTPROV csp;
7120 BOOL ret;
7121 PCERT_PUBLIC_KEY_INFO info = NULL;
7123 /* Just in case a previous run failed, delete this thing */
7124 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7125 CRYPT_DELETEKEYSET);
7126 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7127 CRYPT_NEWKEYSET);
7129 testExportPublicKey(csp, &info);
7130 testImportPublicKey(csp, info);
7132 HeapFree(GetProcessHeap(), 0, info);
7133 CryptReleaseContext(csp, 0);
7134 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7135 CRYPT_DELETEKEYSET);
7138 START_TEST(encode)
7140 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7141 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7142 HMODULE hCrypt32;
7143 DWORD i;
7145 hCrypt32 = GetModuleHandleA("crypt32.dll");
7146 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7147 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7148 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7150 skip("CryptDecodeObjectEx() is not available\n");
7151 return;
7154 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7156 test_encodeInt(encodings[i]);
7157 test_decodeInt(encodings[i]);
7158 test_encodeEnumerated(encodings[i]);
7159 test_decodeEnumerated(encodings[i]);
7160 test_encodeFiletime(encodings[i]);
7161 test_decodeFiletime(encodings[i]);
7162 test_encodeName(encodings[i]);
7163 test_decodeName(encodings[i]);
7164 test_encodeUnicodeName(encodings[i]);
7165 test_decodeUnicodeName(encodings[i]);
7166 test_encodeNameValue(encodings[i]);
7167 test_decodeNameValue(encodings[i]);
7168 test_encodeUnicodeNameValue(encodings[i]);
7169 test_decodeUnicodeNameValue(encodings[i]);
7170 test_encodeAltName(encodings[i]);
7171 test_decodeAltName(encodings[i]);
7172 test_encodeOctets(encodings[i]);
7173 test_decodeOctets(encodings[i]);
7174 test_encodeBits(encodings[i]);
7175 test_decodeBits(encodings[i]);
7176 test_encodeBasicConstraints(encodings[i]);
7177 test_decodeBasicConstraints(encodings[i]);
7178 test_encodeRsaPublicKey(encodings[i]);
7179 test_decodeRsaPublicKey(encodings[i]);
7180 test_encodeSequenceOfAny(encodings[i]);
7181 test_decodeSequenceOfAny(encodings[i]);
7182 test_encodeExtensions(encodings[i]);
7183 test_decodeExtensions(encodings[i]);
7184 test_encodePublicKeyInfo(encodings[i]);
7185 test_decodePublicKeyInfo(encodings[i]);
7186 test_encodeCertToBeSigned(encodings[i]);
7187 test_decodeCertToBeSigned(encodings[i]);
7188 test_encodeCert(encodings[i]);
7189 test_decodeCert(encodings[i]);
7190 test_encodeCRLDistPoints(encodings[i]);
7191 test_decodeCRLDistPoints(encodings[i]);
7192 test_encodeCRLIssuingDistPoint(encodings[i]);
7193 test_decodeCRLIssuingDistPoint(encodings[i]);
7194 test_encodeCRLToBeSigned(encodings[i]);
7195 test_decodeCRLToBeSigned(encodings[i]);
7196 test_encodeEnhancedKeyUsage(encodings[i]);
7197 test_decodeEnhancedKeyUsage(encodings[i]);
7198 test_encodeAuthorityKeyId(encodings[i]);
7199 test_decodeAuthorityKeyId(encodings[i]);
7200 test_encodeAuthorityKeyId2(encodings[i]);
7201 test_decodeAuthorityKeyId2(encodings[i]);
7202 test_encodeAuthorityInfoAccess(encodings[i]);
7203 test_decodeAuthorityInfoAccess(encodings[i]);
7204 test_encodeCTL(encodings[i]);
7205 test_decodeCTL(encodings[i]);
7206 test_encodePKCSContentInfo(encodings[i]);
7207 test_decodePKCSContentInfo(encodings[i]);
7208 test_encodePKCSAttribute(encodings[i]);
7209 test_decodePKCSAttribute(encodings[i]);
7210 test_encodePKCSAttributes(encodings[i]);
7211 test_decodePKCSAttributes(encodings[i]);
7212 test_encodePKCSSMimeCapabilities(encodings[i]);
7213 test_decodePKCSSMimeCapabilities(encodings[i]);
7214 test_encodePKCSSignerInfo(encodings[i]);
7215 test_decodePKCSSignerInfo(encodings[i]);
7216 test_encodeCMSSignerInfo(encodings[i]);
7217 test_decodeCMSSignerInfo(encodings[i]);
7218 test_encodeNameConstraints(encodings[i]);
7219 test_decodeNameConstraints(encodings[i]);
7221 testPortPublicKeyInfo();