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 = { { 0 } };
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 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");
4301 /* a real CRL from verisign that has extensions */
4302 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4303 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4304 NULL, (BYTE *)&buf, &size);
4305 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4308 CRL_INFO *info = (CRL_INFO *)buf;
4311 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4312 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4314 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4315 entry = info->rgCRLEntry;
4316 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4320 /* another real CRL from verisign that has lots of entries */
4321 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4322 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4323 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4324 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4327 CRL_INFO *info = (CRL_INFO *)buf;
4329 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4330 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4332 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4336 /* and finally, with an extension */
4337 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4338 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4339 NULL, (BYTE *)&buf, &size);
4340 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4343 CRL_INFO *info = (CRL_INFO *)buf;
4346 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4347 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4349 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4350 entry = info->rgCRLEntry;
4351 ok(entry->SerialNumber.cbData == 1,
4352 "Expected serial number size 1, got %d\n",
4353 entry->SerialNumber.cbData);
4354 ok(*entry->SerialNumber.pbData == *serialNum,
4355 "Expected serial number %d, got %d\n", *serialNum,
4356 *entry->SerialNumber.pbData);
4357 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4358 "Wrong issuer size %d\n", info->Issuer.cbData);
4359 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4360 "Unexpected issuer\n");
4361 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4365 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4366 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4367 NULL, (BYTE *)&buf, &size);
4368 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4371 CRL_INFO *info = (CRL_INFO *)buf;
4373 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4377 /* And again, with an issuing dist point */
4378 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4379 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4380 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4381 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4384 CRL_INFO *info = (CRL_INFO *)buf;
4386 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4392 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4393 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4394 static const BYTE encodedUsage[] = {
4395 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4396 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4397 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4399 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4404 CERT_ENHKEY_USAGE usage;
4406 /* Test with empty usage */
4407 usage.cUsageIdentifier = 0;
4408 ret = CryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4409 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4410 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4413 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4414 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4417 /* Test with a few usages */
4418 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4419 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4420 ret = CryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4421 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4422 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4425 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4426 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4431 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4437 ret = CryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4438 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4439 (BYTE *)&buf, &size);
4440 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4443 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4445 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4446 "Wrong size %d\n", size);
4447 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4448 usage->cUsageIdentifier);
4451 ret = CryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4452 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4453 (BYTE *)&buf, &size);
4454 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4457 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4460 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4461 "Wrong size %d\n", size);
4462 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4463 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4464 for (i = 0; i < usage->cUsageIdentifier; i++)
4465 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4466 "Expected OID %s, got %s\n", keyUsages[i],
4467 usage->rgpszUsageIdentifier[i]);
4472 static BYTE keyId[] = { 1,2,3,4 };
4473 static const BYTE authorityKeyIdWithId[] = {
4474 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4475 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4476 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4477 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4478 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4480 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4482 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4487 /* Test with empty id */
4488 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4489 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4490 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4493 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4494 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4497 /* With just a key id */
4498 info.KeyId.cbData = sizeof(keyId);
4499 info.KeyId.pbData = keyId;
4500 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4501 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4502 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4505 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4506 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4509 /* With just an issuer */
4510 info.KeyId.cbData = 0;
4511 info.CertIssuer.cbData = sizeof(encodedCommonName);
4512 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4513 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4514 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4515 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4518 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4520 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4523 /* With just a serial number */
4524 info.CertIssuer.cbData = 0;
4525 info.CertSerialNumber.cbData = sizeof(serialNum);
4526 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4527 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4528 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4529 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4532 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4534 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4539 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4545 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4546 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4547 (BYTE *)&buf, &size);
4548 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4551 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4553 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4555 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4556 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4557 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4560 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4561 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4562 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4563 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4566 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4568 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4570 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4571 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4572 "Unexpected key id\n");
4573 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4574 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4577 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4578 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4579 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4580 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4583 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4585 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4587 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4588 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4589 "Unexpected issuer len\n");
4590 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4591 sizeof(encodedCommonName)), "Unexpected issuer\n");
4592 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4595 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4596 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4597 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4598 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4601 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4603 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4605 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4606 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4607 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4608 "Unexpected serial number len\n");
4609 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4610 "Unexpected serial number\n");
4615 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4616 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4619 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4621 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4622 CERT_ALT_NAME_ENTRY entry = { 0 };
4627 /* Test with empty id */
4628 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4629 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4630 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4633 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4634 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4637 /* With just a key id */
4638 info.KeyId.cbData = sizeof(keyId);
4639 info.KeyId.pbData = keyId;
4640 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4641 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4642 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4645 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4647 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4650 /* With a bogus issuer name */
4651 info.KeyId.cbData = 0;
4652 info.AuthorityCertIssuer.cAltEntry = 1;
4653 info.AuthorityCertIssuer.rgAltEntry = &entry;
4654 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4655 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4656 ok(!ret && GetLastError() == E_INVALIDARG,
4657 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4658 /* With an issuer name */
4659 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4660 U(entry).pwszURL = (LPWSTR)url;
4661 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4662 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4663 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4666 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4668 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4669 "Unexpected value\n");
4672 /* With just a serial number */
4673 info.AuthorityCertIssuer.cAltEntry = 0;
4674 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4675 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4676 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4677 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4678 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4681 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4683 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4688 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4694 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4695 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4696 (BYTE *)&buf, &size);
4697 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4700 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4702 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4704 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4705 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4706 "Expected no issuer name entries\n");
4707 ok(info->AuthorityCertSerialNumber.cbData == 0,
4708 "Expected no serial number\n");
4711 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4712 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4713 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4714 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4717 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4719 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4721 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4722 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4723 "Unexpected key id\n");
4724 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4725 "Expected no issuer name entries\n");
4726 ok(info->AuthorityCertSerialNumber.cbData == 0,
4727 "Expected no serial number\n");
4730 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4731 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4732 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4733 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4736 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4738 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4740 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4741 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4742 "Expected 1 issuer entry, got %d\n",
4743 info->AuthorityCertIssuer.cAltEntry);
4744 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4745 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4746 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4747 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4748 url), "Unexpected URL\n");
4749 ok(info->AuthorityCertSerialNumber.cbData == 0,
4750 "Expected no serial number\n");
4753 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4754 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4755 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4756 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4759 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4761 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4763 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4764 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4765 "Expected no issuer name entries\n");
4766 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4767 "Unexpected serial number len\n");
4768 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4769 sizeof(serialNum)), "Unexpected serial number\n");
4774 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
4775 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
4777 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
4779 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
4780 0x03,0x02,0x01,0x01 };
4781 static BYTE bogusDER[] = { 1 };
4783 static void test_encodePKCSContentInfo(DWORD dwEncoding)
4788 CRYPT_CONTENT_INFO info = { 0 };
4789 char oid1[] = "1.2.3";
4791 SetLastError(0xdeadbeef);
4792 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
4793 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4794 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4795 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
4796 SetLastError(0xdeadbeef);
4797 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4798 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4799 ok(!ret && GetLastError() == E_INVALIDARG,
4800 "Expected E_INVALIDARG, got %x\n", GetLastError());
4801 info.pszObjId = oid1;
4802 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4803 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4804 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4807 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
4808 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
4811 info.Content.pbData = bogusDER;
4812 info.Content.cbData = sizeof(bogusDER);
4813 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4814 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4815 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
4818 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
4819 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
4822 info.Content.pbData = (BYTE *)ints[0].encoded;
4823 info.Content.cbData = ints[0].encoded[1] + 2;
4824 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4825 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4828 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
4829 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
4834 static const BYTE indefiniteSignedPKCSContent[] = {
4835 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
4836 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
4837 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
4838 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
4839 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
4840 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
4841 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
4842 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
4843 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
4844 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
4845 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
4846 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
4847 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
4848 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
4849 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
4850 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
4851 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
4852 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
4853 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
4854 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
4855 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
4856 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
4857 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
4858 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
4859 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
4860 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
4861 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
4862 0x00,0x00,0x00,0x00,0x00,0x00 };
4864 static void test_decodePKCSContentInfo(DWORD dwEncoding)
4869 CRYPT_CONTENT_INFO *info;
4871 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4872 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
4873 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4874 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4877 info = (CRYPT_CONTENT_INFO *)buf;
4879 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4881 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
4882 info->Content.cbData);
4885 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4886 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
4887 0, NULL, NULL, &size);
4888 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4889 SetLastError(0xdeadbeef);
4890 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4891 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
4892 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4893 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
4894 * I doubt an app depends on that.
4896 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
4897 GetLastError() == CRYPT_E_ASN1_CORRUPT),
4898 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
4900 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4901 intPKCSContentInfo, sizeof(intPKCSContentInfo),
4902 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4903 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4906 info = (CRYPT_CONTENT_INFO *)buf;
4908 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4910 ok(info->Content.cbData == ints[0].encoded[1] + 2,
4911 "Unexpected size %d\n", info->Content.cbData);
4912 ok(!memcmp(info->Content.pbData, ints[0].encoded,
4913 info->Content.cbData), "Unexpected value\n");
4916 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4917 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
4918 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4919 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4922 info = (CRYPT_CONTENT_INFO *)buf;
4924 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
4925 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
4926 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
4927 info->Content.cbData);
4932 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
4934 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
4936 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
4939 static void test_encodePKCSAttribute(DWORD dwEncoding)
4941 CRYPT_ATTRIBUTE attr = { 0 };
4945 CRYPT_ATTR_BLOB blob;
4946 char oid[] = "1.2.3";
4948 SetLastError(0xdeadbeef);
4949 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
4950 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4951 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4952 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
4953 SetLastError(0xdeadbeef);
4954 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4955 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4956 ok(!ret && GetLastError() == E_INVALIDARG,
4957 "Expected E_INVALIDARG, got %x\n", GetLastError());
4958 attr.pszObjId = oid;
4959 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4960 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4961 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4964 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
4965 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
4968 blob.cbData = sizeof(bogusDER);
4969 blob.pbData = bogusDER;
4971 attr.rgValue = &blob;
4972 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4973 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4974 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4977 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
4978 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
4981 blob.pbData = (BYTE *)ints[0].encoded;
4982 blob.cbData = ints[0].encoded[1] + 2;
4983 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4984 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4987 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
4988 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
4993 static void test_decodePKCSAttribute(DWORD dwEncoding)
4998 CRYPT_ATTRIBUTE *attr;
5000 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5001 emptyPKCSAttr, sizeof(emptyPKCSAttr),
5002 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5003 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5006 attr = (CRYPT_ATTRIBUTE *)buf;
5008 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5010 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5013 SetLastError(0xdeadbeef);
5014 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5015 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5016 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5017 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5018 * I doubt an app depends on that.
5020 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5021 GetLastError() == CRYPT_E_ASN1_CORRUPT),
5022 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5024 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5025 intPKCSAttr, sizeof(intPKCSAttr),
5026 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5027 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5030 attr = (CRYPT_ATTRIBUTE *)buf;
5032 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5034 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5035 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5036 "Unexpected size %d\n", attr->rgValue[0].cbData);
5037 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5038 attr->rgValue[0].cbData), "Unexpected value\n");
5043 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5044 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5045 0x2a,0x03,0x31,0x00 };
5046 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5047 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5049 static void test_encodePKCSAttributes(DWORD dwEncoding)
5051 CRYPT_ATTRIBUTES attributes = { 0 };
5052 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5053 CRYPT_ATTR_BLOB blob;
5057 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5059 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5060 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5061 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5064 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5065 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5068 attributes.cAttr = 1;
5069 attributes.rgAttr = attr;
5070 SetLastError(0xdeadbeef);
5071 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5072 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5073 ok(!ret && GetLastError() == E_INVALIDARG,
5074 "Expected E_INVALIDARG, got %x\n", GetLastError());
5075 attr[0].pszObjId = oid1;
5076 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5077 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5080 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5081 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5084 attr[1].pszObjId = oid2;
5086 attr[1].rgValue = &blob;
5087 blob.pbData = (BYTE *)ints[0].encoded;
5088 blob.cbData = ints[0].encoded[1] + 2;
5089 attributes.cAttr = 2;
5090 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5091 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5092 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5095 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5096 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5101 static void test_decodePKCSAttributes(DWORD dwEncoding)
5106 CRYPT_ATTRIBUTES *attributes;
5108 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5109 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5110 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5111 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5114 attributes = (CRYPT_ATTRIBUTES *)buf;
5115 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5119 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5120 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5121 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5122 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5125 attributes = (CRYPT_ATTRIBUTES *)buf;
5126 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5128 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5129 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5130 ok(attributes->rgAttr[0].cValue == 0,
5131 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5134 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5135 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5136 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5137 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5140 attributes = (CRYPT_ATTRIBUTES *)buf;
5141 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5143 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5144 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5145 ok(attributes->rgAttr[0].cValue == 0,
5146 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5147 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5148 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5149 ok(attributes->rgAttr[1].cValue == 1,
5150 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5151 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5152 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5153 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5154 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5159 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
5160 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5162 static const BYTE minimalPKCSSigner[] = {
5163 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5164 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5165 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
5166 static const BYTE PKCSSignerWithSerial[] = {
5167 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5168 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5169 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5171 static const BYTE PKCSSignerWithHashAlgo[] = {
5172 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5173 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5174 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5176 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
5177 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5178 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5179 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5180 0x06,0x05,0x00,0x04,0x00 };
5181 static const BYTE PKCSSignerWithHash[] = {
5182 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5183 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5184 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5185 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
5186 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5187 static const BYTE PKCSSignerWithAuthAttr[] = {
5188 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5189 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5190 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
5191 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
5192 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
5193 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
5194 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5196 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
5198 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
5202 CMSG_SIGNER_INFO info = { 0 };
5203 char oid_common_name[] = szOID_COMMON_NAME;
5204 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
5205 (LPBYTE)encodedCommonName };
5206 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
5208 SetLastError(0xdeadbeef);
5209 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5210 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5211 ok(!ret && GetLastError() == E_INVALIDARG,
5212 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5213 /* To be encoded, a signer must have an issuer at least, and the encoding
5214 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
5215 * see decoding tests.)
5217 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
5218 info.Issuer.pbData = encodedCommonNameNoNull;
5219 SetLastError(0xdeadbeef);
5220 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5221 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5222 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5223 ok(!ret && GetLastError() == E_INVALIDARG,
5224 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5227 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5230 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
5231 if (size == sizeof(minimalPKCSSigner))
5232 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
5234 ok(0, "Unexpected value\n");
5238 info.SerialNumber.cbData = sizeof(serialNum);
5239 info.SerialNumber.pbData = (BYTE *)serialNum;
5240 SetLastError(0xdeadbeef);
5241 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5242 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5243 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5244 ok(!ret && GetLastError() == E_INVALIDARG,
5245 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5248 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5251 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
5253 if (size == sizeof(PKCSSignerWithSerial))
5254 ok(!memcmp(buf, PKCSSignerWithSerial, size),
5255 "Unexpected value\n");
5257 ok(0, "Unexpected value\n");
5261 info.HashAlgorithm.pszObjId = oid1;
5262 SetLastError(0xdeadbeef);
5263 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5264 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5265 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5266 ok(!ret && GetLastError() == E_INVALIDARG,
5267 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5270 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5273 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
5275 if (size == sizeof(PKCSSignerWithHashAlgo))
5276 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
5277 "Unexpected value\n");
5279 ok(0, "Unexpected value\n");
5283 info.HashEncryptionAlgorithm.pszObjId = oid2;
5284 SetLastError(0xdeadbeef);
5285 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5286 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5287 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5288 ok(!ret && GetLastError() == E_INVALIDARG,
5289 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5292 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5295 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
5296 "Unexpected size %d\n", size);
5297 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
5298 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
5299 "Unexpected value\n");
5301 ok(0, "Unexpected value\n");
5305 info.EncryptedHash.cbData = sizeof(hash);
5306 info.EncryptedHash.pbData = (BYTE *)hash;
5307 SetLastError(0xdeadbeef);
5308 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5309 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5310 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5311 ok(!ret && GetLastError() == E_INVALIDARG,
5312 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5315 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5318 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
5320 if (size == sizeof(PKCSSignerWithHash))
5321 ok(!memcmp(buf, PKCSSignerWithHash, size),
5322 "Unexpected value\n");
5324 ok(0, "Unexpected value\n");
5328 info.AuthAttrs.cAttr = 1;
5329 info.AuthAttrs.rgAttr = &attr;
5330 SetLastError(0xdeadbeef);
5331 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5332 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5333 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5334 ok(!ret && GetLastError() == E_INVALIDARG,
5335 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5338 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5341 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
5343 if (size == sizeof(PKCSSignerWithAuthAttr))
5344 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
5345 "Unexpected value\n");
5347 ok(0, "Unexpected value\n");
5353 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
5358 CMSG_SIGNER_INFO *info;
5360 /* A PKCS signer can't be decoded without a serial number. */
5361 SetLastError(0xdeadbeef);
5362 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5363 minimalPKCSSigner, sizeof(minimalPKCSSigner),
5364 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5365 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
5366 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
5367 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5368 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
5369 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5370 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5373 info = (CMSG_SIGNER_INFO *)buf;
5374 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5376 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5377 "Unexpected size %d\n", info->Issuer.cbData);
5378 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5379 info->Issuer.cbData), "Unexpected value\n");
5380 ok(info->SerialNumber.cbData == sizeof(serialNum),
5381 "Unexpected size %d\n", info->SerialNumber.cbData);
5382 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5383 "Unexpected value\n");
5386 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5387 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
5388 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5391 info = (CMSG_SIGNER_INFO *)buf;
5392 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5394 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5395 "Unexpected size %d\n", info->Issuer.cbData);
5396 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5397 info->Issuer.cbData), "Unexpected value\n");
5398 ok(info->SerialNumber.cbData == sizeof(serialNum),
5399 "Unexpected size %d\n", info->SerialNumber.cbData);
5400 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5401 "Unexpected value\n");
5402 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5403 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5406 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5407 PKCSSignerWithHashAndEncryptionAlgo,
5408 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
5409 NULL, (BYTE *)&buf, &size);
5412 info = (CMSG_SIGNER_INFO *)buf;
5413 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5415 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5416 "Unexpected size %d\n", info->Issuer.cbData);
5417 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5418 info->Issuer.cbData), "Unexpected value\n");
5419 ok(info->SerialNumber.cbData == sizeof(serialNum),
5420 "Unexpected size %d\n", info->SerialNumber.cbData);
5421 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5422 "Unexpected value\n");
5423 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5424 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5425 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
5426 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
5429 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5430 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
5431 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5434 info = (CMSG_SIGNER_INFO *)buf;
5435 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5437 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5438 "Unexpected size %d\n", info->Issuer.cbData);
5439 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5440 info->Issuer.cbData), "Unexpected value\n");
5441 ok(info->SerialNumber.cbData == sizeof(serialNum),
5442 "Unexpected size %d\n", info->SerialNumber.cbData);
5443 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5444 "Unexpected value\n");
5445 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5446 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5447 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
5448 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
5449 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
5450 info->EncryptedHash.cbData);
5451 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
5452 "Unexpected value\n");
5455 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5456 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
5457 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5460 info = (CMSG_SIGNER_INFO *)buf;
5461 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
5462 info->AuthAttrs.cAttr);
5463 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
5464 "Expected %s, got %s\n", szOID_COMMON_NAME,
5465 info->AuthAttrs.rgAttr[0].pszObjId);
5466 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
5467 info->AuthAttrs.rgAttr[0].cValue);
5468 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
5469 sizeof(encodedCommonName), "Unexpected size %d\n",
5470 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
5471 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
5472 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
5477 static BYTE emptyDNSPermittedConstraints[] = {
5478 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
5479 static BYTE emptyDNSExcludedConstraints[] = {
5480 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
5481 static BYTE DNSExcludedConstraints[] = {
5482 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
5483 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5484 static BYTE permittedAndExcludedConstraints[] = {
5485 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5486 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
5487 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5488 static BYTE permittedAndExcludedWithMinConstraints[] = {
5489 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5490 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
5491 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5492 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
5493 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5494 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
5495 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5497 static void test_encodeNameConstraints(DWORD dwEncoding)
5500 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
5501 CERT_GENERAL_SUBTREE permitted = { { 0 } };
5502 CERT_GENERAL_SUBTREE excluded = { { 0 } };
5506 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5507 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5508 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5511 ok(size == sizeof(emptySequence), "Unexpected size\n");
5512 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
5515 constraints.cPermittedSubtree = 1;
5516 constraints.rgPermittedSubtree = &permitted;
5517 SetLastError(0xdeadbeef);
5518 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5519 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5520 ok(!ret && GetLastError() == E_INVALIDARG,
5521 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5522 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
5523 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5524 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5525 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5528 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
5529 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
5530 "Unexpected value\n");
5533 constraints.cPermittedSubtree = 0;
5534 constraints.cExcludedSubtree = 1;
5535 constraints.rgExcludedSubtree = &excluded;
5536 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
5537 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5538 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5539 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5542 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
5543 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
5544 "Unexpected value\n");
5547 U(excluded.Base).pwszURL = (LPWSTR)url;
5548 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5549 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5550 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5553 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
5554 ok(!memcmp(buf, DNSExcludedConstraints, size),
5555 "Unexpected value\n");
5558 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
5559 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
5560 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
5561 constraints.cPermittedSubtree = 1;
5562 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5563 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5564 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5567 ok(size == sizeof(permittedAndExcludedConstraints),
5568 "Unexpected size\n");
5569 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
5570 "Unexpected value\n");
5573 permitted.dwMinimum = 5;
5574 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5575 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5576 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5579 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
5580 "Unexpected size\n");
5581 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
5582 "Unexpected value\n");
5585 permitted.fMaximum = TRUE;
5586 permitted.dwMaximum = 3;
5587 SetLastError(0xdeadbeef);
5588 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5589 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5590 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5593 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
5594 "Unexpected size\n");
5595 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
5596 "Unexpected value\n");
5601 struct EncodedNameConstraints
5603 CRYPT_DATA_BLOB encoded;
5604 CERT_NAME_CONSTRAINTS_INFO constraints;
5607 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
5608 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
5609 static CERT_GENERAL_SUBTREE DNSSubtree = {
5610 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
5611 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
5612 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
5613 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
5614 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
5615 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
5616 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
5618 struct EncodedNameConstraints encodedNameConstraints[] = {
5619 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
5620 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
5621 { 1, &emptyDNSSubtree, 0, NULL } },
5622 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
5623 { 0, NULL, 1, &emptyDNSSubtree } },
5624 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
5625 { 0, NULL, 1, &DNSSubtree } },
5626 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
5627 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
5628 { { sizeof(permittedAndExcludedWithMinConstraints),
5629 permittedAndExcludedWithMinConstraints },
5630 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
5631 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
5632 permittedAndExcludedWithMinMaxConstraints },
5633 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
5636 static void test_decodeNameConstraints(DWORD dwEncoding)
5640 CERT_NAME_CONSTRAINTS_INFO *constraints;
5642 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
5643 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
5644 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
5645 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
5646 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
5647 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
5648 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
5650 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
5655 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
5656 encodedNameConstraints[i].encoded.pbData,
5657 encodedNameConstraints[i].encoded.cbData,
5658 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
5659 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
5664 if (constraints->cPermittedSubtree !=
5665 encodedNameConstraints[i].constraints.cPermittedSubtree)
5666 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
5667 encodedNameConstraints[i].constraints.cPermittedSubtree,
5668 constraints->cPermittedSubtree);
5669 if (constraints->cPermittedSubtree ==
5670 encodedNameConstraints[i].constraints.cPermittedSubtree)
5672 for (j = 0; j < constraints->cPermittedSubtree; j++)
5674 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
5675 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
5678 if (constraints->cExcludedSubtree !=
5679 encodedNameConstraints[i].constraints.cExcludedSubtree)
5680 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
5681 encodedNameConstraints[i].constraints.cExcludedSubtree,
5682 constraints->cExcludedSubtree);
5683 if (constraints->cExcludedSubtree ==
5684 encodedNameConstraints[i].constraints.cExcludedSubtree)
5686 for (j = 0; j < constraints->cExcludedSubtree; j++)
5688 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
5689 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
5692 LocalFree(constraints);
5697 /* Free *pInfo with HeapFree */
5698 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
5705 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
5707 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
5708 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5709 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5710 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
5712 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5713 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5714 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
5716 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5717 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5718 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
5719 0, NULL, NULL, &size);
5720 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5721 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5722 /* Test with no key */
5723 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
5724 0, NULL, NULL, &size);
5725 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
5727 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
5728 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
5731 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
5732 NULL, 0, NULL, NULL, &size);
5733 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
5734 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
5737 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
5738 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
5739 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
5743 /* By default (we passed NULL as the OID) the OID is
5746 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
5747 "Expected %s, got %s\n", szOID_RSA_RSA,
5748 (*pInfo)->Algorithm.pszObjId);
5752 CryptDestroyKey(key);
5755 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
5756 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
5757 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
5758 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
5759 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
5760 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
5761 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
5762 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
5763 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
5764 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
5765 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
5766 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
5767 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
5768 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
5769 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
5770 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
5771 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
5772 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
5773 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
5774 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
5775 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
5776 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
5777 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
5778 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
5779 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
5781 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
5785 PCCERT_CONTEXT context;
5788 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
5789 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
5790 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
5791 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
5794 ret = CryptImportPublicKeyInfoEx(0, 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(csp, 0, info, 0, 0, NULL, &key);
5798 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
5799 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
5800 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
5802 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5803 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5804 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
5806 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
5807 CryptDestroyKey(key);
5809 /* Test importing a public key from a certificate context */
5810 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
5811 sizeof(expiredCert));
5812 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
5816 ok(!strcmp(szOID_RSA_RSA,
5817 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
5818 "Expected %s, got %s\n", szOID_RSA_RSA,
5819 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
5820 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
5821 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
5822 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
5823 CryptDestroyKey(key);
5824 CertFreeCertificateContext(context);
5828 static const char cspName[] = "WineCryptTemp";
5830 static void testPortPublicKeyInfo(void)
5834 PCERT_PUBLIC_KEY_INFO info = NULL;
5836 /* Just in case a previous run failed, delete this thing */
5837 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5838 CRYPT_DELETEKEYSET);
5839 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5842 testExportPublicKey(csp, &info);
5843 testImportPublicKey(csp, info);
5845 HeapFree(GetProcessHeap(), 0, info);
5846 CryptReleaseContext(csp, 0);
5847 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5848 CRYPT_DELETEKEYSET);
5853 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
5854 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
5857 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
5859 test_encodeInt(encodings[i]);
5860 test_decodeInt(encodings[i]);
5861 test_encodeEnumerated(encodings[i]);
5862 test_decodeEnumerated(encodings[i]);
5863 test_encodeFiletime(encodings[i]);
5864 test_decodeFiletime(encodings[i]);
5865 test_encodeName(encodings[i]);
5866 test_decodeName(encodings[i]);
5867 test_encodeUnicodeName(encodings[i]);
5868 test_decodeUnicodeName(encodings[i]);
5869 test_encodeNameValue(encodings[i]);
5870 test_decodeNameValue(encodings[i]);
5871 test_encodeUnicodeNameValue(encodings[i]);
5872 test_decodeUnicodeNameValue(encodings[i]);
5873 test_encodeAltName(encodings[i]);
5874 test_decodeAltName(encodings[i]);
5875 test_encodeOctets(encodings[i]);
5876 test_decodeOctets(encodings[i]);
5877 test_encodeBits(encodings[i]);
5878 test_decodeBits(encodings[i]);
5879 test_encodeBasicConstraints(encodings[i]);
5880 test_decodeBasicConstraints(encodings[i]);
5881 test_encodeRsaPublicKey(encodings[i]);
5882 test_decodeRsaPublicKey(encodings[i]);
5883 test_encodeSequenceOfAny(encodings[i]);
5884 test_decodeSequenceOfAny(encodings[i]);
5885 test_encodeExtensions(encodings[i]);
5886 test_decodeExtensions(encodings[i]);
5887 test_encodePublicKeyInfo(encodings[i]);
5888 test_decodePublicKeyInfo(encodings[i]);
5889 test_encodeCertToBeSigned(encodings[i]);
5890 test_decodeCertToBeSigned(encodings[i]);
5891 test_encodeCert(encodings[i]);
5892 test_decodeCert(encodings[i]);
5893 test_encodeCRLDistPoints(encodings[i]);
5894 test_decodeCRLDistPoints(encodings[i]);
5895 test_encodeCRLIssuingDistPoint(encodings[i]);
5896 test_decodeCRLIssuingDistPoint(encodings[i]);
5897 test_encodeCRLToBeSigned(encodings[i]);
5898 test_decodeCRLToBeSigned(encodings[i]);
5899 test_encodeEnhancedKeyUsage(encodings[i]);
5900 test_decodeEnhancedKeyUsage(encodings[i]);
5901 test_encodeAuthorityKeyId(encodings[i]);
5902 test_decodeAuthorityKeyId(encodings[i]);
5903 test_encodeAuthorityKeyId2(encodings[i]);
5904 test_decodeAuthorityKeyId2(encodings[i]);
5905 test_encodePKCSContentInfo(encodings[i]);
5906 test_decodePKCSContentInfo(encodings[i]);
5907 test_encodePKCSAttribute(encodings[i]);
5908 test_decodePKCSAttribute(encodings[i]);
5909 test_encodePKCSAttributes(encodings[i]);
5910 test_decodePKCSAttributes(encodings[i]);
5911 test_encodePKCSSignerInfo(encodings[i]);
5912 test_decodePKCSSignerInfo(encodings[i]);
5913 test_encodeNameConstraints(encodings[i]);
5914 test_decodeNameConstraints(encodings[i]);
5916 testPortPublicKeyInfo();