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 const char *printSystemTime(const SYSTEMTIME *st)
469 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay,
470 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
474 static const char *printFileTime(const FILETIME *ft)
479 FileTimeToSystemTime(ft, &st);
480 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay,
481 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
485 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got)
489 FileTimeToSystemTime(got, &st);
490 ok(expected->wYear == st.wYear &&
491 expected->wMonth == st.wMonth &&
492 expected->wDay == st.wDay &&
493 expected->wHour == st.wHour &&
494 expected->wMinute == st.wMinute &&
495 expected->wSecond == st.wSecond &&
496 abs(expected->wMilliseconds - st.wMilliseconds) <= 1,
497 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
498 printSystemTime(expected), printFileTime(got));
501 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
502 const struct encodedFiletime *time)
505 DWORD size = sizeof(ft);
508 ret = CryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
509 time->encodedTime[1] + 2, 0, NULL, &ft, &size);
510 /* years other than 1950-2050 are not allowed for encodings other than
511 * X509_CHOICE_OF_TIME.
513 if (structType == X509_CHOICE_OF_TIME ||
514 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
516 ok(ret, "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
518 compareTime(&time->sysTime, &ft);
521 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
522 "Expected CRYPT_E_ASN1_BADTAG, got 0x%08x\n", GetLastError());
525 static const BYTE bin20[] = {
526 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
527 static const BYTE bin21[] = {
528 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
529 static const BYTE bin22[] = {
530 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
532 static const struct encodedFiletime times[] = {
533 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
534 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
535 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
538 static void test_encodeFiletime(DWORD dwEncoding)
542 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
544 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]);
545 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, ×[i]);
546 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, ×[i]);
550 static const BYTE bin23[] = {
551 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
552 static const BYTE bin24[] = {
553 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
554 static const BYTE bin25[] = {
555 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
556 static const BYTE bin26[] = {
557 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
558 static const BYTE bin27[] = {
559 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
560 static const BYTE bin28[] = {
561 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
562 static const BYTE bin29[] = {
563 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
564 static const BYTE bin30[] = {
565 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
566 static const BYTE bin31[] = {
567 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
568 static const BYTE bin32[] = {
569 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
570 static const BYTE bin33[] = {
571 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
572 static const BYTE bin34[] = {
573 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
574 static const BYTE bin35[] = {
575 0x17,0x08, '4','5','0','6','0','6','1','6'};
576 static const BYTE bin36[] = {
577 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
578 static const BYTE bin37[] = {
579 0x18,0x04, '2','1','4','5'};
580 static const BYTE bin38[] = {
581 0x18,0x08, '2','1','4','5','0','6','0','6'};
583 static void test_decodeFiletime(DWORD dwEncoding)
585 static const struct encodedFiletime otherTimes[] = {
586 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
587 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
588 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
589 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
590 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
591 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
592 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
593 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
594 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
595 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
596 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
597 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
599 /* An oddball case that succeeds in Windows, but doesn't seem correct
600 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
602 static const unsigned char *bogusTimes[] = {
603 /* oddly, this succeeds on Windows, with year 2765
604 "\x18" "\x0f" "21r50606161000Z",
612 FILETIME ft1 = { 0 }, ft2 = { 0 };
615 /* Check bogus length with non-NULL buffer */
616 ret = SystemTimeToFileTime(×[0].sysTime, &ft1);
617 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
619 ret = CryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
620 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
621 ok(!ret && GetLastError() == ERROR_MORE_DATA,
622 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
624 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
626 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]);
627 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, ×[i]);
628 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, ×[i]);
630 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
632 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
633 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
634 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
636 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
639 ret = CryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
640 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
641 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
642 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
646 static const char commonName[] = "Juan Lang";
647 static const char surName[] = "Lang";
649 static const BYTE emptySequence[] = { 0x30, 0 };
650 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
651 static const BYTE twoRDNs[] = {
652 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
653 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
654 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
655 static const BYTE encodedTwoRDNs[] = {
656 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
657 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
658 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
662 static const BYTE us[] = { 0x55, 0x53 };
663 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
665 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
666 0x6f, 0x6c, 0x69, 0x73 };
667 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
668 0x76, 0x65, 0x72, 0x73 };
669 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
670 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
671 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
673 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
674 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
676 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
677 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
679 static CHAR oid_us[] = "2.5.4.6",
680 oid_minnesota[] = "2.5.4.8",
681 oid_minneapolis[] = "2.5.4.7",
682 oid_codeweavers[] = "2.5.4.10",
683 oid_wine[] = "2.5.4.11",
684 oid_localhostAttr[] = "2.5.4.3",
685 oid_aric[] = "1.2.840.113549.1.9.1";
686 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
688 { RDNA(minneapolis) },
689 { RDNA(codeweavers) },
691 { RDNA(localhostAttr) },
693 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
694 { RDNA(localhostAttr) },
696 { RDNA(minneapolis) },
697 { RDNA(codeweavers) },
704 static const BYTE encodedRDNAttrs[] = {
705 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
706 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
707 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
708 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
709 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
710 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
711 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
712 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
713 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
714 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
717 static void test_encodeName(DWORD dwEncoding)
719 CERT_RDN_ATTR attrs[2];
722 static CHAR oid_common_name[] = szOID_COMMON_NAME,
723 oid_sur_name[] = szOID_SUR_NAME;
728 /* Test with NULL pvStructInfo */
729 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
730 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
731 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
732 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
733 /* Test with empty CERT_NAME_INFO */
736 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
737 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
738 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
741 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
742 "Got unexpected encoding for empty name\n");
745 /* Test with bogus CERT_RDN */
747 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
748 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
749 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
750 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
751 /* Test with empty CERT_RDN */
753 rdn.rgRDNAttr = NULL;
756 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
757 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
758 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
761 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
762 "Got unexpected encoding for empty RDN array\n");
765 /* Test with bogus attr array */
767 rdn.rgRDNAttr = NULL;
768 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
769 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
770 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
771 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
772 /* oddly, a bogus OID is accepted by Windows XP; not testing.
773 attrs[0].pszObjId = "bogus";
774 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
775 attrs[0].Value.cbData = sizeof(commonName);
776 attrs[0].Value.pbData = (BYTE *)commonName;
778 rdn.rgRDNAttr = attrs;
779 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
780 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
781 ok(!ret, "Expected failure, got success\n");
783 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
784 * the encoded attributes to be swapped.
786 attrs[0].pszObjId = oid_common_name;
787 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
788 attrs[0].Value.cbData = sizeof(commonName);
789 attrs[0].Value.pbData = (BYTE *)commonName;
790 attrs[1].pszObjId = oid_sur_name;
791 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
792 attrs[1].Value.cbData = sizeof(surName);
793 attrs[1].Value.pbData = (BYTE *)surName;
795 rdn.rgRDNAttr = attrs;
796 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
797 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
798 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
801 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
802 "Got unexpected encoding for two RDN array\n");
805 /* A name can be "encoded" with previously encoded RDN attrs. */
806 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
807 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
808 attrs[0].Value.cbData = sizeof(twoRDNs);
810 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
811 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
812 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
815 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
816 ok(!memcmp(buf, encodedTwoRDNs, size),
817 "Unexpected value for re-endoded two RDN array\n");
820 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
822 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
823 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
824 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
825 ok(!ret && GetLastError() == E_INVALIDARG,
826 "Expected E_INVALIDARG, got %08x\n", GetLastError());
827 /* Test a more complex name */
828 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
829 rdn.rgRDNAttr = (PCERT_RDN_ATTR)rdnAttrs;
834 ret = CryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
835 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
836 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
839 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
840 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
845 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
846 static WCHAR surNameW[] = { 'L','a','n','g',0 };
848 static const BYTE twoRDNsNoNull[] = {
849 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
850 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
851 0x20,0x4c,0x61,0x6e,0x67 };
852 static const BYTE anyType[] = {
853 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
854 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
855 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
856 0x61,0x4c,0x67,0x6e };
858 static void test_encodeUnicodeName(DWORD dwEncoding)
860 CERT_RDN_ATTR attrs[2];
863 static CHAR oid_common_name[] = szOID_COMMON_NAME,
864 oid_sur_name[] = szOID_SUR_NAME;
869 /* Test with NULL pvStructInfo */
870 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
871 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
872 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
873 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
874 /* Test with empty CERT_NAME_INFO */
877 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
878 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
879 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
882 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
883 "Got unexpected encoding for empty name\n");
886 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
887 * encoding (the NULL).
889 attrs[0].pszObjId = oid_common_name;
890 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
891 attrs[0].Value.cbData = sizeof(commonNameW);
892 attrs[0].Value.pbData = (BYTE *)commonNameW;
894 rdn.rgRDNAttr = attrs;
897 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
898 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
899 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
900 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
901 ok(size == 9, "Unexpected error index %08x\n", size);
902 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
903 * forces the order of the encoded attributes to be swapped.
905 attrs[0].pszObjId = oid_common_name;
906 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
907 attrs[0].Value.cbData = 0;
908 attrs[0].Value.pbData = (BYTE *)commonNameW;
909 attrs[1].pszObjId = oid_sur_name;
910 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
911 attrs[1].Value.cbData = 0;
912 attrs[1].Value.pbData = (BYTE *)surNameW;
914 rdn.rgRDNAttr = attrs;
917 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
918 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
919 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
922 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
923 "Got unexpected encoding for two RDN array\n");
926 /* A name can be "encoded" with previously encoded RDN attrs. */
927 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
928 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
929 attrs[0].Value.cbData = sizeof(twoRDNs);
931 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
932 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
933 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
936 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
937 ok(!memcmp(buf, encodedTwoRDNs, size),
938 "Unexpected value for re-endoded two RDN array\n");
941 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
943 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
944 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
945 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
946 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
949 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
950 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
955 static void compareNameValues(const CERT_NAME_VALUE *expected,
956 const CERT_NAME_VALUE *got)
958 ok(got->dwValueType == expected->dwValueType,
959 "Expected string type %d, got %d\n", expected->dwValueType,
961 ok(got->Value.cbData == expected->Value.cbData,
962 "String type %d: unexpected data size, got %d, expected %d\n",
963 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
964 if (got->Value.cbData && got->Value.pbData)
965 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
966 min(got->Value.cbData, expected->Value.cbData)),
967 "String type %d: unexpected value\n", expected->dwValueType);
970 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
971 const CERT_RDN_ATTR *got)
973 if (expected->pszObjId && strlen(expected->pszObjId))
975 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
979 ok(!strcmp(got->pszObjId, expected->pszObjId),
980 "Got unexpected OID %s, expected %s\n", got->pszObjId,
984 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
985 (const CERT_NAME_VALUE *)&got->dwValueType);
988 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
990 ok(got->cRDNAttr == expected->cRDNAttr,
991 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
996 for (i = 0; i < got->cRDNAttr; i++)
997 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1001 static void compareNames(const CERT_NAME_INFO *expected,
1002 const CERT_NAME_INFO *got)
1004 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
1005 expected->cRDN, got->cRDN);
1010 for (i = 0; i < got->cRDN; i++)
1011 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1015 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1016 static const BYTE twoRDNsExtraBytes[] = {
1017 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1018 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1019 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1021 static void test_decodeName(DWORD dwEncoding)
1027 CERT_NAME_INFO info = { 1, &rdn };
1029 /* test empty name */
1031 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1032 emptySequence[1] + 2,
1033 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1034 (BYTE *)&buf, &bufSize);
1035 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1036 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1037 * decoder works the same way, so only test the count.
1041 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1042 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1043 "Expected 0 RDNs in empty info, got %d\n",
1044 ((CERT_NAME_INFO *)buf)->cRDN);
1047 /* test empty name with indefinite-length encoding */
1048 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1049 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1050 (BYTE *)&buf, &bufSize);
1051 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1054 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1055 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1056 "Expected 0 RDNs in empty info, got %d\n",
1057 ((CERT_NAME_INFO *)buf)->cRDN);
1060 /* test empty RDN */
1062 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1064 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1065 (BYTE *)&buf, &bufSize);
1066 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1069 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1071 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1072 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1073 "Got unexpected value for empty RDN\n");
1076 /* test two RDN attrs */
1078 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1080 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1081 (BYTE *)&buf, &bufSize);
1082 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1085 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1086 oid_common_name[] = szOID_COMMON_NAME;
1088 CERT_RDN_ATTR attrs[] = {
1089 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1090 (BYTE *)surName } },
1091 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1092 (BYTE *)commonName } },
1095 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1096 rdn.rgRDNAttr = attrs;
1097 compareNames(&info, (CERT_NAME_INFO *)buf);
1100 /* test that two RDN attrs with extra bytes succeeds */
1102 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1103 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1104 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1105 /* And, a slightly more complicated name */
1108 ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1109 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1110 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1113 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1114 rdn.rgRDNAttr = (PCERT_RDN_ATTR)decodedRdnAttrs;
1115 compareNames(&info, (CERT_NAME_INFO *)buf);
1120 static void test_decodeUnicodeName(DWORD dwEncoding)
1126 CERT_NAME_INFO info = { 1, &rdn };
1128 /* test empty name */
1130 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1131 emptySequence[1] + 2,
1132 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1133 (BYTE *)&buf, &bufSize);
1134 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1137 ok(bufSize == sizeof(CERT_NAME_INFO),
1138 "Got wrong bufSize %d\n", bufSize);
1139 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1140 "Expected 0 RDNs in empty info, got %d\n",
1141 ((CERT_NAME_INFO *)buf)->cRDN);
1144 /* test empty RDN */
1146 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1148 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1149 (BYTE *)&buf, &bufSize);
1150 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1153 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1155 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1156 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1157 "Got unexpected value for empty RDN\n");
1160 /* test two RDN attrs */
1162 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1163 sizeof(twoRDNsNoNull),
1164 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1165 (BYTE *)&buf, &bufSize);
1166 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1169 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1170 oid_common_name[] = szOID_COMMON_NAME;
1172 CERT_RDN_ATTR attrs[] = {
1173 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1174 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1175 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1176 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1179 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1180 rdn.rgRDNAttr = attrs;
1181 compareNames(&info, (CERT_NAME_INFO *)buf);
1186 struct EncodedNameValue
1188 CERT_NAME_VALUE value;
1189 const BYTE *encoded;
1193 static const char bogusIA5[] = "\x80";
1194 static const char bogusPrintable[] = "~";
1195 static const char bogusNumeric[] = "A";
1196 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1197 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1198 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1199 static BYTE octetCommonNameValue[] = {
1200 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1201 static BYTE numericCommonNameValue[] = {
1202 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1203 static BYTE printableCommonNameValue[] = {
1204 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1205 static BYTE t61CommonNameValue[] = {
1206 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1207 static BYTE videotexCommonNameValue[] = {
1208 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1209 static BYTE ia5CommonNameValue[] = {
1210 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1211 static BYTE graphicCommonNameValue[] = {
1212 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1213 static BYTE visibleCommonNameValue[] = {
1214 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1215 static BYTE generalCommonNameValue[] = {
1216 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1217 static BYTE bmpCommonNameValue[] = {
1218 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1219 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1220 static BYTE utf8CommonNameValue[] = {
1221 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1223 static struct EncodedNameValue nameValues[] = {
1224 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1225 octetCommonNameValue, sizeof(octetCommonNameValue) },
1226 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1227 numericCommonNameValue, sizeof(numericCommonNameValue) },
1228 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1229 printableCommonNameValue, sizeof(printableCommonNameValue) },
1230 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1231 t61CommonNameValue, sizeof(t61CommonNameValue) },
1232 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1233 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1234 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1235 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1236 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1237 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1238 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1239 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1240 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1241 generalCommonNameValue, sizeof(generalCommonNameValue) },
1242 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1243 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1244 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1245 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1246 /* The following tests succeed under Windows, but really should fail,
1247 * they contain characters that are illegal for the encoding. I'm
1248 * including them to justify my lazy encoding.
1250 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1252 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1253 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1254 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1255 bin44, sizeof(bin44) },
1258 static void test_encodeNameValue(DWORD dwEncoding)
1263 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1265 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1266 value.Value.pbData = printableCommonNameValue;
1267 value.Value.cbData = sizeof(printableCommonNameValue);
1268 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1269 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1270 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1273 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1275 ok(!memcmp(buf, printableCommonNameValue, size),
1276 "Unexpected encoding\n");
1279 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1281 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1282 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1284 ok(ret, "Type %d: CryptEncodeObjectEx failed: %08x\n",
1285 nameValues[i].value.dwValueType, GetLastError());
1288 ok(size == nameValues[i].encodedSize,
1289 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1290 ok(!memcmp(buf, nameValues[i].encoded, size),
1291 "Got unexpected encoding\n");
1297 static void test_decodeNameValue(DWORD dwEncoding)
1304 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1306 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1307 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1308 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1309 (BYTE *)&buf, &bufSize);
1310 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1311 nameValues[i].value.dwValueType, GetLastError());
1314 compareNameValues(&nameValues[i].value,
1315 (const CERT_NAME_VALUE *)buf);
1321 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1322 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1323 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1324 'h','q','.','o','r','g',0 };
1325 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1326 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1328 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1330 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1331 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1332 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1333 static const BYTE localhost[] = { 127, 0, 0, 1 };
1334 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1336 static const unsigned char encodedCommonName[] = {
1337 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1338 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1339 static const BYTE encodedDirectoryName[] = {
1340 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1341 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1343 static void test_encodeAltName(DWORD dwEncoding)
1345 CERT_ALT_NAME_INFO info = { 0 };
1346 CERT_ALT_NAME_ENTRY entry = { 0 };
1350 char oid[] = "1.2.3";
1352 /* Test with empty info */
1353 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1354 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1357 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1358 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1361 /* Test with an empty entry */
1363 info.rgAltEntry = &entry;
1364 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1365 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1366 ok(!ret && GetLastError() == E_INVALIDARG,
1367 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1368 /* Test with an empty pointer */
1369 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1370 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1371 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1374 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1375 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1378 /* Test with a real URL */
1379 U(entry).pwszURL = (LPWSTR)url;
1380 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1381 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1384 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1385 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1388 /* Now with the URL containing an invalid IA5 char */
1389 U(entry).pwszURL = (LPWSTR)nihongoURL;
1390 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1391 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1392 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1393 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1394 /* The first invalid character is at index 7 */
1395 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1396 "Expected invalid char at index 7, got %d\n",
1397 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1398 /* Now with the URL missing a scheme */
1399 U(entry).pwszURL = (LPWSTR)dnsName;
1400 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1401 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1402 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1405 /* This succeeds, but it shouldn't, so don't worry about conforming */
1408 /* Now with a DNS name */
1409 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1410 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1411 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1412 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1415 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1416 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1419 /* Test with an IP address */
1420 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1421 U(entry).IPAddress.cbData = sizeof(localhost);
1422 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1423 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1424 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1427 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1428 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1432 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1433 U(entry).pszRegisteredID = oid;
1434 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1435 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1438 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1439 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1442 /* Test with directory name */
1443 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1444 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1445 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1446 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1447 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1450 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1451 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1456 static void test_decodeAltName(DWORD dwEncoding)
1458 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1460 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1465 CERT_ALT_NAME_INFO *info;
1467 /* Test some bogus ones first */
1468 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1469 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1470 NULL, (BYTE *)&buf, &bufSize);
1471 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1472 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
1473 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1474 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1476 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
1477 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
1478 /* Now expected cases */
1479 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1480 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1482 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1485 info = (CERT_ALT_NAME_INFO *)buf;
1487 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1491 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1492 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1494 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1497 info = (CERT_ALT_NAME_INFO *)buf;
1499 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1501 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1502 "Expected CERT_ALT_NAME_URL, got %d\n",
1503 info->rgAltEntry[0].dwAltNameChoice);
1504 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1505 "Expected empty URL\n");
1508 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1509 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1510 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1511 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1512 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1514 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1517 info = (CERT_ALT_NAME_INFO *)buf;
1519 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1521 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1522 "Expected CERT_ALT_NAME_URL, got %d\n",
1523 info->rgAltEntry[0].dwAltNameChoice);
1524 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1527 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1528 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1530 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1533 info = (CERT_ALT_NAME_INFO *)buf;
1535 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1537 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1538 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1539 info->rgAltEntry[0].dwAltNameChoice);
1540 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1541 "Unexpected DNS name\n");
1544 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1545 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1547 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1550 info = (CERT_ALT_NAME_INFO *)buf;
1552 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1554 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1555 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1556 info->rgAltEntry[0].dwAltNameChoice);
1557 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1558 "Unexpected IP address length %d\n",
1559 U(info->rgAltEntry[0]).IPAddress.cbData);
1560 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1561 sizeof(localhost)), "Unexpected IP address value\n");
1564 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1565 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1567 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1570 info = (CERT_ALT_NAME_INFO *)buf;
1572 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1574 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1575 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1576 info->rgAltEntry[0].dwAltNameChoice);
1577 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1578 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1581 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1582 encodedDirectoryName, sizeof(encodedDirectoryName),
1583 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1584 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1587 info = (CERT_ALT_NAME_INFO *)buf;
1589 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1591 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1592 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1593 info->rgAltEntry[0].dwAltNameChoice);
1594 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1595 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1596 U(info->rgAltEntry[0]).DirectoryName.cbData);
1597 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1598 encodedCommonName, sizeof(encodedCommonName)),
1599 "Unexpected directory name value\n");
1604 struct UnicodeExpectedError
1612 static const WCHAR oneW[] = { '1',0 };
1613 static const WCHAR aW[] = { 'a',0 };
1614 static const WCHAR quoteW[] = { '"', 0 };
1616 static struct UnicodeExpectedError unicodeErrors[] = {
1617 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1618 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1619 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1620 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1621 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1622 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1625 struct UnicodeExpectedResult
1629 CRYPT_DATA_BLOB encoded;
1632 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1633 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1634 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1635 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1636 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1637 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1638 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1639 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1640 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1641 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1642 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1643 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1645 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1647 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1648 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1649 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1650 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1652 static struct UnicodeExpectedResult unicodeResults[] = {
1653 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1654 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1655 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1656 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1657 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1658 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1659 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1660 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1661 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1662 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1663 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1664 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1665 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1668 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1669 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1670 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1673 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1678 CERT_NAME_VALUE value;
1680 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1681 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1682 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1683 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1684 /* Have to have a string of some sort */
1685 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1686 value.Value.pbData = NULL;
1687 value.Value.cbData = 0;
1688 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1689 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1690 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1691 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1692 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1693 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1694 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1695 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1696 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1697 value.dwValueType = CERT_RDN_ANY_TYPE;
1698 value.Value.pbData = (LPBYTE)oneW;
1699 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1700 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1701 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1702 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1703 value.Value.cbData = sizeof(oneW);
1704 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1705 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1706 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1707 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1708 /* An encoded string with specified length isn't good enough either */
1709 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1710 value.Value.pbData = oneUniversal;
1711 value.Value.cbData = sizeof(oneUniversal);
1712 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1713 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1714 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1715 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1716 /* More failure checking */
1717 value.Value.cbData = 0;
1718 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1720 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1721 value.dwValueType = unicodeErrors[i].valueType;
1722 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1723 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1724 ok(!ret && GetLastError() == unicodeErrors[i].error,
1725 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1726 unicodeErrors[i].error, GetLastError());
1727 ok(size == unicodeErrors[i].errorIndex,
1728 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1731 /* cbData can be zero if the string is NULL-terminated */
1732 value.Value.cbData = 0;
1733 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1735 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1736 value.dwValueType = unicodeResults[i].valueType;
1737 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1738 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1739 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1742 ok(size == unicodeResults[i].encoded.cbData,
1743 "Value type %d: expected size %d, got %d\n",
1744 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1745 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1746 "Value type %d: unexpected value\n", value.dwValueType);
1750 /* These "encode," but they do so by truncating each unicode character
1751 * rather than properly encoding it. Kept separate from the proper results,
1752 * because the encoded forms won't decode to their original strings.
1754 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1756 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1757 value.dwValueType = unicodeWeirdness[i].valueType;
1758 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1759 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1760 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1763 ok(size == unicodeWeirdness[i].encoded.cbData,
1764 "Value type %d: expected size %d, got %d\n",
1765 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1766 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1767 "Value type %d: unexpected value\n", value.dwValueType);
1773 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1775 if (n <= 0) return 0;
1776 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1777 return *str1 - *str2;
1780 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1784 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1790 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1791 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1792 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1793 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1796 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1798 ok(value->dwValueType == unicodeResults[i].valueType,
1799 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1800 value->dwValueType);
1801 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1802 value->Value.cbData / sizeof(WCHAR)),
1803 "Unexpected decoded value for index %d (value type %d)\n", i,
1804 unicodeResults[i].valueType);
1810 struct encodedOctets
1813 const BYTE *encoded;
1816 static const unsigned char bin46[] = { 'h','i',0 };
1817 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1818 static const unsigned char bin48[] = {
1819 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1820 static const unsigned char bin49[] = {
1821 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1822 static const unsigned char bin50[] = { 0 };
1823 static const unsigned char bin51[] = { 0x04,0x00,0 };
1825 static const struct encodedOctets octets[] = {
1831 static void test_encodeOctets(DWORD dwEncoding)
1833 CRYPT_DATA_BLOB blob;
1836 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1842 blob.cbData = strlen((const char*)octets[i].val);
1843 blob.pbData = (BYTE*)octets[i].val;
1844 ret = CryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1845 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1846 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1850 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1851 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1852 buf[1], octets[i].encoded[1]);
1853 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1854 octets[i].encoded[1] + 1), "Got unexpected value\n");
1860 static void test_decodeOctets(DWORD dwEncoding)
1864 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1870 ret = CryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1871 (BYTE *)octets[i].encoded, octets[i].encoded[1] + 2,
1872 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1873 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1874 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1875 "Expected size >= %d, got %d\n",
1876 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1877 ok(buf != NULL, "Expected allocated buffer\n");
1880 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
1883 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
1884 "Unexpected value\n");
1890 static const BYTE bytesToEncode[] = { 0xff, 0xff };
1895 const BYTE *encoded;
1897 const BYTE *decoded;
1900 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
1901 static const unsigned char bin53[] = { 0xff,0xff };
1902 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
1903 static const unsigned char bin55[] = { 0xff,0xfe };
1904 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
1905 static const unsigned char bin57[] = { 0xfe };
1906 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
1908 static const struct encodedBits bits[] = {
1909 /* normal test cases */
1910 { 0, bin52, 2, bin53 },
1911 { 1, bin54, 2, bin55 },
1912 /* strange test case, showing cUnusedBits >= 8 is allowed */
1913 { 9, bin56, 1, bin57 },
1914 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1915 { 17, bin58, 0, NULL },
1918 static void test_encodeBits(DWORD dwEncoding)
1922 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1924 CRYPT_BIT_BLOB blob;
1929 blob.cbData = sizeof(bytesToEncode);
1930 blob.pbData = (BYTE *)bytesToEncode;
1931 blob.cUnusedBits = bits[i].cUnusedBits;
1932 ret = CryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
1933 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1934 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1937 ok(bufSize == bits[i].encoded[1] + 2,
1938 "Got unexpected size %d, expected %d\n", bufSize,
1939 bits[i].encoded[1] + 2);
1940 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
1941 "Unexpected value\n");
1947 static void test_decodeBits(DWORD dwEncoding)
1949 static const BYTE ber[] = "\x03\x02\x01\xff";
1950 static const BYTE berDecoded = 0xfe;
1957 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1959 ret = CryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
1960 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1962 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1965 CRYPT_BIT_BLOB *blob;
1967 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
1968 "Got unexpected size %d\n", bufSize);
1969 blob = (CRYPT_BIT_BLOB *)buf;
1970 ok(blob->cbData == bits[i].cbDecoded,
1971 "Got unexpected length %d, expected %d\n", blob->cbData,
1973 if (blob->cbData && bits[i].cbDecoded)
1974 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
1975 "Unexpected value\n");
1979 /* special case: check that something that's valid in BER but not in DER
1980 * decodes successfully
1982 ret = CryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
1983 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1984 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1987 CRYPT_BIT_BLOB *blob;
1989 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
1990 "Got unexpected size %d\n", bufSize);
1991 blob = (CRYPT_BIT_BLOB *)buf;
1992 ok(blob->cbData == sizeof(berDecoded),
1993 "Got unexpected length %d\n", blob->cbData);
1995 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2002 CERT_BASIC_CONSTRAINTS2_INFO info;
2003 const BYTE *encoded;
2006 static const unsigned char bin59[] = { 0x30,0x00 };
2007 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2008 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2009 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2010 static const struct Constraints2 constraints2[] = {
2011 /* empty constraints */
2012 { { FALSE, FALSE, 0}, bin59 },
2014 { { TRUE, FALSE, 0}, bin60 },
2015 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2016 * but that's not the case
2018 { { FALSE, TRUE, 0}, bin61 },
2019 /* can be a CA and has path length constraints set */
2020 { { TRUE, TRUE, 1}, bin62 },
2023 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2024 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2025 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2026 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2027 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2028 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2029 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2030 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2031 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2032 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2034 static void test_encodeBasicConstraints(DWORD dwEncoding)
2036 DWORD i, bufSize = 0;
2037 CERT_BASIC_CONSTRAINTS_INFO info;
2038 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2039 (LPBYTE)encodedDomainName };
2043 /* First test with the simpler info2 */
2044 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2046 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2047 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2049 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2052 ok(bufSize == constraints2[i].encoded[1] + 2,
2053 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2055 ok(!memcmp(buf, constraints2[i].encoded,
2056 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2060 /* Now test with more complex basic constraints */
2061 info.SubjectType.cbData = 0;
2062 info.fPathLenConstraint = FALSE;
2063 info.cSubtreesConstraint = 0;
2064 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2065 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2066 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2069 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2070 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2071 "Unexpected value\n");
2074 /* None of the certs I examined had any subtree constraint, but I test one
2075 * anyway just in case.
2077 info.cSubtreesConstraint = 1;
2078 info.rgSubtreesConstraint = &nameBlob;
2079 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2080 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2081 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2084 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2085 ok(!memcmp(buf, constraintWithDomainName,
2086 sizeof(constraintWithDomainName)), "Unexpected value\n");
2089 /* FIXME: test encoding with subject type. */
2092 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2094 static void test_decodeBasicConstraints(DWORD dwEncoding)
2096 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2098 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2104 /* First test with simpler info2 */
2105 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2107 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2108 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2109 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2110 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2114 CERT_BASIC_CONSTRAINTS2_INFO *info =
2115 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2117 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2118 "Unexpected value for item %d\n", i);
2122 /* Check with the order of encoded elements inverted */
2124 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2125 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2127 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2128 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2129 ok(!buf, "Expected buf to be set to NULL\n");
2130 /* Check with a non-DER bool */
2131 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2132 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2133 (BYTE *)&buf, &bufSize);
2134 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2137 CERT_BASIC_CONSTRAINTS2_INFO *info =
2138 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2140 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2143 /* Check with a non-basic constraints value */
2144 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2145 (LPBYTE)encodedCommonName, encodedCommonName[1] + 2,
2146 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2147 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2148 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2149 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2150 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2151 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2152 (BYTE *)&buf, &bufSize);
2153 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2156 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2158 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2159 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2160 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2163 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2164 constraintWithDomainName, sizeof(constraintWithDomainName),
2165 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2166 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2169 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2171 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2172 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2173 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2174 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2176 ok(info->rgSubtreesConstraint[0].cbData ==
2177 sizeof(encodedDomainName), "Wrong size %d\n",
2178 info->rgSubtreesConstraint[0].cbData);
2179 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2180 sizeof(encodedDomainName)), "Unexpected value\n");
2186 /* These are terrible public keys of course, I'm just testing encoding */
2187 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2188 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2189 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2190 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2191 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2192 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2193 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2194 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2196 struct EncodedRSAPubKey
2198 const BYTE *modulus;
2200 const BYTE *encoded;
2201 size_t decodedModulusLen;
2204 struct EncodedRSAPubKey rsaPubKeys[] = {
2205 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2206 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2207 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2208 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2211 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2213 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2214 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2215 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2218 DWORD bufSize = 0, i;
2220 /* Try with a bogus blob type */
2222 hdr->bVersion = CUR_BLOB_VERSION;
2224 hdr->aiKeyAlg = CALG_RSA_KEYX;
2225 rsaPubKey->magic = 0x31415352;
2226 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2227 rsaPubKey->pubexp = 65537;
2228 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2231 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2232 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2234 ok(!ret && GetLastError() == E_INVALIDARG,
2235 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2236 /* Now with a bogus reserved field */
2237 hdr->bType = PUBLICKEYBLOB;
2239 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2240 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2244 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2245 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2246 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2249 /* Now with a bogus blob version */
2252 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2253 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2257 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2258 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2259 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2262 /* And with a bogus alg ID */
2263 hdr->bVersion = CUR_BLOB_VERSION;
2264 hdr->aiKeyAlg = CALG_DES;
2265 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2266 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2270 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2271 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2272 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2275 /* Check a couple of RSA-related OIDs */
2276 hdr->aiKeyAlg = CALG_RSA_KEYX;
2277 ret = CryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2278 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2279 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2280 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2281 ret = CryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2282 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2283 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2284 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2285 /* Finally, all valid */
2286 hdr->aiKeyAlg = CALG_RSA_KEYX;
2287 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2289 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2290 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2291 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2292 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2293 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2296 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2297 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2299 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2300 "Unexpected value\n");
2306 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2313 /* Try with a bad length */
2314 ret = CryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2315 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2316 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2317 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2318 "Expected CRYPT_E_ASN1_EOD, got %08x\n", CRYPT_E_ASN1_EOD);
2319 /* Try with a couple of RSA-related OIDs */
2320 ret = CryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2321 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2322 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2323 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2324 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2325 ret = CryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2326 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2327 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2328 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2329 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2330 /* Now try success cases */
2331 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2334 ret = CryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2335 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2336 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2337 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2340 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2341 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2343 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2344 rsaPubKeys[i].decodedModulusLen,
2345 "Wrong size %d\n", bufSize);
2346 ok(hdr->bType == PUBLICKEYBLOB,
2347 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2349 ok(hdr->bVersion == CUR_BLOB_VERSION,
2350 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2351 CUR_BLOB_VERSION, hdr->bVersion);
2352 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2354 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2355 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2356 ok(rsaPubKey->magic == 0x31415352,
2357 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2358 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2359 "Wrong bit len %d\n", rsaPubKey->bitlen);
2360 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2362 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2363 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2364 "Unexpected modulus\n");
2370 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2371 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2372 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2374 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2375 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2376 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2377 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2379 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2381 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2382 CRYPT_SEQUENCE_OF_ANY seq;
2388 /* Encode a homogenous sequence */
2389 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2391 blobs[i].cbData = ints[i].encoded[1] + 2;
2392 blobs[i].pbData = (BYTE *)ints[i].encoded;
2394 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2395 seq.rgValue = blobs;
2397 ret = CryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2398 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2399 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2402 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2403 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2406 /* Change the type of the first element in the sequence, and give it
2409 blobs[0].cbData = times[0].encodedTime[1] + 2;
2410 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2411 ret = CryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2412 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2413 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2416 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2417 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2418 "Unexpected value\n");
2423 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2429 ret = CryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2430 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2431 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2434 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2437 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2438 "Wrong elements %d\n", seq->cValue);
2439 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2441 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2442 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2443 seq->rgValue[i].cbData);
2444 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2445 ints[i].encoded[1] + 2), "Unexpected value\n");
2449 ret = CryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2450 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2452 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2455 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2457 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2458 "Wrong elements %d\n", seq->cValue);
2459 /* Just check the first element since it's all that changed */
2460 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2461 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2462 seq->rgValue[0].cbData);
2463 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2464 times[0].encodedTime[1] + 2), "Unexpected value\n");
2469 struct encodedExtensions
2471 CERT_EXTENSIONS exts;
2472 const BYTE *encoded;
2475 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2476 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2477 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2478 static CERT_EXTENSION criticalExt =
2479 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2480 static CERT_EXTENSION nonCriticalExt =
2481 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2483 static const BYTE ext0[] = { 0x30,0x00 };
2484 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2485 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2486 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2487 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2489 static const struct encodedExtensions exts[] = {
2490 { { 0, NULL }, ext0 },
2491 { { 1, &criticalExt }, ext1 },
2492 { { 1, &nonCriticalExt }, ext2 },
2495 static void test_encodeExtensions(DWORD dwEncoding)
2499 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2505 ret = CryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2506 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2507 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2510 ok(bufSize == exts[i].encoded[1] + 2,
2511 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2512 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2513 "Unexpected value\n");
2519 static void test_decodeExtensions(DWORD dwEncoding)
2523 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2529 ret = CryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2530 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2531 NULL, (BYTE *)&buf, &bufSize);
2532 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2535 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2538 ok(ext->cExtension == exts[i].exts.cExtension,
2539 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2541 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2543 ok(!strcmp(ext->rgExtension[j].pszObjId,
2544 exts[i].exts.rgExtension[j].pszObjId),
2545 "Expected OID %s, got %s\n",
2546 exts[i].exts.rgExtension[j].pszObjId,
2547 ext->rgExtension[j].pszObjId);
2548 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2549 exts[i].exts.rgExtension[j].Value.pbData,
2550 exts[i].exts.rgExtension[j].Value.cbData),
2551 "Unexpected value\n");
2558 /* MS encodes public key info with a NULL if the algorithm identifier's
2559 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2560 * it encodes them by omitting the algorithm parameters. This latter approach
2561 * seems more correct, so accept either form.
2563 struct encodedPublicKey
2565 CERT_PUBLIC_KEY_INFO info;
2566 const BYTE *encoded;
2567 const BYTE *encodedNoNull;
2568 CERT_PUBLIC_KEY_INFO decoded;
2571 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2573 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2575 static const unsigned char bin64[] = {
2576 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2577 static const unsigned char bin65[] = {
2578 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2579 static const unsigned char bin66[] = {
2580 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2581 static const unsigned char bin67[] = {
2582 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2583 static const unsigned char bin68[] = {
2584 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2585 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2586 static const unsigned char bin69[] = {
2587 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2588 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2589 static const unsigned char bin70[] = {
2590 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2591 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2593 static const unsigned char bin71[] = {
2594 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2595 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2597 static unsigned char bin72[] = { 0x05,0x00};
2599 static CHAR oid_bogus[] = "1.2.3",
2600 oid_rsa[] = szOID_RSA;
2602 static const struct encodedPublicKey pubKeys[] = {
2603 /* with a bogus OID */
2604 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2606 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2607 /* some normal keys */
2608 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2610 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2611 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2613 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2614 /* with add'l parameters--note they must be DER-encoded */
2615 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2616 (BYTE *)aKey, 0 } },
2618 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2619 (BYTE *)aKey, 0 } } },
2622 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2626 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2632 ret = CryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2633 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2635 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2638 ok(bufSize == pubKeys[i].encoded[1] + 2 ||
2639 bufSize == pubKeys[i].encodedNoNull[1] + 2,
2640 "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
2641 pubKeys[i].encodedNoNull[1] + 2, bufSize);
2642 if (bufSize == pubKeys[i].encoded[1] + 2)
2643 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2644 "Unexpected value\n");
2645 else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
2646 ok(!memcmp(buf, pubKeys[i].encodedNoNull,
2647 pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
2653 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2654 const CERT_PUBLIC_KEY_INFO *got)
2656 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2657 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2658 got->Algorithm.pszObjId);
2659 ok(expected->Algorithm.Parameters.cbData ==
2660 got->Algorithm.Parameters.cbData,
2661 "Expected parameters of %d bytes, got %d\n",
2662 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2663 if (expected->Algorithm.Parameters.cbData)
2664 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2665 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2666 "Unexpected algorithm parameters\n");
2667 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2668 "Expected public key of %d bytes, got %d\n",
2669 expected->PublicKey.cbData, got->PublicKey.cbData);
2670 if (expected->PublicKey.cbData)
2671 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2672 got->PublicKey.cbData), "Unexpected public key value\n");
2675 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2677 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2678 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2679 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2680 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2686 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2688 /* The NULL form decodes to the decoded member */
2689 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2690 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2691 NULL, (BYTE *)&buf, &bufSize);
2692 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2695 comparePublicKeyInfo(&pubKeys[i].decoded,
2696 (CERT_PUBLIC_KEY_INFO *)buf);
2699 /* The non-NULL form decodes to the original */
2700 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2701 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2702 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2703 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2706 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2710 /* Test with bogus (not valid DER) parameters */
2711 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2712 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2713 NULL, (BYTE *)&buf, &bufSize);
2714 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2715 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2718 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2719 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2720 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2721 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2722 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2723 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2724 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2725 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2726 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2727 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2728 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2729 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2730 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2731 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2732 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2733 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2734 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2735 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2736 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2737 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2738 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2739 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2740 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2741 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2742 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2743 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2744 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2745 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2746 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2747 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2748 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2749 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2750 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2751 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2752 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2753 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2754 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2755 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2756 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2757 static const BYTE v1CertWithPubKey[] = {
2758 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2759 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2760 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2761 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2762 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2763 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2764 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2765 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2766 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2767 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2769 static const BYTE v1CertWithPubKeyNoNull[] = {
2770 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2771 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2772 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2773 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2774 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2775 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2776 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2777 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2778 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2779 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2780 static const BYTE v1CertWithSubjectKeyId[] = {
2781 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2782 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2783 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2784 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2785 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2786 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2787 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2788 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2789 0x4c,0x61,0x6e,0x67,0x00 };
2791 static const BYTE serialNum[] = { 0x01 };
2793 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2798 CERT_INFO info = { 0 };
2799 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2800 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2803 /* Test with NULL pvStructInfo */
2804 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2805 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2806 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2807 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2808 /* Test with a V1 cert */
2809 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2810 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2811 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2814 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2815 v1Cert[1] + 2, size);
2816 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2820 info.dwVersion = CERT_V2;
2821 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2822 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2823 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2826 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2827 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2831 info.dwVersion = CERT_V3;
2832 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2833 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2834 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2837 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2838 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2841 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2842 * API doesn't prevent it)
2844 info.dwVersion = CERT_V1;
2845 info.cExtension = 1;
2846 info.rgExtension = &criticalExt;
2847 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2848 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2849 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2852 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2853 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2856 /* test v1 cert with a serial number */
2857 info.SerialNumber.cbData = sizeof(serialNum);
2858 info.SerialNumber.pbData = (BYTE *)serialNum;
2859 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2860 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2863 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2864 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2867 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2868 info.Issuer.cbData = sizeof(encodedCommonName);
2869 info.Issuer.pbData = (BYTE *)encodedCommonName;
2870 info.Subject.cbData = sizeof(encodedCommonName);
2871 info.Subject.pbData = (BYTE *)encodedCommonName;
2872 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2873 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2876 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
2877 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
2880 /* Add a public key */
2881 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2882 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2883 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
2884 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2885 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2888 ok(size == sizeof(v1CertWithPubKey) ||
2889 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
2890 if (size == sizeof(v1CertWithPubKey))
2891 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
2892 else if (size == sizeof(v1CertWithPubKeyNoNull))
2893 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
2894 "Got unexpected value\n");
2897 /* Remove the public key, and add a subject key identifier extension */
2898 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2899 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
2900 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
2901 ext.pszObjId = oid_subject_key_identifier;
2902 ext.fCritical = FALSE;
2903 ext.Value.cbData = sizeof(octetCommonNameValue);
2904 ext.Value.pbData = (BYTE *)octetCommonNameValue;
2905 info.cExtension = 1;
2906 info.rgExtension = &ext;
2907 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2908 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2911 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
2912 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
2917 static void test_decodeCertToBeSigned(DWORD dwEncoding)
2919 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
2920 v1CertWithConstraints, v1CertWithSerial };
2925 /* Test with NULL pbEncoded */
2926 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
2927 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2928 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2929 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2930 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
2931 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2932 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2933 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2934 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
2935 * minimum a cert must have a non-zero serial number, an issuer, and a
2938 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
2940 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
2941 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2942 (BYTE *)&buf, &size);
2943 ok(!ret, "Expected failure\n");
2945 /* Now check with serial number, subject and issuer specified */
2946 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
2947 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2948 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2951 CERT_INFO *info = (CERT_INFO *)buf;
2953 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
2954 ok(info->SerialNumber.cbData == 1,
2955 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
2956 ok(*info->SerialNumber.pbData == *serialNum,
2957 "Expected serial number %d, got %d\n", *serialNum,
2958 *info->SerialNumber.pbData);
2959 ok(info->Issuer.cbData == sizeof(encodedCommonName),
2960 "Wrong size %d\n", info->Issuer.cbData);
2961 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
2962 "Unexpected issuer\n");
2963 ok(info->Subject.cbData == sizeof(encodedCommonName),
2964 "Wrong size %d\n", info->Subject.cbData);
2965 ok(!memcmp(info->Subject.pbData, encodedCommonName,
2966 info->Subject.cbData), "Unexpected subject\n");
2969 /* Check again with pub key specified */
2970 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
2971 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
2972 (BYTE *)&buf, &size);
2973 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2976 CERT_INFO *info = (CERT_INFO *)buf;
2978 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
2979 ok(info->SerialNumber.cbData == 1,
2980 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
2981 ok(*info->SerialNumber.pbData == *serialNum,
2982 "Expected serial number %d, got %d\n", *serialNum,
2983 *info->SerialNumber.pbData);
2984 ok(info->Issuer.cbData == sizeof(encodedCommonName),
2985 "Wrong size %d\n", info->Issuer.cbData);
2986 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
2987 "Unexpected issuer\n");
2988 ok(info->Subject.cbData == sizeof(encodedCommonName),
2989 "Wrong size %d\n", info->Subject.cbData);
2990 ok(!memcmp(info->Subject.pbData, encodedCommonName,
2991 info->Subject.cbData), "Unexpected subject\n");
2992 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
2993 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
2994 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
2995 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
2996 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
2997 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
2998 sizeof(aKey)), "Unexpected public key\n");
3003 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3006 static const BYTE signedBigCert[] = {
3007 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3008 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3009 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3010 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3011 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3012 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3013 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3014 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3015 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3016 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3017 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3018 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3020 static void test_encodeCert(DWORD dwEncoding)
3022 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3023 * also that bigCert is a NULL-terminated string, so don't count its
3024 * last byte (otherwise the signed cert won't decode.)
3026 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3027 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3032 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3033 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
3034 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3037 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3038 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3043 static void test_decodeCert(DWORD dwEncoding)
3049 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3050 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3051 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3054 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3056 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3057 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3058 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3059 "Unexpected cert\n");
3060 ok(info->Signature.cbData == sizeof(hash),
3061 "Wrong signature size %d\n", info->Signature.cbData);
3062 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3063 "Unexpected signature\n");
3066 /* A signed cert decodes as a CERT_INFO too */
3067 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3068 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3069 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3072 CERT_INFO *info = (CERT_INFO *)buf;
3074 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3075 ok(info->SerialNumber.cbData == 1,
3076 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3077 ok(*info->SerialNumber.pbData == *serialNum,
3078 "Expected serial number %d, got %d\n", *serialNum,
3079 *info->SerialNumber.pbData);
3080 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3081 "Wrong size %d\n", info->Issuer.cbData);
3082 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3083 "Unexpected issuer\n");
3084 ok(info->Subject.cbData == sizeof(encodedCommonName),
3085 "Wrong size %d\n", info->Subject.cbData);
3086 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3087 info->Subject.cbData), "Unexpected subject\n");
3092 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3093 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3094 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3095 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3096 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3098 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3099 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3100 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3101 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3102 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3103 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3104 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3105 0x2e, 0x6f, 0x72, 0x67 };
3106 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3107 CRL_REASON_AFFILIATION_CHANGED;
3109 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3111 CRL_DIST_POINTS_INFO info = { 0 };
3112 CRL_DIST_POINT point = { { 0 } };
3113 CERT_ALT_NAME_ENTRY entry = { 0 };
3118 /* Test with an empty info */
3119 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3120 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3121 ok(!ret && GetLastError() == E_INVALIDARG,
3122 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3123 /* Test with one empty dist point */
3124 info.cDistPoint = 1;
3125 info.rgDistPoint = &point;
3126 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3127 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3130 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3131 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3134 /* A dist point with an invalid name */
3135 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3136 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3137 U(entry).pwszURL = (LPWSTR)nihongoURL;
3138 U(point.DistPointName).FullName.cAltEntry = 1;
3139 U(point.DistPointName).FullName.rgAltEntry = &entry;
3140 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3141 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3142 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3143 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3144 /* The first invalid character is at index 7 */
3145 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3146 "Expected invalid char at index 7, got %d\n",
3147 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3148 /* A dist point with (just) a valid name */
3149 U(entry).pwszURL = (LPWSTR)url;
3150 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3151 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3154 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3155 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3158 /* A dist point with (just) reason flags */
3159 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3160 point.ReasonFlags.cbData = sizeof(crlReason);
3161 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3162 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3163 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3166 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3167 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3170 /* A dist point with just an issuer */
3171 point.ReasonFlags.cbData = 0;
3172 point.CRLIssuer.cAltEntry = 1;
3173 point.CRLIssuer.rgAltEntry = &entry;
3174 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3175 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3178 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3179 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3182 /* A dist point with both a name and an issuer */
3183 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3184 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3185 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3188 ok(size == sizeof(distPointWithUrlAndIssuer),
3189 "Wrong size %d\n", size);
3190 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3195 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3200 PCRL_DIST_POINTS_INFO info;
3201 PCRL_DIST_POINT point;
3202 PCERT_ALT_NAME_ENTRY entry;
3204 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3205 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3206 (BYTE *)&buf, &size);
3209 info = (PCRL_DIST_POINTS_INFO)buf;
3210 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3211 "Wrong size %d\n", size);
3212 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3214 point = info->rgDistPoint;
3215 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3216 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3217 point->DistPointName.dwDistPointNameChoice);
3218 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3219 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3222 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3223 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3224 (BYTE *)&buf, &size);
3227 info = (PCRL_DIST_POINTS_INFO)buf;
3228 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3229 "Wrong size %d\n", size);
3230 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3232 point = info->rgDistPoint;
3233 ok(point->DistPointName.dwDistPointNameChoice ==
3234 CRL_DIST_POINT_FULL_NAME,
3235 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3236 point->DistPointName.dwDistPointNameChoice);
3237 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3238 "Expected 1 name entry, got %d\n",
3239 U(point->DistPointName).FullName.cAltEntry);
3240 entry = U(point->DistPointName).FullName.rgAltEntry;
3241 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3242 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3243 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3244 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3245 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3248 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3249 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3250 NULL, (BYTE *)&buf, &size);
3253 info = (PCRL_DIST_POINTS_INFO)buf;
3254 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3255 "Wrong size %d\n", size);
3256 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3258 point = info->rgDistPoint;
3259 ok(point->DistPointName.dwDistPointNameChoice ==
3260 CRL_DIST_POINT_NO_NAME,
3261 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3262 point->DistPointName.dwDistPointNameChoice);
3263 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3264 "Expected reason length\n");
3265 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3266 "Unexpected reason\n");
3267 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3270 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3271 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3272 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3275 info = (PCRL_DIST_POINTS_INFO)buf;
3276 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3277 "Wrong size %d\n", size);
3278 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3280 point = info->rgDistPoint;
3281 ok(point->DistPointName.dwDistPointNameChoice ==
3282 CRL_DIST_POINT_FULL_NAME,
3283 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3284 point->DistPointName.dwDistPointNameChoice);
3285 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3286 "Expected 1 name entry, got %d\n",
3287 U(point->DistPointName).FullName.cAltEntry);
3288 entry = U(point->DistPointName).FullName.rgAltEntry;
3289 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3290 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3291 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3292 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3293 ok(point->CRLIssuer.cAltEntry == 1,
3294 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3295 entry = point->CRLIssuer.rgAltEntry;
3296 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3297 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3298 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3303 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3304 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3305 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3306 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3309 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3314 CRL_ISSUING_DIST_POINT point = { { 0 } };
3315 CERT_ALT_NAME_ENTRY entry;
3317 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3318 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3319 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3321 skip("no X509_ISSUING_DIST_POINT encode support\n");
3324 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3325 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3326 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3327 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3328 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3331 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3332 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3335 /* nonsensical flags */
3336 point.fOnlyContainsUserCerts = TRUE;
3337 point.fOnlyContainsCACerts = TRUE;
3338 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3339 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3340 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3343 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3344 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3347 /* unimplemented name type */
3348 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3349 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3350 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3351 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3352 ok(!ret && GetLastError() == E_INVALIDARG,
3353 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3355 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3356 U(point.DistPointName).FullName.cAltEntry = 0;
3357 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3358 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3359 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3362 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3363 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3366 /* name with URL entry */
3367 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3368 U(entry).pwszURL = (LPWSTR)url;
3369 U(point.DistPointName).FullName.cAltEntry = 1;
3370 U(point.DistPointName).FullName.rgAltEntry = &entry;
3371 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3372 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3373 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3376 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3377 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3382 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3383 const CERT_ALT_NAME_ENTRY *got)
3385 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3386 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3387 got->dwAltNameChoice);
3388 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3390 switch (got->dwAltNameChoice)
3392 case CERT_ALT_NAME_RFC822_NAME:
3393 case CERT_ALT_NAME_DNS_NAME:
3394 case CERT_ALT_NAME_EDI_PARTY_NAME:
3395 case CERT_ALT_NAME_URL:
3396 case CERT_ALT_NAME_REGISTERED_ID:
3397 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3398 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3399 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3400 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3401 "Unexpected name\n");
3403 case CERT_ALT_NAME_X400_ADDRESS:
3404 case CERT_ALT_NAME_DIRECTORY_NAME:
3405 case CERT_ALT_NAME_IP_ADDRESS:
3406 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3407 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3408 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3409 U(*got).IPAddress.cbData), "Unexpected value\n");
3415 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3416 const CERT_ALT_NAME_INFO *got)
3420 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3421 expected->cAltEntry, got->cAltEntry);
3422 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3423 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3426 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3427 const CRL_DIST_POINT_NAME *got)
3429 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3430 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3431 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3432 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3435 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3436 const CRL_ISSUING_DIST_POINT *got)
3438 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3439 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3440 "Unexpected fOnlyContainsUserCerts\n");
3441 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3442 "Unexpected fOnlyContainsCACerts\n");
3443 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3444 "Unexpected reason flags\n");
3445 ok(got->fIndirectCRL == expected->fIndirectCRL,
3446 "Unexpected fIndirectCRL\n");
3449 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3454 CRL_ISSUING_DIST_POINT point = { { 0 } };
3456 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3457 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3458 (BYTE *)&buf, &size);
3459 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3461 skip("no X509_ISSUING_DIST_POINT decode support\n");
3464 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3467 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3470 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3471 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3472 (BYTE *)&buf, &size);
3473 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3476 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3477 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3480 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3481 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3482 (BYTE *)&buf, &size);
3483 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3486 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3487 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3488 U(point.DistPointName).FullName.cAltEntry = 0;
3489 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3492 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3493 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3494 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3497 CERT_ALT_NAME_ENTRY entry;
3499 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3500 U(entry).pwszURL = (LPWSTR)url;
3501 U(point.DistPointName).FullName.cAltEntry = 1;
3502 U(point.DistPointName).FullName.rgAltEntry = &entry;
3503 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3508 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3509 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3511 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3512 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3513 0x30, 0x30, 0x30, 0x30, 0x5a };
3514 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3515 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3516 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3517 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3519 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3520 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3521 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3522 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3523 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3524 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3525 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3526 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3527 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3528 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3529 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3530 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3531 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3532 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3533 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3534 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3535 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3536 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3537 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3538 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3539 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3540 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3541 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3542 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3543 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3544 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3545 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3546 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3547 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3548 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3549 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3550 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3551 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3552 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3553 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3554 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3555 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3556 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3557 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3558 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3560 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3564 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3566 CRL_INFO info = { 0 };
3567 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3570 /* Test with a V1 CRL */
3571 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3572 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3573 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3576 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3577 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3581 info.dwVersion = CRL_V2;
3582 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3583 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3584 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3587 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3588 v2CRL[1] + 2, size);
3589 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3592 /* v1 CRL with a name */
3593 info.dwVersion = CRL_V1;
3594 info.Issuer.cbData = sizeof(encodedCommonName);
3595 info.Issuer.pbData = (BYTE *)encodedCommonName;
3596 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3597 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3598 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3601 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3602 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3605 /* v1 CRL with a name and a NULL entry pointer */
3607 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3608 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3609 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3610 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3611 /* now set an empty entry */
3612 info.rgCRLEntry = &entry;
3613 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3614 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3617 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3618 "Wrong size %d\n", size);
3619 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3620 "Got unexpected value\n");
3623 /* an entry with a serial number */
3624 entry.SerialNumber.cbData = sizeof(serialNum);
3625 entry.SerialNumber.pbData = (BYTE *)serialNum;
3626 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3627 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3630 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3631 "Wrong size %d\n", size);
3632 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3633 "Got unexpected value\n");
3636 /* an entry with an extension */
3637 entry.cExtension = 1;
3638 entry.rgExtension = &criticalExt;
3639 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3640 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3641 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3644 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3645 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3648 /* a CRL with an extension */
3649 entry.cExtension = 0;
3650 info.cExtension = 1;
3651 info.rgExtension = &criticalExt;
3652 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3653 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3654 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3657 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3658 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3661 /* a v2 CRL with an extension, this time non-critical */
3662 info.dwVersion = CRL_V2;
3663 info.rgExtension = &nonCriticalExt;
3664 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3665 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3666 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3669 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3670 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3673 /* a v2 CRL with an issuing dist point extension */
3674 ext.pszObjId = oid_issuing_dist_point;
3675 ext.fCritical = TRUE;
3676 ext.Value.cbData = sizeof(urlIDP);
3677 ext.Value.pbData = (LPBYTE)urlIDP;
3678 entry.rgExtension = &ext;
3679 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3680 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3681 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3684 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3685 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3690 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3691 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3692 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3693 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3694 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3695 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3696 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3697 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3698 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3699 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3700 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3701 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3702 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3703 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3704 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3705 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3706 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3707 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3708 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3709 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3710 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3711 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3712 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3713 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3714 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3715 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3716 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3717 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3718 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3719 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3720 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3721 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3722 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3723 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3725 static const BYTE verisignCRLWithLotsOfEntries[] = {
3726 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3727 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3728 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3729 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3730 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3731 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3732 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3733 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3734 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3735 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3736 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3737 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3738 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3739 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3740 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3741 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3742 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3743 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3744 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3745 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3746 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3747 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3748 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3749 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3750 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3751 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3752 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3753 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3754 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3755 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3756 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3757 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3758 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3759 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3760 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3761 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3762 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3763 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3764 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3765 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3766 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3767 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3768 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3769 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3770 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3771 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3772 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3773 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3774 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3775 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3776 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3777 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3778 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3779 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3780 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3781 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3782 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3783 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3784 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3785 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3786 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3787 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3788 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3789 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3790 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3791 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3792 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3793 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3794 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3795 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3796 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3797 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3798 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3799 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3800 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3801 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3802 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3803 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3804 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3805 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3806 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3807 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3808 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3809 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3810 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3811 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3812 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3813 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3814 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3815 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3816 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3817 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3818 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3819 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3820 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3821 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3822 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3823 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3824 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3825 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3826 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3827 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3828 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3829 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3830 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3831 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3832 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3833 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3834 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3835 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3836 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3837 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3838 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3839 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3840 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3841 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3842 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3843 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3844 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3845 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3846 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3847 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3848 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3849 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3850 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3851 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3852 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3853 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3854 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3855 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3856 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3857 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3858 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3859 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3860 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3861 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3862 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3863 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3864 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3865 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3866 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3867 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3868 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3869 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3870 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3871 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3872 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3873 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3874 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3875 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3876 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3877 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3878 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3879 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3880 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3881 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3882 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3883 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3884 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3885 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3886 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3887 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3888 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3889 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3890 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3891 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3892 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3893 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3894 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3895 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3896 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3897 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3898 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3899 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3900 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3901 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3902 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3903 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3904 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3905 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3906 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3907 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
3908 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
3909 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
3910 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
3911 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
3912 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
3913 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
3914 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
3915 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
3916 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
3917 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
3918 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
3919 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
3920 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
3921 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
3922 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
3923 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
3924 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
3925 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
3926 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
3927 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
3928 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
3929 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
3930 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
3931 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
3932 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
3933 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
3934 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
3935 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
3936 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
3937 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
3938 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
3939 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
3940 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
3941 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
3942 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
3943 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
3944 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
3945 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
3946 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
3947 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
3948 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
3949 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
3950 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
3951 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
3952 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
3953 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
3954 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
3955 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
3956 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
3957 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
3958 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
3959 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
3960 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
3961 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
3962 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
3963 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
3964 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
3965 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
3966 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
3967 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
3968 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
3969 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
3970 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
3971 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
3972 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
3973 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
3974 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
3975 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
3976 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
3977 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
3978 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
3979 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
3980 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
3981 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
3982 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
3983 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
3984 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
3985 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
3986 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
3987 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
3988 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
3989 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
3990 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
3991 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
3992 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
3993 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
3994 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
3995 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
3996 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
3997 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
3998 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
3999 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4000 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4001 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4002 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4003 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4004 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4005 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4006 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4007 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4008 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4009 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4010 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4011 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4012 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4013 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4014 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4015 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4016 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4017 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4018 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4019 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4020 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4021 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4022 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4023 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4024 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4025 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4026 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4027 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4028 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4029 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4030 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4031 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4032 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4033 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4034 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4035 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4036 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4037 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4038 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4039 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4040 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4041 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4042 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4043 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4044 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4045 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4046 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4047 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4048 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4049 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4050 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4051 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4052 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4053 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4054 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4055 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4056 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4057 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4058 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4059 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4060 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4061 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4062 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4063 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4064 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4065 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4066 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4067 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4068 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4069 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4070 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4071 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4072 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4073 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4074 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4075 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4076 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4077 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4078 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4079 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4080 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4081 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4082 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4083 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4084 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4085 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4086 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4087 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4088 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4089 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4090 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4091 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4092 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4093 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4094 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4095 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4096 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4097 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4098 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4099 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4100 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4101 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4102 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4103 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4104 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4105 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4106 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4107 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4108 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4109 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4110 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4111 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4112 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4113 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4114 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4115 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4116 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4117 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4118 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4119 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4120 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4121 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4122 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4123 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4124 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4125 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4126 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4127 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4128 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4129 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4130 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4131 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4132 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4133 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4134 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4135 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4136 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4137 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4138 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4139 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4140 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4141 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4142 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4143 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4144 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4145 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4146 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4147 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4148 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4149 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4150 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4151 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4152 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4153 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4154 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4155 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4156 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4157 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4158 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4159 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4160 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4161 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4162 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4163 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4164 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4165 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4166 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4167 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4168 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4169 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4170 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4171 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4172 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4173 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4174 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4175 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4176 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4177 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4178 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4179 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4180 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4181 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4182 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4183 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4184 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4185 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4186 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4187 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4188 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4189 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4190 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4191 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4192 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4193 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4194 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4195 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4196 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4197 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4198 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4199 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4200 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4201 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4202 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4203 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4204 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4205 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4206 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4207 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4208 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4209 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4210 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4211 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4212 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4213 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4214 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4215 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4216 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4217 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4218 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4219 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4220 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4221 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4222 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4223 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4224 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4225 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4226 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4227 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4228 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4229 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4230 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4231 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4232 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4233 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4235 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4237 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4242 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4244 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4245 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4246 (BYTE *)&buf, &size);
4247 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT),
4248 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4250 /* at a minimum, a CRL must contain an issuer: */
4251 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4252 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4253 (BYTE *)&buf, &size);
4254 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4257 CRL_INFO *info = (CRL_INFO *)buf;
4259 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4260 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4262 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4263 "Wrong issuer size %d\n", info->Issuer.cbData);
4264 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4265 "Unexpected issuer\n");
4268 /* check decoding with an empty CRL entry */
4269 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4270 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4271 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4272 todo_wine ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
4273 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4274 /* with a real CRL entry */
4275 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4276 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4277 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4278 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4281 CRL_INFO *info = (CRL_INFO *)buf;
4284 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4285 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4287 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4288 entry = info->rgCRLEntry;
4289 ok(entry->SerialNumber.cbData == 1,
4290 "Expected serial number size 1, got %d\n",
4291 entry->SerialNumber.cbData);
4292 ok(*entry->SerialNumber.pbData == *serialNum,
4293 "Expected serial number %d, got %d\n", *serialNum,
4294 *entry->SerialNumber.pbData);
4295 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4296 "Wrong issuer size %d\n", info->Issuer.cbData);
4297 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4298 "Unexpected issuer\n");
4300 /* a real CRL from verisign that has extensions */
4301 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4302 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4303 NULL, (BYTE *)&buf, &size);
4304 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4307 CRL_INFO *info = (CRL_INFO *)buf;
4310 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4311 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4313 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4314 entry = info->rgCRLEntry;
4315 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4319 /* another real CRL from verisign that has lots of entries */
4320 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4321 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4322 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4323 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4326 CRL_INFO *info = (CRL_INFO *)buf;
4328 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4329 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4331 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4335 /* and finally, with an extension */
4336 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4337 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4338 NULL, (BYTE *)&buf, &size);
4339 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4342 CRL_INFO *info = (CRL_INFO *)buf;
4345 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4346 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4348 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4349 entry = info->rgCRLEntry;
4350 ok(entry->SerialNumber.cbData == 1,
4351 "Expected serial number size 1, got %d\n",
4352 entry->SerialNumber.cbData);
4353 ok(*entry->SerialNumber.pbData == *serialNum,
4354 "Expected serial number %d, got %d\n", *serialNum,
4355 *entry->SerialNumber.pbData);
4356 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4357 "Wrong issuer size %d\n", info->Issuer.cbData);
4358 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4359 "Unexpected issuer\n");
4360 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4363 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4364 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4365 NULL, (BYTE *)&buf, &size);
4366 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4369 CRL_INFO *info = (CRL_INFO *)buf;
4371 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4375 /* And again, with an issuing dist point */
4376 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4377 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4378 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4379 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4382 CRL_INFO *info = (CRL_INFO *)buf;
4384 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4390 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4391 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4392 static const BYTE encodedUsage[] = {
4393 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4394 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4395 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4397 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4402 CERT_ENHKEY_USAGE usage;
4404 /* Test with empty usage */
4405 usage.cUsageIdentifier = 0;
4406 ret = CryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4407 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4408 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4411 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4412 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4415 /* Test with a few usages */
4416 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4417 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4418 ret = CryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4419 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4420 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4423 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4424 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4429 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4435 ret = CryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4436 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4437 (BYTE *)&buf, &size);
4438 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4441 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4443 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4444 "Wrong size %d\n", size);
4445 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4446 usage->cUsageIdentifier);
4449 ret = CryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4450 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4451 (BYTE *)&buf, &size);
4452 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4455 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4458 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4459 "Wrong size %d\n", size);
4460 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4461 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4462 for (i = 0; i < usage->cUsageIdentifier; i++)
4463 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4464 "Expected OID %s, got %s\n", keyUsages[i],
4465 usage->rgpszUsageIdentifier[i]);
4470 static BYTE keyId[] = { 1,2,3,4 };
4471 static const BYTE authorityKeyIdWithId[] = {
4472 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4473 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4474 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4475 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4476 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4478 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4480 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4485 /* Test with empty id */
4486 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4487 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4488 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4491 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4492 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4495 /* With just a key id */
4496 info.KeyId.cbData = sizeof(keyId);
4497 info.KeyId.pbData = keyId;
4498 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4499 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4500 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4503 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4504 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4507 /* With just an issuer */
4508 info.KeyId.cbData = 0;
4509 info.CertIssuer.cbData = sizeof(encodedCommonName);
4510 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4511 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4512 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4513 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4516 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4518 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4521 /* With just a serial number */
4522 info.CertIssuer.cbData = 0;
4523 info.CertSerialNumber.cbData = sizeof(serialNum);
4524 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4525 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4526 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4527 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4530 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4532 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4537 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4543 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4544 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4545 (BYTE *)&buf, &size);
4546 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4549 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4551 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4553 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4554 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4555 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4558 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4559 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4560 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4561 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4564 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4566 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4568 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4569 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4570 "Unexpected key id\n");
4571 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4572 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4575 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4576 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4577 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4578 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4581 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4583 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4585 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4586 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4587 "Unexpected issuer len\n");
4588 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4589 sizeof(encodedCommonName)), "Unexpected issuer\n");
4590 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4593 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4594 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4595 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4596 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4599 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4601 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4603 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4604 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4605 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4606 "Unexpected serial number len\n");
4607 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4608 "Unexpected serial number\n");
4613 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4614 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4617 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4619 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4620 CERT_ALT_NAME_ENTRY entry = { 0 };
4625 /* Test with empty id */
4626 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4627 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4628 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4631 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4632 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4635 /* With just a key id */
4636 info.KeyId.cbData = sizeof(keyId);
4637 info.KeyId.pbData = keyId;
4638 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4639 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4640 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4643 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4645 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4648 /* With a bogus issuer name */
4649 info.KeyId.cbData = 0;
4650 info.AuthorityCertIssuer.cAltEntry = 1;
4651 info.AuthorityCertIssuer.rgAltEntry = &entry;
4652 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4653 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4654 ok(!ret && GetLastError() == E_INVALIDARG,
4655 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4656 /* With an issuer name */
4657 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4658 U(entry).pwszURL = (LPWSTR)url;
4659 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4660 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4661 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4664 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4666 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4667 "Unexpected value\n");
4670 /* With just a serial number */
4671 info.AuthorityCertIssuer.cAltEntry = 0;
4672 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4673 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4674 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4675 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4676 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4679 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4681 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4686 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4692 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4693 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4694 (BYTE *)&buf, &size);
4695 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4698 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4700 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4702 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4703 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4704 "Expected no issuer name entries\n");
4705 ok(info->AuthorityCertSerialNumber.cbData == 0,
4706 "Expected no serial number\n");
4709 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4710 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4711 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4712 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4715 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4717 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4719 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4720 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4721 "Unexpected key id\n");
4722 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4723 "Expected no issuer name entries\n");
4724 ok(info->AuthorityCertSerialNumber.cbData == 0,
4725 "Expected no serial number\n");
4728 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4729 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4730 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4731 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4734 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4736 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4738 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4739 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4740 "Expected 1 issuer entry, got %d\n",
4741 info->AuthorityCertIssuer.cAltEntry);
4742 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4743 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4744 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4745 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4746 url), "Unexpected URL\n");
4747 ok(info->AuthorityCertSerialNumber.cbData == 0,
4748 "Expected no serial number\n");
4751 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4752 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4753 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4754 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4757 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4759 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4761 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4762 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4763 "Expected no issuer name entries\n");
4764 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4765 "Unexpected serial number len\n");
4766 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4767 sizeof(serialNum)), "Unexpected serial number\n");
4772 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
4773 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
4775 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
4777 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
4778 0x03,0x02,0x01,0x01 };
4779 static BYTE bogusDER[] = { 1 };
4781 static void test_encodePKCSContentInfo(DWORD dwEncoding)
4786 CRYPT_CONTENT_INFO info = { 0 };
4787 char oid1[] = "1.2.3";
4789 SetLastError(0xdeadbeef);
4790 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
4791 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4792 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4793 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
4794 SetLastError(0xdeadbeef);
4795 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4796 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4797 ok(!ret && GetLastError() == E_INVALIDARG,
4798 "Expected E_INVALIDARG, got %x\n", GetLastError());
4799 info.pszObjId = oid1;
4800 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4801 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4802 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4805 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
4806 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
4809 info.Content.pbData = bogusDER;
4810 info.Content.cbData = sizeof(bogusDER);
4811 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4812 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4813 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
4816 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
4817 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
4820 info.Content.pbData = (BYTE *)ints[0].encoded;
4821 info.Content.cbData = ints[0].encoded[1] + 2;
4822 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4823 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4826 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
4827 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
4832 static const BYTE indefiniteSignedPKCSContent[] = {
4833 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
4834 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
4835 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
4836 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
4837 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
4838 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
4839 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
4840 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
4841 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
4842 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
4843 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
4844 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
4845 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
4846 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
4847 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
4848 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
4849 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
4850 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
4851 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
4852 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
4853 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
4854 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
4855 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
4856 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
4857 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
4858 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
4859 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
4860 0x00,0x00,0x00,0x00,0x00,0x00 };
4862 static void test_decodePKCSContentInfo(DWORD dwEncoding)
4867 CRYPT_CONTENT_INFO *info;
4869 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4870 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
4871 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4872 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4875 info = (CRYPT_CONTENT_INFO *)buf;
4877 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4879 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
4880 info->Content.cbData);
4883 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4884 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
4885 0, NULL, NULL, &size);
4886 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4887 SetLastError(0xdeadbeef);
4888 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4889 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
4890 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4891 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
4892 * I doubt an app depends on that.
4894 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
4895 GetLastError() == CRYPT_E_ASN1_CORRUPT),
4896 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
4898 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4899 intPKCSContentInfo, sizeof(intPKCSContentInfo),
4900 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4901 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4904 info = (CRYPT_CONTENT_INFO *)buf;
4906 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4908 ok(info->Content.cbData == ints[0].encoded[1] + 2,
4909 "Unexpected size %d\n", info->Content.cbData);
4910 ok(!memcmp(info->Content.pbData, ints[0].encoded,
4911 info->Content.cbData), "Unexpected value\n");
4914 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4915 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
4916 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4917 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4920 info = (CRYPT_CONTENT_INFO *)buf;
4922 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
4923 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
4924 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
4925 info->Content.cbData);
4930 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
4932 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
4934 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
4937 static void test_encodePKCSAttribute(DWORD dwEncoding)
4939 CRYPT_ATTRIBUTE attr = { 0 };
4943 CRYPT_ATTR_BLOB blob;
4944 char oid[] = "1.2.3";
4946 SetLastError(0xdeadbeef);
4947 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
4948 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4949 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4950 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
4951 SetLastError(0xdeadbeef);
4952 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4953 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4954 ok(!ret && GetLastError() == E_INVALIDARG,
4955 "Expected E_INVALIDARG, got %x\n", GetLastError());
4956 attr.pszObjId = oid;
4957 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4958 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4959 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4962 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
4963 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
4966 blob.cbData = sizeof(bogusDER);
4967 blob.pbData = bogusDER;
4969 attr.rgValue = &blob;
4970 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4971 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4972 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4975 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
4976 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
4979 blob.pbData = (BYTE *)ints[0].encoded;
4980 blob.cbData = ints[0].encoded[1] + 2;
4981 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4982 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4985 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
4986 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
4991 static void test_decodePKCSAttribute(DWORD dwEncoding)
4996 CRYPT_ATTRIBUTE *attr;
4998 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
4999 emptyPKCSAttr, sizeof(emptyPKCSAttr),
5000 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5001 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5004 attr = (CRYPT_ATTRIBUTE *)buf;
5006 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5008 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5011 SetLastError(0xdeadbeef);
5012 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5013 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5014 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5015 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5016 * I doubt an app depends on that.
5018 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5019 GetLastError() == CRYPT_E_ASN1_CORRUPT),
5020 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5022 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5023 intPKCSAttr, sizeof(intPKCSAttr),
5024 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5025 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5028 attr = (CRYPT_ATTRIBUTE *)buf;
5030 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5032 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5033 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5034 "Unexpected size %d\n", attr->rgValue[0].cbData);
5035 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5036 attr->rgValue[0].cbData), "Unexpected value\n");
5040 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5041 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5042 0x2a,0x03,0x31,0x00 };
5043 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5044 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5046 static void test_encodePKCSAttributes(DWORD dwEncoding)
5048 CRYPT_ATTRIBUTES attributes = { 0 };
5049 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5050 CRYPT_ATTR_BLOB blob;
5054 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5056 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5057 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5058 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5061 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5062 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5065 attributes.cAttr = 1;
5066 attributes.rgAttr = attr;
5067 SetLastError(0xdeadbeef);
5068 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5069 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5070 ok(!ret && GetLastError() == E_INVALIDARG,
5071 "Expected E_INVALIDARG, got %x\n", GetLastError());
5072 attr[0].pszObjId = oid1;
5073 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5074 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5077 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5078 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5081 attr[1].pszObjId = oid2;
5083 attr[1].rgValue = &blob;
5084 blob.pbData = (BYTE *)ints[0].encoded;
5085 blob.cbData = ints[0].encoded[1] + 2;
5086 attributes.cAttr = 2;
5087 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5088 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5089 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5092 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5093 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5098 static void test_decodePKCSAttributes(DWORD dwEncoding)
5103 CRYPT_ATTRIBUTES *attributes;
5105 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5106 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5107 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5108 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5111 attributes = (CRYPT_ATTRIBUTES *)buf;
5112 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5116 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5117 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5118 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5119 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5122 attributes = (CRYPT_ATTRIBUTES *)buf;
5123 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5125 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5126 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5127 ok(attributes->rgAttr[0].cValue == 0,
5128 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5131 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5132 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5133 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5134 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5137 attributes = (CRYPT_ATTRIBUTES *)buf;
5138 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5140 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5141 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5142 ok(attributes->rgAttr[0].cValue == 0,
5143 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5144 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5145 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5146 ok(attributes->rgAttr[1].cValue == 1,
5147 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5148 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5149 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5150 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5151 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5156 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
5157 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5159 static const BYTE minimalPKCSSigner[] = {
5160 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5161 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5162 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
5163 static const BYTE PKCSSignerWithSerial[] = {
5164 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5165 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5166 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5168 static const BYTE PKCSSignerWithHashAlgo[] = {
5169 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5170 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5171 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5173 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
5174 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5175 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5176 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5177 0x06,0x05,0x00,0x04,0x00 };
5178 static const BYTE PKCSSignerWithHash[] = {
5179 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5180 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5181 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5182 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
5183 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5184 static const BYTE PKCSSignerWithAuthAttr[] = {
5185 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5186 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5187 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
5188 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
5189 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
5190 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
5191 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5193 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
5195 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
5199 CMSG_SIGNER_INFO info = { 0 };
5200 char oid_common_name[] = szOID_COMMON_NAME;
5201 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
5202 (LPBYTE)encodedCommonName };
5203 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
5205 SetLastError(0xdeadbeef);
5206 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5207 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5208 ok(!ret && GetLastError() == E_INVALIDARG,
5209 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5210 /* To be encoded, a signer must have an issuer at least, and the encoding
5211 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
5212 * see decoding tests.)
5214 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
5215 info.Issuer.pbData = encodedCommonNameNoNull;
5216 SetLastError(0xdeadbeef);
5217 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5218 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5219 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5220 ok(!ret && GetLastError() == E_INVALIDARG,
5221 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5224 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5227 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
5228 if (size == sizeof(minimalPKCSSigner))
5229 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
5231 ok(0, "Unexpected value\n");
5235 info.SerialNumber.cbData = sizeof(serialNum);
5236 info.SerialNumber.pbData = (BYTE *)serialNum;
5237 SetLastError(0xdeadbeef);
5238 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5239 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5240 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5241 ok(!ret && GetLastError() == E_INVALIDARG,
5242 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5245 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5248 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
5250 if (size == sizeof(PKCSSignerWithSerial))
5251 ok(!memcmp(buf, PKCSSignerWithSerial, size),
5252 "Unexpected value\n");
5254 ok(0, "Unexpected value\n");
5258 info.HashAlgorithm.pszObjId = oid1;
5259 SetLastError(0xdeadbeef);
5260 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5261 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5262 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5263 ok(!ret && GetLastError() == E_INVALIDARG,
5264 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5267 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5270 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
5272 if (size == sizeof(PKCSSignerWithHashAlgo))
5273 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
5274 "Unexpected value\n");
5276 ok(0, "Unexpected value\n");
5280 info.HashEncryptionAlgorithm.pszObjId = oid2;
5281 SetLastError(0xdeadbeef);
5282 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5283 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5284 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5285 ok(!ret && GetLastError() == E_INVALIDARG,
5286 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5289 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5292 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
5293 "Unexpected size %d\n", size);
5294 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
5295 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
5296 "Unexpected value\n");
5298 ok(0, "Unexpected value\n");
5302 info.EncryptedHash.cbData = sizeof(hash);
5303 info.EncryptedHash.pbData = (BYTE *)hash;
5304 SetLastError(0xdeadbeef);
5305 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5306 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5307 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5308 ok(!ret && GetLastError() == E_INVALIDARG,
5309 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5312 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5315 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
5317 if (size == sizeof(PKCSSignerWithHash))
5318 ok(!memcmp(buf, PKCSSignerWithHash, size),
5319 "Unexpected value\n");
5321 ok(0, "Unexpected value\n");
5325 info.AuthAttrs.cAttr = 1;
5326 info.AuthAttrs.rgAttr = &attr;
5327 SetLastError(0xdeadbeef);
5328 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5329 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5330 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5331 ok(!ret && GetLastError() == E_INVALIDARG,
5332 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5335 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5338 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
5340 if (size == sizeof(PKCSSignerWithAuthAttr))
5341 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
5342 "Unexpected value\n");
5344 ok(0, "Unexpected value\n");
5350 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
5355 CMSG_SIGNER_INFO *info;
5357 /* A PKCS signer can't be decoded without a serial number. */
5358 SetLastError(0xdeadbeef);
5359 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5360 minimalPKCSSigner, sizeof(minimalPKCSSigner),
5361 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5362 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
5363 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
5364 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5365 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
5366 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5367 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5370 info = (CMSG_SIGNER_INFO *)buf;
5371 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5373 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5374 "Unexpected size %d\n", info->Issuer.cbData);
5375 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5376 info->Issuer.cbData), "Unexpected value\n");
5377 ok(info->SerialNumber.cbData == sizeof(serialNum),
5378 "Unexpected size %d\n", info->SerialNumber.cbData);
5379 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5380 "Unexpected value\n");
5383 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5384 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
5385 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5388 info = (CMSG_SIGNER_INFO *)buf;
5389 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5391 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5392 "Unexpected size %d\n", info->Issuer.cbData);
5393 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5394 info->Issuer.cbData), "Unexpected value\n");
5395 ok(info->SerialNumber.cbData == sizeof(serialNum),
5396 "Unexpected size %d\n", info->SerialNumber.cbData);
5397 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5398 "Unexpected value\n");
5399 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5400 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5403 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5404 PKCSSignerWithHashAndEncryptionAlgo,
5405 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
5406 NULL, (BYTE *)&buf, &size);
5409 info = (CMSG_SIGNER_INFO *)buf;
5410 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5412 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5413 "Unexpected size %d\n", info->Issuer.cbData);
5414 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5415 info->Issuer.cbData), "Unexpected value\n");
5416 ok(info->SerialNumber.cbData == sizeof(serialNum),
5417 "Unexpected size %d\n", info->SerialNumber.cbData);
5418 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5419 "Unexpected value\n");
5420 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5421 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5422 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
5423 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
5426 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5427 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
5428 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5431 info = (CMSG_SIGNER_INFO *)buf;
5432 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5434 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5435 "Unexpected size %d\n", info->Issuer.cbData);
5436 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5437 info->Issuer.cbData), "Unexpected value\n");
5438 ok(info->SerialNumber.cbData == sizeof(serialNum),
5439 "Unexpected size %d\n", info->SerialNumber.cbData);
5440 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5441 "Unexpected value\n");
5442 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5443 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5444 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
5445 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
5446 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
5447 info->EncryptedHash.cbData);
5448 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
5449 "Unexpected value\n");
5452 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5453 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
5454 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5457 info = (CMSG_SIGNER_INFO *)buf;
5458 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
5459 info->AuthAttrs.cAttr);
5460 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
5461 "Expected %s, got %s\n", szOID_COMMON_NAME,
5462 info->AuthAttrs.rgAttr[0].pszObjId);
5463 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
5464 info->AuthAttrs.rgAttr[0].cValue);
5465 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
5466 sizeof(encodedCommonName), "Unexpected size %d\n",
5467 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
5468 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
5469 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
5474 static BYTE emptyDNSPermittedConstraints[] = {
5475 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
5476 static BYTE emptyDNSExcludedConstraints[] = {
5477 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
5478 static BYTE DNSExcludedConstraints[] = {
5479 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
5480 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5481 static BYTE permittedAndExcludedConstraints[] = {
5482 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5483 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
5484 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5485 static BYTE permittedAndExcludedWithMinConstraints[] = {
5486 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5487 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
5488 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5489 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
5490 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5491 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
5492 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5494 static void test_encodeNameConstraints(DWORD dwEncoding)
5497 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
5498 CERT_GENERAL_SUBTREE permitted = { { 0 } };
5499 CERT_GENERAL_SUBTREE excluded = { { 0 } };
5503 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5504 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5505 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5508 ok(size == sizeof(emptySequence), "Unexpected size\n");
5509 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
5512 constraints.cPermittedSubtree = 1;
5513 constraints.rgPermittedSubtree = &permitted;
5514 SetLastError(0xdeadbeef);
5515 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5516 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5517 ok(!ret && GetLastError() == E_INVALIDARG,
5518 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5519 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
5520 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5521 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5522 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5525 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
5526 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
5527 "Unexpected value\n");
5530 constraints.cPermittedSubtree = 0;
5531 constraints.cExcludedSubtree = 1;
5532 constraints.rgExcludedSubtree = &excluded;
5533 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
5534 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5535 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5536 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5539 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
5540 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
5541 "Unexpected value\n");
5544 excluded.Base.pwszURL = (LPWSTR)url;
5545 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5546 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5547 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5550 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
5551 ok(!memcmp(buf, DNSExcludedConstraints, size),
5552 "Unexpected value\n");
5555 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
5556 permitted.Base.IPAddress.cbData = sizeof(encodedIPAddr);
5557 permitted.Base.IPAddress.pbData = (LPBYTE)encodedIPAddr;
5558 constraints.cPermittedSubtree = 1;
5559 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5560 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5561 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5564 ok(size == sizeof(permittedAndExcludedConstraints),
5565 "Unexpected size\n");
5566 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
5567 "Unexpected value\n");
5570 permitted.dwMinimum = 5;
5571 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5572 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5573 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5576 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
5577 "Unexpected size\n");
5578 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
5579 "Unexpected value\n");
5582 permitted.fMaximum = TRUE;
5583 permitted.dwMaximum = 3;
5584 SetLastError(0xdeadbeef);
5585 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5586 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5587 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5590 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
5591 "Unexpected size\n");
5592 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
5593 "Unexpected value\n");
5598 struct EncodedNameConstraints
5600 CRYPT_DATA_BLOB encoded;
5601 CERT_NAME_CONSTRAINTS_INFO constraints;
5604 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
5605 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
5606 static CERT_GENERAL_SUBTREE DNSSubtree = {
5607 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
5608 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
5609 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
5610 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
5611 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
5612 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
5613 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
5615 struct EncodedNameConstraints encodedNameConstraints[] = {
5616 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
5617 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
5618 { 1, &emptyDNSSubtree, 0, NULL } },
5619 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
5620 { 0, NULL, 1, &emptyDNSSubtree } },
5621 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
5622 { 0, NULL, 1, &DNSSubtree } },
5623 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
5624 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
5625 { { sizeof(permittedAndExcludedWithMinConstraints),
5626 permittedAndExcludedWithMinConstraints },
5627 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
5628 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
5629 permittedAndExcludedWithMinMaxConstraints },
5630 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
5633 static void test_decodeNameConstraints(DWORD dwEncoding)
5637 CERT_NAME_CONSTRAINTS_INFO *constraints;
5639 DNSSubtree.Base.pwszURL = (LPWSTR)url;
5640 IPAddressSubtree.Base.IPAddress.cbData = sizeof(encodedIPAddr);
5641 IPAddressSubtree.Base.IPAddress.pbData = (LPBYTE)encodedIPAddr;
5642 IPAddressWithMinSubtree.Base.IPAddress.cbData = sizeof(encodedIPAddr);
5643 IPAddressWithMinSubtree.Base.IPAddress.pbData = (LPBYTE)encodedIPAddr;
5644 IPAddressWithMinMaxSubtree.Base.IPAddress.cbData = sizeof(encodedIPAddr);
5645 IPAddressWithMinMaxSubtree.Base.IPAddress.pbData = (LPBYTE)encodedIPAddr;
5647 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
5652 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
5653 encodedNameConstraints[i].encoded.pbData,
5654 encodedNameConstraints[i].encoded.cbData,
5655 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
5657 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
5662 if (constraints->cPermittedSubtree !=
5663 encodedNameConstraints[i].constraints.cPermittedSubtree)
5664 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
5665 encodedNameConstraints[i].constraints.cPermittedSubtree,
5666 constraints->cPermittedSubtree);
5667 if (constraints->cPermittedSubtree ==
5668 encodedNameConstraints[i].constraints.cPermittedSubtree)
5670 for (j = 0; j < constraints->cPermittedSubtree; j++)
5672 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
5673 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
5676 if (constraints->cExcludedSubtree !=
5677 encodedNameConstraints[i].constraints.cExcludedSubtree)
5678 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
5679 encodedNameConstraints[i].constraints.cExcludedSubtree,
5680 constraints->cExcludedSubtree);
5681 if (constraints->cExcludedSubtree ==
5682 encodedNameConstraints[i].constraints.cExcludedSubtree)
5684 for (j = 0; j < constraints->cExcludedSubtree; j++)
5686 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
5687 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
5690 LocalFree(constraints);
5695 /* Free *pInfo with HeapFree */
5696 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
5703 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
5705 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
5706 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5707 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5708 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
5710 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5711 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5712 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
5714 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5715 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5716 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
5717 0, NULL, NULL, &size);
5718 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5719 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5720 /* Test with no key */
5721 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
5722 0, NULL, NULL, &size);
5723 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
5725 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
5726 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
5729 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
5730 NULL, 0, NULL, NULL, &size);
5731 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
5732 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
5735 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
5736 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
5737 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
5741 /* By default (we passed NULL as the OID) the OID is
5744 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
5745 "Expected %s, got %s\n", szOID_RSA_RSA,
5746 (*pInfo)->Algorithm.pszObjId);
5752 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
5753 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
5754 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
5755 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
5756 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
5757 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
5758 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
5759 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
5760 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
5761 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
5762 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
5763 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
5764 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
5765 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
5766 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
5767 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
5768 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
5769 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
5770 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
5771 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
5772 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
5773 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
5774 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
5775 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
5776 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
5778 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
5782 PCCERT_CONTEXT context;
5785 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
5786 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
5787 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
5788 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
5791 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
5792 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
5793 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
5794 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
5795 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
5796 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
5797 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
5799 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5800 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5801 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
5803 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
5804 CryptDestroyKey(key);
5806 /* Test importing a public key from a certificate context */
5807 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
5808 sizeof(expiredCert));
5809 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
5813 ok(!strcmp(szOID_RSA_RSA,
5814 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
5815 "Expected %s, got %s\n", szOID_RSA_RSA,
5816 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
5817 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
5818 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
5819 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
5820 CryptDestroyKey(key);
5821 CertFreeCertificateContext(context);
5825 static const char cspName[] = "WineCryptTemp";
5827 static void testPortPublicKeyInfo(void)
5831 PCERT_PUBLIC_KEY_INFO info = NULL;
5833 /* Just in case a previous run failed, delete this thing */
5834 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5835 CRYPT_DELETEKEYSET);
5836 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5839 testExportPublicKey(csp, &info);
5840 testImportPublicKey(csp, info);
5842 HeapFree(GetProcessHeap(), 0, info);
5843 CryptReleaseContext(csp, 0);
5844 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5845 CRYPT_DELETEKEYSET);
5850 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
5851 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
5854 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
5856 test_encodeInt(encodings[i]);
5857 test_decodeInt(encodings[i]);
5858 test_encodeEnumerated(encodings[i]);
5859 test_decodeEnumerated(encodings[i]);
5860 test_encodeFiletime(encodings[i]);
5861 test_decodeFiletime(encodings[i]);
5862 test_encodeName(encodings[i]);
5863 test_decodeName(encodings[i]);
5864 test_encodeUnicodeName(encodings[i]);
5865 test_decodeUnicodeName(encodings[i]);
5866 test_encodeNameValue(encodings[i]);
5867 test_decodeNameValue(encodings[i]);
5868 test_encodeUnicodeNameValue(encodings[i]);
5869 test_decodeUnicodeNameValue(encodings[i]);
5870 test_encodeAltName(encodings[i]);
5871 test_decodeAltName(encodings[i]);
5872 test_encodeOctets(encodings[i]);
5873 test_decodeOctets(encodings[i]);
5874 test_encodeBits(encodings[i]);
5875 test_decodeBits(encodings[i]);
5876 test_encodeBasicConstraints(encodings[i]);
5877 test_decodeBasicConstraints(encodings[i]);
5878 test_encodeRsaPublicKey(encodings[i]);
5879 test_decodeRsaPublicKey(encodings[i]);
5880 test_encodeSequenceOfAny(encodings[i]);
5881 test_decodeSequenceOfAny(encodings[i]);
5882 test_encodeExtensions(encodings[i]);
5883 test_decodeExtensions(encodings[i]);
5884 test_encodePublicKeyInfo(encodings[i]);
5885 test_decodePublicKeyInfo(encodings[i]);
5886 test_encodeCertToBeSigned(encodings[i]);
5887 test_decodeCertToBeSigned(encodings[i]);
5888 test_encodeCert(encodings[i]);
5889 test_decodeCert(encodings[i]);
5890 test_encodeCRLDistPoints(encodings[i]);
5891 test_decodeCRLDistPoints(encodings[i]);
5892 test_encodeCRLIssuingDistPoint(encodings[i]);
5893 test_decodeCRLIssuingDistPoint(encodings[i]);
5894 test_encodeCRLToBeSigned(encodings[i]);
5895 test_decodeCRLToBeSigned(encodings[i]);
5896 test_encodeEnhancedKeyUsage(encodings[i]);
5897 test_decodeEnhancedKeyUsage(encodings[i]);
5898 test_encodeAuthorityKeyId(encodings[i]);
5899 test_decodeAuthorityKeyId(encodings[i]);
5900 test_encodeAuthorityKeyId2(encodings[i]);
5901 test_decodeAuthorityKeyId2(encodings[i]);
5902 test_encodePKCSContentInfo(encodings[i]);
5903 test_decodePKCSContentInfo(encodings[i]);
5904 test_encodePKCSAttribute(encodings[i]);
5905 test_decodePKCSAttribute(encodings[i]);
5906 test_encodePKCSAttributes(encodings[i]);
5907 test_decodePKCSAttributes(encodings[i]);
5908 test_encodePKCSSignerInfo(encodings[i]);
5909 test_decodePKCSSignerInfo(encodings[i]);
5910 test_encodeNameConstraints(encodings[i]);
5911 test_decodeNameConstraints(encodings[i]);
5913 testPortPublicKeyInfo();