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
27 #include "wine/test.h"
35 static const BYTE bin1[] = {0x02,0x01,0x01};
36 static const BYTE bin2[] = {0x02,0x01,0x7f};
37 static const BYTE bin3[] = {0x02,0x02,0x00,0x80};
38 static const BYTE bin4[] = {0x02,0x02,0x01,0x00};
39 static const BYTE bin5[] = {0x02,0x01,0x80};
40 static const BYTE bin6[] = {0x02,0x02,0xff,0x7f};
41 static const BYTE bin7[] = {0x02,0x04,0xba,0xdd,0xf0,0x0d};
43 static const struct encodedInt ints[] = {
60 static const BYTE bin8[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
61 static const BYTE bin9[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
62 static const BYTE bin10[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
64 static const BYTE bin11[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
65 static const BYTE bin12[] = {0x02,0x09,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
66 static const BYTE bin13[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0};
68 static const struct encodedBigInt bigInts[] = {
69 { bin8, bin9, bin10 },
70 { bin11, bin12, bin13 },
73 static const BYTE bin14[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
74 static const BYTE bin15[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
75 static const BYTE bin16[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
76 static const BYTE bin17[] = {0x02,0x0c,0x00,0xff,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
78 /* Decoded is the same as original, so don't bother storing a separate copy */
79 static const struct encodedBigInt bigUInts[] = {
80 { bin14, bin15, NULL },
81 { bin16, bin17, NULL },
84 static void test_encodeInt(DWORD dwEncoding)
89 CRYPT_INTEGER_BLOB blob;
92 /* CryptEncodeObjectEx with NULL bufSize crashes..
93 ret = CryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
96 /* check bogus encoding */
97 ret = CryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
99 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
100 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
101 /* check with NULL integer buffer. Windows XP incorrectly returns an
104 ret = CryptEncodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, NULL, NULL,
106 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
107 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
108 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
110 /* encode as normal integer */
111 ret = CryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 0,
112 NULL, NULL, &bufSize);
113 ok(ret, "Expected success, got %d\n", GetLastError());
114 ret = CryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val,
115 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
116 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
119 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
121 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
122 buf[1], ints[i].encoded[1]);
123 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
124 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
127 /* encode as multibyte integer */
128 blob.cbData = sizeof(ints[i].val);
129 blob.pbData = (BYTE *)&ints[i].val;
130 ret = CryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
131 0, NULL, NULL, &bufSize);
132 ok(ret, "Expected success, got %d\n", GetLastError());
133 ret = CryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
134 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
135 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
138 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
140 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
141 buf[1], ints[i].encoded[1]);
142 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
143 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
147 /* encode a couple bigger ints, just to show it's little-endian and leading
148 * sign bytes are dropped
150 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
152 blob.cbData = strlen((const char*)bigInts[i].val);
153 blob.pbData = (BYTE *)bigInts[i].val;
154 ret = CryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
155 0, NULL, NULL, &bufSize);
156 ok(ret, "Expected success, got %d\n", GetLastError());
157 ret = CryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
158 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
159 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
162 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
164 ok(buf[1] == bigInts[i].encoded[1], "Got length %d, expected %d\n",
165 buf[1], bigInts[i].encoded[1]);
166 ok(!memcmp(buf + 1, bigInts[i].encoded + 1,
167 bigInts[i].encoded[1] + 1),
168 "Encoded value didn't match expected\n");
172 /* and, encode some uints */
173 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
175 blob.cbData = strlen((const char*)bigUInts[i].val);
176 blob.pbData = (BYTE*)bigUInts[i].val;
177 ret = CryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
178 0, NULL, NULL, &bufSize);
179 ok(ret, "Expected success, got %d\n", GetLastError());
180 ret = CryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
181 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
182 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
185 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
187 ok(buf[1] == bigUInts[i].encoded[1], "Got length %d, expected %d\n",
188 buf[1], bigUInts[i].encoded[1]);
189 ok(!memcmp(buf + 1, bigUInts[i].encoded + 1,
190 bigUInts[i].encoded[1] + 1),
191 "Encoded value didn't match expected\n");
197 static void test_decodeInt(DWORD dwEncoding)
199 static const BYTE bigInt[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff };
200 static const BYTE testStr[] = { 0x16, 4, 't', 'e', 's', 't' };
201 static const BYTE longForm[] = { 2, 0x81, 0x01, 0x01 };
202 static const BYTE bigBogus[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 };
203 static const BYTE extraBytes[] = { 2, 1, 1, 0, 0, 0, 0 };
209 /* CryptDecodeObjectEx with NULL bufSize crashes..
210 ret = CryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded,
211 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
213 /* check bogus encoding */
214 ret = CryptDecodeObjectEx(3, X509_INTEGER, (BYTE *)&ints[0].encoded,
215 ints[0].encoded[1] + 2, 0, NULL, NULL, &bufSize);
216 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
217 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
218 /* check with NULL integer buffer */
219 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, 0, NULL, NULL,
221 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
222 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
223 /* check with a valid, but too large, integer */
224 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER, bigInt, bigInt[1] + 2,
225 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
226 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
227 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
228 /* check with a DER-encoded string */
229 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER, testStr, testStr[1] + 2,
230 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
231 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
232 "Expected CRYPT_E_ASN1_BADTAG, got %d\n", GetLastError());
233 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
235 /* When the output buffer is NULL, this always succeeds */
236 SetLastError(0xdeadbeef);
237 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER,
238 ints[i].encoded, ints[i].encoded[1] + 2, 0, NULL, NULL,
240 ok(ret && GetLastError() == NOERROR,
241 "Expected success and NOERROR, got %d\n", GetLastError());
242 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER,
243 ints[i].encoded, ints[i].encoded[1] + 2,
244 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
245 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
246 ok(bufSize == sizeof(int), "Wrong size %d\n", bufSize);
247 ok(buf != NULL, "Expected allocated buffer\n");
250 ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n",
251 ints[i].val, *(int *)buf);
255 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
257 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
258 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 0, NULL, NULL,
260 ok(ret && GetLastError() == NOERROR,
261 "Expected success and NOERROR, got %d\n", GetLastError());
262 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
263 bigInts[i].encoded, bigInts[i].encoded[1] + 2,
264 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
265 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
266 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
267 ok(buf != NULL, "Expected allocated buffer\n");
270 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
272 ok(blob->cbData == strlen((const char*)bigInts[i].decoded),
273 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts[i].decoded),
275 ok(!memcmp(blob->pbData, bigInts[i].decoded, blob->cbData),
276 "Unexpected value\n");
280 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
282 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
283 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 0, NULL, NULL,
285 ok(ret && GetLastError() == NOERROR,
286 "Expected success and NOERROR, got %d\n", GetLastError());
287 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
288 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2,
289 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
290 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
291 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
292 ok(buf != NULL, "Expected allocated buffer\n");
295 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
297 ok(blob->cbData == strlen((const char*)bigUInts[i].val),
298 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts[i].val),
300 ok(!memcmp(blob->pbData, bigUInts[i].val, blob->cbData),
301 "Unexpected value\n");
305 /* Decode the value 1 with long-form length */
306 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, longForm,
307 sizeof(longForm), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
308 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
311 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
314 /* check with extra bytes at the end */
315 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER, extraBytes,
316 sizeof(extraBytes), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
317 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
320 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
323 /* Try to decode some bogus large items */
324 /* The buffer size is smaller than the encoded length, so this should fail
325 * with CRYPT_E_ASN1_EOD if it's being decoded.
326 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit
327 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes.
328 * So this test unfortunately isn't useful.
329 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig,
330 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
331 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
332 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
334 /* This will try to decode the buffer and overflow it, check that it's
339 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
340 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, bigBogus,
341 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
342 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
343 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
347 static const BYTE bin18[] = {0x0a,0x01,0x01};
348 static const BYTE bin19[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
350 /* These are always encoded unsigned, and aren't constrained to be any
353 static const struct encodedInt enums[] = {
358 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
361 static const LPCSTR enumeratedTypes[] = { X509_ENUMERATED,
362 szOID_CRL_REASON_CODE };
364 static void test_encodeEnumerated(DWORD dwEncoding)
368 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
370 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
376 ret = CryptEncodeObjectEx(dwEncoding, enumeratedTypes[i],
377 &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
379 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
383 "Got unexpected type %d for enumerated (expected 0xa)\n",
385 ok(buf[1] == enums[j].encoded[1],
386 "Got length %d, expected %d\n", buf[1], enums[j].encoded[1]);
387 ok(!memcmp(buf + 1, enums[j].encoded + 1,
388 enums[j].encoded[1] + 1),
389 "Encoded value of 0x%08x didn't match expected\n",
397 static void test_decodeEnumerated(DWORD dwEncoding)
401 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
403 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
406 DWORD bufSize = sizeof(int);
409 ret = CryptDecodeObjectEx(dwEncoding, enumeratedTypes[i],
410 enums[j].encoded, enums[j].encoded[1] + 2, 0, NULL,
411 (BYTE *)&val, &bufSize);
412 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
413 ok(bufSize == sizeof(int),
414 "Got unexpected size %d for enumerated\n", bufSize);
415 ok(val == enums[j].val, "Unexpected value %d, expected %d\n",
421 struct encodedFiletime
424 const BYTE *encodedTime;
427 static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType,
428 const struct encodedFiletime *time)
435 ret = SystemTimeToFileTime(&time->sysTime, &ft);
436 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
437 ret = CryptEncodeObjectEx(dwEncoding, structType, &ft,
438 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
439 /* years other than 1950-2050 are not allowed for encodings other than
440 * X509_CHOICE_OF_TIME.
442 if (structType == X509_CHOICE_OF_TIME ||
443 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
445 ok(ret, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
447 ok(buf != NULL, "Expected an allocated buffer\n");
450 ok(buf[0] == time->encodedTime[0],
451 "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0],
453 ok(buf[1] == time->encodedTime[1], "Expected %d bytes, got %d\n",
454 time->encodedTime[1], bufSize);
455 ok(!memcmp(time->encodedTime + 2, buf + 2, time->encodedTime[1]),
456 "Got unexpected value for time encoding\n");
461 ok(!ret && GetLastError() == CRYPT_E_BAD_ENCODE,
462 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
465 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
466 const struct encodedFiletime *time)
468 FILETIME ft1 = { 0 }, ft2 = { 0 };
469 DWORD size = sizeof(ft2);
472 ret = SystemTimeToFileTime(&time->sysTime, &ft1);
473 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
474 ret = CryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
475 time->encodedTime[1] + 2, 0, NULL, &ft2, &size);
476 /* years other than 1950-2050 are not allowed for encodings other than
477 * X509_CHOICE_OF_TIME.
479 if (structType == X509_CHOICE_OF_TIME ||
480 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
482 ok(ret, "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
484 ok(!memcmp(&ft1, &ft2, sizeof(ft1)),
485 "Got unexpected value for time decoding\n");
488 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
489 "Expected CRYPT_E_ASN1_BADTAG, got 0x%08x\n", GetLastError());
492 static const BYTE bin20[] = {
493 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
494 static const BYTE bin21[] = {
495 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
496 static const BYTE bin22[] = {
497 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
499 static const struct encodedFiletime times[] = {
500 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
501 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
502 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
505 static void test_encodeFiletime(DWORD dwEncoding)
509 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
511 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]);
512 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, ×[i]);
513 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, ×[i]);
517 static const BYTE bin23[] = {
518 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
519 static const BYTE bin24[] = {
520 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
521 static const BYTE bin25[] = {
522 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
523 static const BYTE bin26[] = {
524 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
525 static const BYTE bin27[] = {
526 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
527 static const BYTE bin28[] = {
528 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
529 static const BYTE bin29[] = {
530 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
531 static const BYTE bin30[] = {
532 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
533 static const BYTE bin31[] = {
534 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
535 static const BYTE bin32[] = {
536 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
537 static const BYTE bin33[] = {
538 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
539 static const BYTE bin34[] = {
540 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
541 static const BYTE bin35[] = {
542 0x17,0x08, '4','5','0','6','0','6','1','6'};
543 static const BYTE bin36[] = {
544 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
545 static const BYTE bin37[] = {
546 0x18,0x04, '2','1','4','5'};
547 static const BYTE bin38[] = {
548 0x18,0x08, '2','1','4','5','0','6','0','6'};
550 static void test_decodeFiletime(DWORD dwEncoding)
552 static const struct encodedFiletime otherTimes[] = {
553 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
554 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
555 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
556 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
557 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
558 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
559 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
560 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
561 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
562 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
563 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
564 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
566 /* An oddball case that succeeds in Windows, but doesn't seem correct
567 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
569 static const unsigned char *bogusTimes[] = {
570 /* oddly, this succeeds on Windows, with year 2765
571 "\x18" "\x0f" "21r50606161000Z",
579 FILETIME ft1 = { 0 }, ft2 = { 0 };
582 /* Check bogus length with non-NULL buffer */
583 ret = SystemTimeToFileTime(×[0].sysTime, &ft1);
584 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
586 ret = CryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
587 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
588 ok(!ret && GetLastError() == ERROR_MORE_DATA,
589 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
591 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
593 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]);
594 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, ×[i]);
595 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, ×[i]);
597 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
599 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
600 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
601 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
603 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
606 ret = CryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
607 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
608 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
609 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
613 static const char commonName[] = "Juan Lang";
614 static const char surName[] = "Lang";
616 static const BYTE emptySequence[] = { 0x30, 0 };
617 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
618 static const BYTE twoRDNs[] = {
619 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
620 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
621 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
622 static const BYTE encodedTwoRDNs[] = {
623 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
624 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
625 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
629 static const BYTE us[] = { 0x55, 0x53 };
630 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
632 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
633 0x6f, 0x6c, 0x69, 0x73 };
634 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
635 0x76, 0x65, 0x72, 0x73 };
636 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
637 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
638 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
640 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
641 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
643 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
644 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
646 static CHAR oid_us[] = "2.5.4.6",
647 oid_minnesota[] = "2.5.4.8",
648 oid_minneapolis[] = "2.5.4.7",
649 oid_codeweavers[] = "2.5.4.10",
650 oid_wine[] = "2.5.4.11",
651 oid_localhostAttr[] = "2.5.4.3",
652 oid_aric[] = "1.2.840.113549.1.9.1";
653 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
655 { RDNA(minneapolis) },
656 { RDNA(codeweavers) },
658 { RDNA(localhostAttr) },
660 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
661 { RDNA(localhostAttr) },
663 { RDNA(minneapolis) },
664 { RDNA(codeweavers) },
671 static const BYTE encodedRDNAttrs[] = {
672 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
673 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
674 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
675 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
676 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
677 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
678 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
679 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
680 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
681 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
684 static void test_encodeName(DWORD dwEncoding)
686 CERT_RDN_ATTR attrs[2];
689 static CHAR oid_common_name[] = szOID_COMMON_NAME,
690 oid_sur_name[] = szOID_SUR_NAME;
695 /* Test with NULL pvStructInfo */
696 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
697 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
698 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
699 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
700 /* Test with empty CERT_NAME_INFO */
703 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
704 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
705 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
708 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
709 "Got unexpected encoding for empty name\n");
712 /* Test with bogus CERT_RDN */
714 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
715 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
716 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
717 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
718 /* Test with empty CERT_RDN */
720 rdn.rgRDNAttr = NULL;
723 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
724 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
725 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
728 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
729 "Got unexpected encoding for empty RDN array\n");
732 /* Test with bogus attr array */
734 rdn.rgRDNAttr = NULL;
735 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
736 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
737 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
738 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
739 /* oddly, a bogus OID is accepted by Windows XP; not testing.
740 attrs[0].pszObjId = "bogus";
741 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
742 attrs[0].Value.cbData = sizeof(commonName);
743 attrs[0].Value.pbData = (BYTE *)commonName;
745 rdn.rgRDNAttr = attrs;
746 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
747 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
748 ok(!ret, "Expected failure, got success\n");
750 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
751 * the encoded attributes to be swapped.
753 attrs[0].pszObjId = oid_common_name;
754 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
755 attrs[0].Value.cbData = sizeof(commonName);
756 attrs[0].Value.pbData = (BYTE *)commonName;
757 attrs[1].pszObjId = oid_sur_name;
758 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
759 attrs[1].Value.cbData = sizeof(surName);
760 attrs[1].Value.pbData = (BYTE *)surName;
762 rdn.rgRDNAttr = attrs;
763 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
764 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
765 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
768 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
769 "Got unexpected encoding for two RDN array\n");
772 /* A name can be "encoded" with previously encoded RDN attrs. */
773 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
774 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
775 attrs[0].Value.cbData = sizeof(twoRDNs);
777 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
778 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
779 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
782 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
783 ok(!memcmp(buf, encodedTwoRDNs, size),
784 "Unexpected value for re-endoded two RDN array\n");
787 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
789 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
790 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
791 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
792 ok(!ret && GetLastError() == E_INVALIDARG,
793 "Expected E_INVALIDARG, got %08x\n", GetLastError());
794 /* Test a more complex name */
795 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
796 rdn.rgRDNAttr = (PCERT_RDN_ATTR)rdnAttrs;
801 ret = CryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
802 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
803 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
806 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
807 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
812 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
813 static WCHAR surNameW[] = { 'L','a','n','g',0 };
815 static const BYTE twoRDNsNoNull[] = {
816 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
817 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
818 0x20,0x4c,0x61,0x6e,0x67 };
819 static const BYTE anyType[] = {
820 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
821 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
822 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
823 0x61,0x4c,0x67,0x6e };
825 static void test_encodeUnicodeName(DWORD dwEncoding)
827 CERT_RDN_ATTR attrs[2];
830 static CHAR oid_common_name[] = szOID_COMMON_NAME,
831 oid_sur_name[] = szOID_SUR_NAME;
836 /* Test with NULL pvStructInfo */
837 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
838 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
839 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
840 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
841 /* Test with empty CERT_NAME_INFO */
844 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
845 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
846 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
849 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
850 "Got unexpected encoding for empty name\n");
853 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
854 * encoding (the NULL).
856 attrs[0].pszObjId = oid_common_name;
857 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
858 attrs[0].Value.cbData = sizeof(commonNameW);
859 attrs[0].Value.pbData = (BYTE *)commonNameW;
861 rdn.rgRDNAttr = attrs;
864 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
865 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
866 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
867 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
868 ok(size == 9, "Unexpected error index %08x\n", size);
869 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
870 * forces the order of the encoded attributes to be swapped.
872 attrs[0].pszObjId = oid_common_name;
873 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
874 attrs[0].Value.cbData = 0;
875 attrs[0].Value.pbData = (BYTE *)commonNameW;
876 attrs[1].pszObjId = oid_sur_name;
877 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
878 attrs[1].Value.cbData = 0;
879 attrs[1].Value.pbData = (BYTE *)surNameW;
881 rdn.rgRDNAttr = attrs;
884 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
885 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
886 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
889 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
890 "Got unexpected encoding for two RDN array\n");
893 /* A name can be "encoded" with previously encoded RDN attrs. */
894 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
895 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
896 attrs[0].Value.cbData = sizeof(twoRDNs);
898 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
899 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
900 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
903 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
904 ok(!memcmp(buf, encodedTwoRDNs, size),
905 "Unexpected value for re-endoded two RDN array\n");
908 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
910 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
911 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
912 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
913 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
916 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
917 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
922 static void compareNameValues(const CERT_NAME_VALUE *expected,
923 const CERT_NAME_VALUE *got)
925 ok(got->dwValueType == expected->dwValueType,
926 "Expected string type %d, got %d\n", expected->dwValueType,
928 ok(got->Value.cbData == expected->Value.cbData,
929 "String type %d: unexpected data size, got %d, expected %d\n",
930 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
931 if (got->Value.cbData && got->Value.pbData)
932 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
933 min(got->Value.cbData, expected->Value.cbData)),
934 "String type %d: unexpected value\n", expected->dwValueType);
937 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
938 const CERT_RDN_ATTR *got)
940 if (expected->pszObjId && strlen(expected->pszObjId))
942 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
946 ok(!strcmp(got->pszObjId, expected->pszObjId),
947 "Got unexpected OID %s, expected %s\n", got->pszObjId,
951 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
952 (const CERT_NAME_VALUE *)&got->dwValueType);
955 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
957 ok(got->cRDNAttr == expected->cRDNAttr,
958 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
963 for (i = 0; i < got->cRDNAttr; i++)
964 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
968 static void compareNames(const CERT_NAME_INFO *expected,
969 const CERT_NAME_INFO *got)
971 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
972 expected->cRDN, got->cRDN);
977 for (i = 0; i < got->cRDN; i++)
978 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
982 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
983 static const BYTE twoRDNsExtraBytes[] = {
984 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
985 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
986 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
988 static void test_decodeName(DWORD dwEncoding)
994 CERT_NAME_INFO info = { 1, &rdn };
996 /* test empty name */
998 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
999 emptySequence[1] + 2,
1000 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1001 (BYTE *)&buf, &bufSize);
1002 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1003 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1004 * decoder works the same way, so only test the count.
1008 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1009 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1010 "Expected 0 RDNs in empty info, got %d\n",
1011 ((CERT_NAME_INFO *)buf)->cRDN);
1014 /* test empty name with indefinite-length encoding */
1015 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1016 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1017 (BYTE *)&buf, &bufSize);
1018 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1021 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1022 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1023 "Expected 0 RDNs in empty info, got %d\n",
1024 ((CERT_NAME_INFO *)buf)->cRDN);
1027 /* test empty RDN */
1029 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1031 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1032 (BYTE *)&buf, &bufSize);
1033 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1036 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1038 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1039 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1040 "Got unexpected value for empty RDN\n");
1043 /* test two RDN attrs */
1045 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1047 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1048 (BYTE *)&buf, &bufSize);
1049 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1052 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1053 oid_common_name[] = szOID_COMMON_NAME;
1055 CERT_RDN_ATTR attrs[] = {
1056 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1057 (BYTE *)surName } },
1058 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1059 (BYTE *)commonName } },
1062 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1063 rdn.rgRDNAttr = attrs;
1064 compareNames(&info, (CERT_NAME_INFO *)buf);
1067 /* test that two RDN attrs with extra bytes succeeds */
1069 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1070 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1071 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1072 /* And, a slightly more complicated name */
1075 ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1076 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1077 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1080 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1081 rdn.rgRDNAttr = (PCERT_RDN_ATTR)decodedRdnAttrs;
1082 compareNames(&info, (CERT_NAME_INFO *)buf);
1087 static void test_decodeUnicodeName(DWORD dwEncoding)
1093 CERT_NAME_INFO info = { 1, &rdn };
1095 /* test empty name */
1097 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1098 emptySequence[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());
1104 ok(bufSize == sizeof(CERT_NAME_INFO),
1105 "Got wrong bufSize %d\n", bufSize);
1106 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1107 "Expected 0 RDNs in empty info, got %d\n",
1108 ((CERT_NAME_INFO *)buf)->cRDN);
1111 /* test empty RDN */
1113 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1115 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1116 (BYTE *)&buf, &bufSize);
1117 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1120 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1122 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1123 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1124 "Got unexpected value for empty RDN\n");
1127 /* test two RDN attrs */
1129 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1130 sizeof(twoRDNsNoNull),
1131 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1132 (BYTE *)&buf, &bufSize);
1133 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1136 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1137 oid_common_name[] = szOID_COMMON_NAME;
1139 CERT_RDN_ATTR attrs[] = {
1140 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1141 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1142 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1143 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1146 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1147 rdn.rgRDNAttr = attrs;
1148 compareNames(&info, (CERT_NAME_INFO *)buf);
1153 struct EncodedNameValue
1155 CERT_NAME_VALUE value;
1156 const BYTE *encoded;
1160 static const char bogusIA5[] = "\x80";
1161 static const char bogusPrintable[] = "~";
1162 static const char bogusNumeric[] = "A";
1163 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1164 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1165 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1166 static BYTE octetCommonNameValue[] = {
1167 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1168 static BYTE numericCommonNameValue[] = {
1169 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1170 static BYTE printableCommonNameValue[] = {
1171 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1172 static BYTE t61CommonNameValue[] = {
1173 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1174 static BYTE videotexCommonNameValue[] = {
1175 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1176 static BYTE ia5CommonNameValue[] = {
1177 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1178 static BYTE graphicCommonNameValue[] = {
1179 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1180 static BYTE visibleCommonNameValue[] = {
1181 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1182 static BYTE generalCommonNameValue[] = {
1183 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1184 static BYTE bmpCommonNameValue[] = {
1185 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1186 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1187 static BYTE utf8CommonNameValue[] = {
1188 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1190 static struct EncodedNameValue nameValues[] = {
1191 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1192 octetCommonNameValue, sizeof(octetCommonNameValue) },
1193 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1194 numericCommonNameValue, sizeof(numericCommonNameValue) },
1195 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1196 printableCommonNameValue, sizeof(printableCommonNameValue) },
1197 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1198 t61CommonNameValue, sizeof(t61CommonNameValue) },
1199 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1200 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1201 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1202 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1203 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1204 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1205 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1206 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1207 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1208 generalCommonNameValue, sizeof(generalCommonNameValue) },
1209 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1210 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1211 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1212 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1213 /* The following tests succeed under Windows, but really should fail,
1214 * they contain characters that are illegal for the encoding. I'm
1215 * including them to justify my lazy encoding.
1217 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1219 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1220 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1221 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1222 bin44, sizeof(bin44) },
1225 static void test_encodeNameValue(DWORD dwEncoding)
1230 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1232 value.dwValueType = 14;
1233 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1234 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1235 ok(!ret && GetLastError() == CRYPT_E_ASN1_CHOICE,
1236 "Expected CRYPT_E_ASN1_CHOICE, got %08x\n", GetLastError());
1237 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1238 value.Value.pbData = printableCommonNameValue;
1239 value.Value.cbData = sizeof(printableCommonNameValue);
1240 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1241 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1242 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1245 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1247 ok(!memcmp(buf, printableCommonNameValue, size),
1248 "Unexpected encoding\n");
1251 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1253 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1254 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1256 ok(ret, "Type %d: CryptEncodeObjectEx failed: %08x\n",
1257 nameValues[i].value.dwValueType, GetLastError());
1260 ok(size == nameValues[i].encodedSize,
1261 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1262 ok(!memcmp(buf, nameValues[i].encoded, size),
1263 "Got unexpected encoding\n");
1269 static void test_decodeNameValue(DWORD dwEncoding)
1276 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1278 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1279 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1280 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1281 (BYTE *)&buf, &bufSize);
1282 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1283 nameValues[i].value.dwValueType, GetLastError());
1286 compareNameValues(&nameValues[i].value,
1287 (const CERT_NAME_VALUE *)buf);
1293 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1294 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1295 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1296 'h','q','.','o','r','g',0 };
1297 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1298 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1300 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1302 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1303 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1304 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1305 static const BYTE localhost[] = { 127, 0, 0, 1 };
1306 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1308 static const unsigned char encodedCommonName[] = {
1309 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1310 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1311 static const BYTE encodedDirectoryName[] = {
1312 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1313 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1315 static void test_encodeAltName(DWORD dwEncoding)
1317 CERT_ALT_NAME_INFO info = { 0 };
1318 CERT_ALT_NAME_ENTRY entry = { 0 };
1322 char oid[] = "1.2.3";
1324 /* Test with empty info */
1325 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1326 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1329 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1330 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1333 /* Test with an empty entry */
1335 info.rgAltEntry = &entry;
1336 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1337 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1338 ok(!ret && GetLastError() == E_INVALIDARG,
1339 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1340 /* Test with an empty pointer */
1341 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1342 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1343 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1346 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1347 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1350 /* Test with a real URL */
1351 U(entry).pwszURL = (LPWSTR)url;
1352 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1353 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1356 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1357 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1360 /* Now with the URL containing an invalid IA5 char */
1361 U(entry).pwszURL = (LPWSTR)nihongoURL;
1362 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1363 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1364 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1365 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1366 /* The first invalid character is at index 7 */
1367 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1368 "Expected invalid char at index 7, got %d\n",
1369 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1370 /* Now with the URL missing a scheme */
1371 U(entry).pwszURL = (LPWSTR)dnsName;
1372 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1373 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1374 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1377 /* This succeeds, but it shouldn't, so don't worry about conforming */
1380 /* Now with a DNS name */
1381 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1382 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1383 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1384 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1387 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1388 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1391 /* Test with an IP address */
1392 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1393 U(entry).IPAddress.cbData = sizeof(localhost);
1394 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1395 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1396 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1399 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1400 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1404 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1405 U(entry).pszRegisteredID = oid;
1406 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1407 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1410 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1411 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1414 /* Test with directory name */
1415 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1416 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1417 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1418 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1419 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1422 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1423 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1428 static void test_decodeAltName(DWORD dwEncoding)
1430 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1432 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1437 CERT_ALT_NAME_INFO *info;
1439 /* Test some bogus ones first */
1440 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1441 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1442 NULL, (BYTE *)&buf, &bufSize);
1443 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1444 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
1445 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1446 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1448 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
1449 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
1450 /* Now expected cases */
1451 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1452 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1454 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1457 info = (CERT_ALT_NAME_INFO *)buf;
1459 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1463 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1464 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1466 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1469 info = (CERT_ALT_NAME_INFO *)buf;
1471 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1473 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1474 "Expected CERT_ALT_NAME_URL, got %d\n",
1475 info->rgAltEntry[0].dwAltNameChoice);
1476 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1477 "Expected empty URL\n");
1480 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1481 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1482 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1483 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1484 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1486 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1489 info = (CERT_ALT_NAME_INFO *)buf;
1491 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1493 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1494 "Expected CERT_ALT_NAME_URL, got %d\n",
1495 info->rgAltEntry[0].dwAltNameChoice);
1496 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1499 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1500 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1502 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1505 info = (CERT_ALT_NAME_INFO *)buf;
1507 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1509 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1510 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1511 info->rgAltEntry[0].dwAltNameChoice);
1512 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1513 "Unexpected DNS name\n");
1516 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1517 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1519 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1522 info = (CERT_ALT_NAME_INFO *)buf;
1524 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1526 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1527 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1528 info->rgAltEntry[0].dwAltNameChoice);
1529 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1530 "Unexpected IP address length %d\n",
1531 U(info->rgAltEntry[0]).IPAddress.cbData);
1532 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1533 sizeof(localhost)), "Unexpected IP address value\n");
1536 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1537 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1539 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1542 info = (CERT_ALT_NAME_INFO *)buf;
1544 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1546 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1547 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1548 info->rgAltEntry[0].dwAltNameChoice);
1549 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1550 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1553 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1554 encodedDirectoryName, sizeof(encodedDirectoryName),
1555 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1556 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1559 info = (CERT_ALT_NAME_INFO *)buf;
1561 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1563 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1564 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1565 info->rgAltEntry[0].dwAltNameChoice);
1566 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1567 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1568 U(info->rgAltEntry[0]).DirectoryName.cbData);
1569 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1570 encodedCommonName, sizeof(encodedCommonName)),
1571 "Unexpected directory name value\n");
1576 struct UnicodeExpectedError
1584 static const WCHAR oneW[] = { '1',0 };
1585 static const WCHAR aW[] = { 'a',0 };
1586 static const WCHAR quoteW[] = { '"', 0 };
1588 static struct UnicodeExpectedError unicodeErrors[] = {
1589 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1590 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1591 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1592 { 14, oneW, 0, CRYPT_E_ASN1_CHOICE },
1593 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1594 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1595 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1598 struct UnicodeExpectedResult
1602 CRYPT_DATA_BLOB encoded;
1605 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1606 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1607 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1608 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1609 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1610 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1611 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1612 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1613 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1614 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1615 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1616 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1618 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1620 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1621 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1622 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1623 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1625 static struct UnicodeExpectedResult unicodeResults[] = {
1626 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1627 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1628 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1629 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1630 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1631 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1632 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1633 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1634 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1635 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1636 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1637 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1638 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1641 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1642 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1643 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1646 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1651 CERT_NAME_VALUE value;
1653 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1654 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1655 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1656 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1657 /* Have to have a string of some sort */
1658 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1659 value.Value.pbData = NULL;
1660 value.Value.cbData = 0;
1661 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1662 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1663 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1664 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1665 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1666 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1667 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1668 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1669 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1670 value.dwValueType = CERT_RDN_ANY_TYPE;
1671 value.Value.pbData = (LPBYTE)oneW;
1672 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1673 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1674 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1675 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1676 value.Value.cbData = sizeof(oneW);
1677 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1678 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1679 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1680 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1681 /* An encoded string with specified length isn't good enough either */
1682 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1683 value.Value.pbData = oneUniversal;
1684 value.Value.cbData = sizeof(oneUniversal);
1685 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1686 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1687 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1688 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1689 /* More failure checking */
1690 value.Value.cbData = 0;
1691 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1693 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1694 value.dwValueType = unicodeErrors[i].valueType;
1695 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1696 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1697 ok(!ret && GetLastError() == unicodeErrors[i].error,
1698 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1699 unicodeErrors[i].error, GetLastError());
1700 ok(size == unicodeErrors[i].errorIndex,
1701 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1704 /* cbData can be zero if the string is NULL-terminated */
1705 value.Value.cbData = 0;
1706 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1708 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1709 value.dwValueType = unicodeResults[i].valueType;
1710 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1711 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1712 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1715 ok(size == unicodeResults[i].encoded.cbData,
1716 "Value type %d: expected size %d, got %d\n",
1717 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1718 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1719 "Value type %d: unexpected value\n", value.dwValueType);
1723 /* These "encode," but they do so by truncating each unicode character
1724 * rather than properly encoding it. Kept separate from the proper results,
1725 * because the encoded forms won't decode to their original strings.
1727 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1729 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1730 value.dwValueType = unicodeWeirdness[i].valueType;
1731 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1732 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1733 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1736 ok(size == unicodeWeirdness[i].encoded.cbData,
1737 "Value type %d: expected size %d, got %d\n",
1738 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1739 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1740 "Value type %d: unexpected value\n", value.dwValueType);
1746 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1748 if (n <= 0) return 0;
1749 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1750 return *str1 - *str2;
1753 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1757 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1763 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1764 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1765 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1766 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1769 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1771 ok(value->dwValueType == unicodeResults[i].valueType,
1772 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1773 value->dwValueType);
1774 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1775 value->Value.cbData / sizeof(WCHAR)),
1776 "Unexpected decoded value for index %d (value type %d)\n", i,
1777 unicodeResults[i].valueType);
1783 struct encodedOctets
1786 const BYTE *encoded;
1789 static const unsigned char bin46[] = { 'h','i',0 };
1790 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1791 static const unsigned char bin48[] = {
1792 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1793 static const unsigned char bin49[] = {
1794 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1795 static const unsigned char bin50[] = { 0 };
1796 static const unsigned char bin51[] = { 0x04,0x00,0 };
1798 static const struct encodedOctets octets[] = {
1804 static void test_encodeOctets(DWORD dwEncoding)
1806 CRYPT_DATA_BLOB blob;
1809 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1815 blob.cbData = strlen((const char*)octets[i].val);
1816 blob.pbData = (BYTE*)octets[i].val;
1817 ret = CryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1818 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1819 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1823 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1824 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1825 buf[1], octets[i].encoded[1]);
1826 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1827 octets[i].encoded[1] + 1), "Got unexpected value\n");
1833 static void test_decodeOctets(DWORD dwEncoding)
1837 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1843 ret = CryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1844 (BYTE *)octets[i].encoded, octets[i].encoded[1] + 2,
1845 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1846 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1847 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1848 "Expected size >= %d, got %d\n",
1849 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1850 ok(buf != NULL, "Expected allocated buffer\n");
1853 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
1856 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
1857 "Unexpected value\n");
1863 static const BYTE bytesToEncode[] = { 0xff, 0xff };
1868 const BYTE *encoded;
1870 const BYTE *decoded;
1873 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
1874 static const unsigned char bin53[] = { 0xff,0xff };
1875 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
1876 static const unsigned char bin55[] = { 0xff,0xfe };
1877 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
1878 static const unsigned char bin57[] = { 0xfe };
1879 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
1881 static const struct encodedBits bits[] = {
1882 /* normal test cases */
1883 { 0, bin52, 2, bin53 },
1884 { 1, bin54, 2, bin55 },
1885 /* strange test case, showing cUnusedBits >= 8 is allowed */
1886 { 9, bin56, 1, bin57 },
1887 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1888 { 17, bin58, 0, NULL },
1891 static void test_encodeBits(DWORD dwEncoding)
1895 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1897 CRYPT_BIT_BLOB blob;
1902 blob.cbData = sizeof(bytesToEncode);
1903 blob.pbData = (BYTE *)bytesToEncode;
1904 blob.cUnusedBits = bits[i].cUnusedBits;
1905 ret = CryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
1906 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1907 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1910 ok(bufSize == bits[i].encoded[1] + 2,
1911 "Got unexpected size %d, expected %d\n", bufSize,
1912 bits[i].encoded[1] + 2);
1913 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
1914 "Unexpected value\n");
1920 static void test_decodeBits(DWORD dwEncoding)
1922 static const BYTE ber[] = "\x03\x02\x01\xff";
1923 static const BYTE berDecoded = 0xfe;
1930 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1932 ret = CryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
1933 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1935 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1938 CRYPT_BIT_BLOB *blob;
1940 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
1941 "Got unexpected size %d\n", bufSize);
1942 blob = (CRYPT_BIT_BLOB *)buf;
1943 ok(blob->cbData == bits[i].cbDecoded,
1944 "Got unexpected length %d, expected %d\n", blob->cbData,
1946 if (blob->cbData && bits[i].cbDecoded)
1947 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
1948 "Unexpected value\n");
1952 /* special case: check that something that's valid in BER but not in DER
1953 * decodes successfully
1955 ret = CryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
1956 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1957 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1960 CRYPT_BIT_BLOB *blob;
1962 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
1963 "Got unexpected size %d\n", bufSize);
1964 blob = (CRYPT_BIT_BLOB *)buf;
1965 ok(blob->cbData == sizeof(berDecoded),
1966 "Got unexpected length %d\n", blob->cbData);
1968 ok(*blob->pbData == berDecoded, "Unexpected value\n");
1975 CERT_BASIC_CONSTRAINTS2_INFO info;
1976 const BYTE *encoded;
1979 static const unsigned char bin59[] = { 0x30,0x00 };
1980 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
1981 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
1982 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1983 static const struct Constraints2 constraints2[] = {
1984 /* empty constraints */
1985 { { FALSE, FALSE, 0}, bin59 },
1987 { { TRUE, FALSE, 0}, bin60 },
1988 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
1989 * but that's not the case
1991 { { FALSE, TRUE, 0}, bin61 },
1992 /* can be a CA and has path length constraints set */
1993 { { TRUE, TRUE, 1}, bin62 },
1996 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
1997 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
1998 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
1999 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2000 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2001 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2002 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2003 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2004 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2005 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2007 static void test_encodeBasicConstraints(DWORD dwEncoding)
2009 DWORD i, bufSize = 0;
2010 CERT_BASIC_CONSTRAINTS_INFO info;
2011 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2012 (LPBYTE)encodedDomainName };
2016 /* First test with the simpler info2 */
2017 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2019 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2020 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2022 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2025 ok(bufSize == constraints2[i].encoded[1] + 2,
2026 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2028 ok(!memcmp(buf, constraints2[i].encoded,
2029 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2033 /* Now test with more complex basic constraints */
2034 info.SubjectType.cbData = 0;
2035 info.fPathLenConstraint = FALSE;
2036 info.cSubtreesConstraint = 0;
2037 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2038 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2039 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2042 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2043 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2044 "Unexpected value\n");
2047 /* None of the certs I examined had any subtree constraint, but I test one
2048 * anyway just in case.
2050 info.cSubtreesConstraint = 1;
2051 info.rgSubtreesConstraint = &nameBlob;
2052 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2053 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2054 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2057 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2058 ok(!memcmp(buf, constraintWithDomainName,
2059 sizeof(constraintWithDomainName)), "Unexpected value\n");
2062 /* FIXME: test encoding with subject type. */
2065 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2067 static void test_decodeBasicConstraints(DWORD dwEncoding)
2069 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2071 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2077 /* First test with simpler info2 */
2078 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2080 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2081 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2082 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2083 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2087 CERT_BASIC_CONSTRAINTS2_INFO *info =
2088 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2090 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2091 "Unexpected value for item %d\n", i);
2095 /* Check with the order of encoded elements inverted */
2097 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2098 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2100 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2101 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2102 ok(!buf, "Expected buf to be set to NULL\n");
2103 /* Check with a non-DER bool */
2104 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2105 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2106 (BYTE *)&buf, &bufSize);
2107 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2110 CERT_BASIC_CONSTRAINTS2_INFO *info =
2111 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2113 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2116 /* Check with a non-basic constraints value */
2117 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2118 (LPBYTE)encodedCommonName, encodedCommonName[1] + 2,
2119 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2120 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2121 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2122 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2123 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2124 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2125 (BYTE *)&buf, &bufSize);
2126 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2129 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2131 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2132 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2133 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2136 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2137 constraintWithDomainName, sizeof(constraintWithDomainName),
2138 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2139 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2142 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2144 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2145 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2146 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2147 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2149 ok(info->rgSubtreesConstraint[0].cbData ==
2150 sizeof(encodedDomainName), "Wrong size %d\n",
2151 info->rgSubtreesConstraint[0].cbData);
2152 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2153 sizeof(encodedDomainName)), "Unexpected value\n");
2159 /* These are terrible public keys of course, I'm just testing encoding */
2160 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2161 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2162 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2163 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2164 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2165 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2166 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2167 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2169 struct EncodedRSAPubKey
2171 const BYTE *modulus;
2173 const BYTE *encoded;
2174 size_t decodedModulusLen;
2177 struct EncodedRSAPubKey rsaPubKeys[] = {
2178 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2179 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2180 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2181 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2184 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2186 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2187 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2188 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2191 DWORD bufSize = 0, i;
2193 /* Try with a bogus blob type */
2195 hdr->bVersion = CUR_BLOB_VERSION;
2197 hdr->aiKeyAlg = CALG_RSA_KEYX;
2198 rsaPubKey->magic = 0x31415352;
2199 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2200 rsaPubKey->pubexp = 65537;
2201 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2204 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2205 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2207 ok(!ret && GetLastError() == E_INVALIDARG,
2208 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2209 /* Now with a bogus reserved field */
2210 hdr->bType = PUBLICKEYBLOB;
2212 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2213 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2217 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2218 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2219 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2222 /* Now with a bogus blob version */
2225 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2226 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2230 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2231 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2232 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2235 /* And with a bogus alg ID */
2236 hdr->bVersion = CUR_BLOB_VERSION;
2237 hdr->aiKeyAlg = CALG_DES;
2238 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2239 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2243 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2244 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2245 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2248 /* Check a couple of RSA-related OIDs */
2249 hdr->aiKeyAlg = CALG_RSA_KEYX;
2250 ret = CryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2251 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2252 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2253 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2254 ret = CryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2255 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2256 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2257 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2258 /* Finally, all valid */
2259 hdr->aiKeyAlg = CALG_RSA_KEYX;
2260 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2262 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2263 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2264 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2265 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2266 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2269 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2270 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2272 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2273 "Unexpected value\n");
2279 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2286 /* Try with a bad length */
2287 ret = CryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2288 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2289 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2290 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2291 "Expected CRYPT_E_ASN1_EOD, got %08x\n", CRYPT_E_ASN1_EOD);
2292 /* Try with a couple of RSA-related OIDs */
2293 ret = CryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2294 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2295 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2296 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2297 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2298 ret = CryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2299 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2300 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2301 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2302 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2303 /* Now try success cases */
2304 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2307 ret = CryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2308 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2309 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2310 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2313 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2314 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2316 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2317 rsaPubKeys[i].decodedModulusLen,
2318 "Wrong size %d\n", bufSize);
2319 ok(hdr->bType == PUBLICKEYBLOB,
2320 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2322 ok(hdr->bVersion == CUR_BLOB_VERSION,
2323 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2324 CUR_BLOB_VERSION, hdr->bVersion);
2325 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2327 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2328 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2329 ok(rsaPubKey->magic == 0x31415352,
2330 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2331 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2332 "Wrong bit len %d\n", rsaPubKey->bitlen);
2333 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2335 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2336 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2337 "Unexpected modulus\n");
2343 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2344 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2345 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2347 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2348 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2349 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2350 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2352 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2354 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2355 CRYPT_SEQUENCE_OF_ANY seq;
2361 /* Encode a homogenous sequence */
2362 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2364 blobs[i].cbData = ints[i].encoded[1] + 2;
2365 blobs[i].pbData = (BYTE *)ints[i].encoded;
2367 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2368 seq.rgValue = blobs;
2370 ret = CryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2371 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2372 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2375 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2376 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2379 /* Change the type of the first element in the sequence, and give it
2382 blobs[0].cbData = times[0].encodedTime[1] + 2;
2383 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2384 ret = CryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2385 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2386 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2389 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2390 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2391 "Unexpected value\n");
2396 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2402 ret = CryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2403 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2404 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2407 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2410 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2411 "Wrong elements %d\n", seq->cValue);
2412 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2414 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2415 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2416 seq->rgValue[i].cbData);
2417 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2418 ints[i].encoded[1] + 2), "Unexpected value\n");
2422 ret = CryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2423 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2425 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2428 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2430 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2431 "Wrong elements %d\n", seq->cValue);
2432 /* Just check the first element since it's all that changed */
2433 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2434 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2435 seq->rgValue[0].cbData);
2436 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2437 times[0].encodedTime[1] + 2), "Unexpected value\n");
2442 struct encodedExtensions
2444 CERT_EXTENSIONS exts;
2445 const BYTE *encoded;
2448 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2449 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2450 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2451 static CERT_EXTENSION criticalExt =
2452 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2453 static CERT_EXTENSION nonCriticalExt =
2454 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2456 static const BYTE ext0[] = { 0x30,0x00 };
2457 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2458 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2459 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2460 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2462 static const struct encodedExtensions exts[] = {
2463 { { 0, NULL }, ext0 },
2464 { { 1, &criticalExt }, ext1 },
2465 { { 1, &nonCriticalExt }, ext2 },
2468 static void test_encodeExtensions(DWORD dwEncoding)
2472 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2478 ret = CryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2479 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2480 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2483 ok(bufSize == exts[i].encoded[1] + 2,
2484 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2485 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2486 "Unexpected value\n");
2492 static void test_decodeExtensions(DWORD dwEncoding)
2496 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2502 ret = CryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2503 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2504 NULL, (BYTE *)&buf, &bufSize);
2505 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2508 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2511 ok(ext->cExtension == exts[i].exts.cExtension,
2512 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2514 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2516 ok(!strcmp(ext->rgExtension[j].pszObjId,
2517 exts[i].exts.rgExtension[j].pszObjId),
2518 "Expected OID %s, got %s\n",
2519 exts[i].exts.rgExtension[j].pszObjId,
2520 ext->rgExtension[j].pszObjId);
2521 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2522 exts[i].exts.rgExtension[j].Value.pbData,
2523 exts[i].exts.rgExtension[j].Value.cbData),
2524 "Unexpected value\n");
2531 /* MS encodes public key info with a NULL if the algorithm identifier's
2532 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2533 * it encodes them by omitting the algorithm parameters. This latter approach
2534 * seems more correct, so accept either form.
2536 struct encodedPublicKey
2538 CERT_PUBLIC_KEY_INFO info;
2539 const BYTE *encoded;
2540 const BYTE *encodedNoNull;
2541 CERT_PUBLIC_KEY_INFO decoded;
2544 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2546 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2548 static const unsigned char bin64[] = {
2549 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2550 static const unsigned char bin65[] = {
2551 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2552 static const unsigned char bin66[] = {
2553 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2554 static const unsigned char bin67[] = {
2555 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2556 static const unsigned char bin68[] = {
2557 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2558 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2559 static const unsigned char bin69[] = {
2560 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2561 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2562 static const unsigned char bin70[] = {
2563 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2564 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2566 static const unsigned char bin71[] = {
2567 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2568 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2570 static unsigned char bin72[] = { 0x05,0x00};
2572 static CHAR oid_bogus[] = "1.2.3",
2573 oid_rsa[] = szOID_RSA;
2575 static const struct encodedPublicKey pubKeys[] = {
2576 /* with a bogus OID */
2577 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2579 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2580 /* some normal keys */
2581 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2583 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2584 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2586 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2587 /* with add'l parameters--note they must be DER-encoded */
2588 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2589 (BYTE *)aKey, 0 } },
2591 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2592 (BYTE *)aKey, 0 } } },
2595 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2599 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2605 ret = CryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2606 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2608 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2611 ok(bufSize == pubKeys[i].encoded[1] + 2 ||
2612 bufSize == pubKeys[i].encodedNoNull[1] + 2,
2613 "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
2614 pubKeys[i].encodedNoNull[1] + 2, bufSize);
2615 if (bufSize == pubKeys[i].encoded[1] + 2)
2616 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2617 "Unexpected value\n");
2618 else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
2619 ok(!memcmp(buf, pubKeys[i].encodedNoNull,
2620 pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
2626 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2627 const CERT_PUBLIC_KEY_INFO *got)
2629 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2630 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2631 got->Algorithm.pszObjId);
2632 ok(expected->Algorithm.Parameters.cbData ==
2633 got->Algorithm.Parameters.cbData,
2634 "Expected parameters of %d bytes, got %d\n",
2635 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2636 if (expected->Algorithm.Parameters.cbData)
2637 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2638 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2639 "Unexpected algorithm parameters\n");
2640 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2641 "Expected public key of %d bytes, got %d\n",
2642 expected->PublicKey.cbData, got->PublicKey.cbData);
2643 if (expected->PublicKey.cbData)
2644 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2645 got->PublicKey.cbData), "Unexpected public key value\n");
2648 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2650 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2651 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2652 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2653 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2659 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2661 /* The NULL form decodes to the decoded member */
2662 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2663 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2664 NULL, (BYTE *)&buf, &bufSize);
2665 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2668 comparePublicKeyInfo(&pubKeys[i].decoded,
2669 (CERT_PUBLIC_KEY_INFO *)buf);
2672 /* The non-NULL form decodes to the original */
2673 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2674 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2675 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2676 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2679 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2683 /* Test with bogus (not valid DER) parameters */
2684 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2685 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2686 NULL, (BYTE *)&buf, &bufSize);
2687 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2688 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2691 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2692 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2693 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2694 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2695 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2696 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2697 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2698 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2699 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2700 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2701 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2702 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2703 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2704 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2705 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2706 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2707 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2708 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2709 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2710 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2711 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2712 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2713 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2714 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2715 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2716 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2717 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2718 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2719 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2720 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2721 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2722 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2723 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2724 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2725 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2726 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2727 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2728 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2729 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2730 static const BYTE v1CertWithPubKey[] = {
2731 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2732 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2733 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2734 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2735 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2736 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2737 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2738 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2739 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2740 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2742 static const BYTE v1CertWithPubKeyNoNull[] = {
2743 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2744 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2745 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2746 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2747 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2748 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2749 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2750 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2751 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2752 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2753 static const BYTE v1CertWithSubjectKeyId[] = {
2754 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2755 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2756 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2757 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2758 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2759 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2760 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2761 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2762 0x4c,0x61,0x6e,0x67,0x00 };
2764 static const BYTE serialNum[] = { 0x01 };
2766 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2771 CERT_INFO info = { 0 };
2772 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2773 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2776 /* Test with NULL pvStructInfo */
2777 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2778 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2779 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2780 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2781 /* Test with a V1 cert */
2782 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2783 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2784 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2787 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2788 v1Cert[1] + 2, size);
2789 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2793 info.dwVersion = CERT_V2;
2794 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2795 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2796 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2799 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2800 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2804 info.dwVersion = CERT_V3;
2805 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2806 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2807 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2810 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2811 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2814 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2815 * API doesn't prevent it)
2817 info.dwVersion = CERT_V1;
2818 info.cExtension = 1;
2819 info.rgExtension = &criticalExt;
2820 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2821 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2822 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2825 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2826 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2829 /* test v1 cert with a serial number */
2830 info.SerialNumber.cbData = sizeof(serialNum);
2831 info.SerialNumber.pbData = (BYTE *)serialNum;
2832 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2833 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2836 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2837 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2840 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2841 info.Issuer.cbData = sizeof(encodedCommonName);
2842 info.Issuer.pbData = (BYTE *)encodedCommonName;
2843 info.Subject.cbData = sizeof(encodedCommonName);
2844 info.Subject.pbData = (BYTE *)encodedCommonName;
2845 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2846 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2849 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
2850 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
2853 /* Add a public key */
2854 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2855 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2856 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
2857 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2858 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2861 ok(size == sizeof(v1CertWithPubKey) ||
2862 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
2863 if (size == sizeof(v1CertWithPubKey))
2864 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
2865 else if (size == sizeof(v1CertWithPubKeyNoNull))
2866 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
2867 "Got unexpected value\n");
2870 /* Remove the public key, and add a subject key identifier extension */
2871 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2872 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
2873 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
2874 ext.pszObjId = oid_subject_key_identifier;
2875 ext.fCritical = FALSE;
2876 ext.Value.cbData = sizeof(octetCommonNameValue);
2877 ext.Value.pbData = (BYTE *)octetCommonNameValue;
2878 info.cExtension = 1;
2879 info.rgExtension = &ext;
2880 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2881 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2884 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
2885 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
2890 static void test_decodeCertToBeSigned(DWORD dwEncoding)
2892 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
2893 v1CertWithConstraints, v1CertWithSerial };
2898 /* Test with NULL pbEncoded */
2899 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
2900 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2901 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2902 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2903 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
2904 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2905 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2906 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2907 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
2908 * minimum a cert must have a non-zero serial number, an issuer, and a
2911 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
2913 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
2914 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2915 (BYTE *)&buf, &size);
2916 ok(!ret, "Expected failure\n");
2918 /* Now check with serial number, subject and issuer specified */
2919 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
2920 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2921 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2924 CERT_INFO *info = (CERT_INFO *)buf;
2926 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
2927 ok(info->SerialNumber.cbData == 1,
2928 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
2929 ok(*info->SerialNumber.pbData == *serialNum,
2930 "Expected serial number %d, got %d\n", *serialNum,
2931 *info->SerialNumber.pbData);
2932 ok(info->Issuer.cbData == sizeof(encodedCommonName),
2933 "Wrong size %d\n", info->Issuer.cbData);
2934 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
2935 "Unexpected issuer\n");
2936 ok(info->Subject.cbData == sizeof(encodedCommonName),
2937 "Wrong size %d\n", info->Subject.cbData);
2938 ok(!memcmp(info->Subject.pbData, encodedCommonName,
2939 info->Subject.cbData), "Unexpected subject\n");
2942 /* Check again with pub key specified */
2943 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
2944 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
2945 (BYTE *)&buf, &size);
2946 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2949 CERT_INFO *info = (CERT_INFO *)buf;
2951 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
2952 ok(info->SerialNumber.cbData == 1,
2953 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
2954 ok(*info->SerialNumber.pbData == *serialNum,
2955 "Expected serial number %d, got %d\n", *serialNum,
2956 *info->SerialNumber.pbData);
2957 ok(info->Issuer.cbData == sizeof(encodedCommonName),
2958 "Wrong size %d\n", info->Issuer.cbData);
2959 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
2960 "Unexpected issuer\n");
2961 ok(info->Subject.cbData == sizeof(encodedCommonName),
2962 "Wrong size %d\n", info->Subject.cbData);
2963 ok(!memcmp(info->Subject.pbData, encodedCommonName,
2964 info->Subject.cbData), "Unexpected subject\n");
2965 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
2966 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
2967 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
2968 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
2969 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
2970 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
2971 sizeof(aKey)), "Unexpected public key\n");
2976 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2979 static const BYTE signedBigCert[] = {
2980 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
2981 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
2982 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
2983 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2984 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2985 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
2986 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
2987 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
2988 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
2989 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2990 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
2991 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
2993 static void test_encodeCert(DWORD dwEncoding)
2995 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
2996 * also that bigCert is a NULL-terminated string, so don't count its
2997 * last byte (otherwise the signed cert won't decode.)
2999 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3000 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3005 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3006 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
3007 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3010 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3011 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3016 static void test_decodeCert(DWORD dwEncoding)
3022 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3023 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3024 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3027 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3029 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3030 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3031 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3032 "Unexpected cert\n");
3033 ok(info->Signature.cbData == sizeof(hash),
3034 "Wrong signature size %d\n", info->Signature.cbData);
3035 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3036 "Unexpected signature\n");
3039 /* A signed cert decodes as a CERT_INFO too */
3040 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3041 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3042 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3045 CERT_INFO *info = (CERT_INFO *)buf;
3047 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3048 ok(info->SerialNumber.cbData == 1,
3049 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3050 ok(*info->SerialNumber.pbData == *serialNum,
3051 "Expected serial number %d, got %d\n", *serialNum,
3052 *info->SerialNumber.pbData);
3053 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3054 "Wrong size %d\n", info->Issuer.cbData);
3055 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3056 "Unexpected issuer\n");
3057 ok(info->Subject.cbData == sizeof(encodedCommonName),
3058 "Wrong size %d\n", info->Subject.cbData);
3059 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3060 info->Subject.cbData), "Unexpected subject\n");
3065 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3066 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3067 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3068 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3069 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3071 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3072 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3073 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3074 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3075 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3076 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3077 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3078 0x2e, 0x6f, 0x72, 0x67 };
3079 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3080 CRL_REASON_AFFILIATION_CHANGED;
3082 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3084 CRL_DIST_POINTS_INFO info = { 0 };
3085 CRL_DIST_POINT point = { { 0 } };
3086 CERT_ALT_NAME_ENTRY entry = { 0 };
3091 /* Test with an empty info */
3092 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3093 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3094 ok(!ret && GetLastError() == E_INVALIDARG,
3095 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3096 /* Test with one empty dist point */
3097 info.cDistPoint = 1;
3098 info.rgDistPoint = &point;
3099 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3100 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3103 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3104 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3107 /* A dist point with an invalid name */
3108 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3109 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3110 U(entry).pwszURL = (LPWSTR)nihongoURL;
3111 U(point.DistPointName).FullName.cAltEntry = 1;
3112 U(point.DistPointName).FullName.rgAltEntry = &entry;
3113 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3114 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3115 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3116 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3117 /* The first invalid character is at index 7 */
3118 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3119 "Expected invalid char at index 7, got %d\n",
3120 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3121 /* A dist point with (just) a valid name */
3122 U(entry).pwszURL = (LPWSTR)url;
3123 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3124 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3127 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3128 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3131 /* A dist point with (just) reason flags */
3132 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3133 point.ReasonFlags.cbData = sizeof(crlReason);
3134 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3135 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3136 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3139 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3140 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3143 /* A dist point with just an issuer */
3144 point.ReasonFlags.cbData = 0;
3145 point.CRLIssuer.cAltEntry = 1;
3146 point.CRLIssuer.rgAltEntry = &entry;
3147 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3148 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3151 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3152 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3155 /* A dist point with both a name and an issuer */
3156 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3157 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3158 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3161 ok(size == sizeof(distPointWithUrlAndIssuer),
3162 "Wrong size %d\n", size);
3163 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3168 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3173 PCRL_DIST_POINTS_INFO info;
3174 PCRL_DIST_POINT point;
3175 PCERT_ALT_NAME_ENTRY entry;
3177 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3178 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3179 (BYTE *)&buf, &size);
3182 info = (PCRL_DIST_POINTS_INFO)buf;
3183 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3184 "Wrong size %d\n", size);
3185 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3187 point = info->rgDistPoint;
3188 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3189 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3190 point->DistPointName.dwDistPointNameChoice);
3191 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3192 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3195 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3196 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3197 (BYTE *)&buf, &size);
3200 info = (PCRL_DIST_POINTS_INFO)buf;
3201 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3202 "Wrong size %d\n", size);
3203 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3205 point = info->rgDistPoint;
3206 ok(point->DistPointName.dwDistPointNameChoice ==
3207 CRL_DIST_POINT_FULL_NAME,
3208 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3209 point->DistPointName.dwDistPointNameChoice);
3210 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3211 "Expected 1 name entry, got %d\n",
3212 U(point->DistPointName).FullName.cAltEntry);
3213 entry = U(point->DistPointName).FullName.rgAltEntry;
3214 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3215 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3216 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3217 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3218 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3221 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3222 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3223 NULL, (BYTE *)&buf, &size);
3226 info = (PCRL_DIST_POINTS_INFO)buf;
3227 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3228 "Wrong size %d\n", size);
3229 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3231 point = info->rgDistPoint;
3232 ok(point->DistPointName.dwDistPointNameChoice ==
3233 CRL_DIST_POINT_NO_NAME,
3234 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3235 point->DistPointName.dwDistPointNameChoice);
3236 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3237 "Expected reason length\n");
3238 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3239 "Unexpected reason\n");
3240 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3243 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3244 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3245 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3248 info = (PCRL_DIST_POINTS_INFO)buf;
3249 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3250 "Wrong size %d\n", size);
3251 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3253 point = info->rgDistPoint;
3254 ok(point->DistPointName.dwDistPointNameChoice ==
3255 CRL_DIST_POINT_FULL_NAME,
3256 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3257 point->DistPointName.dwDistPointNameChoice);
3258 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3259 "Expected 1 name entry, got %d\n",
3260 U(point->DistPointName).FullName.cAltEntry);
3261 entry = U(point->DistPointName).FullName.rgAltEntry;
3262 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3263 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3264 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3265 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3266 ok(point->CRLIssuer.cAltEntry == 1,
3267 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3268 entry = point->CRLIssuer.rgAltEntry;
3269 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3270 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3271 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3276 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3277 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3278 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3279 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3282 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3287 CRL_ISSUING_DIST_POINT point = { { 0 } };
3288 CERT_ALT_NAME_ENTRY entry;
3290 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3291 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3292 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3294 skip("no X509_ISSUING_DIST_POINT encode support\n");
3297 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3298 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3299 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3300 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3301 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3304 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3305 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3308 /* nonsensical flags */
3309 point.fOnlyContainsUserCerts = TRUE;
3310 point.fOnlyContainsCACerts = TRUE;
3311 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3312 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3313 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3316 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3317 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3320 /* unimplemented name type */
3321 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3322 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3323 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3324 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3325 ok(!ret && GetLastError() == E_INVALIDARG,
3326 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3328 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3329 U(point.DistPointName).FullName.cAltEntry = 0;
3330 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3331 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3332 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3335 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3336 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3339 /* name with URL entry */
3340 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3341 U(entry).pwszURL = (LPWSTR)url;
3342 U(point.DistPointName).FullName.cAltEntry = 1;
3343 U(point.DistPointName).FullName.rgAltEntry = &entry;
3344 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3345 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3346 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3349 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3350 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3355 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3356 const CERT_ALT_NAME_ENTRY *got)
3358 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3359 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3360 got->dwAltNameChoice);
3361 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3363 switch (got->dwAltNameChoice)
3365 case CERT_ALT_NAME_RFC822_NAME:
3366 case CERT_ALT_NAME_DNS_NAME:
3367 case CERT_ALT_NAME_EDI_PARTY_NAME:
3368 case CERT_ALT_NAME_URL:
3369 case CERT_ALT_NAME_REGISTERED_ID:
3370 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3371 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL), "Unexpected name\n");
3373 case CERT_ALT_NAME_X400_ADDRESS:
3374 case CERT_ALT_NAME_DIRECTORY_NAME:
3375 case CERT_ALT_NAME_IP_ADDRESS:
3376 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3377 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3378 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3379 U(*got).IPAddress.cbData), "Unexpected value\n");
3385 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3386 const CERT_ALT_NAME_INFO *got)
3390 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3391 expected->cAltEntry, got->cAltEntry);
3392 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3393 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3396 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3397 const CRL_DIST_POINT_NAME *got)
3399 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3400 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3401 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3402 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3405 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3406 const CRL_ISSUING_DIST_POINT *got)
3408 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3409 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3410 "Unexpected fOnlyContainsUserCerts\n");
3411 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3412 "Unexpected fOnlyContainsCACerts\n");
3413 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3414 "Unexpected reason flags\n");
3415 ok(got->fIndirectCRL == expected->fIndirectCRL,
3416 "Unexpected fIndirectCRL\n");
3419 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3424 CRL_ISSUING_DIST_POINT point = { { 0 } };
3426 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3427 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3428 (BYTE *)&buf, &size);
3429 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3431 skip("no X509_ISSUING_DIST_POINT decode support\n");
3434 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3437 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3440 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3441 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3442 (BYTE *)&buf, &size);
3443 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3446 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3447 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3450 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3451 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3452 (BYTE *)&buf, &size);
3453 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3456 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3457 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3458 U(point.DistPointName).FullName.cAltEntry = 0;
3459 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3462 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3463 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3464 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3467 CERT_ALT_NAME_ENTRY entry;
3469 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3470 U(entry).pwszURL = (LPWSTR)url;
3471 U(point.DistPointName).FullName.cAltEntry = 1;
3472 U(point.DistPointName).FullName.rgAltEntry = &entry;
3473 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3478 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3479 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3481 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3482 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3483 0x30, 0x30, 0x30, 0x30, 0x5a };
3484 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3485 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3486 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3487 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3489 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3490 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3491 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3492 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3493 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3494 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3495 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3496 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3497 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3498 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3499 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3500 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3501 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3502 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3503 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3504 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3505 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3506 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3507 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3508 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3509 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3510 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3511 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3512 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3513 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3514 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3515 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3516 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3517 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3518 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3519 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3520 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3521 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3522 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3523 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3524 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3525 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3526 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3527 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3528 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3530 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3534 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3536 CRL_INFO info = { 0 };
3537 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3540 /* Test with a V1 CRL */
3541 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3542 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3543 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3546 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3547 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3551 info.dwVersion = CRL_V2;
3552 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3553 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3554 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3557 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3558 v2CRL[1] + 2, size);
3559 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3562 /* v1 CRL with a name */
3563 info.dwVersion = CRL_V1;
3564 info.Issuer.cbData = sizeof(encodedCommonName);
3565 info.Issuer.pbData = (BYTE *)encodedCommonName;
3566 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3567 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3568 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3571 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3572 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3575 /* v1 CRL with a name and a NULL entry pointer */
3577 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3578 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3579 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3580 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3581 /* now set an empty entry */
3582 info.rgCRLEntry = &entry;
3583 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3584 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3587 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3588 "Wrong size %d\n", size);
3589 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3590 "Got unexpected value\n");
3593 /* an entry with a serial number */
3594 entry.SerialNumber.cbData = sizeof(serialNum);
3595 entry.SerialNumber.pbData = (BYTE *)serialNum;
3596 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3597 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3600 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3601 "Wrong size %d\n", size);
3602 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3603 "Got unexpected value\n");
3606 /* an entry with an extension */
3607 entry.cExtension = 1;
3608 entry.rgExtension = &criticalExt;
3609 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3610 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3611 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3614 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3615 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3618 /* a CRL with an extension */
3619 entry.cExtension = 0;
3620 info.cExtension = 1;
3621 info.rgExtension = &criticalExt;
3622 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3623 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3624 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3627 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3628 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3631 /* a v2 CRL with an extension, this time non-critical */
3632 info.dwVersion = CRL_V2;
3633 info.rgExtension = &nonCriticalExt;
3634 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3635 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3636 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3639 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3640 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3643 /* a v2 CRL with an issuing dist point extension */
3644 ext.pszObjId = oid_issuing_dist_point;
3645 ext.fCritical = TRUE;
3646 ext.Value.cbData = sizeof(urlIDP);
3647 ext.Value.pbData = (LPBYTE)urlIDP;
3648 entry.rgExtension = &ext;
3649 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3650 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3651 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3654 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3655 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3660 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3661 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3662 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3663 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3664 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3665 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3666 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3667 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3668 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3669 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3670 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3671 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3672 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3673 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3674 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3675 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3676 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3677 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3678 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3679 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3680 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3681 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3682 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3683 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3684 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3685 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3686 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3687 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3688 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3689 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3690 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3691 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3692 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3693 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3695 static const BYTE verisignCRLWithLotsOfEntries[] = {
3696 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3697 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3698 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3699 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3700 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3701 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3702 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3703 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3704 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3705 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3706 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3707 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3708 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3709 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3710 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3711 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3712 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3713 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3714 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3715 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3716 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3717 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3718 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3719 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3720 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3721 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3722 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3723 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3724 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3725 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3726 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3727 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3728 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3729 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3730 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3731 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3732 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3733 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3734 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3735 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3736 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3737 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3738 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3739 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3740 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3741 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3742 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3743 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3744 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3745 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3746 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3747 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3748 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3749 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3750 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3751 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3752 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3753 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3754 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3755 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3756 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3757 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3758 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3759 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3760 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3761 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3762 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3763 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3764 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3765 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3766 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3767 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3768 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3769 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3770 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3771 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3772 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3773 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3774 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3775 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3776 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3777 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3778 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3779 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3780 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3781 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3782 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3783 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3784 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3785 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3786 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3787 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3788 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3789 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3790 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3791 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3792 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3793 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3794 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3795 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3796 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3797 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3798 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3799 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3800 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3801 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3802 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3803 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3804 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3805 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3806 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3807 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3808 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3809 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3810 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3811 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3812 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3813 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3814 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3815 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3816 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3817 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3818 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3819 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3820 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3821 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3822 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3823 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3824 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3825 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3826 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3827 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3828 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3829 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3830 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3831 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3832 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3833 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3834 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3835 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3836 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3837 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3838 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3839 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3840 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3841 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3842 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3843 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3844 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3845 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3846 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3847 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3848 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3849 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3850 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3851 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3852 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3853 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3854 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3855 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3856 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3857 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3858 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3859 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3860 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3861 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3862 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3863 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3864 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3865 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3866 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3867 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3868 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3869 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3870 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3871 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3872 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3873 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3874 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3875 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3876 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3877 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
3878 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
3879 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
3880 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
3881 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
3882 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
3883 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
3884 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
3885 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
3886 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
3887 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
3888 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
3889 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
3890 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
3891 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
3892 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
3893 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
3894 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
3895 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
3896 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
3897 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
3898 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
3899 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
3900 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
3901 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
3902 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
3903 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
3904 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
3905 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
3906 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
3907 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
3908 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
3909 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
3910 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
3911 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
3912 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
3913 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
3914 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
3915 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
3916 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
3917 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
3918 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
3919 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
3920 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
3921 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
3922 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
3923 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
3924 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
3925 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
3926 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
3927 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
3928 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
3929 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
3930 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
3931 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
3932 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
3933 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
3934 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
3935 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
3936 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
3937 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
3938 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
3939 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
3940 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
3941 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
3942 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
3943 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
3944 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
3945 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
3946 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
3947 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
3948 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
3949 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
3950 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
3951 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
3952 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
3953 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
3954 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
3955 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
3956 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
3957 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
3958 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
3959 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
3960 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
3961 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
3962 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
3963 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
3964 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
3965 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
3966 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
3967 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
3968 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
3969 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
3970 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
3971 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
3972 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
3973 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
3974 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
3975 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
3976 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
3977 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
3978 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
3979 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
3980 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
3981 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
3982 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
3983 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
3984 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
3985 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
3986 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
3987 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
3988 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
3989 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
3990 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
3991 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
3992 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
3993 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
3994 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
3995 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
3996 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
3997 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
3998 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
3999 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4000 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4001 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4002 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4003 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4004 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4005 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4006 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4007 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4008 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4009 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4010 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4011 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4012 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4013 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4014 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4015 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4016 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4017 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4018 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4019 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4020 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4021 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4022 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4023 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4024 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4025 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4026 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4027 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4028 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4029 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4030 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4031 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4032 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4033 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4034 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4035 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4036 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4037 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4038 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4039 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4040 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4041 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4042 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4043 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4044 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4045 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4046 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4047 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4048 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4049 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4050 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4051 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4052 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4053 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4054 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4055 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4056 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4057 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4058 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4059 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4060 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4061 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4062 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4063 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4064 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4065 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4066 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4067 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4068 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4069 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4070 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4071 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4072 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4073 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4074 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4075 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4076 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4077 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4078 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4079 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4080 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4081 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4082 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4083 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4084 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4085 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4086 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4087 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4088 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4089 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4090 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4091 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4092 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4093 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4094 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4095 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4096 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4097 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4098 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4099 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4100 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4101 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4102 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4103 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4104 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4105 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4106 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4107 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4108 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4109 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4110 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4111 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4112 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4113 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4114 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4115 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4116 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4117 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4118 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4119 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4120 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4121 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4122 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4123 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4124 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4125 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4126 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4127 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4128 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4129 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4130 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4131 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4132 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4133 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4134 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4135 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4136 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4137 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4138 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4139 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4140 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4141 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4142 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4143 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4144 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4145 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4146 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4147 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4148 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4149 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4150 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4151 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4152 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4153 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4154 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4155 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4156 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4157 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4158 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4159 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4160 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4161 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4162 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4163 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4164 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4165 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4166 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4167 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4168 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4169 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4170 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4171 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4172 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4173 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4174 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4175 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4176 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4177 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4178 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4179 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4180 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4181 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4182 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4183 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4184 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4185 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4186 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4187 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4188 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4189 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4190 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4191 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4192 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4193 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4194 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4195 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4196 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4197 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4198 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4199 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4200 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4201 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4202 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4203 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4205 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4207 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4212 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4214 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4215 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4216 (BYTE *)&buf, &size);
4217 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT),
4218 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4220 /* at a minimum, a CRL must contain an issuer: */
4221 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4222 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4223 (BYTE *)&buf, &size);
4224 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4227 CRL_INFO *info = (CRL_INFO *)buf;
4229 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4230 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4232 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4233 "Wrong issuer size %d\n", info->Issuer.cbData);
4234 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4235 "Unexpected issuer\n");
4238 /* check decoding with an empty CRL entry */
4239 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4240 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4241 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4242 todo_wine ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
4243 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4244 /* with a real CRL entry */
4245 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4246 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4247 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4248 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4251 CRL_INFO *info = (CRL_INFO *)buf;
4254 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4255 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4257 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4258 entry = info->rgCRLEntry;
4259 ok(entry->SerialNumber.cbData == 1,
4260 "Expected serial number size 1, got %d\n",
4261 entry->SerialNumber.cbData);
4262 ok(*entry->SerialNumber.pbData == *serialNum,
4263 "Expected serial number %d, got %d\n", *serialNum,
4264 *entry->SerialNumber.pbData);
4265 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4266 "Wrong issuer size %d\n", info->Issuer.cbData);
4267 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4268 "Unexpected issuer\n");
4270 /* a real CRL from verisign that has extensions */
4271 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4272 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4273 NULL, (BYTE *)&buf, &size);
4274 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4277 CRL_INFO *info = (CRL_INFO *)buf;
4280 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4281 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4283 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4284 entry = info->rgCRLEntry;
4285 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4289 /* another real CRL from verisign that has lots of entries */
4290 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4291 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4292 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4293 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4296 CRL_INFO *info = (CRL_INFO *)buf;
4298 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4299 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4301 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4305 /* and finally, with an extension */
4306 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4307 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4308 NULL, (BYTE *)&buf, &size);
4309 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4312 CRL_INFO *info = (CRL_INFO *)buf;
4315 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4316 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4318 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4319 entry = info->rgCRLEntry;
4320 ok(entry->SerialNumber.cbData == 1,
4321 "Expected serial number size 1, got %d\n",
4322 entry->SerialNumber.cbData);
4323 ok(*entry->SerialNumber.pbData == *serialNum,
4324 "Expected serial number %d, got %d\n", *serialNum,
4325 *entry->SerialNumber.pbData);
4326 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4327 "Wrong issuer size %d\n", info->Issuer.cbData);
4328 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4329 "Unexpected issuer\n");
4330 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4333 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4334 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4335 NULL, (BYTE *)&buf, &size);
4336 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4339 CRL_INFO *info = (CRL_INFO *)buf;
4341 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4345 /* And again, with an issuing dist point */
4346 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4347 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4348 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4349 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4352 CRL_INFO *info = (CRL_INFO *)buf;
4354 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4360 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4361 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4362 static const BYTE encodedUsage[] = {
4363 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4364 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4365 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4367 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4372 CERT_ENHKEY_USAGE usage;
4374 /* Test with empty usage */
4375 usage.cUsageIdentifier = 0;
4376 ret = CryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4377 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4378 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4381 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4382 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4385 /* Test with a few usages */
4386 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4387 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4388 ret = CryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4389 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4390 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4393 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4394 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4399 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4405 ret = CryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4406 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4407 (BYTE *)&buf, &size);
4408 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4411 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4413 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4414 "Wrong size %d\n", size);
4415 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4416 usage->cUsageIdentifier);
4419 ret = CryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4420 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4421 (BYTE *)&buf, &size);
4422 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4425 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4428 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4429 "Wrong size %d\n", size);
4430 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4431 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4432 for (i = 0; i < usage->cUsageIdentifier; i++)
4433 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4434 "Expected OID %s, got %s\n", keyUsages[i],
4435 usage->rgpszUsageIdentifier[i]);
4440 static BYTE keyId[] = { 1,2,3,4 };
4441 static const BYTE authorityKeyIdWithId[] = {
4442 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4443 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4444 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4445 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4446 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4448 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4450 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4455 /* Test with empty id */
4456 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4457 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4458 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4461 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4462 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4465 /* With just a key id */
4466 info.KeyId.cbData = sizeof(keyId);
4467 info.KeyId.pbData = keyId;
4468 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4469 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4470 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4473 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4474 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4477 /* With just an issuer */
4478 info.KeyId.cbData = 0;
4479 info.CertIssuer.cbData = sizeof(encodedCommonName);
4480 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4481 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4482 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4483 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4486 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4488 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4491 /* With just a serial number */
4492 info.CertIssuer.cbData = 0;
4493 info.CertSerialNumber.cbData = sizeof(serialNum);
4494 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4495 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4496 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4497 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4500 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4502 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4507 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4513 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4514 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4515 (BYTE *)&buf, &size);
4516 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4519 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4521 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4523 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4524 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4525 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4528 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4529 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4530 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4531 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4534 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4536 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4538 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4539 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4540 "Unexpected key id\n");
4541 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4542 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4545 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4546 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4547 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4548 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4551 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4553 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4555 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4556 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4557 "Unexpected issuer len\n");
4558 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4559 sizeof(encodedCommonName)), "Unexpected issuer\n");
4560 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4563 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4564 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4565 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4566 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4569 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4571 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4573 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4574 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4575 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4576 "Unexpected serial number len\n");
4577 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4578 "Unexpected serial number\n");
4583 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4584 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4587 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4589 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4590 CERT_ALT_NAME_ENTRY entry = { 0 };
4595 /* Test with empty id */
4596 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4597 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4598 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4601 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4602 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4605 /* With just a key id */
4606 info.KeyId.cbData = sizeof(keyId);
4607 info.KeyId.pbData = keyId;
4608 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4609 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4610 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4613 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4615 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4618 /* With a bogus issuer name */
4619 info.KeyId.cbData = 0;
4620 info.AuthorityCertIssuer.cAltEntry = 1;
4621 info.AuthorityCertIssuer.rgAltEntry = &entry;
4622 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4623 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4624 ok(!ret && GetLastError() == E_INVALIDARG,
4625 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4626 /* With an issuer name */
4627 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4628 U(entry).pwszURL = (LPWSTR)url;
4629 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4630 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4631 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4634 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4636 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4637 "Unexpected value\n");
4640 /* With just a serial number */
4641 info.AuthorityCertIssuer.cAltEntry = 0;
4642 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4643 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4644 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4645 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4646 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4649 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4651 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4656 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4662 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4663 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4664 (BYTE *)&buf, &size);
4665 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4668 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4670 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4672 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4673 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4674 "Expected no issuer name entries\n");
4675 ok(info->AuthorityCertSerialNumber.cbData == 0,
4676 "Expected no serial number\n");
4679 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4680 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4681 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4682 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4685 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4687 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4689 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4690 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4691 "Unexpected key id\n");
4692 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4693 "Expected no issuer name entries\n");
4694 ok(info->AuthorityCertSerialNumber.cbData == 0,
4695 "Expected no serial number\n");
4698 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4699 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4700 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4701 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4704 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4706 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4708 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4709 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4710 "Expected 1 issuer entry, got %d\n",
4711 info->AuthorityCertIssuer.cAltEntry);
4712 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4713 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4714 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4715 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4716 url), "Unexpected URL\n");
4717 ok(info->AuthorityCertSerialNumber.cbData == 0,
4718 "Expected no serial number\n");
4721 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4722 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4723 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4724 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4727 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4729 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4731 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4732 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4733 "Expected no issuer name entries\n");
4734 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4735 "Unexpected serial number len\n");
4736 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4737 sizeof(serialNum)), "Unexpected serial number\n");
4742 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
4743 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
4745 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
4747 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
4748 0x03,0x02,0x01,0x01 };
4749 static BYTE bogusDER[] = { 1 };
4751 static void test_encodePKCSContentInfo(DWORD dwEncoding)
4756 CRYPT_CONTENT_INFO info = { 0 };
4757 char oid1[] = "1.2.3";
4759 SetLastError(0xdeadbeef);
4760 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
4761 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4762 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4763 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
4764 SetLastError(0xdeadbeef);
4765 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4766 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4767 ok(!ret && GetLastError() == E_INVALIDARG,
4768 "Expected E_INVALIDARG, got %x\n", GetLastError());
4769 info.pszObjId = oid1;
4770 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4771 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4772 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4775 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
4776 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
4779 info.Content.pbData = bogusDER;
4780 info.Content.cbData = sizeof(bogusDER);
4781 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4782 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4783 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
4786 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
4787 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
4790 info.Content.pbData = (BYTE *)ints[0].encoded;
4791 info.Content.cbData = ints[0].encoded[1] + 2;
4792 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4793 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4796 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
4797 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
4802 static const BYTE indefiniteSignedPKCSContent[] = {
4803 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
4804 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
4805 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
4806 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
4807 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
4808 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
4809 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
4810 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
4811 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
4812 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
4813 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
4814 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
4815 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
4816 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
4817 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
4818 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
4819 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
4820 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
4821 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
4822 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
4823 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
4824 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
4825 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
4826 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
4827 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
4828 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
4829 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
4830 0x00,0x00,0x00,0x00,0x00,0x00 };
4832 static void test_decodePKCSContentInfo(DWORD dwEncoding)
4837 CRYPT_CONTENT_INFO *info;
4839 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4840 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
4841 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4842 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4845 info = (CRYPT_CONTENT_INFO *)buf;
4847 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4849 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
4850 info->Content.cbData);
4853 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4854 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
4855 0, NULL, NULL, &size);
4856 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4857 SetLastError(0xdeadbeef);
4858 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4859 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
4860 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4861 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
4862 * I doubt an app depends on that.
4864 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
4865 GetLastError() == CRYPT_E_ASN1_CORRUPT),
4866 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
4868 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4869 intPKCSContentInfo, sizeof(intPKCSContentInfo),
4870 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4871 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4874 info = (CRYPT_CONTENT_INFO *)buf;
4876 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4878 ok(info->Content.cbData == ints[0].encoded[1] + 2,
4879 "Unexpected size %d\n", info->Content.cbData);
4880 ok(!memcmp(info->Content.pbData, ints[0].encoded,
4881 info->Content.cbData), "Unexpected value\n");
4884 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4885 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
4886 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4887 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4890 info = (CRYPT_CONTENT_INFO *)buf;
4892 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
4893 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
4894 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
4895 info->Content.cbData);
4900 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
4902 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
4904 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
4907 static void test_encodePKCSAttribute(DWORD dwEncoding)
4909 CRYPT_ATTRIBUTE attr = { 0 };
4913 CRYPT_ATTR_BLOB blob;
4914 char oid[] = "1.2.3";
4916 SetLastError(0xdeadbeef);
4917 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
4918 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4919 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4920 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
4921 SetLastError(0xdeadbeef);
4922 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4923 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4924 ok(!ret && GetLastError() == E_INVALIDARG,
4925 "Expected E_INVALIDARG, got %x\n", GetLastError());
4926 attr.pszObjId = oid;
4927 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4928 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4929 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4932 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
4933 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
4936 blob.cbData = sizeof(bogusDER);
4937 blob.pbData = bogusDER;
4939 attr.rgValue = &blob;
4940 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4941 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4942 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4945 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
4946 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
4949 blob.pbData = (BYTE *)ints[0].encoded;
4950 blob.cbData = ints[0].encoded[1] + 2;
4951 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4952 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4955 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
4956 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
4961 static void test_decodePKCSAttribute(DWORD dwEncoding)
4966 CRYPT_ATTRIBUTE *attr;
4968 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
4969 emptyPKCSAttr, sizeof(emptyPKCSAttr),
4970 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4971 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4974 attr = (CRYPT_ATTRIBUTE *)buf;
4976 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4978 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
4981 SetLastError(0xdeadbeef);
4982 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
4983 bogusPKCSAttr, sizeof(bogusPKCSAttr),
4984 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4985 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
4986 * I doubt an app depends on that.
4988 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
4989 GetLastError() == CRYPT_E_ASN1_CORRUPT),
4990 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
4992 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
4993 intPKCSAttr, sizeof(intPKCSAttr),
4994 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4995 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4998 attr = (CRYPT_ATTRIBUTE *)buf;
5000 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5002 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5003 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5004 "Unexpected size %d\n", attr->rgValue[0].cbData);
5005 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5006 attr->rgValue[0].cbData), "Unexpected value\n");
5010 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5011 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5012 0x2a,0x03,0x31,0x00 };
5013 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5014 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5016 static void test_encodePKCSAttributes(DWORD dwEncoding)
5018 CRYPT_ATTRIBUTES attributes = { 0 };
5019 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5020 CRYPT_ATTR_BLOB blob;
5024 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5026 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5027 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5028 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5031 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5032 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5035 attributes.cAttr = 1;
5036 attributes.rgAttr = attr;
5037 SetLastError(0xdeadbeef);
5038 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5039 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5040 ok(!ret && GetLastError() == E_INVALIDARG,
5041 "Expected E_INVALIDARG, got %x\n", GetLastError());
5042 attr[0].pszObjId = oid1;
5043 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5044 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5047 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5048 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5051 attr[1].pszObjId = oid2;
5053 attr[1].rgValue = &blob;
5054 blob.pbData = (BYTE *)ints[0].encoded;
5055 blob.cbData = ints[0].encoded[1] + 2;
5056 attributes.cAttr = 2;
5057 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5058 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5059 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5062 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5063 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5068 static void test_decodePKCSAttributes(DWORD dwEncoding)
5073 CRYPT_ATTRIBUTES *attributes;
5075 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5076 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5077 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5078 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5081 attributes = (CRYPT_ATTRIBUTES *)buf;
5082 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5086 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5087 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5088 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5089 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5092 attributes = (CRYPT_ATTRIBUTES *)buf;
5093 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5095 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5096 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5097 ok(attributes->rgAttr[0].cValue == 0,
5098 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5101 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5102 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5103 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5104 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5107 attributes = (CRYPT_ATTRIBUTES *)buf;
5108 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5110 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5111 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5112 ok(attributes->rgAttr[0].cValue == 0,
5113 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5114 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5115 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5116 ok(attributes->rgAttr[1].cValue == 1,
5117 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5118 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5119 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5120 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5121 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5126 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
5127 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5129 static const BYTE minimalPKCSSigner[] = {
5130 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5131 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5132 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
5133 static const BYTE PKCSSignerWithSerial[] = {
5134 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5135 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5136 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5138 static const BYTE PKCSSignerWithHashAlgo[] = {
5139 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5140 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5141 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5143 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
5144 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5145 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5146 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5147 0x06,0x05,0x00,0x04,0x00 };
5148 static const BYTE PKCSSignerWithHash[] = {
5149 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5150 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5151 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5152 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
5153 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5154 static const BYTE PKCSSignerWithAuthAttr[] = {
5155 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5156 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5157 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
5158 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
5159 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
5160 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
5161 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5163 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
5165 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
5169 CMSG_SIGNER_INFO info = { 0 };
5170 char oid_common_name[] = szOID_COMMON_NAME;
5171 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
5172 (LPBYTE)encodedCommonName };
5173 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
5175 SetLastError(0xdeadbeef);
5176 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5177 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5178 ok(!ret && GetLastError() == E_INVALIDARG,
5179 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5180 /* To be encoded, a signer must have an issuer at least, and the encoding
5181 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
5182 * see decoding tests.)
5184 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
5185 info.Issuer.pbData = encodedCommonNameNoNull;
5186 SetLastError(0xdeadbeef);
5187 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5188 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5189 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5190 ok(!ret && GetLastError() == E_INVALIDARG,
5191 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5194 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5197 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
5198 if (size == sizeof(minimalPKCSSigner))
5199 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
5201 ok(0, "Unexpected value\n");
5205 info.SerialNumber.cbData = sizeof(serialNum);
5206 info.SerialNumber.pbData = (BYTE *)serialNum;
5207 SetLastError(0xdeadbeef);
5208 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5209 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5210 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5211 ok(!ret && GetLastError() == E_INVALIDARG,
5212 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5215 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5218 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
5220 if (size == sizeof(PKCSSignerWithSerial))
5221 ok(!memcmp(buf, PKCSSignerWithSerial, size),
5222 "Unexpected value\n");
5224 ok(0, "Unexpected value\n");
5228 info.HashAlgorithm.pszObjId = oid1;
5229 SetLastError(0xdeadbeef);
5230 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5231 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5232 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5233 ok(!ret && GetLastError() == E_INVALIDARG,
5234 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5237 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5240 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
5242 if (size == sizeof(PKCSSignerWithHashAlgo))
5243 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
5244 "Unexpected value\n");
5246 ok(0, "Unexpected value\n");
5250 info.HashEncryptionAlgorithm.pszObjId = oid2;
5251 SetLastError(0xdeadbeef);
5252 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5253 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5254 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5255 ok(!ret && GetLastError() == E_INVALIDARG,
5256 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5259 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5262 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
5263 "Unexpected size %d\n", size);
5264 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
5265 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
5266 "Unexpected value\n");
5268 ok(0, "Unexpected value\n");
5272 info.EncryptedHash.cbData = sizeof(hash);
5273 info.EncryptedHash.pbData = (BYTE *)hash;
5274 SetLastError(0xdeadbeef);
5275 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5276 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5277 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5278 ok(!ret && GetLastError() == E_INVALIDARG,
5279 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5282 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5285 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
5287 if (size == sizeof(PKCSSignerWithHash))
5288 ok(!memcmp(buf, PKCSSignerWithHash, size),
5289 "Unexpected value\n");
5291 ok(0, "Unexpected value\n");
5295 info.AuthAttrs.cAttr = 1;
5296 info.AuthAttrs.rgAttr = &attr;
5297 SetLastError(0xdeadbeef);
5298 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5299 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5300 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5301 ok(!ret && GetLastError() == E_INVALIDARG,
5302 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5305 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5308 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
5310 if (size == sizeof(PKCSSignerWithAuthAttr))
5311 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
5312 "Unexpected value\n");
5314 ok(0, "Unexpected value\n");
5320 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
5325 CMSG_SIGNER_INFO *info;
5327 /* A PKCS signer can't be decoded without a serial number. */
5328 SetLastError(0xdeadbeef);
5329 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5330 minimalPKCSSigner, sizeof(minimalPKCSSigner),
5331 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5332 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
5333 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
5334 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5335 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
5336 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5337 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5340 info = (CMSG_SIGNER_INFO *)buf;
5341 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5343 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5344 "Unexpected size %d\n", info->Issuer.cbData);
5345 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5346 info->Issuer.cbData), "Unexpected value\n");
5347 ok(info->SerialNumber.cbData == sizeof(serialNum),
5348 "Unexpected size %d\n", info->SerialNumber.cbData);
5349 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5350 "Unexpected value\n");
5353 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5354 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
5355 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5358 info = (CMSG_SIGNER_INFO *)buf;
5359 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5361 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5362 "Unexpected size %d\n", info->Issuer.cbData);
5363 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5364 info->Issuer.cbData), "Unexpected value\n");
5365 ok(info->SerialNumber.cbData == sizeof(serialNum),
5366 "Unexpected size %d\n", info->SerialNumber.cbData);
5367 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5368 "Unexpected value\n");
5369 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5370 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5373 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5374 PKCSSignerWithHashAndEncryptionAlgo,
5375 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
5376 NULL, (BYTE *)&buf, &size);
5379 info = (CMSG_SIGNER_INFO *)buf;
5380 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5382 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5383 "Unexpected size %d\n", info->Issuer.cbData);
5384 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5385 info->Issuer.cbData), "Unexpected value\n");
5386 ok(info->SerialNumber.cbData == sizeof(serialNum),
5387 "Unexpected size %d\n", info->SerialNumber.cbData);
5388 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5389 "Unexpected value\n");
5390 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5391 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5392 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
5393 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
5396 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5397 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
5398 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5401 info = (CMSG_SIGNER_INFO *)buf;
5402 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5404 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5405 "Unexpected size %d\n", info->Issuer.cbData);
5406 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5407 info->Issuer.cbData), "Unexpected value\n");
5408 ok(info->SerialNumber.cbData == sizeof(serialNum),
5409 "Unexpected size %d\n", info->SerialNumber.cbData);
5410 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5411 "Unexpected value\n");
5412 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5413 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5414 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
5415 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
5416 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
5417 info->EncryptedHash.cbData);
5418 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
5419 "Unexpected value\n");
5422 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5423 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
5424 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5427 info = (CMSG_SIGNER_INFO *)buf;
5428 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
5429 info->AuthAttrs.cAttr);
5430 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
5431 "Expected %s, got %s\n", szOID_COMMON_NAME,
5432 info->AuthAttrs.rgAttr[0].pszObjId);
5433 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
5434 info->AuthAttrs.rgAttr[0].cValue);
5435 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
5436 sizeof(encodedCommonName), "Unexpected size %d\n",
5437 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
5438 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
5439 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
5444 /* Free *pInfo with HeapFree */
5445 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
5452 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
5454 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
5455 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5456 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5457 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
5459 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5460 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5461 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
5463 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5464 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5465 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
5466 0, NULL, NULL, &size);
5467 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5468 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5469 /* Test with no key */
5470 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
5471 0, NULL, NULL, &size);
5472 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
5474 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
5475 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
5478 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
5479 NULL, 0, NULL, NULL, &size);
5480 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
5481 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
5484 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
5485 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
5486 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
5490 /* By default (we passed NULL as the OID) the OID is
5493 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
5494 "Expected %s, got %s\n", szOID_RSA_RSA,
5495 (*pInfo)->Algorithm.pszObjId);
5501 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
5502 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
5503 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
5504 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
5505 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
5506 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
5507 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
5508 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
5509 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
5510 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
5511 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
5512 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
5513 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
5514 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
5515 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
5516 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
5517 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
5518 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
5519 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
5520 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
5521 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
5522 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
5523 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
5524 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
5525 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
5527 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
5531 PCCERT_CONTEXT context;
5534 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
5535 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
5536 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
5537 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
5540 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
5541 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
5542 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
5543 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
5544 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
5545 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
5546 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
5548 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5549 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5550 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
5552 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
5553 CryptDestroyKey(key);
5555 /* Test importing a public key from a certificate context */
5556 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
5557 sizeof(expiredCert));
5558 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
5562 ok(!strcmp(szOID_RSA_RSA,
5563 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
5564 "Expected %s, got %s\n", szOID_RSA_RSA,
5565 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
5566 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
5567 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
5568 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
5569 CryptDestroyKey(key);
5570 CertFreeCertificateContext(context);
5574 static const char cspName[] = "WineCryptTemp";
5576 static void testPortPublicKeyInfo(void)
5580 PCERT_PUBLIC_KEY_INFO info = NULL;
5582 /* Just in case a previous run failed, delete this thing */
5583 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5584 CRYPT_DELETEKEYSET);
5585 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5588 testExportPublicKey(csp, &info);
5589 testImportPublicKey(csp, info);
5591 HeapFree(GetProcessHeap(), 0, info);
5592 CryptReleaseContext(csp, 0);
5593 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5594 CRYPT_DELETEKEYSET);
5599 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
5600 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
5603 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
5605 test_encodeInt(encodings[i]);
5606 test_decodeInt(encodings[i]);
5607 test_encodeEnumerated(encodings[i]);
5608 test_decodeEnumerated(encodings[i]);
5609 test_encodeFiletime(encodings[i]);
5610 test_decodeFiletime(encodings[i]);
5611 test_encodeName(encodings[i]);
5612 test_decodeName(encodings[i]);
5613 test_encodeUnicodeName(encodings[i]);
5614 test_decodeUnicodeName(encodings[i]);
5615 test_encodeNameValue(encodings[i]);
5616 test_decodeNameValue(encodings[i]);
5617 test_encodeUnicodeNameValue(encodings[i]);
5618 test_decodeUnicodeNameValue(encodings[i]);
5619 test_encodeAltName(encodings[i]);
5620 test_decodeAltName(encodings[i]);
5621 test_encodeOctets(encodings[i]);
5622 test_decodeOctets(encodings[i]);
5623 test_encodeBits(encodings[i]);
5624 test_decodeBits(encodings[i]);
5625 test_encodeBasicConstraints(encodings[i]);
5626 test_decodeBasicConstraints(encodings[i]);
5627 test_encodeRsaPublicKey(encodings[i]);
5628 test_decodeRsaPublicKey(encodings[i]);
5629 test_encodeSequenceOfAny(encodings[i]);
5630 test_decodeSequenceOfAny(encodings[i]);
5631 test_encodeExtensions(encodings[i]);
5632 test_decodeExtensions(encodings[i]);
5633 test_encodePublicKeyInfo(encodings[i]);
5634 test_decodePublicKeyInfo(encodings[i]);
5635 test_encodeCertToBeSigned(encodings[i]);
5636 test_decodeCertToBeSigned(encodings[i]);
5637 test_encodeCert(encodings[i]);
5638 test_decodeCert(encodings[i]);
5639 test_encodeCRLDistPoints(encodings[i]);
5640 test_decodeCRLDistPoints(encodings[i]);
5641 test_encodeCRLIssuingDistPoint(encodings[i]);
5642 test_decodeCRLIssuingDistPoint(encodings[i]);
5643 test_encodeCRLToBeSigned(encodings[i]);
5644 test_decodeCRLToBeSigned(encodings[i]);
5645 test_encodeEnhancedKeyUsage(encodings[i]);
5646 test_decodeEnhancedKeyUsage(encodings[i]);
5647 test_encodeAuthorityKeyId(encodings[i]);
5648 test_decodeAuthorityKeyId(encodings[i]);
5649 test_encodeAuthorityKeyId2(encodings[i]);
5650 test_decodeAuthorityKeyId2(encodings[i]);
5651 test_encodePKCSContentInfo(encodings[i]);
5652 test_decodePKCSContentInfo(encodings[i]);
5653 test_encodePKCSAttribute(encodings[i]);
5654 test_decodePKCSAttribute(encodings[i]);
5655 test_encodePKCSAttributes(encodings[i]);
5656 test_decodePKCSAttributes(encodings[i]);
5657 test_encodePKCSSignerInfo(encodings[i]);
5658 test_decodePKCSSignerInfo(encodings[i]);
5660 testPortPublicKeyInfo();