2 * Unit test suite for crypt32.dll's CryptEncodeObjectEx/CryptDecodeObjectEx
4 * Copyright 2005 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/test.h"
35 static const BYTE bin1[] = {0x02,0x01,0x01};
36 static const BYTE bin2[] = {0x02,0x01,0x7f};
37 static const BYTE bin3[] = {0x02,0x02,0x00,0x80};
38 static const BYTE bin4[] = {0x02,0x02,0x01,0x00};
39 static const BYTE bin5[] = {0x02,0x01,0x80};
40 static const BYTE bin6[] = {0x02,0x02,0xff,0x7f};
41 static const BYTE bin7[] = {0x02,0x04,0xba,0xdd,0xf0,0x0d};
43 static const struct encodedInt ints[] = {
60 static const BYTE bin8[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
61 static const BYTE bin9[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
62 static const BYTE bin10[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
64 static const BYTE bin11[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
65 static const BYTE bin12[] = {0x02,0x09,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
66 static const BYTE bin13[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0};
68 static const struct encodedBigInt bigInts[] = {
69 { bin8, bin9, bin10 },
70 { bin11, bin12, bin13 },
73 static const BYTE bin14[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
74 static const BYTE bin15[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
75 static const BYTE bin16[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
76 static const BYTE bin17[] = {0x02,0x0c,0x00,0xff,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
78 /* Decoded is the same as original, so don't bother storing a separate copy */
79 static const struct encodedBigInt bigUInts[] = {
80 { bin14, bin15, NULL },
81 { bin16, bin17, NULL },
84 static void test_encodeInt(DWORD dwEncoding)
89 CRYPT_INTEGER_BLOB blob;
92 /* CryptEncodeObjectEx with NULL bufSize crashes..
93 ret = CryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
96 /* check bogus encoding */
97 ret = CryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
99 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
100 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
101 /* check with NULL integer buffer. Windows XP incorrectly returns an
104 ret = CryptEncodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, NULL, NULL,
106 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
107 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
108 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
110 /* encode as normal integer */
111 ret = CryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 0,
112 NULL, NULL, &bufSize);
113 ok(ret, "Expected success, got %d\n", GetLastError());
114 ret = CryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val,
115 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
116 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
119 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
121 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
122 buf[1], ints[i].encoded[1]);
123 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
124 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
127 /* encode as multibyte integer */
128 blob.cbData = sizeof(ints[i].val);
129 blob.pbData = (BYTE *)&ints[i].val;
130 ret = CryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
131 0, NULL, NULL, &bufSize);
132 ok(ret, "Expected success, got %d\n", GetLastError());
133 ret = CryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
134 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
135 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
138 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
140 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
141 buf[1], ints[i].encoded[1]);
142 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
143 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
147 /* encode a couple bigger ints, just to show it's little-endian and leading
148 * sign bytes are dropped
150 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
152 blob.cbData = strlen((const char*)bigInts[i].val);
153 blob.pbData = (BYTE *)bigInts[i].val;
154 ret = CryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
155 0, NULL, NULL, &bufSize);
156 ok(ret, "Expected success, got %d\n", GetLastError());
157 ret = CryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
158 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
159 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
162 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
164 ok(buf[1] == bigInts[i].encoded[1], "Got length %d, expected %d\n",
165 buf[1], bigInts[i].encoded[1]);
166 ok(!memcmp(buf + 1, bigInts[i].encoded + 1,
167 bigInts[i].encoded[1] + 1),
168 "Encoded value didn't match expected\n");
172 /* and, encode some uints */
173 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
175 blob.cbData = strlen((const char*)bigUInts[i].val);
176 blob.pbData = (BYTE*)bigUInts[i].val;
177 ret = CryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
178 0, NULL, NULL, &bufSize);
179 ok(ret, "Expected success, got %d\n", GetLastError());
180 ret = CryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
181 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
182 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
185 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
187 ok(buf[1] == bigUInts[i].encoded[1], "Got length %d, expected %d\n",
188 buf[1], bigUInts[i].encoded[1]);
189 ok(!memcmp(buf + 1, bigUInts[i].encoded + 1,
190 bigUInts[i].encoded[1] + 1),
191 "Encoded value didn't match expected\n");
197 static void test_decodeInt(DWORD dwEncoding)
199 static const BYTE bigInt[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff };
200 static const BYTE testStr[] = { 0x16, 4, 't', 'e', 's', 't' };
201 static const BYTE longForm[] = { 2, 0x81, 0x01, 0x01 };
202 static const BYTE bigBogus[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 };
203 static const BYTE extraBytes[] = { 2, 1, 1, 0, 0, 0, 0 };
209 /* CryptDecodeObjectEx with NULL bufSize crashes..
210 ret = CryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded,
211 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
213 /* check bogus encoding */
214 ret = CryptDecodeObjectEx(3, X509_INTEGER, (BYTE *)&ints[0].encoded,
215 ints[0].encoded[1] + 2, 0, NULL, NULL, &bufSize);
216 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
217 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
218 /* check with NULL integer buffer */
219 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, 0, NULL, NULL,
221 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
222 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
223 /* check with a valid, but too large, integer */
224 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER, bigInt, bigInt[1] + 2,
225 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
226 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
227 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
228 /* check with a DER-encoded string */
229 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER, testStr, testStr[1] + 2,
230 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
231 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
232 "Expected CRYPT_E_ASN1_BADTAG, got %d\n", GetLastError());
233 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
235 /* When the output buffer is NULL, this always succeeds */
236 SetLastError(0xdeadbeef);
237 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER,
238 ints[i].encoded, ints[i].encoded[1] + 2, 0, NULL, NULL,
240 ok(ret && GetLastError() == NOERROR,
241 "Expected success and NOERROR, got %d\n", GetLastError());
242 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER,
243 ints[i].encoded, ints[i].encoded[1] + 2,
244 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
245 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
246 ok(bufSize == sizeof(int), "Wrong size %d\n", bufSize);
247 ok(buf != NULL, "Expected allocated buffer\n");
250 ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n",
251 ints[i].val, *(int *)buf);
255 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
257 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
258 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 0, NULL, NULL,
260 ok(ret && GetLastError() == NOERROR,
261 "Expected success and NOERROR, got %d\n", GetLastError());
262 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
263 bigInts[i].encoded, bigInts[i].encoded[1] + 2,
264 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
265 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
266 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
267 ok(buf != NULL, "Expected allocated buffer\n");
270 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
272 ok(blob->cbData == strlen((const char*)bigInts[i].decoded),
273 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts[i].decoded),
275 ok(!memcmp(blob->pbData, bigInts[i].decoded, blob->cbData),
276 "Unexpected value\n");
280 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
282 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
283 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 0, NULL, NULL,
285 ok(ret && GetLastError() == NOERROR,
286 "Expected success and NOERROR, got %d\n", GetLastError());
287 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
288 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2,
289 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
290 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
291 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
292 ok(buf != NULL, "Expected allocated buffer\n");
295 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
297 ok(blob->cbData == strlen((const char*)bigUInts[i].val),
298 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts[i].val),
300 ok(!memcmp(blob->pbData, bigUInts[i].val, blob->cbData),
301 "Unexpected value\n");
305 /* Decode the value 1 with long-form length */
306 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, longForm,
307 sizeof(longForm), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
308 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
311 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
314 /* check with extra bytes at the end */
315 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER, extraBytes,
316 sizeof(extraBytes), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
317 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
320 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
323 /* Try to decode some bogus large items */
324 /* The buffer size is smaller than the encoded length, so this should fail
325 * with CRYPT_E_ASN1_EOD if it's being decoded.
326 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit
327 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes.
328 * So this test unfortunately isn't useful.
329 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig,
330 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
331 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
332 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
334 /* This will try to decode the buffer and overflow it, check that it's
339 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
340 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, bigBogus,
341 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
342 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
343 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
347 static const BYTE bin18[] = {0x0a,0x01,0x01};
348 static const BYTE bin19[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
350 /* These are always encoded unsigned, and aren't constrained to be any
353 static const struct encodedInt enums[] = {
358 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
361 static const LPCSTR enumeratedTypes[] = { X509_ENUMERATED,
362 szOID_CRL_REASON_CODE };
364 static void test_encodeEnumerated(DWORD dwEncoding)
368 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
370 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
376 ret = CryptEncodeObjectEx(dwEncoding, enumeratedTypes[i],
377 &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
379 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
383 "Got unexpected type %d for enumerated (expected 0xa)\n",
385 ok(buf[1] == enums[j].encoded[1],
386 "Got length %d, expected %d\n", buf[1], enums[j].encoded[1]);
387 ok(!memcmp(buf + 1, enums[j].encoded + 1,
388 enums[j].encoded[1] + 1),
389 "Encoded value of 0x%08x didn't match expected\n",
397 static void test_decodeEnumerated(DWORD dwEncoding)
401 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
403 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
406 DWORD bufSize = sizeof(int);
409 ret = CryptDecodeObjectEx(dwEncoding, enumeratedTypes[i],
410 enums[j].encoded, enums[j].encoded[1] + 2, 0, NULL,
411 (BYTE *)&val, &bufSize);
412 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
413 ok(bufSize == sizeof(int),
414 "Got unexpected size %d for enumerated\n", bufSize);
415 ok(val == enums[j].val, "Unexpected value %d, expected %d\n",
421 struct encodedFiletime
424 const BYTE *encodedTime;
427 static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType,
428 const struct encodedFiletime *time)
435 ret = SystemTimeToFileTime(&time->sysTime, &ft);
436 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
437 ret = CryptEncodeObjectEx(dwEncoding, structType, &ft,
438 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
439 /* years other than 1950-2050 are not allowed for encodings other than
440 * X509_CHOICE_OF_TIME.
442 if (structType == X509_CHOICE_OF_TIME ||
443 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
445 ok(ret, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
447 ok(buf != NULL, "Expected an allocated buffer\n");
450 ok(buf[0] == time->encodedTime[0],
451 "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0],
453 ok(buf[1] == time->encodedTime[1], "Expected %d bytes, got %d\n",
454 time->encodedTime[1], bufSize);
455 ok(!memcmp(time->encodedTime + 2, buf + 2, time->encodedTime[1]),
456 "Got unexpected value for time encoding\n");
461 ok(!ret && GetLastError() == CRYPT_E_BAD_ENCODE,
462 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
465 static const char *printSystemTime(const SYSTEMTIME *st)
469 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay,
470 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
474 static const char *printFileTime(const FILETIME *ft)
479 FileTimeToSystemTime(ft, &st);
480 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay,
481 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
485 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got)
489 FileTimeToSystemTime(got, &st);
490 ok(expected->wYear == st.wYear &&
491 expected->wMonth == st.wMonth &&
492 expected->wDay == st.wDay &&
493 expected->wHour == st.wHour &&
494 expected->wMinute == st.wMinute &&
495 expected->wSecond == st.wSecond &&
496 abs(expected->wMilliseconds - st.wMilliseconds) <= 1,
497 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
498 printSystemTime(expected), printFileTime(got));
501 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
502 const struct encodedFiletime *time)
505 DWORD size = sizeof(ft);
508 ret = CryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
509 time->encodedTime[1] + 2, 0, NULL, &ft, &size);
510 /* years other than 1950-2050 are not allowed for encodings other than
511 * X509_CHOICE_OF_TIME.
513 if (structType == X509_CHOICE_OF_TIME ||
514 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
516 ok(ret, "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
518 compareTime(&time->sysTime, &ft);
521 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
522 "Expected CRYPT_E_ASN1_BADTAG, got 0x%08x\n", GetLastError());
525 static const BYTE bin20[] = {
526 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
527 static const BYTE bin21[] = {
528 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
529 static const BYTE bin22[] = {
530 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
532 static const struct encodedFiletime times[] = {
533 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
534 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
535 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
538 static void test_encodeFiletime(DWORD dwEncoding)
542 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
544 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]);
545 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, ×[i]);
546 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, ×[i]);
550 static const BYTE bin23[] = {
551 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
552 static const BYTE bin24[] = {
553 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
554 static const BYTE bin25[] = {
555 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
556 static const BYTE bin26[] = {
557 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
558 static const BYTE bin27[] = {
559 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
560 static const BYTE bin28[] = {
561 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
562 static const BYTE bin29[] = {
563 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
564 static const BYTE bin30[] = {
565 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
566 static const BYTE bin31[] = {
567 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
568 static const BYTE bin32[] = {
569 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
570 static const BYTE bin33[] = {
571 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
572 static const BYTE bin34[] = {
573 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
574 static const BYTE bin35[] = {
575 0x17,0x08, '4','5','0','6','0','6','1','6'};
576 static const BYTE bin36[] = {
577 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
578 static const BYTE bin37[] = {
579 0x18,0x04, '2','1','4','5'};
580 static const BYTE bin38[] = {
581 0x18,0x08, '2','1','4','5','0','6','0','6'};
583 static void test_decodeFiletime(DWORD dwEncoding)
585 static const struct encodedFiletime otherTimes[] = {
586 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
587 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
588 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
589 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
590 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
591 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
592 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
593 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
594 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
595 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
596 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
597 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
599 /* An oddball case that succeeds in Windows, but doesn't seem correct
600 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
602 static const unsigned char *bogusTimes[] = {
603 /* oddly, this succeeds on Windows, with year 2765
604 "\x18" "\x0f" "21r50606161000Z",
612 FILETIME ft1 = { 0 }, ft2 = { 0 };
615 /* Check bogus length with non-NULL buffer */
616 ret = SystemTimeToFileTime(×[0].sysTime, &ft1);
617 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
619 ret = CryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
620 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
621 ok(!ret && GetLastError() == ERROR_MORE_DATA,
622 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
624 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
626 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]);
627 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, ×[i]);
628 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, ×[i]);
630 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
632 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
633 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
634 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
636 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
639 ret = CryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
640 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
641 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
642 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
646 static const char commonName[] = "Juan Lang";
647 static const char surName[] = "Lang";
649 static const BYTE emptySequence[] = { 0x30, 0 };
650 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
651 static const BYTE twoRDNs[] = {
652 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
653 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
654 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
655 static const BYTE encodedTwoRDNs[] = {
656 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
657 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
658 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
662 static const BYTE us[] = { 0x55, 0x53 };
663 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
665 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
666 0x6f, 0x6c, 0x69, 0x73 };
667 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
668 0x76, 0x65, 0x72, 0x73 };
669 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
670 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
671 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
673 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
674 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
676 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
677 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
679 static CHAR oid_us[] = "2.5.4.6",
680 oid_minnesota[] = "2.5.4.8",
681 oid_minneapolis[] = "2.5.4.7",
682 oid_codeweavers[] = "2.5.4.10",
683 oid_wine[] = "2.5.4.11",
684 oid_localhostAttr[] = "2.5.4.3",
685 oid_aric[] = "1.2.840.113549.1.9.1";
686 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
688 { RDNA(minneapolis) },
689 { RDNA(codeweavers) },
691 { RDNA(localhostAttr) },
693 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
694 { RDNA(localhostAttr) },
696 { RDNA(minneapolis) },
697 { RDNA(codeweavers) },
704 static const BYTE encodedRDNAttrs[] = {
705 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
706 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
707 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
708 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
709 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
710 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
711 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
712 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
713 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
714 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
717 static void test_encodeName(DWORD dwEncoding)
719 CERT_RDN_ATTR attrs[2];
722 static CHAR oid_common_name[] = szOID_COMMON_NAME,
723 oid_sur_name[] = szOID_SUR_NAME;
728 /* Test with NULL pvStructInfo */
729 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
730 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
731 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
732 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
733 /* Test with empty CERT_NAME_INFO */
736 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
737 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
738 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
741 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
742 "Got unexpected encoding for empty name\n");
745 /* Test with bogus CERT_RDN */
747 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
748 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
749 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
750 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
751 /* Test with empty CERT_RDN */
753 rdn.rgRDNAttr = NULL;
756 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
757 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
758 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
761 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
762 "Got unexpected encoding for empty RDN array\n");
765 /* Test with bogus attr array */
767 rdn.rgRDNAttr = NULL;
768 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
769 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
770 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
771 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
772 /* oddly, a bogus OID is accepted by Windows XP; not testing.
773 attrs[0].pszObjId = "bogus";
774 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
775 attrs[0].Value.cbData = sizeof(commonName);
776 attrs[0].Value.pbData = (BYTE *)commonName;
778 rdn.rgRDNAttr = attrs;
779 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
780 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
781 ok(!ret, "Expected failure, got success\n");
783 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
784 * the encoded attributes to be swapped.
786 attrs[0].pszObjId = oid_common_name;
787 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
788 attrs[0].Value.cbData = sizeof(commonName);
789 attrs[0].Value.pbData = (BYTE *)commonName;
790 attrs[1].pszObjId = oid_sur_name;
791 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
792 attrs[1].Value.cbData = sizeof(surName);
793 attrs[1].Value.pbData = (BYTE *)surName;
795 rdn.rgRDNAttr = attrs;
796 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
797 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
798 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
801 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
802 "Got unexpected encoding for two RDN array\n");
805 /* A name can be "encoded" with previously encoded RDN attrs. */
806 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
807 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
808 attrs[0].Value.cbData = sizeof(twoRDNs);
810 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
811 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
812 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
815 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
816 ok(!memcmp(buf, encodedTwoRDNs, size),
817 "Unexpected value for re-endoded two RDN array\n");
820 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
822 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
823 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
824 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
825 ok(!ret && GetLastError() == E_INVALIDARG,
826 "Expected E_INVALIDARG, got %08x\n", GetLastError());
827 /* Test a more complex name */
828 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
829 rdn.rgRDNAttr = (PCERT_RDN_ATTR)rdnAttrs;
834 ret = CryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
835 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
836 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
839 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
840 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
845 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
846 static WCHAR surNameW[] = { 'L','a','n','g',0 };
848 static const BYTE twoRDNsNoNull[] = {
849 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
850 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
851 0x20,0x4c,0x61,0x6e,0x67 };
852 static const BYTE anyType[] = {
853 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
854 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
855 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
856 0x61,0x4c,0x67,0x6e };
858 static void test_encodeUnicodeName(DWORD dwEncoding)
860 CERT_RDN_ATTR attrs[2];
863 static CHAR oid_common_name[] = szOID_COMMON_NAME,
864 oid_sur_name[] = szOID_SUR_NAME;
869 /* Test with NULL pvStructInfo */
870 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
871 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
872 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
873 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
874 /* Test with empty CERT_NAME_INFO */
877 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
878 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
879 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
882 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
883 "Got unexpected encoding for empty name\n");
886 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
887 * encoding (the NULL).
889 attrs[0].pszObjId = oid_common_name;
890 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
891 attrs[0].Value.cbData = sizeof(commonNameW);
892 attrs[0].Value.pbData = (BYTE *)commonNameW;
894 rdn.rgRDNAttr = attrs;
897 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
898 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
899 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
900 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
901 ok(size == 9, "Unexpected error index %08x\n", size);
902 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
903 * forces the order of the encoded attributes to be swapped.
905 attrs[0].pszObjId = oid_common_name;
906 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
907 attrs[0].Value.cbData = 0;
908 attrs[0].Value.pbData = (BYTE *)commonNameW;
909 attrs[1].pszObjId = oid_sur_name;
910 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
911 attrs[1].Value.cbData = 0;
912 attrs[1].Value.pbData = (BYTE *)surNameW;
914 rdn.rgRDNAttr = attrs;
917 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
918 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
919 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
922 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
923 "Got unexpected encoding for two RDN array\n");
926 /* A name can be "encoded" with previously encoded RDN attrs. */
927 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
928 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
929 attrs[0].Value.cbData = sizeof(twoRDNs);
931 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
932 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
933 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
936 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
937 ok(!memcmp(buf, encodedTwoRDNs, size),
938 "Unexpected value for re-endoded two RDN array\n");
941 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
943 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
944 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
945 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
946 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
949 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
950 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
955 static void compareNameValues(const CERT_NAME_VALUE *expected,
956 const CERT_NAME_VALUE *got)
958 ok(got->dwValueType == expected->dwValueType,
959 "Expected string type %d, got %d\n", expected->dwValueType,
961 ok(got->Value.cbData == expected->Value.cbData,
962 "String type %d: unexpected data size, got %d, expected %d\n",
963 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
964 if (got->Value.cbData && got->Value.pbData)
965 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
966 min(got->Value.cbData, expected->Value.cbData)),
967 "String type %d: unexpected value\n", expected->dwValueType);
970 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
971 const CERT_RDN_ATTR *got)
973 if (expected->pszObjId && strlen(expected->pszObjId))
975 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
979 ok(!strcmp(got->pszObjId, expected->pszObjId),
980 "Got unexpected OID %s, expected %s\n", got->pszObjId,
984 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
985 (const CERT_NAME_VALUE *)&got->dwValueType);
988 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
990 ok(got->cRDNAttr == expected->cRDNAttr,
991 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
996 for (i = 0; i < got->cRDNAttr; i++)
997 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1001 static void compareNames(const CERT_NAME_INFO *expected,
1002 const CERT_NAME_INFO *got)
1004 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
1005 expected->cRDN, got->cRDN);
1010 for (i = 0; i < got->cRDN; i++)
1011 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1015 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1016 static const BYTE twoRDNsExtraBytes[] = {
1017 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1018 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1019 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1021 static void test_decodeName(DWORD dwEncoding)
1027 CERT_NAME_INFO info = { 1, &rdn };
1029 /* test empty name */
1031 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1032 emptySequence[1] + 2,
1033 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1034 (BYTE *)&buf, &bufSize);
1035 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1036 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1037 * decoder works the same way, so only test the count.
1041 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1042 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1043 "Expected 0 RDNs in empty info, got %d\n",
1044 ((CERT_NAME_INFO *)buf)->cRDN);
1047 /* test empty name with indefinite-length encoding */
1048 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1049 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1050 (BYTE *)&buf, &bufSize);
1051 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1054 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1055 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1056 "Expected 0 RDNs in empty info, got %d\n",
1057 ((CERT_NAME_INFO *)buf)->cRDN);
1060 /* test empty RDN */
1062 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1064 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1065 (BYTE *)&buf, &bufSize);
1066 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1069 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1071 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1072 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1073 "Got unexpected value for empty RDN\n");
1076 /* test two RDN attrs */
1078 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1080 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1081 (BYTE *)&buf, &bufSize);
1082 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1085 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1086 oid_common_name[] = szOID_COMMON_NAME;
1088 CERT_RDN_ATTR attrs[] = {
1089 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1090 (BYTE *)surName } },
1091 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1092 (BYTE *)commonName } },
1095 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1096 rdn.rgRDNAttr = attrs;
1097 compareNames(&info, (CERT_NAME_INFO *)buf);
1100 /* test that two RDN attrs with extra bytes succeeds */
1102 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1103 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1104 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1105 /* And, a slightly more complicated name */
1108 ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1109 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1110 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1113 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1114 rdn.rgRDNAttr = (PCERT_RDN_ATTR)decodedRdnAttrs;
1115 compareNames(&info, (CERT_NAME_INFO *)buf);
1120 static void test_decodeUnicodeName(DWORD dwEncoding)
1126 CERT_NAME_INFO info = { 1, &rdn };
1128 /* test empty name */
1130 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1131 emptySequence[1] + 2,
1132 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1133 (BYTE *)&buf, &bufSize);
1134 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1137 ok(bufSize == sizeof(CERT_NAME_INFO),
1138 "Got wrong bufSize %d\n", bufSize);
1139 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1140 "Expected 0 RDNs in empty info, got %d\n",
1141 ((CERT_NAME_INFO *)buf)->cRDN);
1144 /* test empty RDN */
1146 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1148 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1149 (BYTE *)&buf, &bufSize);
1150 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1153 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1155 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1156 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1157 "Got unexpected value for empty RDN\n");
1160 /* test two RDN attrs */
1162 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1163 sizeof(twoRDNsNoNull),
1164 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1165 (BYTE *)&buf, &bufSize);
1166 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1169 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1170 oid_common_name[] = szOID_COMMON_NAME;
1172 CERT_RDN_ATTR attrs[] = {
1173 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1174 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1175 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1176 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1179 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1180 rdn.rgRDNAttr = attrs;
1181 compareNames(&info, (CERT_NAME_INFO *)buf);
1186 struct EncodedNameValue
1188 CERT_NAME_VALUE value;
1189 const BYTE *encoded;
1193 static const char bogusIA5[] = "\x80";
1194 static const char bogusPrintable[] = "~";
1195 static const char bogusNumeric[] = "A";
1196 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1197 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1198 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1199 static BYTE octetCommonNameValue[] = {
1200 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1201 static BYTE numericCommonNameValue[] = {
1202 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1203 static BYTE printableCommonNameValue[] = {
1204 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1205 static BYTE t61CommonNameValue[] = {
1206 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1207 static BYTE videotexCommonNameValue[] = {
1208 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1209 static BYTE ia5CommonNameValue[] = {
1210 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1211 static BYTE graphicCommonNameValue[] = {
1212 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1213 static BYTE visibleCommonNameValue[] = {
1214 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1215 static BYTE generalCommonNameValue[] = {
1216 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1217 static BYTE bmpCommonNameValue[] = {
1218 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1219 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1220 static BYTE utf8CommonNameValue[] = {
1221 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1223 static struct EncodedNameValue nameValues[] = {
1224 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1225 octetCommonNameValue, sizeof(octetCommonNameValue) },
1226 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1227 numericCommonNameValue, sizeof(numericCommonNameValue) },
1228 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1229 printableCommonNameValue, sizeof(printableCommonNameValue) },
1230 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1231 t61CommonNameValue, sizeof(t61CommonNameValue) },
1232 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1233 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1234 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1235 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1236 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1237 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1238 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1239 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1240 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1241 generalCommonNameValue, sizeof(generalCommonNameValue) },
1242 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1243 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1244 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1245 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1246 /* The following tests succeed under Windows, but really should fail,
1247 * they contain characters that are illegal for the encoding. I'm
1248 * including them to justify my lazy encoding.
1250 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1252 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1253 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1254 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1255 bin44, sizeof(bin44) },
1258 static void test_encodeNameValue(DWORD dwEncoding)
1263 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1265 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1266 value.Value.pbData = printableCommonNameValue;
1267 value.Value.cbData = sizeof(printableCommonNameValue);
1268 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1269 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1270 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1273 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1275 ok(!memcmp(buf, printableCommonNameValue, size),
1276 "Unexpected encoding\n");
1279 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1281 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1282 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1284 ok(ret, "Type %d: CryptEncodeObjectEx failed: %08x\n",
1285 nameValues[i].value.dwValueType, GetLastError());
1288 ok(size == nameValues[i].encodedSize,
1289 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1290 ok(!memcmp(buf, nameValues[i].encoded, size),
1291 "Got unexpected encoding\n");
1297 static void test_decodeNameValue(DWORD dwEncoding)
1304 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1306 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1307 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1308 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1309 (BYTE *)&buf, &bufSize);
1310 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1311 nameValues[i].value.dwValueType, GetLastError());
1314 compareNameValues(&nameValues[i].value,
1315 (const CERT_NAME_VALUE *)buf);
1321 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1322 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1323 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1324 'h','q','.','o','r','g',0 };
1325 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1326 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1328 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1330 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1331 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1332 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1333 static const BYTE localhost[] = { 127, 0, 0, 1 };
1334 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1336 static const unsigned char encodedCommonName[] = {
1337 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1338 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1339 static const BYTE encodedDirectoryName[] = {
1340 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1341 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1343 static void test_encodeAltName(DWORD dwEncoding)
1345 CERT_ALT_NAME_INFO info = { 0 };
1346 CERT_ALT_NAME_ENTRY entry = { 0 };
1350 char oid[] = "1.2.3";
1352 /* Test with empty info */
1353 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1354 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1357 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1358 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1361 /* Test with an empty entry */
1363 info.rgAltEntry = &entry;
1364 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1365 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1366 ok(!ret && GetLastError() == E_INVALIDARG,
1367 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1368 /* Test with an empty pointer */
1369 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1370 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1371 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1374 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1375 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1378 /* Test with a real URL */
1379 U(entry).pwszURL = (LPWSTR)url;
1380 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1381 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1384 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1385 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1388 /* Now with the URL containing an invalid IA5 char */
1389 U(entry).pwszURL = (LPWSTR)nihongoURL;
1390 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1391 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1392 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1393 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1394 /* The first invalid character is at index 7 */
1395 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1396 "Expected invalid char at index 7, got %d\n",
1397 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1398 /* Now with the URL missing a scheme */
1399 U(entry).pwszURL = (LPWSTR)dnsName;
1400 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1401 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1402 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1405 /* This succeeds, but it shouldn't, so don't worry about conforming */
1408 /* Now with a DNS name */
1409 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1410 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1411 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1412 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1415 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1416 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1419 /* Test with an IP address */
1420 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1421 U(entry).IPAddress.cbData = sizeof(localhost);
1422 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1423 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1424 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1427 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1428 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1432 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1433 U(entry).pszRegisteredID = oid;
1434 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1435 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1438 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1439 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1442 /* Test with directory name */
1443 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1444 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1445 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1446 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1447 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1450 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1451 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1456 static void test_decodeAltName(DWORD dwEncoding)
1458 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1460 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1465 CERT_ALT_NAME_INFO *info;
1467 /* Test some bogus ones first */
1468 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1469 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1470 NULL, (BYTE *)&buf, &bufSize);
1471 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1472 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
1473 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1474 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1476 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
1477 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
1478 /* Now expected cases */
1479 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1480 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1482 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1485 info = (CERT_ALT_NAME_INFO *)buf;
1487 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1491 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1492 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1494 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1497 info = (CERT_ALT_NAME_INFO *)buf;
1499 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1501 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1502 "Expected CERT_ALT_NAME_URL, got %d\n",
1503 info->rgAltEntry[0].dwAltNameChoice);
1504 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1505 "Expected empty URL\n");
1508 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1509 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1510 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1511 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1512 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1514 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1517 info = (CERT_ALT_NAME_INFO *)buf;
1519 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1521 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1522 "Expected CERT_ALT_NAME_URL, got %d\n",
1523 info->rgAltEntry[0].dwAltNameChoice);
1524 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1527 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1528 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1530 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1533 info = (CERT_ALT_NAME_INFO *)buf;
1535 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1537 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1538 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1539 info->rgAltEntry[0].dwAltNameChoice);
1540 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1541 "Unexpected DNS name\n");
1544 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1545 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1547 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1550 info = (CERT_ALT_NAME_INFO *)buf;
1552 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1554 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1555 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1556 info->rgAltEntry[0].dwAltNameChoice);
1557 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1558 "Unexpected IP address length %d\n",
1559 U(info->rgAltEntry[0]).IPAddress.cbData);
1560 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1561 sizeof(localhost)), "Unexpected IP address value\n");
1564 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1565 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1567 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1570 info = (CERT_ALT_NAME_INFO *)buf;
1572 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1574 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1575 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1576 info->rgAltEntry[0].dwAltNameChoice);
1577 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1578 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1581 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1582 encodedDirectoryName, sizeof(encodedDirectoryName),
1583 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1584 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1587 info = (CERT_ALT_NAME_INFO *)buf;
1589 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1591 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1592 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1593 info->rgAltEntry[0].dwAltNameChoice);
1594 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1595 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1596 U(info->rgAltEntry[0]).DirectoryName.cbData);
1597 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1598 encodedCommonName, sizeof(encodedCommonName)),
1599 "Unexpected directory name value\n");
1604 struct UnicodeExpectedError
1612 static const WCHAR oneW[] = { '1',0 };
1613 static const WCHAR aW[] = { 'a',0 };
1614 static const WCHAR quoteW[] = { '"', 0 };
1616 static struct UnicodeExpectedError unicodeErrors[] = {
1617 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1618 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1619 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1620 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1621 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1622 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1625 struct UnicodeExpectedResult
1629 CRYPT_DATA_BLOB encoded;
1632 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1633 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1634 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1635 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1636 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1637 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1638 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1639 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1640 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1641 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1642 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1643 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1645 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1647 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1648 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1649 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1650 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1652 static struct UnicodeExpectedResult unicodeResults[] = {
1653 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1654 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1655 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1656 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1657 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1658 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1659 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1660 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1661 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1662 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1663 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1664 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1665 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1668 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1669 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1670 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1673 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1678 CERT_NAME_VALUE value;
1680 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1681 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1682 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1683 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1684 /* Have to have a string of some sort */
1685 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1686 value.Value.pbData = NULL;
1687 value.Value.cbData = 0;
1688 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1689 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1690 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1691 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1692 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1693 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1694 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1695 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1696 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1697 value.dwValueType = CERT_RDN_ANY_TYPE;
1698 value.Value.pbData = (LPBYTE)oneW;
1699 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1700 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1701 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1702 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1703 value.Value.cbData = sizeof(oneW);
1704 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1705 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1706 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1707 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1708 /* An encoded string with specified length isn't good enough either */
1709 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1710 value.Value.pbData = oneUniversal;
1711 value.Value.cbData = sizeof(oneUniversal);
1712 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1713 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1714 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1715 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1716 /* More failure checking */
1717 value.Value.cbData = 0;
1718 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1720 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1721 value.dwValueType = unicodeErrors[i].valueType;
1722 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1723 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1724 ok(!ret && GetLastError() == unicodeErrors[i].error,
1725 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1726 unicodeErrors[i].error, GetLastError());
1727 ok(size == unicodeErrors[i].errorIndex,
1728 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1731 /* cbData can be zero if the string is NULL-terminated */
1732 value.Value.cbData = 0;
1733 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1735 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1736 value.dwValueType = unicodeResults[i].valueType;
1737 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1738 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1739 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1742 ok(size == unicodeResults[i].encoded.cbData,
1743 "Value type %d: expected size %d, got %d\n",
1744 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1745 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1746 "Value type %d: unexpected value\n", value.dwValueType);
1750 /* These "encode," but they do so by truncating each unicode character
1751 * rather than properly encoding it. Kept separate from the proper results,
1752 * because the encoded forms won't decode to their original strings.
1754 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1756 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1757 value.dwValueType = unicodeWeirdness[i].valueType;
1758 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1759 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1760 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1763 ok(size == unicodeWeirdness[i].encoded.cbData,
1764 "Value type %d: expected size %d, got %d\n",
1765 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1766 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1767 "Value type %d: unexpected value\n", value.dwValueType);
1773 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1775 if (n <= 0) return 0;
1776 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1777 return *str1 - *str2;
1780 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1784 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1790 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1791 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1792 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1793 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1796 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1798 ok(value->dwValueType == unicodeResults[i].valueType,
1799 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1800 value->dwValueType);
1801 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1802 value->Value.cbData / sizeof(WCHAR)),
1803 "Unexpected decoded value for index %d (value type %d)\n", i,
1804 unicodeResults[i].valueType);
1810 struct encodedOctets
1813 const BYTE *encoded;
1816 static const unsigned char bin46[] = { 'h','i',0 };
1817 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1818 static const unsigned char bin48[] = {
1819 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1820 static const unsigned char bin49[] = {
1821 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1822 static const unsigned char bin50[] = { 0 };
1823 static const unsigned char bin51[] = { 0x04,0x00,0 };
1825 static const struct encodedOctets octets[] = {
1831 static void test_encodeOctets(DWORD dwEncoding)
1833 CRYPT_DATA_BLOB blob;
1836 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1842 blob.cbData = strlen((const char*)octets[i].val);
1843 blob.pbData = (BYTE*)octets[i].val;
1844 ret = CryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1845 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1846 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1850 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1851 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1852 buf[1], octets[i].encoded[1]);
1853 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1854 octets[i].encoded[1] + 1), "Got unexpected value\n");
1860 static void test_decodeOctets(DWORD dwEncoding)
1864 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1870 ret = CryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1871 (BYTE *)octets[i].encoded, octets[i].encoded[1] + 2,
1872 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1873 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1874 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1875 "Expected size >= %d, got %d\n",
1876 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1877 ok(buf != NULL, "Expected allocated buffer\n");
1880 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
1883 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
1884 "Unexpected value\n");
1890 static const BYTE bytesToEncode[] = { 0xff, 0xff };
1895 const BYTE *encoded;
1897 const BYTE *decoded;
1900 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
1901 static const unsigned char bin53[] = { 0xff,0xff };
1902 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
1903 static const unsigned char bin55[] = { 0xff,0xfe };
1904 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
1905 static const unsigned char bin57[] = { 0xfe };
1906 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
1908 static const struct encodedBits bits[] = {
1909 /* normal test cases */
1910 { 0, bin52, 2, bin53 },
1911 { 1, bin54, 2, bin55 },
1912 /* strange test case, showing cUnusedBits >= 8 is allowed */
1913 { 9, bin56, 1, bin57 },
1914 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1915 { 17, bin58, 0, NULL },
1918 static void test_encodeBits(DWORD dwEncoding)
1922 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1924 CRYPT_BIT_BLOB blob;
1929 blob.cbData = sizeof(bytesToEncode);
1930 blob.pbData = (BYTE *)bytesToEncode;
1931 blob.cUnusedBits = bits[i].cUnusedBits;
1932 ret = CryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
1933 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1934 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1937 ok(bufSize == bits[i].encoded[1] + 2,
1938 "Got unexpected size %d, expected %d\n", bufSize,
1939 bits[i].encoded[1] + 2);
1940 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
1941 "Unexpected value\n");
1947 static void test_decodeBits(DWORD dwEncoding)
1949 static const BYTE ber[] = "\x03\x02\x01\xff";
1950 static const BYTE berDecoded = 0xfe;
1957 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1959 ret = CryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
1960 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1962 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1965 CRYPT_BIT_BLOB *blob;
1967 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
1968 "Got unexpected size %d\n", bufSize);
1969 blob = (CRYPT_BIT_BLOB *)buf;
1970 ok(blob->cbData == bits[i].cbDecoded,
1971 "Got unexpected length %d, expected %d\n", blob->cbData,
1973 if (blob->cbData && bits[i].cbDecoded)
1974 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
1975 "Unexpected value\n");
1979 /* special case: check that something that's valid in BER but not in DER
1980 * decodes successfully
1982 ret = CryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
1983 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1984 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1987 CRYPT_BIT_BLOB *blob;
1989 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
1990 "Got unexpected size %d\n", bufSize);
1991 blob = (CRYPT_BIT_BLOB *)buf;
1992 ok(blob->cbData == sizeof(berDecoded),
1993 "Got unexpected length %d\n", blob->cbData);
1995 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2002 CERT_BASIC_CONSTRAINTS2_INFO info;
2003 const BYTE *encoded;
2006 static const unsigned char bin59[] = { 0x30,0x00 };
2007 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2008 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2009 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2010 static const struct Constraints2 constraints2[] = {
2011 /* empty constraints */
2012 { { FALSE, FALSE, 0}, bin59 },
2014 { { TRUE, FALSE, 0}, bin60 },
2015 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2016 * but that's not the case
2018 { { FALSE, TRUE, 0}, bin61 },
2019 /* can be a CA and has path length constraints set */
2020 { { TRUE, TRUE, 1}, bin62 },
2023 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2024 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2025 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2026 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2027 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2028 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2029 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2030 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2031 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2032 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2034 static void test_encodeBasicConstraints(DWORD dwEncoding)
2036 DWORD i, bufSize = 0;
2037 CERT_BASIC_CONSTRAINTS_INFO info;
2038 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2039 (LPBYTE)encodedDomainName };
2043 /* First test with the simpler info2 */
2044 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2046 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2047 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2049 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2052 ok(bufSize == constraints2[i].encoded[1] + 2,
2053 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2055 ok(!memcmp(buf, constraints2[i].encoded,
2056 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2060 /* Now test with more complex basic constraints */
2061 info.SubjectType.cbData = 0;
2062 info.fPathLenConstraint = FALSE;
2063 info.cSubtreesConstraint = 0;
2064 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2065 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2066 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2069 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2070 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2071 "Unexpected value\n");
2074 /* None of the certs I examined had any subtree constraint, but I test one
2075 * anyway just in case.
2077 info.cSubtreesConstraint = 1;
2078 info.rgSubtreesConstraint = &nameBlob;
2079 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2080 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2081 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2084 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2085 ok(!memcmp(buf, constraintWithDomainName,
2086 sizeof(constraintWithDomainName)), "Unexpected value\n");
2089 /* FIXME: test encoding with subject type. */
2092 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2094 static void test_decodeBasicConstraints(DWORD dwEncoding)
2096 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2098 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2104 /* First test with simpler info2 */
2105 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2107 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2108 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2109 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2110 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2114 CERT_BASIC_CONSTRAINTS2_INFO *info =
2115 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2117 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2118 "Unexpected value for item %d\n", i);
2122 /* Check with the order of encoded elements inverted */
2124 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2125 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2127 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2128 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2129 ok(!buf, "Expected buf to be set to NULL\n");
2130 /* Check with a non-DER bool */
2131 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2132 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2133 (BYTE *)&buf, &bufSize);
2134 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2137 CERT_BASIC_CONSTRAINTS2_INFO *info =
2138 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2140 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2143 /* Check with a non-basic constraints value */
2144 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2145 (LPBYTE)encodedCommonName, encodedCommonName[1] + 2,
2146 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2147 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2148 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2149 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2150 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2151 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2152 (BYTE *)&buf, &bufSize);
2153 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2156 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2158 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2159 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2160 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2163 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2164 constraintWithDomainName, sizeof(constraintWithDomainName),
2165 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2166 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2169 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2171 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2172 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2173 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2174 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2176 ok(info->rgSubtreesConstraint[0].cbData ==
2177 sizeof(encodedDomainName), "Wrong size %d\n",
2178 info->rgSubtreesConstraint[0].cbData);
2179 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2180 sizeof(encodedDomainName)), "Unexpected value\n");
2186 /* These are terrible public keys of course, I'm just testing encoding */
2187 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2188 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2189 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2190 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2191 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2192 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2193 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2194 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2196 struct EncodedRSAPubKey
2198 const BYTE *modulus;
2200 const BYTE *encoded;
2201 size_t decodedModulusLen;
2204 struct EncodedRSAPubKey rsaPubKeys[] = {
2205 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2206 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2207 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2208 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2211 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2213 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2214 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2215 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2218 DWORD bufSize = 0, i;
2220 /* Try with a bogus blob type */
2222 hdr->bVersion = CUR_BLOB_VERSION;
2224 hdr->aiKeyAlg = CALG_RSA_KEYX;
2225 rsaPubKey->magic = 0x31415352;
2226 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2227 rsaPubKey->pubexp = 65537;
2228 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2231 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2232 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2234 ok(!ret && GetLastError() == E_INVALIDARG,
2235 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2236 /* Now with a bogus reserved field */
2237 hdr->bType = PUBLICKEYBLOB;
2239 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2240 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2244 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2245 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2246 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2249 /* Now with a bogus blob version */
2252 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2253 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2257 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2258 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2259 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2262 /* And with a bogus alg ID */
2263 hdr->bVersion = CUR_BLOB_VERSION;
2264 hdr->aiKeyAlg = CALG_DES;
2265 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2266 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2270 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2271 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2272 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2275 /* Check a couple of RSA-related OIDs */
2276 hdr->aiKeyAlg = CALG_RSA_KEYX;
2277 ret = CryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2278 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2279 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2280 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2281 ret = CryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2282 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2283 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2284 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2285 /* Finally, all valid */
2286 hdr->aiKeyAlg = CALG_RSA_KEYX;
2287 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2289 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2290 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2291 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2292 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2293 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2296 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2297 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2299 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2300 "Unexpected value\n");
2306 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2313 /* Try with a bad length */
2314 ret = CryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2315 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2316 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2317 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2318 "Expected CRYPT_E_ASN1_EOD, got %08x\n", CRYPT_E_ASN1_EOD);
2319 /* Try with a couple of RSA-related OIDs */
2320 ret = CryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2321 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2322 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2323 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2324 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2325 ret = CryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2326 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2327 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2328 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2329 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2330 /* Now try success cases */
2331 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2334 ret = CryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2335 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2336 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2337 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2340 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2341 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2343 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2344 rsaPubKeys[i].decodedModulusLen,
2345 "Wrong size %d\n", bufSize);
2346 ok(hdr->bType == PUBLICKEYBLOB,
2347 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2349 ok(hdr->bVersion == CUR_BLOB_VERSION,
2350 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2351 CUR_BLOB_VERSION, hdr->bVersion);
2352 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2354 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2355 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2356 ok(rsaPubKey->magic == 0x31415352,
2357 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2358 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2359 "Wrong bit len %d\n", rsaPubKey->bitlen);
2360 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2362 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2363 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2364 "Unexpected modulus\n");
2370 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2371 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2372 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2374 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2375 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2376 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2377 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2379 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2381 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2382 CRYPT_SEQUENCE_OF_ANY seq;
2388 /* Encode a homogenous sequence */
2389 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2391 blobs[i].cbData = ints[i].encoded[1] + 2;
2392 blobs[i].pbData = (BYTE *)ints[i].encoded;
2394 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2395 seq.rgValue = blobs;
2397 ret = CryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2398 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2399 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2402 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2403 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2406 /* Change the type of the first element in the sequence, and give it
2409 blobs[0].cbData = times[0].encodedTime[1] + 2;
2410 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2411 ret = CryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2412 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2413 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2416 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2417 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2418 "Unexpected value\n");
2423 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2429 ret = CryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2430 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2431 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2434 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2437 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2438 "Wrong elements %d\n", seq->cValue);
2439 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2441 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2442 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2443 seq->rgValue[i].cbData);
2444 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2445 ints[i].encoded[1] + 2), "Unexpected value\n");
2449 ret = CryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2450 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2452 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2455 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2457 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2458 "Wrong elements %d\n", seq->cValue);
2459 /* Just check the first element since it's all that changed */
2460 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2461 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2462 seq->rgValue[0].cbData);
2463 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2464 times[0].encodedTime[1] + 2), "Unexpected value\n");
2469 struct encodedExtensions
2471 CERT_EXTENSIONS exts;
2472 const BYTE *encoded;
2475 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2476 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2477 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2478 static CERT_EXTENSION criticalExt =
2479 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2480 static CERT_EXTENSION nonCriticalExt =
2481 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2483 static const BYTE ext0[] = { 0x30,0x00 };
2484 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2485 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2486 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2487 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2489 static const struct encodedExtensions exts[] = {
2490 { { 0, NULL }, ext0 },
2491 { { 1, &criticalExt }, ext1 },
2492 { { 1, &nonCriticalExt }, ext2 },
2495 static void test_encodeExtensions(DWORD dwEncoding)
2499 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2505 ret = CryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2506 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2507 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2510 ok(bufSize == exts[i].encoded[1] + 2,
2511 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2512 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2513 "Unexpected value\n");
2519 static void test_decodeExtensions(DWORD dwEncoding)
2523 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2529 ret = CryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2530 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2531 NULL, (BYTE *)&buf, &bufSize);
2532 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2535 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2538 ok(ext->cExtension == exts[i].exts.cExtension,
2539 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2541 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2543 ok(!strcmp(ext->rgExtension[j].pszObjId,
2544 exts[i].exts.rgExtension[j].pszObjId),
2545 "Expected OID %s, got %s\n",
2546 exts[i].exts.rgExtension[j].pszObjId,
2547 ext->rgExtension[j].pszObjId);
2548 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2549 exts[i].exts.rgExtension[j].Value.pbData,
2550 exts[i].exts.rgExtension[j].Value.cbData),
2551 "Unexpected value\n");
2558 /* MS encodes public key info with a NULL if the algorithm identifier's
2559 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2560 * it encodes them by omitting the algorithm parameters. This latter approach
2561 * seems more correct, so accept either form.
2563 struct encodedPublicKey
2565 CERT_PUBLIC_KEY_INFO info;
2566 const BYTE *encoded;
2567 const BYTE *encodedNoNull;
2568 CERT_PUBLIC_KEY_INFO decoded;
2571 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2573 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2575 static const unsigned char bin64[] = {
2576 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2577 static const unsigned char bin65[] = {
2578 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2579 static const unsigned char bin66[] = {
2580 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2581 static const unsigned char bin67[] = {
2582 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2583 static const unsigned char bin68[] = {
2584 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2585 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2586 static const unsigned char bin69[] = {
2587 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2588 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2589 static const unsigned char bin70[] = {
2590 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2591 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2593 static const unsigned char bin71[] = {
2594 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2595 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2597 static unsigned char bin72[] = { 0x05,0x00};
2599 static CHAR oid_bogus[] = "1.2.3",
2600 oid_rsa[] = szOID_RSA;
2602 static const struct encodedPublicKey pubKeys[] = {
2603 /* with a bogus OID */
2604 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2606 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2607 /* some normal keys */
2608 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2610 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2611 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2613 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2614 /* with add'l parameters--note they must be DER-encoded */
2615 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2616 (BYTE *)aKey, 0 } },
2618 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2619 (BYTE *)aKey, 0 } } },
2622 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2626 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2632 ret = CryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2633 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2635 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2638 ok(bufSize == pubKeys[i].encoded[1] + 2 ||
2639 bufSize == pubKeys[i].encodedNoNull[1] + 2,
2640 "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
2641 pubKeys[i].encodedNoNull[1] + 2, bufSize);
2642 if (bufSize == pubKeys[i].encoded[1] + 2)
2643 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2644 "Unexpected value\n");
2645 else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
2646 ok(!memcmp(buf, pubKeys[i].encodedNoNull,
2647 pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
2653 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2654 const CERT_PUBLIC_KEY_INFO *got)
2656 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2657 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2658 got->Algorithm.pszObjId);
2659 ok(expected->Algorithm.Parameters.cbData ==
2660 got->Algorithm.Parameters.cbData,
2661 "Expected parameters of %d bytes, got %d\n",
2662 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2663 if (expected->Algorithm.Parameters.cbData)
2664 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2665 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2666 "Unexpected algorithm parameters\n");
2667 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2668 "Expected public key of %d bytes, got %d\n",
2669 expected->PublicKey.cbData, got->PublicKey.cbData);
2670 if (expected->PublicKey.cbData)
2671 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2672 got->PublicKey.cbData), "Unexpected public key value\n");
2675 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2677 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2678 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2679 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2680 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2686 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2688 /* The NULL form decodes to the decoded member */
2689 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2690 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2691 NULL, (BYTE *)&buf, &bufSize);
2692 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2695 comparePublicKeyInfo(&pubKeys[i].decoded,
2696 (CERT_PUBLIC_KEY_INFO *)buf);
2699 /* The non-NULL form decodes to the original */
2700 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2701 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2702 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2703 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2706 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2710 /* Test with bogus (not valid DER) parameters */
2711 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2712 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2713 NULL, (BYTE *)&buf, &bufSize);
2714 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2715 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2718 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2719 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2720 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2721 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2722 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2723 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2724 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2725 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2726 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2727 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2728 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2729 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2730 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2731 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2732 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2733 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2734 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2735 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2736 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2737 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2738 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2739 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2740 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2741 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2742 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2743 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2744 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2745 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2746 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2747 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2748 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2749 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2750 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2751 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2752 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2753 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2754 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2755 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2756 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2757 static const BYTE v1CertWithPubKey[] = {
2758 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2759 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2760 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2761 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2762 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2763 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2764 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2765 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2766 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2767 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2769 static const BYTE v1CertWithPubKeyNoNull[] = {
2770 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2771 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2772 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2773 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2774 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2775 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2776 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2777 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2778 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2779 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2780 static const BYTE v1CertWithSubjectKeyId[] = {
2781 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2782 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2783 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2784 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2785 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2786 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2787 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2788 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2789 0x4c,0x61,0x6e,0x67,0x00 };
2791 static const BYTE serialNum[] = { 0x01 };
2793 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2798 CERT_INFO info = { 0 };
2799 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2800 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2803 /* Test with NULL pvStructInfo */
2804 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2805 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2806 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2807 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2808 /* Test with a V1 cert */
2809 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2810 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2811 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2814 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2815 v1Cert[1] + 2, size);
2816 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2820 info.dwVersion = CERT_V2;
2821 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2822 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2823 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2826 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2827 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2831 info.dwVersion = CERT_V3;
2832 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2833 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2834 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2837 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2838 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2841 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2842 * API doesn't prevent it)
2844 info.dwVersion = CERT_V1;
2845 info.cExtension = 1;
2846 info.rgExtension = &criticalExt;
2847 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2848 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2849 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2852 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2853 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2856 /* test v1 cert with a serial number */
2857 info.SerialNumber.cbData = sizeof(serialNum);
2858 info.SerialNumber.pbData = (BYTE *)serialNum;
2859 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2860 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2863 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2864 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2867 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2868 info.Issuer.cbData = sizeof(encodedCommonName);
2869 info.Issuer.pbData = (BYTE *)encodedCommonName;
2870 info.Subject.cbData = sizeof(encodedCommonName);
2871 info.Subject.pbData = (BYTE *)encodedCommonName;
2872 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2873 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2876 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
2877 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
2880 /* Add a public key */
2881 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2882 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2883 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
2884 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2885 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2888 ok(size == sizeof(v1CertWithPubKey) ||
2889 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
2890 if (size == sizeof(v1CertWithPubKey))
2891 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
2892 else if (size == sizeof(v1CertWithPubKeyNoNull))
2893 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
2894 "Got unexpected value\n");
2897 /* Remove the public key, and add a subject key identifier extension */
2898 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2899 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
2900 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
2901 ext.pszObjId = oid_subject_key_identifier;
2902 ext.fCritical = FALSE;
2903 ext.Value.cbData = sizeof(octetCommonNameValue);
2904 ext.Value.pbData = (BYTE *)octetCommonNameValue;
2905 info.cExtension = 1;
2906 info.rgExtension = &ext;
2907 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2908 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2911 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
2912 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
2917 static void test_decodeCertToBeSigned(DWORD dwEncoding)
2919 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
2920 v1CertWithConstraints, v1CertWithSerial };
2925 /* Test with NULL pbEncoded */
2926 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
2927 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2928 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2929 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2930 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
2931 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2932 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2933 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2934 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
2935 * minimum a cert must have a non-zero serial number, an issuer, and a
2938 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
2940 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
2941 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2942 (BYTE *)&buf, &size);
2943 ok(!ret, "Expected failure\n");
2945 /* Now check with serial number, subject and issuer specified */
2946 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
2947 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2948 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2951 CERT_INFO *info = (CERT_INFO *)buf;
2953 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
2954 ok(info->SerialNumber.cbData == 1,
2955 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
2956 ok(*info->SerialNumber.pbData == *serialNum,
2957 "Expected serial number %d, got %d\n", *serialNum,
2958 *info->SerialNumber.pbData);
2959 ok(info->Issuer.cbData == sizeof(encodedCommonName),
2960 "Wrong size %d\n", info->Issuer.cbData);
2961 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
2962 "Unexpected issuer\n");
2963 ok(info->Subject.cbData == sizeof(encodedCommonName),
2964 "Wrong size %d\n", info->Subject.cbData);
2965 ok(!memcmp(info->Subject.pbData, encodedCommonName,
2966 info->Subject.cbData), "Unexpected subject\n");
2969 /* Check again with pub key specified */
2970 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
2971 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
2972 (BYTE *)&buf, &size);
2973 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2976 CERT_INFO *info = (CERT_INFO *)buf;
2978 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
2979 ok(info->SerialNumber.cbData == 1,
2980 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
2981 ok(*info->SerialNumber.pbData == *serialNum,
2982 "Expected serial number %d, got %d\n", *serialNum,
2983 *info->SerialNumber.pbData);
2984 ok(info->Issuer.cbData == sizeof(encodedCommonName),
2985 "Wrong size %d\n", info->Issuer.cbData);
2986 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
2987 "Unexpected issuer\n");
2988 ok(info->Subject.cbData == sizeof(encodedCommonName),
2989 "Wrong size %d\n", info->Subject.cbData);
2990 ok(!memcmp(info->Subject.pbData, encodedCommonName,
2991 info->Subject.cbData), "Unexpected subject\n");
2992 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
2993 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
2994 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
2995 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
2996 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
2997 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
2998 sizeof(aKey)), "Unexpected public key\n");
3003 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3006 static const BYTE signedBigCert[] = {
3007 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3008 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3009 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3010 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3011 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3012 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3013 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3014 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3015 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3016 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3017 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3018 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3020 static void test_encodeCert(DWORD dwEncoding)
3022 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3023 * also that bigCert is a NULL-terminated string, so don't count its
3024 * last byte (otherwise the signed cert won't decode.)
3026 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3027 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3032 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3033 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
3034 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3037 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3038 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3043 static void test_decodeCert(DWORD dwEncoding)
3049 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3050 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3051 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3054 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3056 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3057 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3058 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3059 "Unexpected cert\n");
3060 ok(info->Signature.cbData == sizeof(hash),
3061 "Wrong signature size %d\n", info->Signature.cbData);
3062 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3063 "Unexpected signature\n");
3066 /* A signed cert decodes as a CERT_INFO too */
3067 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3068 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3069 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3072 CERT_INFO *info = (CERT_INFO *)buf;
3074 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3075 ok(info->SerialNumber.cbData == 1,
3076 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3077 ok(*info->SerialNumber.pbData == *serialNum,
3078 "Expected serial number %d, got %d\n", *serialNum,
3079 *info->SerialNumber.pbData);
3080 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3081 "Wrong size %d\n", info->Issuer.cbData);
3082 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3083 "Unexpected issuer\n");
3084 ok(info->Subject.cbData == sizeof(encodedCommonName),
3085 "Wrong size %d\n", info->Subject.cbData);
3086 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3087 info->Subject.cbData), "Unexpected subject\n");
3092 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3093 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3094 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3095 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3096 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3098 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3099 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3100 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3101 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3102 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3103 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3104 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3105 0x2e, 0x6f, 0x72, 0x67 };
3106 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3107 CRL_REASON_AFFILIATION_CHANGED;
3109 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3111 CRL_DIST_POINTS_INFO info = { 0 };
3112 CRL_DIST_POINT point = { { 0 } };
3113 CERT_ALT_NAME_ENTRY entry = { 0 };
3118 /* Test with an empty info */
3119 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3120 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3121 ok(!ret && GetLastError() == E_INVALIDARG,
3122 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3123 /* Test with one empty dist point */
3124 info.cDistPoint = 1;
3125 info.rgDistPoint = &point;
3126 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3127 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3130 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3131 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3134 /* A dist point with an invalid name */
3135 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3136 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3137 U(entry).pwszURL = (LPWSTR)nihongoURL;
3138 U(point.DistPointName).FullName.cAltEntry = 1;
3139 U(point.DistPointName).FullName.rgAltEntry = &entry;
3140 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3141 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3142 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3143 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3144 /* The first invalid character is at index 7 */
3145 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3146 "Expected invalid char at index 7, got %d\n",
3147 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3148 /* A dist point with (just) a valid name */
3149 U(entry).pwszURL = (LPWSTR)url;
3150 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3151 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3154 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3155 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3158 /* A dist point with (just) reason flags */
3159 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3160 point.ReasonFlags.cbData = sizeof(crlReason);
3161 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3162 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3163 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3166 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3167 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3170 /* A dist point with just an issuer */
3171 point.ReasonFlags.cbData = 0;
3172 point.CRLIssuer.cAltEntry = 1;
3173 point.CRLIssuer.rgAltEntry = &entry;
3174 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3175 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3178 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3179 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3182 /* A dist point with both a name and an issuer */
3183 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3184 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3185 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3188 ok(size == sizeof(distPointWithUrlAndIssuer),
3189 "Wrong size %d\n", size);
3190 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3195 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3200 PCRL_DIST_POINTS_INFO info;
3201 PCRL_DIST_POINT point;
3202 PCERT_ALT_NAME_ENTRY entry;
3204 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3205 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3206 (BYTE *)&buf, &size);
3209 info = (PCRL_DIST_POINTS_INFO)buf;
3210 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3211 "Wrong size %d\n", size);
3212 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3214 point = info->rgDistPoint;
3215 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3216 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3217 point->DistPointName.dwDistPointNameChoice);
3218 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3219 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3222 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3223 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3224 (BYTE *)&buf, &size);
3227 info = (PCRL_DIST_POINTS_INFO)buf;
3228 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3229 "Wrong size %d\n", size);
3230 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3232 point = info->rgDistPoint;
3233 ok(point->DistPointName.dwDistPointNameChoice ==
3234 CRL_DIST_POINT_FULL_NAME,
3235 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3236 point->DistPointName.dwDistPointNameChoice);
3237 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3238 "Expected 1 name entry, got %d\n",
3239 U(point->DistPointName).FullName.cAltEntry);
3240 entry = U(point->DistPointName).FullName.rgAltEntry;
3241 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3242 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3243 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3244 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3245 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3248 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3249 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3250 NULL, (BYTE *)&buf, &size);
3253 info = (PCRL_DIST_POINTS_INFO)buf;
3254 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3255 "Wrong size %d\n", size);
3256 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3258 point = info->rgDistPoint;
3259 ok(point->DistPointName.dwDistPointNameChoice ==
3260 CRL_DIST_POINT_NO_NAME,
3261 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3262 point->DistPointName.dwDistPointNameChoice);
3263 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3264 "Expected reason length\n");
3265 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3266 "Unexpected reason\n");
3267 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3270 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3271 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3272 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3275 info = (PCRL_DIST_POINTS_INFO)buf;
3276 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3277 "Wrong size %d\n", size);
3278 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3280 point = info->rgDistPoint;
3281 ok(point->DistPointName.dwDistPointNameChoice ==
3282 CRL_DIST_POINT_FULL_NAME,
3283 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3284 point->DistPointName.dwDistPointNameChoice);
3285 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3286 "Expected 1 name entry, got %d\n",
3287 U(point->DistPointName).FullName.cAltEntry);
3288 entry = U(point->DistPointName).FullName.rgAltEntry;
3289 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3290 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3291 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3292 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3293 ok(point->CRLIssuer.cAltEntry == 1,
3294 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3295 entry = point->CRLIssuer.rgAltEntry;
3296 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3297 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3298 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3303 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3304 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3305 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3306 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3309 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3314 CRL_ISSUING_DIST_POINT point = { { 0 } };
3315 CERT_ALT_NAME_ENTRY entry;
3317 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3318 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3319 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3321 skip("no X509_ISSUING_DIST_POINT encode support\n");
3324 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3325 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3326 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3327 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3328 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3331 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3332 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3335 /* nonsensical flags */
3336 point.fOnlyContainsUserCerts = TRUE;
3337 point.fOnlyContainsCACerts = TRUE;
3338 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3339 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3340 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3343 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3344 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3347 /* unimplemented name type */
3348 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3349 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3350 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3351 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3352 ok(!ret && GetLastError() == E_INVALIDARG,
3353 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3355 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3356 U(point.DistPointName).FullName.cAltEntry = 0;
3357 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3358 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3359 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3362 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3363 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3366 /* name with URL entry */
3367 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3368 U(entry).pwszURL = (LPWSTR)url;
3369 U(point.DistPointName).FullName.cAltEntry = 1;
3370 U(point.DistPointName).FullName.rgAltEntry = &entry;
3371 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3372 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3373 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3376 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3377 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3382 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3383 const CERT_ALT_NAME_ENTRY *got)
3385 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3386 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3387 got->dwAltNameChoice);
3388 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3390 switch (got->dwAltNameChoice)
3392 case CERT_ALT_NAME_RFC822_NAME:
3393 case CERT_ALT_NAME_DNS_NAME:
3394 case CERT_ALT_NAME_EDI_PARTY_NAME:
3395 case CERT_ALT_NAME_URL:
3396 case CERT_ALT_NAME_REGISTERED_ID:
3397 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3398 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL), "Unexpected name\n");
3400 case CERT_ALT_NAME_X400_ADDRESS:
3401 case CERT_ALT_NAME_DIRECTORY_NAME:
3402 case CERT_ALT_NAME_IP_ADDRESS:
3403 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3404 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3405 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3406 U(*got).IPAddress.cbData), "Unexpected value\n");
3412 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3413 const CERT_ALT_NAME_INFO *got)
3417 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3418 expected->cAltEntry, got->cAltEntry);
3419 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3420 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3423 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3424 const CRL_DIST_POINT_NAME *got)
3426 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3427 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3428 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3429 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3432 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3433 const CRL_ISSUING_DIST_POINT *got)
3435 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3436 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3437 "Unexpected fOnlyContainsUserCerts\n");
3438 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3439 "Unexpected fOnlyContainsCACerts\n");
3440 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3441 "Unexpected reason flags\n");
3442 ok(got->fIndirectCRL == expected->fIndirectCRL,
3443 "Unexpected fIndirectCRL\n");
3446 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3451 CRL_ISSUING_DIST_POINT point = { { 0 } };
3453 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3454 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3455 (BYTE *)&buf, &size);
3456 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3458 skip("no X509_ISSUING_DIST_POINT decode support\n");
3461 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3464 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3467 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3468 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3469 (BYTE *)&buf, &size);
3470 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3473 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3474 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3477 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3478 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3479 (BYTE *)&buf, &size);
3480 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3483 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3484 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3485 U(point.DistPointName).FullName.cAltEntry = 0;
3486 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3489 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3490 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3491 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3494 CERT_ALT_NAME_ENTRY entry;
3496 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3497 U(entry).pwszURL = (LPWSTR)url;
3498 U(point.DistPointName).FullName.cAltEntry = 1;
3499 U(point.DistPointName).FullName.rgAltEntry = &entry;
3500 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3505 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3506 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3508 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3509 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3510 0x30, 0x30, 0x30, 0x30, 0x5a };
3511 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3512 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3513 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3514 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3516 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3517 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3518 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3519 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3520 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3521 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3522 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3523 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3524 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3525 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3526 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3527 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3528 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3529 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3530 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3531 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3532 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3533 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3534 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3535 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3536 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3537 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3538 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3539 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3540 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3541 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3542 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3543 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3544 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3545 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3546 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3547 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3548 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3549 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3550 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3551 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3552 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3553 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3554 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3555 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3557 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3561 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3563 CRL_INFO info = { 0 };
3564 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3567 /* Test with a V1 CRL */
3568 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3569 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3570 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3573 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3574 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3578 info.dwVersion = CRL_V2;
3579 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3580 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3581 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3584 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3585 v2CRL[1] + 2, size);
3586 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3589 /* v1 CRL with a name */
3590 info.dwVersion = CRL_V1;
3591 info.Issuer.cbData = sizeof(encodedCommonName);
3592 info.Issuer.pbData = (BYTE *)encodedCommonName;
3593 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3594 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3595 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3598 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3599 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3602 /* v1 CRL with a name and a NULL entry pointer */
3604 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3605 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3606 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3607 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3608 /* now set an empty entry */
3609 info.rgCRLEntry = &entry;
3610 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3611 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3614 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3615 "Wrong size %d\n", size);
3616 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3617 "Got unexpected value\n");
3620 /* an entry with a serial number */
3621 entry.SerialNumber.cbData = sizeof(serialNum);
3622 entry.SerialNumber.pbData = (BYTE *)serialNum;
3623 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3624 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3627 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3628 "Wrong size %d\n", size);
3629 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3630 "Got unexpected value\n");
3633 /* an entry with an extension */
3634 entry.cExtension = 1;
3635 entry.rgExtension = &criticalExt;
3636 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3637 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3638 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3641 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3642 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3645 /* a CRL with an extension */
3646 entry.cExtension = 0;
3647 info.cExtension = 1;
3648 info.rgExtension = &criticalExt;
3649 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3650 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3651 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3654 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3655 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3658 /* a v2 CRL with an extension, this time non-critical */
3659 info.dwVersion = CRL_V2;
3660 info.rgExtension = &nonCriticalExt;
3661 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3662 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3663 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3666 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3667 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3670 /* a v2 CRL with an issuing dist point extension */
3671 ext.pszObjId = oid_issuing_dist_point;
3672 ext.fCritical = TRUE;
3673 ext.Value.cbData = sizeof(urlIDP);
3674 ext.Value.pbData = (LPBYTE)urlIDP;
3675 entry.rgExtension = &ext;
3676 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3677 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3678 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3681 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3682 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3687 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3688 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3689 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3690 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3691 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3692 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3693 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3694 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3695 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3696 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3697 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3698 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3699 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3700 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3701 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3702 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3703 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3704 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3705 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3706 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3707 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3708 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3709 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3710 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3711 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3712 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3713 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3714 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3715 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3716 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3717 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3718 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3719 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3720 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3722 static const BYTE verisignCRLWithLotsOfEntries[] = {
3723 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3724 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3725 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3726 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3727 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3728 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3729 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3730 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3731 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3732 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3733 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3734 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3735 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3736 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3737 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3738 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3739 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3740 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3741 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3742 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3743 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3744 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3745 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3746 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3747 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3748 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3749 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3750 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3751 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3752 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3753 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3754 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3755 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3756 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3757 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3758 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3759 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3760 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3761 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3762 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3763 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3764 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3765 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3766 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3767 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3768 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3769 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3770 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3771 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3772 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3773 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3774 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3775 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3776 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3777 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3778 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3779 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3780 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3781 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3782 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3783 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3784 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3785 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3786 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3787 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3788 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3789 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3790 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3791 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3792 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3793 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3794 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3795 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3796 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3797 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3798 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3799 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3800 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3801 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3802 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3803 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3804 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3805 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3806 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3807 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3808 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3809 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3810 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3811 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3812 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3813 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3814 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3815 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3816 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3817 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3818 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3819 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3820 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3821 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3822 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3823 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3824 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3825 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3826 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3827 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3828 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3829 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3830 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3831 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3832 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3833 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3834 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3835 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3836 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3837 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3838 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3839 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3840 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3841 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3842 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3843 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3844 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3845 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3846 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3847 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3848 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3849 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3850 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3851 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3852 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3853 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3854 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3855 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3856 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3857 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3858 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3859 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3860 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3861 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3862 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3863 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3864 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3865 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3866 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3867 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3868 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3869 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3870 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3871 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3872 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3873 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3874 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3875 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3876 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3877 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3878 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3879 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3880 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3881 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3882 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3883 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3884 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3885 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3886 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3887 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3888 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3889 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3890 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3891 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3892 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3893 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3894 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3895 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3896 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3897 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3898 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3899 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3900 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3901 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3902 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3903 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3904 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
3905 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
3906 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
3907 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
3908 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
3909 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
3910 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
3911 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
3912 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
3913 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
3914 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
3915 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
3916 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
3917 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
3918 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
3919 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
3920 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
3921 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
3922 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
3923 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
3924 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
3925 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
3926 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
3927 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
3928 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
3929 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
3930 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
3931 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
3932 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
3933 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
3934 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
3935 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
3936 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
3937 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
3938 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
3939 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
3940 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
3941 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
3942 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
3943 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
3944 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
3945 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
3946 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
3947 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
3948 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
3949 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
3950 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
3951 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
3952 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
3953 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
3954 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
3955 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
3956 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
3957 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
3958 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
3959 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
3960 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
3961 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
3962 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
3963 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
3964 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
3965 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
3966 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
3967 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
3968 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
3969 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
3970 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
3971 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
3972 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
3973 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
3974 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
3975 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
3976 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
3977 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
3978 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
3979 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
3980 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
3981 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
3982 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
3983 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
3984 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
3985 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
3986 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
3987 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
3988 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
3989 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
3990 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
3991 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
3992 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
3993 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
3994 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
3995 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
3996 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
3997 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
3998 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
3999 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4000 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4001 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4002 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4003 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4004 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4005 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4006 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4007 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4008 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4009 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4010 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4011 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4012 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4013 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4014 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4015 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4016 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4017 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4018 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4019 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4020 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4021 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4022 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4023 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4024 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4025 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4026 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4027 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4028 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4029 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4030 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4031 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4032 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4033 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4034 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4035 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4036 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4037 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4038 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4039 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4040 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4041 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4042 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4043 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4044 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4045 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4046 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4047 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4048 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4049 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4050 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4051 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4052 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4053 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4054 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4055 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4056 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4057 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4058 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4059 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4060 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4061 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4062 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4063 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4064 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4065 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4066 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4067 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4068 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4069 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4070 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4071 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4072 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4073 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4074 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4075 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4076 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4077 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4078 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4079 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4080 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4081 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4082 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4083 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4084 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4085 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4086 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4087 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4088 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4089 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4090 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4091 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4092 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4093 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4094 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4095 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4096 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4097 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4098 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4099 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4100 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4101 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4102 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4103 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4104 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4105 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4106 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4107 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4108 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4109 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4110 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4111 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4112 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4113 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4114 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4115 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4116 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4117 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4118 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4119 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4120 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4121 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4122 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4123 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4124 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4125 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4126 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4127 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4128 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4129 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4130 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4131 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4132 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4133 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4134 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4135 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4136 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4137 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4138 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4139 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4140 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4141 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4142 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4143 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4144 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4145 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4146 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4147 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4148 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4149 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4150 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4151 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4152 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4153 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4154 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4155 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4156 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4157 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4158 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4159 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4160 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4161 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4162 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4163 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4164 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4165 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4166 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4167 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4168 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4169 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4170 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4171 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4172 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4173 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4174 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4175 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4176 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4177 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4178 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4179 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4180 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4181 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4182 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4183 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4184 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4185 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4186 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4187 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4188 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4189 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4190 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4191 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4192 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4193 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4194 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4195 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4196 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4197 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4198 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4199 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4200 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4201 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4202 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4203 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4204 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4205 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4206 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4207 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4208 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4209 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4210 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4211 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4212 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4213 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4214 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4215 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4216 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4217 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4218 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4219 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4220 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4221 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4222 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4223 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4224 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4225 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4226 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4227 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4228 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4229 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4230 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4232 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4234 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4239 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4241 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4242 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4243 (BYTE *)&buf, &size);
4244 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT),
4245 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4247 /* at a minimum, a CRL must contain an issuer: */
4248 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4249 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4250 (BYTE *)&buf, &size);
4251 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4254 CRL_INFO *info = (CRL_INFO *)buf;
4256 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4257 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4259 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4260 "Wrong issuer size %d\n", info->Issuer.cbData);
4261 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4262 "Unexpected issuer\n");
4265 /* check decoding with an empty CRL entry */
4266 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4267 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4268 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4269 todo_wine ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
4270 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4271 /* with a real CRL entry */
4272 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4273 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4274 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4275 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4278 CRL_INFO *info = (CRL_INFO *)buf;
4281 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4282 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4284 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4285 entry = info->rgCRLEntry;
4286 ok(entry->SerialNumber.cbData == 1,
4287 "Expected serial number size 1, got %d\n",
4288 entry->SerialNumber.cbData);
4289 ok(*entry->SerialNumber.pbData == *serialNum,
4290 "Expected serial number %d, got %d\n", *serialNum,
4291 *entry->SerialNumber.pbData);
4292 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4293 "Wrong issuer size %d\n", info->Issuer.cbData);
4294 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4295 "Unexpected issuer\n");
4297 /* a real CRL from verisign that has extensions */
4298 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4299 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4300 NULL, (BYTE *)&buf, &size);
4301 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4304 CRL_INFO *info = (CRL_INFO *)buf;
4307 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4308 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4310 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4311 entry = info->rgCRLEntry;
4312 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4316 /* another real CRL from verisign that has lots of entries */
4317 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4318 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4319 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4320 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4323 CRL_INFO *info = (CRL_INFO *)buf;
4325 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4326 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4328 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4332 /* and finally, with an extension */
4333 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4334 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4335 NULL, (BYTE *)&buf, &size);
4336 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4339 CRL_INFO *info = (CRL_INFO *)buf;
4342 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4343 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4345 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4346 entry = info->rgCRLEntry;
4347 ok(entry->SerialNumber.cbData == 1,
4348 "Expected serial number size 1, got %d\n",
4349 entry->SerialNumber.cbData);
4350 ok(*entry->SerialNumber.pbData == *serialNum,
4351 "Expected serial number %d, got %d\n", *serialNum,
4352 *entry->SerialNumber.pbData);
4353 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4354 "Wrong issuer size %d\n", info->Issuer.cbData);
4355 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4356 "Unexpected issuer\n");
4357 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4360 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4361 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4362 NULL, (BYTE *)&buf, &size);
4363 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4366 CRL_INFO *info = (CRL_INFO *)buf;
4368 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4372 /* And again, with an issuing dist point */
4373 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4374 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4375 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4376 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4379 CRL_INFO *info = (CRL_INFO *)buf;
4381 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4387 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4388 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4389 static const BYTE encodedUsage[] = {
4390 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4391 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4392 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4394 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4399 CERT_ENHKEY_USAGE usage;
4401 /* Test with empty usage */
4402 usage.cUsageIdentifier = 0;
4403 ret = CryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4404 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4405 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4408 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4409 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4412 /* Test with a few usages */
4413 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4414 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4415 ret = CryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4416 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4417 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4420 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4421 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4426 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4432 ret = CryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4433 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4434 (BYTE *)&buf, &size);
4435 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4438 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4440 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4441 "Wrong size %d\n", size);
4442 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4443 usage->cUsageIdentifier);
4446 ret = CryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4447 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4448 (BYTE *)&buf, &size);
4449 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4452 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4455 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4456 "Wrong size %d\n", size);
4457 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4458 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4459 for (i = 0; i < usage->cUsageIdentifier; i++)
4460 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4461 "Expected OID %s, got %s\n", keyUsages[i],
4462 usage->rgpszUsageIdentifier[i]);
4467 static BYTE keyId[] = { 1,2,3,4 };
4468 static const BYTE authorityKeyIdWithId[] = {
4469 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4470 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4471 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4472 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4473 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4475 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4477 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4482 /* Test with empty id */
4483 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4484 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4485 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4488 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4489 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4492 /* With just a key id */
4493 info.KeyId.cbData = sizeof(keyId);
4494 info.KeyId.pbData = keyId;
4495 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4496 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4497 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4500 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4501 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4504 /* With just an issuer */
4505 info.KeyId.cbData = 0;
4506 info.CertIssuer.cbData = sizeof(encodedCommonName);
4507 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4508 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4509 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4510 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4513 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4515 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4518 /* With just a serial number */
4519 info.CertIssuer.cbData = 0;
4520 info.CertSerialNumber.cbData = sizeof(serialNum);
4521 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4522 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4523 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4524 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4527 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4529 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4534 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4540 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4541 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4542 (BYTE *)&buf, &size);
4543 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4546 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4548 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4550 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4551 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4552 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4555 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4556 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4557 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4558 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4561 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4563 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4565 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4566 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4567 "Unexpected key id\n");
4568 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4569 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4572 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4573 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4574 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4575 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4578 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4580 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4582 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4583 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4584 "Unexpected issuer len\n");
4585 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4586 sizeof(encodedCommonName)), "Unexpected issuer\n");
4587 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4590 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4591 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4592 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4593 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4596 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4598 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4600 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4601 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4602 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4603 "Unexpected serial number len\n");
4604 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4605 "Unexpected serial number\n");
4610 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4611 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4614 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4616 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4617 CERT_ALT_NAME_ENTRY entry = { 0 };
4622 /* Test with empty id */
4623 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4624 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4625 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4628 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4629 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4632 /* With just a key id */
4633 info.KeyId.cbData = sizeof(keyId);
4634 info.KeyId.pbData = keyId;
4635 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4636 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4637 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4640 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4642 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4645 /* With a bogus issuer name */
4646 info.KeyId.cbData = 0;
4647 info.AuthorityCertIssuer.cAltEntry = 1;
4648 info.AuthorityCertIssuer.rgAltEntry = &entry;
4649 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4650 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4651 ok(!ret && GetLastError() == E_INVALIDARG,
4652 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4653 /* With an issuer name */
4654 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4655 U(entry).pwszURL = (LPWSTR)url;
4656 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4657 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4658 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4661 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4663 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4664 "Unexpected value\n");
4667 /* With just a serial number */
4668 info.AuthorityCertIssuer.cAltEntry = 0;
4669 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4670 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4671 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4672 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4673 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4676 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4678 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4683 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4689 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4690 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4691 (BYTE *)&buf, &size);
4692 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4695 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4697 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4699 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4700 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4701 "Expected no issuer name entries\n");
4702 ok(info->AuthorityCertSerialNumber.cbData == 0,
4703 "Expected no serial number\n");
4706 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4707 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4708 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4709 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4712 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4714 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4716 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4717 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4718 "Unexpected key id\n");
4719 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4720 "Expected no issuer name entries\n");
4721 ok(info->AuthorityCertSerialNumber.cbData == 0,
4722 "Expected no serial number\n");
4725 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4726 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4727 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4728 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4731 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4733 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4735 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4736 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4737 "Expected 1 issuer entry, got %d\n",
4738 info->AuthorityCertIssuer.cAltEntry);
4739 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4740 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4741 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4742 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4743 url), "Unexpected URL\n");
4744 ok(info->AuthorityCertSerialNumber.cbData == 0,
4745 "Expected no serial number\n");
4748 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4749 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4750 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4751 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4754 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4756 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4758 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4759 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4760 "Expected no issuer name entries\n");
4761 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4762 "Unexpected serial number len\n");
4763 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4764 sizeof(serialNum)), "Unexpected serial number\n");
4769 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
4770 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
4772 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
4774 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
4775 0x03,0x02,0x01,0x01 };
4776 static BYTE bogusDER[] = { 1 };
4778 static void test_encodePKCSContentInfo(DWORD dwEncoding)
4783 CRYPT_CONTENT_INFO info = { 0 };
4784 char oid1[] = "1.2.3";
4786 SetLastError(0xdeadbeef);
4787 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
4788 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4789 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4790 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
4791 SetLastError(0xdeadbeef);
4792 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4793 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4794 ok(!ret && GetLastError() == E_INVALIDARG,
4795 "Expected E_INVALIDARG, got %x\n", GetLastError());
4796 info.pszObjId = oid1;
4797 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4798 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4799 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4802 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
4803 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
4806 info.Content.pbData = bogusDER;
4807 info.Content.cbData = sizeof(bogusDER);
4808 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4809 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4810 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
4813 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
4814 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
4817 info.Content.pbData = (BYTE *)ints[0].encoded;
4818 info.Content.cbData = ints[0].encoded[1] + 2;
4819 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4820 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4823 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
4824 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
4829 static const BYTE indefiniteSignedPKCSContent[] = {
4830 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
4831 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
4832 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
4833 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
4834 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
4835 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
4836 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
4837 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
4838 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
4839 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
4840 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
4841 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
4842 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
4843 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
4844 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
4845 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
4846 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
4847 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
4848 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
4849 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
4850 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
4851 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
4852 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
4853 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
4854 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
4855 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
4856 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
4857 0x00,0x00,0x00,0x00,0x00,0x00 };
4859 static void test_decodePKCSContentInfo(DWORD dwEncoding)
4864 CRYPT_CONTENT_INFO *info;
4866 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4867 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
4868 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4869 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4872 info = (CRYPT_CONTENT_INFO *)buf;
4874 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4876 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
4877 info->Content.cbData);
4880 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4881 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
4882 0, NULL, NULL, &size);
4883 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4884 SetLastError(0xdeadbeef);
4885 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4886 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
4887 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4888 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
4889 * I doubt an app depends on that.
4891 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
4892 GetLastError() == CRYPT_E_ASN1_CORRUPT),
4893 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
4895 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4896 intPKCSContentInfo, sizeof(intPKCSContentInfo),
4897 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4898 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4901 info = (CRYPT_CONTENT_INFO *)buf;
4903 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4905 ok(info->Content.cbData == ints[0].encoded[1] + 2,
4906 "Unexpected size %d\n", info->Content.cbData);
4907 ok(!memcmp(info->Content.pbData, ints[0].encoded,
4908 info->Content.cbData), "Unexpected value\n");
4911 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4912 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
4913 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4914 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4917 info = (CRYPT_CONTENT_INFO *)buf;
4919 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
4920 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
4921 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
4922 info->Content.cbData);
4927 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
4929 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
4931 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
4934 static void test_encodePKCSAttribute(DWORD dwEncoding)
4936 CRYPT_ATTRIBUTE attr = { 0 };
4940 CRYPT_ATTR_BLOB blob;
4941 char oid[] = "1.2.3";
4943 SetLastError(0xdeadbeef);
4944 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
4945 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4946 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4947 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
4948 SetLastError(0xdeadbeef);
4949 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4950 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4951 ok(!ret && GetLastError() == E_INVALIDARG,
4952 "Expected E_INVALIDARG, got %x\n", GetLastError());
4953 attr.pszObjId = oid;
4954 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4955 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4956 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4959 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
4960 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
4963 blob.cbData = sizeof(bogusDER);
4964 blob.pbData = bogusDER;
4966 attr.rgValue = &blob;
4967 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4968 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4969 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4972 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
4973 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
4976 blob.pbData = (BYTE *)ints[0].encoded;
4977 blob.cbData = ints[0].encoded[1] + 2;
4978 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4979 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4982 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
4983 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
4988 static void test_decodePKCSAttribute(DWORD dwEncoding)
4993 CRYPT_ATTRIBUTE *attr;
4995 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
4996 emptyPKCSAttr, sizeof(emptyPKCSAttr),
4997 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4998 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5001 attr = (CRYPT_ATTRIBUTE *)buf;
5003 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5005 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5008 SetLastError(0xdeadbeef);
5009 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5010 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5011 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5012 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5013 * I doubt an app depends on that.
5015 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5016 GetLastError() == CRYPT_E_ASN1_CORRUPT),
5017 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5019 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5020 intPKCSAttr, sizeof(intPKCSAttr),
5021 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5022 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5025 attr = (CRYPT_ATTRIBUTE *)buf;
5027 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5029 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5030 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5031 "Unexpected size %d\n", attr->rgValue[0].cbData);
5032 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5033 attr->rgValue[0].cbData), "Unexpected value\n");
5037 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5038 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5039 0x2a,0x03,0x31,0x00 };
5040 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5041 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5043 static void test_encodePKCSAttributes(DWORD dwEncoding)
5045 CRYPT_ATTRIBUTES attributes = { 0 };
5046 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5047 CRYPT_ATTR_BLOB blob;
5051 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5053 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5054 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5055 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5058 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5059 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5062 attributes.cAttr = 1;
5063 attributes.rgAttr = attr;
5064 SetLastError(0xdeadbeef);
5065 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5066 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5067 ok(!ret && GetLastError() == E_INVALIDARG,
5068 "Expected E_INVALIDARG, got %x\n", GetLastError());
5069 attr[0].pszObjId = oid1;
5070 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5071 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5074 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5075 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5078 attr[1].pszObjId = oid2;
5080 attr[1].rgValue = &blob;
5081 blob.pbData = (BYTE *)ints[0].encoded;
5082 blob.cbData = ints[0].encoded[1] + 2;
5083 attributes.cAttr = 2;
5084 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5085 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5086 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5089 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5090 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5095 static void test_decodePKCSAttributes(DWORD dwEncoding)
5100 CRYPT_ATTRIBUTES *attributes;
5102 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5103 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5104 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5105 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5108 attributes = (CRYPT_ATTRIBUTES *)buf;
5109 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5113 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5114 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5115 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5116 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5119 attributes = (CRYPT_ATTRIBUTES *)buf;
5120 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5122 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5123 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5124 ok(attributes->rgAttr[0].cValue == 0,
5125 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5128 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5129 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5130 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5131 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5134 attributes = (CRYPT_ATTRIBUTES *)buf;
5135 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5137 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5138 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5139 ok(attributes->rgAttr[0].cValue == 0,
5140 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5141 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5142 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5143 ok(attributes->rgAttr[1].cValue == 1,
5144 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5145 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5146 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5147 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5148 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5153 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
5154 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5156 static const BYTE minimalPKCSSigner[] = {
5157 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5158 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5159 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
5160 static const BYTE PKCSSignerWithSerial[] = {
5161 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5162 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5163 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5165 static const BYTE PKCSSignerWithHashAlgo[] = {
5166 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5167 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5168 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5170 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
5171 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5172 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5173 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5174 0x06,0x05,0x00,0x04,0x00 };
5175 static const BYTE PKCSSignerWithHash[] = {
5176 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5177 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5178 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5179 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
5180 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5181 static const BYTE PKCSSignerWithAuthAttr[] = {
5182 0x30,0x62,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,0xa0,0x20,0x30,0x1e,0x06,
5185 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
5186 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
5187 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
5188 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5190 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
5192 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
5196 CMSG_SIGNER_INFO info = { 0 };
5197 char oid_common_name[] = szOID_COMMON_NAME;
5198 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
5199 (LPBYTE)encodedCommonName };
5200 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
5202 SetLastError(0xdeadbeef);
5203 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5204 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5205 ok(!ret && GetLastError() == E_INVALIDARG,
5206 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5207 /* To be encoded, a signer must have an issuer at least, and the encoding
5208 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
5209 * see decoding tests.)
5211 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
5212 info.Issuer.pbData = encodedCommonNameNoNull;
5213 SetLastError(0xdeadbeef);
5214 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5215 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5216 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5217 ok(!ret && GetLastError() == E_INVALIDARG,
5218 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5221 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5224 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
5225 if (size == sizeof(minimalPKCSSigner))
5226 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
5228 ok(0, "Unexpected value\n");
5232 info.SerialNumber.cbData = sizeof(serialNum);
5233 info.SerialNumber.pbData = (BYTE *)serialNum;
5234 SetLastError(0xdeadbeef);
5235 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5236 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5237 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5238 ok(!ret && GetLastError() == E_INVALIDARG,
5239 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5242 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5245 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
5247 if (size == sizeof(PKCSSignerWithSerial))
5248 ok(!memcmp(buf, PKCSSignerWithSerial, size),
5249 "Unexpected value\n");
5251 ok(0, "Unexpected value\n");
5255 info.HashAlgorithm.pszObjId = oid1;
5256 SetLastError(0xdeadbeef);
5257 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5258 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5259 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5260 ok(!ret && GetLastError() == E_INVALIDARG,
5261 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5264 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5267 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
5269 if (size == sizeof(PKCSSignerWithHashAlgo))
5270 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
5271 "Unexpected value\n");
5273 ok(0, "Unexpected value\n");
5277 info.HashEncryptionAlgorithm.pszObjId = oid2;
5278 SetLastError(0xdeadbeef);
5279 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5280 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5281 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5282 ok(!ret && GetLastError() == E_INVALIDARG,
5283 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5286 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5289 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
5290 "Unexpected size %d\n", size);
5291 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
5292 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
5293 "Unexpected value\n");
5295 ok(0, "Unexpected value\n");
5299 info.EncryptedHash.cbData = sizeof(hash);
5300 info.EncryptedHash.pbData = (BYTE *)hash;
5301 SetLastError(0xdeadbeef);
5302 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5303 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5304 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5305 ok(!ret && GetLastError() == E_INVALIDARG,
5306 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5309 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5312 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
5314 if (size == sizeof(PKCSSignerWithHash))
5315 ok(!memcmp(buf, PKCSSignerWithHash, size),
5316 "Unexpected value\n");
5318 ok(0, "Unexpected value\n");
5322 info.AuthAttrs.cAttr = 1;
5323 info.AuthAttrs.rgAttr = &attr;
5324 SetLastError(0xdeadbeef);
5325 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5326 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5327 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5328 ok(!ret && GetLastError() == E_INVALIDARG,
5329 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5332 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5335 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
5337 if (size == sizeof(PKCSSignerWithAuthAttr))
5338 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
5339 "Unexpected value\n");
5341 ok(0, "Unexpected value\n");
5347 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
5352 CMSG_SIGNER_INFO *info;
5354 /* A PKCS signer can't be decoded without a serial number. */
5355 SetLastError(0xdeadbeef);
5356 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5357 minimalPKCSSigner, sizeof(minimalPKCSSigner),
5358 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5359 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
5360 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
5361 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5362 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
5363 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5364 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5367 info = (CMSG_SIGNER_INFO *)buf;
5368 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5370 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5371 "Unexpected size %d\n", info->Issuer.cbData);
5372 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5373 info->Issuer.cbData), "Unexpected value\n");
5374 ok(info->SerialNumber.cbData == sizeof(serialNum),
5375 "Unexpected size %d\n", info->SerialNumber.cbData);
5376 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5377 "Unexpected value\n");
5380 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5381 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
5382 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5385 info = (CMSG_SIGNER_INFO *)buf;
5386 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5388 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5389 "Unexpected size %d\n", info->Issuer.cbData);
5390 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5391 info->Issuer.cbData), "Unexpected value\n");
5392 ok(info->SerialNumber.cbData == sizeof(serialNum),
5393 "Unexpected size %d\n", info->SerialNumber.cbData);
5394 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5395 "Unexpected value\n");
5396 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5397 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5400 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5401 PKCSSignerWithHashAndEncryptionAlgo,
5402 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
5403 NULL, (BYTE *)&buf, &size);
5406 info = (CMSG_SIGNER_INFO *)buf;
5407 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5409 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5410 "Unexpected size %d\n", info->Issuer.cbData);
5411 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5412 info->Issuer.cbData), "Unexpected value\n");
5413 ok(info->SerialNumber.cbData == sizeof(serialNum),
5414 "Unexpected size %d\n", info->SerialNumber.cbData);
5415 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5416 "Unexpected value\n");
5417 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5418 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5419 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
5420 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
5423 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5424 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
5425 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5428 info = (CMSG_SIGNER_INFO *)buf;
5429 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5431 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5432 "Unexpected size %d\n", info->Issuer.cbData);
5433 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5434 info->Issuer.cbData), "Unexpected value\n");
5435 ok(info->SerialNumber.cbData == sizeof(serialNum),
5436 "Unexpected size %d\n", info->SerialNumber.cbData);
5437 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5438 "Unexpected value\n");
5439 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5440 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5441 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
5442 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
5443 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
5444 info->EncryptedHash.cbData);
5445 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
5446 "Unexpected value\n");
5449 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5450 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
5451 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5454 info = (CMSG_SIGNER_INFO *)buf;
5455 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
5456 info->AuthAttrs.cAttr);
5457 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
5458 "Expected %s, got %s\n", szOID_COMMON_NAME,
5459 info->AuthAttrs.rgAttr[0].pszObjId);
5460 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
5461 info->AuthAttrs.rgAttr[0].cValue);
5462 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
5463 sizeof(encodedCommonName), "Unexpected size %d\n",
5464 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
5465 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
5466 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
5471 static BYTE emptyDNSPermittedConstraints[] = {
5472 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
5473 static BYTE emptyDNSExcludedConstraints[] = {
5474 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
5475 static BYTE DNSExcludedConstraints[] = {
5476 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
5477 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5478 static BYTE permittedAndExcludedConstraints[] = {
5479 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5480 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
5481 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5482 static BYTE permittedAndExcludedWithMinConstraints[] = {
5483 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5484 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
5485 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5486 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
5487 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5488 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
5489 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5491 static void test_encodeNameConstraints(DWORD dwEncoding)
5494 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
5495 CERT_GENERAL_SUBTREE permitted = { { 0 } };
5496 CERT_GENERAL_SUBTREE excluded = { { 0 } };
5500 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5501 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5502 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5505 ok(size == sizeof(emptySequence), "Unexpected size\n");
5506 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
5509 constraints.cPermittedSubtree = 1;
5510 constraints.rgPermittedSubtree = &permitted;
5511 SetLastError(0xdeadbeef);
5512 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5513 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5514 ok(!ret && GetLastError() == E_INVALIDARG,
5515 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5516 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
5517 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5518 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5519 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5522 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
5523 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
5524 "Unexpected value\n");
5527 constraints.cPermittedSubtree = 0;
5528 constraints.cExcludedSubtree = 1;
5529 constraints.rgExcludedSubtree = &excluded;
5530 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
5531 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5532 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5533 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5536 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
5537 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
5538 "Unexpected value\n");
5541 excluded.Base.pwszURL = (LPWSTR)url;
5542 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5543 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5544 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5547 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
5548 ok(!memcmp(buf, DNSExcludedConstraints, size),
5549 "Unexpected value\n");
5552 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
5553 permitted.Base.IPAddress.cbData = sizeof(encodedIPAddr);
5554 permitted.Base.IPAddress.pbData = (LPBYTE)encodedIPAddr;
5555 constraints.cPermittedSubtree = 1;
5556 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5557 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5558 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5561 ok(size == sizeof(permittedAndExcludedConstraints),
5562 "Unexpected size\n");
5563 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
5564 "Unexpected value\n");
5567 permitted.dwMinimum = 5;
5568 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5569 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5570 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5573 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
5574 "Unexpected size\n");
5575 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
5576 "Unexpected value\n");
5579 permitted.fMaximum = TRUE;
5580 permitted.dwMaximum = 3;
5581 SetLastError(0xdeadbeef);
5582 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5583 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5584 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5587 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
5588 "Unexpected size\n");
5589 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
5590 "Unexpected value\n");
5595 struct EncodedNameConstraints
5597 CRYPT_DATA_BLOB encoded;
5598 CERT_NAME_CONSTRAINTS_INFO constraints;
5601 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
5602 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
5603 static CERT_GENERAL_SUBTREE DNSSubtree = {
5604 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
5605 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
5606 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
5607 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
5608 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
5609 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
5610 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
5612 struct EncodedNameConstraints encodedNameConstraints[] = {
5613 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
5614 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
5615 { 1, &emptyDNSSubtree, 0, NULL } },
5616 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
5617 { 0, NULL, 1, &emptyDNSSubtree } },
5618 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
5619 { 0, NULL, 1, &DNSSubtree } },
5620 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
5621 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
5622 { { sizeof(permittedAndExcludedWithMinConstraints),
5623 permittedAndExcludedWithMinConstraints },
5624 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
5625 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
5626 permittedAndExcludedWithMinMaxConstraints },
5627 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
5630 static void test_decodeNameConstraints(DWORD dwEncoding)
5634 CERT_NAME_CONSTRAINTS_INFO *constraints;
5636 DNSSubtree.Base.pwszURL = (LPWSTR)url;
5637 IPAddressSubtree.Base.IPAddress.cbData = sizeof(encodedIPAddr);
5638 IPAddressSubtree.Base.IPAddress.pbData = (LPBYTE)encodedIPAddr;
5639 IPAddressWithMinSubtree.Base.IPAddress.cbData = sizeof(encodedIPAddr);
5640 IPAddressWithMinSubtree.Base.IPAddress.pbData = (LPBYTE)encodedIPAddr;
5641 IPAddressWithMinMaxSubtree.Base.IPAddress.cbData = sizeof(encodedIPAddr);
5642 IPAddressWithMinMaxSubtree.Base.IPAddress.pbData = (LPBYTE)encodedIPAddr;
5644 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
5649 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
5650 encodedNameConstraints[i].encoded.pbData,
5651 encodedNameConstraints[i].encoded.cbData,
5652 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
5654 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
5659 if (constraints->cPermittedSubtree !=
5660 encodedNameConstraints[i].constraints.cPermittedSubtree)
5661 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
5662 encodedNameConstraints[i].constraints.cPermittedSubtree,
5663 constraints->cPermittedSubtree);
5664 if (constraints->cPermittedSubtree ==
5665 encodedNameConstraints[i].constraints.cPermittedSubtree)
5667 for (j = 0; j < constraints->cPermittedSubtree; j++)
5669 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
5670 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
5673 if (constraints->cExcludedSubtree !=
5674 encodedNameConstraints[i].constraints.cExcludedSubtree)
5675 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
5676 encodedNameConstraints[i].constraints.cExcludedSubtree,
5677 constraints->cExcludedSubtree);
5678 if (constraints->cExcludedSubtree ==
5679 encodedNameConstraints[i].constraints.cExcludedSubtree)
5681 for (j = 0; j < constraints->cExcludedSubtree; j++)
5683 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
5684 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
5687 LocalFree(constraints);
5692 /* Free *pInfo with HeapFree */
5693 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
5700 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
5702 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
5703 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5704 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5705 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
5707 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5708 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5709 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
5711 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5712 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5713 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
5714 0, NULL, NULL, &size);
5715 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5716 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5717 /* Test with no key */
5718 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
5719 0, NULL, NULL, &size);
5720 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
5722 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
5723 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
5726 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
5727 NULL, 0, NULL, NULL, &size);
5728 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
5729 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
5732 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
5733 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
5734 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
5738 /* By default (we passed NULL as the OID) the OID is
5741 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
5742 "Expected %s, got %s\n", szOID_RSA_RSA,
5743 (*pInfo)->Algorithm.pszObjId);
5749 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
5750 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
5751 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
5752 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
5753 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
5754 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
5755 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
5756 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
5757 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
5758 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
5759 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
5760 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
5761 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
5762 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
5763 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
5764 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
5765 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
5766 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
5767 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
5768 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
5769 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
5770 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
5771 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
5772 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
5773 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
5775 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
5779 PCCERT_CONTEXT context;
5782 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
5783 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
5784 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
5785 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
5788 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
5789 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
5790 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
5791 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
5792 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
5793 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
5794 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
5796 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5797 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5798 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
5800 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
5801 CryptDestroyKey(key);
5803 /* Test importing a public key from a certificate context */
5804 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
5805 sizeof(expiredCert));
5806 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
5810 ok(!strcmp(szOID_RSA_RSA,
5811 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
5812 "Expected %s, got %s\n", szOID_RSA_RSA,
5813 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
5814 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
5815 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
5816 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
5817 CryptDestroyKey(key);
5818 CertFreeCertificateContext(context);
5822 static const char cspName[] = "WineCryptTemp";
5824 static void testPortPublicKeyInfo(void)
5828 PCERT_PUBLIC_KEY_INFO info = NULL;
5830 /* Just in case a previous run failed, delete this thing */
5831 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5832 CRYPT_DELETEKEYSET);
5833 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5836 testExportPublicKey(csp, &info);
5837 testImportPublicKey(csp, info);
5839 HeapFree(GetProcessHeap(), 0, info);
5840 CryptReleaseContext(csp, 0);
5841 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5842 CRYPT_DELETEKEYSET);
5847 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
5848 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
5851 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
5853 test_encodeInt(encodings[i]);
5854 test_decodeInt(encodings[i]);
5855 test_encodeEnumerated(encodings[i]);
5856 test_decodeEnumerated(encodings[i]);
5857 test_encodeFiletime(encodings[i]);
5858 test_decodeFiletime(encodings[i]);
5859 test_encodeName(encodings[i]);
5860 test_decodeName(encodings[i]);
5861 test_encodeUnicodeName(encodings[i]);
5862 test_decodeUnicodeName(encodings[i]);
5863 test_encodeNameValue(encodings[i]);
5864 test_decodeNameValue(encodings[i]);
5865 test_encodeUnicodeNameValue(encodings[i]);
5866 test_decodeUnicodeNameValue(encodings[i]);
5867 test_encodeAltName(encodings[i]);
5868 test_decodeAltName(encodings[i]);
5869 test_encodeOctets(encodings[i]);
5870 test_decodeOctets(encodings[i]);
5871 test_encodeBits(encodings[i]);
5872 test_decodeBits(encodings[i]);
5873 test_encodeBasicConstraints(encodings[i]);
5874 test_decodeBasicConstraints(encodings[i]);
5875 test_encodeRsaPublicKey(encodings[i]);
5876 test_decodeRsaPublicKey(encodings[i]);
5877 test_encodeSequenceOfAny(encodings[i]);
5878 test_decodeSequenceOfAny(encodings[i]);
5879 test_encodeExtensions(encodings[i]);
5880 test_decodeExtensions(encodings[i]);
5881 test_encodePublicKeyInfo(encodings[i]);
5882 test_decodePublicKeyInfo(encodings[i]);
5883 test_encodeCertToBeSigned(encodings[i]);
5884 test_decodeCertToBeSigned(encodings[i]);
5885 test_encodeCert(encodings[i]);
5886 test_decodeCert(encodings[i]);
5887 test_encodeCRLDistPoints(encodings[i]);
5888 test_decodeCRLDistPoints(encodings[i]);
5889 test_encodeCRLIssuingDistPoint(encodings[i]);
5890 test_decodeCRLIssuingDistPoint(encodings[i]);
5891 test_encodeCRLToBeSigned(encodings[i]);
5892 test_decodeCRLToBeSigned(encodings[i]);
5893 test_encodeEnhancedKeyUsage(encodings[i]);
5894 test_decodeEnhancedKeyUsage(encodings[i]);
5895 test_encodeAuthorityKeyId(encodings[i]);
5896 test_decodeAuthorityKeyId(encodings[i]);
5897 test_encodeAuthorityKeyId2(encodings[i]);
5898 test_decodeAuthorityKeyId2(encodings[i]);
5899 test_encodePKCSContentInfo(encodings[i]);
5900 test_decodePKCSContentInfo(encodings[i]);
5901 test_encodePKCSAttribute(encodings[i]);
5902 test_decodePKCSAttribute(encodings[i]);
5903 test_encodePKCSAttributes(encodings[i]);
5904 test_decodePKCSAttributes(encodings[i]);
5905 test_encodePKCSSignerInfo(encodings[i]);
5906 test_decodePKCSSignerInfo(encodings[i]);
5907 test_encodeNameConstraints(encodings[i]);
5908 test_decodeNameConstraints(encodings[i]);
5910 testPortPublicKeyInfo();