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 testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
486 const struct encodedFiletime *time)
488 FILETIME ft1 = { 0 }, ft2 = { 0 };
489 DWORD size = sizeof(ft2);
492 ret = SystemTimeToFileTime(&time->sysTime, &ft1);
493 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
494 ret = CryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
495 time->encodedTime[1] + 2, 0, NULL, &ft2, &size);
496 /* years other than 1950-2050 are not allowed for encodings other than
497 * X509_CHOICE_OF_TIME.
499 if (structType == X509_CHOICE_OF_TIME ||
500 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
502 ok(ret, "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
504 ok(!memcmp(&ft1, &ft2, sizeof(ft1)),
505 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
506 printSystemTime(&time->sysTime), printFileTime(&ft2));
509 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
510 "Expected CRYPT_E_ASN1_BADTAG, got 0x%08x\n", GetLastError());
513 static const BYTE bin20[] = {
514 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
515 static const BYTE bin21[] = {
516 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
517 static const BYTE bin22[] = {
518 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
520 static const struct encodedFiletime times[] = {
521 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
522 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
523 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
526 static void test_encodeFiletime(DWORD dwEncoding)
530 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
532 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]);
533 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, ×[i]);
534 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, ×[i]);
538 static const BYTE bin23[] = {
539 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
540 static const BYTE bin24[] = {
541 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
542 static const BYTE bin25[] = {
543 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
544 static const BYTE bin26[] = {
545 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
546 static const BYTE bin27[] = {
547 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
548 static const BYTE bin28[] = {
549 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
550 static const BYTE bin29[] = {
551 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
552 static const BYTE bin30[] = {
553 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
554 static const BYTE bin31[] = {
555 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
556 static const BYTE bin32[] = {
557 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
558 static const BYTE bin33[] = {
559 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
560 static const BYTE bin34[] = {
561 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
562 static const BYTE bin35[] = {
563 0x17,0x08, '4','5','0','6','0','6','1','6'};
564 static const BYTE bin36[] = {
565 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
566 static const BYTE bin37[] = {
567 0x18,0x04, '2','1','4','5'};
568 static const BYTE bin38[] = {
569 0x18,0x08, '2','1','4','5','0','6','0','6'};
571 static void test_decodeFiletime(DWORD dwEncoding)
573 static const struct encodedFiletime otherTimes[] = {
574 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
575 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
576 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
577 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
578 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
579 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
580 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
581 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
582 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
583 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
584 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
585 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
587 /* An oddball case that succeeds in Windows, but doesn't seem correct
588 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
590 static const unsigned char *bogusTimes[] = {
591 /* oddly, this succeeds on Windows, with year 2765
592 "\x18" "\x0f" "21r50606161000Z",
600 FILETIME ft1 = { 0 }, ft2 = { 0 };
603 /* Check bogus length with non-NULL buffer */
604 ret = SystemTimeToFileTime(×[0].sysTime, &ft1);
605 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
607 ret = CryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
608 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
609 ok(!ret && GetLastError() == ERROR_MORE_DATA,
610 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
612 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
614 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]);
615 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, ×[i]);
616 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, ×[i]);
618 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
620 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
621 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
622 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
624 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
627 ret = CryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
628 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
629 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
630 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
634 static const char commonName[] = "Juan Lang";
635 static const char surName[] = "Lang";
637 static const BYTE emptySequence[] = { 0x30, 0 };
638 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
639 static const BYTE twoRDNs[] = {
640 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
641 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
642 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
643 static const BYTE encodedTwoRDNs[] = {
644 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
645 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
646 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
650 static const BYTE us[] = { 0x55, 0x53 };
651 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
653 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
654 0x6f, 0x6c, 0x69, 0x73 };
655 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
656 0x76, 0x65, 0x72, 0x73 };
657 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
658 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
659 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
661 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
662 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
664 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
665 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
667 static CHAR oid_us[] = "2.5.4.6",
668 oid_minnesota[] = "2.5.4.8",
669 oid_minneapolis[] = "2.5.4.7",
670 oid_codeweavers[] = "2.5.4.10",
671 oid_wine[] = "2.5.4.11",
672 oid_localhostAttr[] = "2.5.4.3",
673 oid_aric[] = "1.2.840.113549.1.9.1";
674 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
676 { RDNA(minneapolis) },
677 { RDNA(codeweavers) },
679 { RDNA(localhostAttr) },
681 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
682 { RDNA(localhostAttr) },
684 { RDNA(minneapolis) },
685 { RDNA(codeweavers) },
692 static const BYTE encodedRDNAttrs[] = {
693 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
694 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
695 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
696 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
697 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
698 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
699 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
700 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
701 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
702 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
705 static void test_encodeName(DWORD dwEncoding)
707 CERT_RDN_ATTR attrs[2];
710 static CHAR oid_common_name[] = szOID_COMMON_NAME,
711 oid_sur_name[] = szOID_SUR_NAME;
716 /* Test with NULL pvStructInfo */
717 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
718 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
719 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
720 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
721 /* Test with empty CERT_NAME_INFO */
724 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
725 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
726 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
729 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
730 "Got unexpected encoding for empty name\n");
733 /* Test with bogus CERT_RDN */
735 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
736 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
737 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
738 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
739 /* Test with empty CERT_RDN */
741 rdn.rgRDNAttr = NULL;
744 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
745 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
746 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
749 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
750 "Got unexpected encoding for empty RDN array\n");
753 /* Test with bogus attr array */
755 rdn.rgRDNAttr = NULL;
756 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
757 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
758 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
759 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
760 /* oddly, a bogus OID is accepted by Windows XP; not testing.
761 attrs[0].pszObjId = "bogus";
762 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
763 attrs[0].Value.cbData = sizeof(commonName);
764 attrs[0].Value.pbData = (BYTE *)commonName;
766 rdn.rgRDNAttr = attrs;
767 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
768 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
769 ok(!ret, "Expected failure, got success\n");
771 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
772 * the encoded attributes to be swapped.
774 attrs[0].pszObjId = oid_common_name;
775 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
776 attrs[0].Value.cbData = sizeof(commonName);
777 attrs[0].Value.pbData = (BYTE *)commonName;
778 attrs[1].pszObjId = oid_sur_name;
779 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
780 attrs[1].Value.cbData = sizeof(surName);
781 attrs[1].Value.pbData = (BYTE *)surName;
783 rdn.rgRDNAttr = attrs;
784 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
785 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
786 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
789 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
790 "Got unexpected encoding for two RDN array\n");
793 /* A name can be "encoded" with previously encoded RDN attrs. */
794 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
795 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
796 attrs[0].Value.cbData = sizeof(twoRDNs);
798 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
799 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
800 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
803 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
804 ok(!memcmp(buf, encodedTwoRDNs, size),
805 "Unexpected value for re-endoded two RDN array\n");
808 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
810 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
811 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
812 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
813 ok(!ret && GetLastError() == E_INVALIDARG,
814 "Expected E_INVALIDARG, got %08x\n", GetLastError());
815 /* Test a more complex name */
816 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
817 rdn.rgRDNAttr = (PCERT_RDN_ATTR)rdnAttrs;
822 ret = CryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
823 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
824 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
827 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
828 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
833 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
834 static WCHAR surNameW[] = { 'L','a','n','g',0 };
836 static const BYTE twoRDNsNoNull[] = {
837 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
838 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
839 0x20,0x4c,0x61,0x6e,0x67 };
840 static const BYTE anyType[] = {
841 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
842 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
843 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
844 0x61,0x4c,0x67,0x6e };
846 static void test_encodeUnicodeName(DWORD dwEncoding)
848 CERT_RDN_ATTR attrs[2];
851 static CHAR oid_common_name[] = szOID_COMMON_NAME,
852 oid_sur_name[] = szOID_SUR_NAME;
857 /* Test with NULL pvStructInfo */
858 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
859 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
860 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
861 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
862 /* Test with empty CERT_NAME_INFO */
865 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
866 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
867 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
870 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
871 "Got unexpected encoding for empty name\n");
874 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
875 * encoding (the NULL).
877 attrs[0].pszObjId = oid_common_name;
878 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
879 attrs[0].Value.cbData = sizeof(commonNameW);
880 attrs[0].Value.pbData = (BYTE *)commonNameW;
882 rdn.rgRDNAttr = attrs;
885 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
886 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
887 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
888 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
889 ok(size == 9, "Unexpected error index %08x\n", size);
890 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
891 * forces the order of the encoded attributes to be swapped.
893 attrs[0].pszObjId = oid_common_name;
894 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
895 attrs[0].Value.cbData = 0;
896 attrs[0].Value.pbData = (BYTE *)commonNameW;
897 attrs[1].pszObjId = oid_sur_name;
898 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
899 attrs[1].Value.cbData = 0;
900 attrs[1].Value.pbData = (BYTE *)surNameW;
902 rdn.rgRDNAttr = attrs;
905 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
906 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
907 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
910 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
911 "Got unexpected encoding for two RDN array\n");
914 /* A name can be "encoded" with previously encoded RDN attrs. */
915 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
916 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
917 attrs[0].Value.cbData = sizeof(twoRDNs);
919 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
920 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
921 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
924 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
925 ok(!memcmp(buf, encodedTwoRDNs, size),
926 "Unexpected value for re-endoded two RDN array\n");
929 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
931 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
932 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
933 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
934 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
937 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
938 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
943 static void compareNameValues(const CERT_NAME_VALUE *expected,
944 const CERT_NAME_VALUE *got)
946 ok(got->dwValueType == expected->dwValueType,
947 "Expected string type %d, got %d\n", expected->dwValueType,
949 ok(got->Value.cbData == expected->Value.cbData,
950 "String type %d: unexpected data size, got %d, expected %d\n",
951 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
952 if (got->Value.cbData && got->Value.pbData)
953 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
954 min(got->Value.cbData, expected->Value.cbData)),
955 "String type %d: unexpected value\n", expected->dwValueType);
958 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
959 const CERT_RDN_ATTR *got)
961 if (expected->pszObjId && strlen(expected->pszObjId))
963 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
967 ok(!strcmp(got->pszObjId, expected->pszObjId),
968 "Got unexpected OID %s, expected %s\n", got->pszObjId,
972 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
973 (const CERT_NAME_VALUE *)&got->dwValueType);
976 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
978 ok(got->cRDNAttr == expected->cRDNAttr,
979 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
984 for (i = 0; i < got->cRDNAttr; i++)
985 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
989 static void compareNames(const CERT_NAME_INFO *expected,
990 const CERT_NAME_INFO *got)
992 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
993 expected->cRDN, got->cRDN);
998 for (i = 0; i < got->cRDN; i++)
999 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1003 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1004 static const BYTE twoRDNsExtraBytes[] = {
1005 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1006 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1007 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1009 static void test_decodeName(DWORD dwEncoding)
1015 CERT_NAME_INFO info = { 1, &rdn };
1017 /* test empty name */
1019 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1020 emptySequence[1] + 2,
1021 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1022 (BYTE *)&buf, &bufSize);
1023 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1024 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1025 * decoder works the same way, so only test the count.
1029 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1030 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1031 "Expected 0 RDNs in empty info, got %d\n",
1032 ((CERT_NAME_INFO *)buf)->cRDN);
1035 /* test empty name with indefinite-length encoding */
1036 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1037 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1038 (BYTE *)&buf, &bufSize);
1039 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1042 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1043 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1044 "Expected 0 RDNs in empty info, got %d\n",
1045 ((CERT_NAME_INFO *)buf)->cRDN);
1048 /* test empty RDN */
1050 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1052 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1053 (BYTE *)&buf, &bufSize);
1054 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1057 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1059 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1060 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1061 "Got unexpected value for empty RDN\n");
1064 /* test two RDN attrs */
1066 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1068 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1069 (BYTE *)&buf, &bufSize);
1070 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1073 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1074 oid_common_name[] = szOID_COMMON_NAME;
1076 CERT_RDN_ATTR attrs[] = {
1077 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1078 (BYTE *)surName } },
1079 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1080 (BYTE *)commonName } },
1083 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1084 rdn.rgRDNAttr = attrs;
1085 compareNames(&info, (CERT_NAME_INFO *)buf);
1088 /* test that two RDN attrs with extra bytes succeeds */
1090 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1091 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1092 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1093 /* And, a slightly more complicated name */
1096 ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1097 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1098 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1101 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1102 rdn.rgRDNAttr = (PCERT_RDN_ATTR)decodedRdnAttrs;
1103 compareNames(&info, (CERT_NAME_INFO *)buf);
1108 static void test_decodeUnicodeName(DWORD dwEncoding)
1114 CERT_NAME_INFO info = { 1, &rdn };
1116 /* test empty name */
1118 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1119 emptySequence[1] + 2,
1120 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1121 (BYTE *)&buf, &bufSize);
1122 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1125 ok(bufSize == sizeof(CERT_NAME_INFO),
1126 "Got wrong bufSize %d\n", bufSize);
1127 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1128 "Expected 0 RDNs in empty info, got %d\n",
1129 ((CERT_NAME_INFO *)buf)->cRDN);
1132 /* test empty RDN */
1134 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1136 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1137 (BYTE *)&buf, &bufSize);
1138 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1141 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1143 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1144 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1145 "Got unexpected value for empty RDN\n");
1148 /* test two RDN attrs */
1150 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1151 sizeof(twoRDNsNoNull),
1152 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1153 (BYTE *)&buf, &bufSize);
1154 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1157 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1158 oid_common_name[] = szOID_COMMON_NAME;
1160 CERT_RDN_ATTR attrs[] = {
1161 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1162 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1163 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1164 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1167 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1168 rdn.rgRDNAttr = attrs;
1169 compareNames(&info, (CERT_NAME_INFO *)buf);
1174 struct EncodedNameValue
1176 CERT_NAME_VALUE value;
1177 const BYTE *encoded;
1181 static const char bogusIA5[] = "\x80";
1182 static const char bogusPrintable[] = "~";
1183 static const char bogusNumeric[] = "A";
1184 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1185 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1186 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1187 static BYTE octetCommonNameValue[] = {
1188 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1189 static BYTE numericCommonNameValue[] = {
1190 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1191 static BYTE printableCommonNameValue[] = {
1192 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1193 static BYTE t61CommonNameValue[] = {
1194 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1195 static BYTE videotexCommonNameValue[] = {
1196 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1197 static BYTE ia5CommonNameValue[] = {
1198 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1199 static BYTE graphicCommonNameValue[] = {
1200 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1201 static BYTE visibleCommonNameValue[] = {
1202 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1203 static BYTE generalCommonNameValue[] = {
1204 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1205 static BYTE bmpCommonNameValue[] = {
1206 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1207 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1208 static BYTE utf8CommonNameValue[] = {
1209 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1211 static struct EncodedNameValue nameValues[] = {
1212 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1213 octetCommonNameValue, sizeof(octetCommonNameValue) },
1214 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1215 numericCommonNameValue, sizeof(numericCommonNameValue) },
1216 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1217 printableCommonNameValue, sizeof(printableCommonNameValue) },
1218 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1219 t61CommonNameValue, sizeof(t61CommonNameValue) },
1220 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1221 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1222 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1223 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1224 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1225 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1226 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1227 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1228 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1229 generalCommonNameValue, sizeof(generalCommonNameValue) },
1230 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1231 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1232 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1233 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1234 /* The following tests succeed under Windows, but really should fail,
1235 * they contain characters that are illegal for the encoding. I'm
1236 * including them to justify my lazy encoding.
1238 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1240 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1241 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1242 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1243 bin44, sizeof(bin44) },
1246 static void test_encodeNameValue(DWORD dwEncoding)
1251 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1253 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1254 value.Value.pbData = printableCommonNameValue;
1255 value.Value.cbData = sizeof(printableCommonNameValue);
1256 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1257 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1258 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1261 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1263 ok(!memcmp(buf, printableCommonNameValue, size),
1264 "Unexpected encoding\n");
1267 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1269 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1270 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1272 ok(ret, "Type %d: CryptEncodeObjectEx failed: %08x\n",
1273 nameValues[i].value.dwValueType, GetLastError());
1276 ok(size == nameValues[i].encodedSize,
1277 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1278 ok(!memcmp(buf, nameValues[i].encoded, size),
1279 "Got unexpected encoding\n");
1285 static void test_decodeNameValue(DWORD dwEncoding)
1292 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1294 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1295 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1296 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1297 (BYTE *)&buf, &bufSize);
1298 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1299 nameValues[i].value.dwValueType, GetLastError());
1302 compareNameValues(&nameValues[i].value,
1303 (const CERT_NAME_VALUE *)buf);
1309 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1310 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1311 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1312 'h','q','.','o','r','g',0 };
1313 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1314 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1316 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1318 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1319 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1320 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1321 static const BYTE localhost[] = { 127, 0, 0, 1 };
1322 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1324 static const unsigned char encodedCommonName[] = {
1325 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1326 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1327 static const BYTE encodedDirectoryName[] = {
1328 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1329 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1331 static void test_encodeAltName(DWORD dwEncoding)
1333 CERT_ALT_NAME_INFO info = { 0 };
1334 CERT_ALT_NAME_ENTRY entry = { 0 };
1338 char oid[] = "1.2.3";
1340 /* Test with empty info */
1341 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1342 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1345 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1346 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1349 /* Test with an empty entry */
1351 info.rgAltEntry = &entry;
1352 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1353 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1354 ok(!ret && GetLastError() == E_INVALIDARG,
1355 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1356 /* Test with an empty pointer */
1357 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1358 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1359 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1362 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1363 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1366 /* Test with a real URL */
1367 U(entry).pwszURL = (LPWSTR)url;
1368 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1369 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1372 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1373 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1376 /* Now with the URL containing an invalid IA5 char */
1377 U(entry).pwszURL = (LPWSTR)nihongoURL;
1378 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1379 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1380 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1381 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1382 /* The first invalid character is at index 7 */
1383 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1384 "Expected invalid char at index 7, got %d\n",
1385 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1386 /* Now with the URL missing a scheme */
1387 U(entry).pwszURL = (LPWSTR)dnsName;
1388 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1389 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1390 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1393 /* This succeeds, but it shouldn't, so don't worry about conforming */
1396 /* Now with a DNS name */
1397 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1398 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1399 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1400 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1403 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1404 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1407 /* Test with an IP address */
1408 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1409 U(entry).IPAddress.cbData = sizeof(localhost);
1410 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1411 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1412 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1415 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1416 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1420 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1421 U(entry).pszRegisteredID = oid;
1422 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1423 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1426 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1427 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1430 /* Test with directory name */
1431 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1432 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1433 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1434 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1435 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1438 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1439 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1444 static void test_decodeAltName(DWORD dwEncoding)
1446 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1448 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1453 CERT_ALT_NAME_INFO *info;
1455 /* Test some bogus ones first */
1456 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1457 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1458 NULL, (BYTE *)&buf, &bufSize);
1459 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1460 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
1461 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1462 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1464 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
1465 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
1466 /* Now expected cases */
1467 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1468 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1470 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1473 info = (CERT_ALT_NAME_INFO *)buf;
1475 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1479 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1480 emptyURL[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 == 1, "Expected 1 entries, got %d\n",
1489 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1490 "Expected CERT_ALT_NAME_URL, got %d\n",
1491 info->rgAltEntry[0].dwAltNameChoice);
1492 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1493 "Expected empty URL\n");
1496 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1497 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1498 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1499 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1500 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1502 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1505 info = (CERT_ALT_NAME_INFO *)buf;
1507 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1509 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1510 "Expected CERT_ALT_NAME_URL, got %d\n",
1511 info->rgAltEntry[0].dwAltNameChoice);
1512 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1515 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1516 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1518 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1521 info = (CERT_ALT_NAME_INFO *)buf;
1523 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1525 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1526 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1527 info->rgAltEntry[0].dwAltNameChoice);
1528 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1529 "Unexpected DNS name\n");
1532 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1533 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1535 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1538 info = (CERT_ALT_NAME_INFO *)buf;
1540 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1542 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1543 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1544 info->rgAltEntry[0].dwAltNameChoice);
1545 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1546 "Unexpected IP address length %d\n",
1547 U(info->rgAltEntry[0]).IPAddress.cbData);
1548 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1549 sizeof(localhost)), "Unexpected IP address value\n");
1552 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1553 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1555 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1558 info = (CERT_ALT_NAME_INFO *)buf;
1560 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1562 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1563 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1564 info->rgAltEntry[0].dwAltNameChoice);
1565 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1566 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1569 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1570 encodedDirectoryName, sizeof(encodedDirectoryName),
1571 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1572 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1575 info = (CERT_ALT_NAME_INFO *)buf;
1577 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1579 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1580 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1581 info->rgAltEntry[0].dwAltNameChoice);
1582 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1583 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1584 U(info->rgAltEntry[0]).DirectoryName.cbData);
1585 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1586 encodedCommonName, sizeof(encodedCommonName)),
1587 "Unexpected directory name value\n");
1592 struct UnicodeExpectedError
1600 static const WCHAR oneW[] = { '1',0 };
1601 static const WCHAR aW[] = { 'a',0 };
1602 static const WCHAR quoteW[] = { '"', 0 };
1604 static struct UnicodeExpectedError unicodeErrors[] = {
1605 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1606 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1607 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1608 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1609 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1610 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1613 struct UnicodeExpectedResult
1617 CRYPT_DATA_BLOB encoded;
1620 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1621 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1622 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1623 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1624 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1625 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1626 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1627 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1628 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1629 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1630 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1631 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1633 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1635 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1636 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1637 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1638 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1640 static struct UnicodeExpectedResult unicodeResults[] = {
1641 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1642 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1643 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1644 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1645 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1646 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1647 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1648 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1649 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1650 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1651 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1652 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1653 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1656 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1657 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1658 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1661 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1666 CERT_NAME_VALUE value;
1668 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1669 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1670 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1671 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1672 /* Have to have a string of some sort */
1673 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1674 value.Value.pbData = NULL;
1675 value.Value.cbData = 0;
1676 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1677 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1678 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1679 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1680 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1681 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1682 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1683 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1684 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1685 value.dwValueType = CERT_RDN_ANY_TYPE;
1686 value.Value.pbData = (LPBYTE)oneW;
1687 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1688 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1689 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1690 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1691 value.Value.cbData = sizeof(oneW);
1692 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1693 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1694 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1695 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1696 /* An encoded string with specified length isn't good enough either */
1697 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1698 value.Value.pbData = oneUniversal;
1699 value.Value.cbData = sizeof(oneUniversal);
1700 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1701 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1702 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1703 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1704 /* More failure checking */
1705 value.Value.cbData = 0;
1706 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1708 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1709 value.dwValueType = unicodeErrors[i].valueType;
1710 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1711 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1712 ok(!ret && GetLastError() == unicodeErrors[i].error,
1713 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1714 unicodeErrors[i].error, GetLastError());
1715 ok(size == unicodeErrors[i].errorIndex,
1716 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1719 /* cbData can be zero if the string is NULL-terminated */
1720 value.Value.cbData = 0;
1721 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1723 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1724 value.dwValueType = unicodeResults[i].valueType;
1725 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1726 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1727 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1730 ok(size == unicodeResults[i].encoded.cbData,
1731 "Value type %d: expected size %d, got %d\n",
1732 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1733 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1734 "Value type %d: unexpected value\n", value.dwValueType);
1738 /* These "encode," but they do so by truncating each unicode character
1739 * rather than properly encoding it. Kept separate from the proper results,
1740 * because the encoded forms won't decode to their original strings.
1742 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1744 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1745 value.dwValueType = unicodeWeirdness[i].valueType;
1746 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1747 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1748 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1751 ok(size == unicodeWeirdness[i].encoded.cbData,
1752 "Value type %d: expected size %d, got %d\n",
1753 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1754 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1755 "Value type %d: unexpected value\n", value.dwValueType);
1761 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1763 if (n <= 0) return 0;
1764 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1765 return *str1 - *str2;
1768 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1772 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1778 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1779 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1780 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1781 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1784 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1786 ok(value->dwValueType == unicodeResults[i].valueType,
1787 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1788 value->dwValueType);
1789 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1790 value->Value.cbData / sizeof(WCHAR)),
1791 "Unexpected decoded value for index %d (value type %d)\n", i,
1792 unicodeResults[i].valueType);
1798 struct encodedOctets
1801 const BYTE *encoded;
1804 static const unsigned char bin46[] = { 'h','i',0 };
1805 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1806 static const unsigned char bin48[] = {
1807 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1808 static const unsigned char bin49[] = {
1809 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1810 static const unsigned char bin50[] = { 0 };
1811 static const unsigned char bin51[] = { 0x04,0x00,0 };
1813 static const struct encodedOctets octets[] = {
1819 static void test_encodeOctets(DWORD dwEncoding)
1821 CRYPT_DATA_BLOB blob;
1824 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1830 blob.cbData = strlen((const char*)octets[i].val);
1831 blob.pbData = (BYTE*)octets[i].val;
1832 ret = CryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1833 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1834 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1838 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1839 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1840 buf[1], octets[i].encoded[1]);
1841 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1842 octets[i].encoded[1] + 1), "Got unexpected value\n");
1848 static void test_decodeOctets(DWORD dwEncoding)
1852 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1858 ret = CryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1859 (BYTE *)octets[i].encoded, octets[i].encoded[1] + 2,
1860 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1861 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1862 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1863 "Expected size >= %d, got %d\n",
1864 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1865 ok(buf != NULL, "Expected allocated buffer\n");
1868 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
1871 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
1872 "Unexpected value\n");
1878 static const BYTE bytesToEncode[] = { 0xff, 0xff };
1883 const BYTE *encoded;
1885 const BYTE *decoded;
1888 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
1889 static const unsigned char bin53[] = { 0xff,0xff };
1890 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
1891 static const unsigned char bin55[] = { 0xff,0xfe };
1892 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
1893 static const unsigned char bin57[] = { 0xfe };
1894 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
1896 static const struct encodedBits bits[] = {
1897 /* normal test cases */
1898 { 0, bin52, 2, bin53 },
1899 { 1, bin54, 2, bin55 },
1900 /* strange test case, showing cUnusedBits >= 8 is allowed */
1901 { 9, bin56, 1, bin57 },
1902 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1903 { 17, bin58, 0, NULL },
1906 static void test_encodeBits(DWORD dwEncoding)
1910 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1912 CRYPT_BIT_BLOB blob;
1917 blob.cbData = sizeof(bytesToEncode);
1918 blob.pbData = (BYTE *)bytesToEncode;
1919 blob.cUnusedBits = bits[i].cUnusedBits;
1920 ret = CryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
1921 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1922 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1925 ok(bufSize == bits[i].encoded[1] + 2,
1926 "Got unexpected size %d, expected %d\n", bufSize,
1927 bits[i].encoded[1] + 2);
1928 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
1929 "Unexpected value\n");
1935 static void test_decodeBits(DWORD dwEncoding)
1937 static const BYTE ber[] = "\x03\x02\x01\xff";
1938 static const BYTE berDecoded = 0xfe;
1945 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1947 ret = CryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
1948 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1950 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1953 CRYPT_BIT_BLOB *blob;
1955 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
1956 "Got unexpected size %d\n", bufSize);
1957 blob = (CRYPT_BIT_BLOB *)buf;
1958 ok(blob->cbData == bits[i].cbDecoded,
1959 "Got unexpected length %d, expected %d\n", blob->cbData,
1961 if (blob->cbData && bits[i].cbDecoded)
1962 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
1963 "Unexpected value\n");
1967 /* special case: check that something that's valid in BER but not in DER
1968 * decodes successfully
1970 ret = CryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
1971 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1972 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1975 CRYPT_BIT_BLOB *blob;
1977 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
1978 "Got unexpected size %d\n", bufSize);
1979 blob = (CRYPT_BIT_BLOB *)buf;
1980 ok(blob->cbData == sizeof(berDecoded),
1981 "Got unexpected length %d\n", blob->cbData);
1983 ok(*blob->pbData == berDecoded, "Unexpected value\n");
1990 CERT_BASIC_CONSTRAINTS2_INFO info;
1991 const BYTE *encoded;
1994 static const unsigned char bin59[] = { 0x30,0x00 };
1995 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
1996 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
1997 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1998 static const struct Constraints2 constraints2[] = {
1999 /* empty constraints */
2000 { { FALSE, FALSE, 0}, bin59 },
2002 { { TRUE, FALSE, 0}, bin60 },
2003 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2004 * but that's not the case
2006 { { FALSE, TRUE, 0}, bin61 },
2007 /* can be a CA and has path length constraints set */
2008 { { TRUE, TRUE, 1}, bin62 },
2011 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2012 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2013 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2014 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2015 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2016 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2017 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2018 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2019 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2020 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2022 static void test_encodeBasicConstraints(DWORD dwEncoding)
2024 DWORD i, bufSize = 0;
2025 CERT_BASIC_CONSTRAINTS_INFO info;
2026 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2027 (LPBYTE)encodedDomainName };
2031 /* First test with the simpler info2 */
2032 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2034 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2035 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2037 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2040 ok(bufSize == constraints2[i].encoded[1] + 2,
2041 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2043 ok(!memcmp(buf, constraints2[i].encoded,
2044 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2048 /* Now test with more complex basic constraints */
2049 info.SubjectType.cbData = 0;
2050 info.fPathLenConstraint = FALSE;
2051 info.cSubtreesConstraint = 0;
2052 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2053 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2054 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2057 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2058 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2059 "Unexpected value\n");
2062 /* None of the certs I examined had any subtree constraint, but I test one
2063 * anyway just in case.
2065 info.cSubtreesConstraint = 1;
2066 info.rgSubtreesConstraint = &nameBlob;
2067 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2068 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2069 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2072 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2073 ok(!memcmp(buf, constraintWithDomainName,
2074 sizeof(constraintWithDomainName)), "Unexpected value\n");
2077 /* FIXME: test encoding with subject type. */
2080 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2082 static void test_decodeBasicConstraints(DWORD dwEncoding)
2084 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2086 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2092 /* First test with simpler info2 */
2093 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2095 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2096 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2097 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2098 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2102 CERT_BASIC_CONSTRAINTS2_INFO *info =
2103 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2105 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2106 "Unexpected value for item %d\n", i);
2110 /* Check with the order of encoded elements inverted */
2112 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2113 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2115 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2116 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2117 ok(!buf, "Expected buf to be set to NULL\n");
2118 /* Check with a non-DER bool */
2119 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2120 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2121 (BYTE *)&buf, &bufSize);
2122 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2125 CERT_BASIC_CONSTRAINTS2_INFO *info =
2126 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2128 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2131 /* Check with a non-basic constraints value */
2132 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2133 (LPBYTE)encodedCommonName, encodedCommonName[1] + 2,
2134 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2135 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2136 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2137 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2138 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2139 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2140 (BYTE *)&buf, &bufSize);
2141 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2144 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2146 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2147 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2148 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2151 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2152 constraintWithDomainName, sizeof(constraintWithDomainName),
2153 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2154 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2157 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2159 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2160 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2161 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2162 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2164 ok(info->rgSubtreesConstraint[0].cbData ==
2165 sizeof(encodedDomainName), "Wrong size %d\n",
2166 info->rgSubtreesConstraint[0].cbData);
2167 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2168 sizeof(encodedDomainName)), "Unexpected value\n");
2174 /* These are terrible public keys of course, I'm just testing encoding */
2175 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2176 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2177 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2178 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2179 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2180 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2181 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2182 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2184 struct EncodedRSAPubKey
2186 const BYTE *modulus;
2188 const BYTE *encoded;
2189 size_t decodedModulusLen;
2192 struct EncodedRSAPubKey rsaPubKeys[] = {
2193 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2194 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2195 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2196 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2199 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2201 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2202 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2203 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2206 DWORD bufSize = 0, i;
2208 /* Try with a bogus blob type */
2210 hdr->bVersion = CUR_BLOB_VERSION;
2212 hdr->aiKeyAlg = CALG_RSA_KEYX;
2213 rsaPubKey->magic = 0x31415352;
2214 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2215 rsaPubKey->pubexp = 65537;
2216 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2219 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2220 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2222 ok(!ret && GetLastError() == E_INVALIDARG,
2223 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2224 /* Now with a bogus reserved field */
2225 hdr->bType = PUBLICKEYBLOB;
2227 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2228 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2232 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2233 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2234 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2237 /* Now with a bogus blob version */
2240 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2241 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2245 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2246 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2247 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2250 /* And with a bogus alg ID */
2251 hdr->bVersion = CUR_BLOB_VERSION;
2252 hdr->aiKeyAlg = CALG_DES;
2253 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2254 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2258 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2259 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2260 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2263 /* Check a couple of RSA-related OIDs */
2264 hdr->aiKeyAlg = CALG_RSA_KEYX;
2265 ret = CryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2266 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2267 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2268 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2269 ret = CryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2270 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2271 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2272 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2273 /* Finally, all valid */
2274 hdr->aiKeyAlg = CALG_RSA_KEYX;
2275 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2277 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2278 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2279 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2280 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2281 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2284 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2285 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2287 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2288 "Unexpected value\n");
2294 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2301 /* Try with a bad length */
2302 ret = CryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2303 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2304 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2305 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2306 "Expected CRYPT_E_ASN1_EOD, got %08x\n", CRYPT_E_ASN1_EOD);
2307 /* Try with a couple of RSA-related OIDs */
2308 ret = CryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2309 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2310 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2311 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2312 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2313 ret = CryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2314 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2315 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2316 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2317 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2318 /* Now try success cases */
2319 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2322 ret = CryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2323 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2324 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2325 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2328 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2329 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2331 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2332 rsaPubKeys[i].decodedModulusLen,
2333 "Wrong size %d\n", bufSize);
2334 ok(hdr->bType == PUBLICKEYBLOB,
2335 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2337 ok(hdr->bVersion == CUR_BLOB_VERSION,
2338 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2339 CUR_BLOB_VERSION, hdr->bVersion);
2340 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2342 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2343 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2344 ok(rsaPubKey->magic == 0x31415352,
2345 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2346 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2347 "Wrong bit len %d\n", rsaPubKey->bitlen);
2348 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2350 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2351 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2352 "Unexpected modulus\n");
2358 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2359 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2360 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2362 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2363 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2364 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2365 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2367 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2369 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2370 CRYPT_SEQUENCE_OF_ANY seq;
2376 /* Encode a homogenous sequence */
2377 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2379 blobs[i].cbData = ints[i].encoded[1] + 2;
2380 blobs[i].pbData = (BYTE *)ints[i].encoded;
2382 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2383 seq.rgValue = blobs;
2385 ret = CryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2386 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2387 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2390 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2391 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2394 /* Change the type of the first element in the sequence, and give it
2397 blobs[0].cbData = times[0].encodedTime[1] + 2;
2398 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2399 ret = CryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2400 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2401 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2404 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2405 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2406 "Unexpected value\n");
2411 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2417 ret = CryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2418 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2419 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2422 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2425 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2426 "Wrong elements %d\n", seq->cValue);
2427 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2429 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2430 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2431 seq->rgValue[i].cbData);
2432 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2433 ints[i].encoded[1] + 2), "Unexpected value\n");
2437 ret = CryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2438 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2440 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2443 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2445 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2446 "Wrong elements %d\n", seq->cValue);
2447 /* Just check the first element since it's all that changed */
2448 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2449 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2450 seq->rgValue[0].cbData);
2451 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2452 times[0].encodedTime[1] + 2), "Unexpected value\n");
2457 struct encodedExtensions
2459 CERT_EXTENSIONS exts;
2460 const BYTE *encoded;
2463 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2464 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2465 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2466 static CERT_EXTENSION criticalExt =
2467 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2468 static CERT_EXTENSION nonCriticalExt =
2469 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2471 static const BYTE ext0[] = { 0x30,0x00 };
2472 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2473 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2474 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2475 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2477 static const struct encodedExtensions exts[] = {
2478 { { 0, NULL }, ext0 },
2479 { { 1, &criticalExt }, ext1 },
2480 { { 1, &nonCriticalExt }, ext2 },
2483 static void test_encodeExtensions(DWORD dwEncoding)
2487 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2493 ret = CryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2494 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2495 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2498 ok(bufSize == exts[i].encoded[1] + 2,
2499 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2500 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2501 "Unexpected value\n");
2507 static void test_decodeExtensions(DWORD dwEncoding)
2511 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2517 ret = CryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2518 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2519 NULL, (BYTE *)&buf, &bufSize);
2520 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2523 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2526 ok(ext->cExtension == exts[i].exts.cExtension,
2527 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2529 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2531 ok(!strcmp(ext->rgExtension[j].pszObjId,
2532 exts[i].exts.rgExtension[j].pszObjId),
2533 "Expected OID %s, got %s\n",
2534 exts[i].exts.rgExtension[j].pszObjId,
2535 ext->rgExtension[j].pszObjId);
2536 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2537 exts[i].exts.rgExtension[j].Value.pbData,
2538 exts[i].exts.rgExtension[j].Value.cbData),
2539 "Unexpected value\n");
2546 /* MS encodes public key info with a NULL if the algorithm identifier's
2547 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2548 * it encodes them by omitting the algorithm parameters. This latter approach
2549 * seems more correct, so accept either form.
2551 struct encodedPublicKey
2553 CERT_PUBLIC_KEY_INFO info;
2554 const BYTE *encoded;
2555 const BYTE *encodedNoNull;
2556 CERT_PUBLIC_KEY_INFO decoded;
2559 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2561 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2563 static const unsigned char bin64[] = {
2564 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2565 static const unsigned char bin65[] = {
2566 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2567 static const unsigned char bin66[] = {
2568 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2569 static const unsigned char bin67[] = {
2570 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2571 static const unsigned char bin68[] = {
2572 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2573 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2574 static const unsigned char bin69[] = {
2575 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2576 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2577 static const unsigned char bin70[] = {
2578 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2579 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2581 static const unsigned char bin71[] = {
2582 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2583 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2585 static unsigned char bin72[] = { 0x05,0x00};
2587 static CHAR oid_bogus[] = "1.2.3",
2588 oid_rsa[] = szOID_RSA;
2590 static const struct encodedPublicKey pubKeys[] = {
2591 /* with a bogus OID */
2592 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2594 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2595 /* some normal keys */
2596 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2598 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2599 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2601 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2602 /* with add'l parameters--note they must be DER-encoded */
2603 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2604 (BYTE *)aKey, 0 } },
2606 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2607 (BYTE *)aKey, 0 } } },
2610 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2614 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2620 ret = CryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2621 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2623 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2626 ok(bufSize == pubKeys[i].encoded[1] + 2 ||
2627 bufSize == pubKeys[i].encodedNoNull[1] + 2,
2628 "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
2629 pubKeys[i].encodedNoNull[1] + 2, bufSize);
2630 if (bufSize == pubKeys[i].encoded[1] + 2)
2631 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2632 "Unexpected value\n");
2633 else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
2634 ok(!memcmp(buf, pubKeys[i].encodedNoNull,
2635 pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
2641 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2642 const CERT_PUBLIC_KEY_INFO *got)
2644 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2645 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2646 got->Algorithm.pszObjId);
2647 ok(expected->Algorithm.Parameters.cbData ==
2648 got->Algorithm.Parameters.cbData,
2649 "Expected parameters of %d bytes, got %d\n",
2650 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2651 if (expected->Algorithm.Parameters.cbData)
2652 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2653 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2654 "Unexpected algorithm parameters\n");
2655 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2656 "Expected public key of %d bytes, got %d\n",
2657 expected->PublicKey.cbData, got->PublicKey.cbData);
2658 if (expected->PublicKey.cbData)
2659 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2660 got->PublicKey.cbData), "Unexpected public key value\n");
2663 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2665 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2666 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2667 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2668 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2674 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2676 /* The NULL form decodes to the decoded member */
2677 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2678 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2679 NULL, (BYTE *)&buf, &bufSize);
2680 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2683 comparePublicKeyInfo(&pubKeys[i].decoded,
2684 (CERT_PUBLIC_KEY_INFO *)buf);
2687 /* The non-NULL form decodes to the original */
2688 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2689 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2690 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2691 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2694 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2698 /* Test with bogus (not valid DER) parameters */
2699 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2700 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2701 NULL, (BYTE *)&buf, &bufSize);
2702 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2703 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2706 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2707 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2708 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2709 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2710 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2711 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2712 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2713 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2714 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2715 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2716 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2717 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2718 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2719 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2720 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2721 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2722 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2723 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2724 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2725 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2726 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2727 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2728 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2729 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2730 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2731 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2732 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2733 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2734 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2735 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2736 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2737 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2738 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2739 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2740 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2741 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2742 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2743 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2744 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2745 static const BYTE v1CertWithPubKey[] = {
2746 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2747 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2748 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2749 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2750 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2751 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2752 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2753 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2754 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2755 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2757 static const BYTE v1CertWithPubKeyNoNull[] = {
2758 0x30,0x81,0x93,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,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2765 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2766 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2767 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2768 static const BYTE v1CertWithSubjectKeyId[] = {
2769 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2770 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2771 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2772 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2773 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2774 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2775 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2776 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2777 0x4c,0x61,0x6e,0x67,0x00 };
2779 static const BYTE serialNum[] = { 0x01 };
2781 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2786 CERT_INFO info = { 0 };
2787 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2788 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2791 /* Test with NULL pvStructInfo */
2792 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2793 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2794 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2795 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2796 /* Test with a V1 cert */
2797 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2798 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2799 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2802 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2803 v1Cert[1] + 2, size);
2804 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2808 info.dwVersion = CERT_V2;
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 == sizeof(v2Cert), "Wrong size %d\n", size);
2815 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2819 info.dwVersion = CERT_V3;
2820 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2821 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2822 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2825 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2826 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2829 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2830 * API doesn't prevent it)
2832 info.dwVersion = CERT_V1;
2833 info.cExtension = 1;
2834 info.rgExtension = &criticalExt;
2835 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2836 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2837 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2840 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2841 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2844 /* test v1 cert with a serial number */
2845 info.SerialNumber.cbData = sizeof(serialNum);
2846 info.SerialNumber.pbData = (BYTE *)serialNum;
2847 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2848 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2851 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2852 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2855 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2856 info.Issuer.cbData = sizeof(encodedCommonName);
2857 info.Issuer.pbData = (BYTE *)encodedCommonName;
2858 info.Subject.cbData = sizeof(encodedCommonName);
2859 info.Subject.pbData = (BYTE *)encodedCommonName;
2860 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2861 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2864 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
2865 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
2868 /* Add a public key */
2869 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2870 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2871 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
2872 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2873 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2876 ok(size == sizeof(v1CertWithPubKey) ||
2877 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
2878 if (size == sizeof(v1CertWithPubKey))
2879 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
2880 else if (size == sizeof(v1CertWithPubKeyNoNull))
2881 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
2882 "Got unexpected value\n");
2885 /* Remove the public key, and add a subject key identifier extension */
2886 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2887 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
2888 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
2889 ext.pszObjId = oid_subject_key_identifier;
2890 ext.fCritical = FALSE;
2891 ext.Value.cbData = sizeof(octetCommonNameValue);
2892 ext.Value.pbData = (BYTE *)octetCommonNameValue;
2893 info.cExtension = 1;
2894 info.rgExtension = &ext;
2895 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2896 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2899 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
2900 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
2905 static void test_decodeCertToBeSigned(DWORD dwEncoding)
2907 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
2908 v1CertWithConstraints, v1CertWithSerial };
2913 /* Test with NULL pbEncoded */
2914 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
2915 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2916 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2917 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2918 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
2919 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2920 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2921 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2922 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
2923 * minimum a cert must have a non-zero serial number, an issuer, and a
2926 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
2928 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
2929 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2930 (BYTE *)&buf, &size);
2931 ok(!ret, "Expected failure\n");
2933 /* Now check with serial number, subject and issuer specified */
2934 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
2935 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2936 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2939 CERT_INFO *info = (CERT_INFO *)buf;
2941 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
2942 ok(info->SerialNumber.cbData == 1,
2943 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
2944 ok(*info->SerialNumber.pbData == *serialNum,
2945 "Expected serial number %d, got %d\n", *serialNum,
2946 *info->SerialNumber.pbData);
2947 ok(info->Issuer.cbData == sizeof(encodedCommonName),
2948 "Wrong size %d\n", info->Issuer.cbData);
2949 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
2950 "Unexpected issuer\n");
2951 ok(info->Subject.cbData == sizeof(encodedCommonName),
2952 "Wrong size %d\n", info->Subject.cbData);
2953 ok(!memcmp(info->Subject.pbData, encodedCommonName,
2954 info->Subject.cbData), "Unexpected subject\n");
2957 /* Check again with pub key specified */
2958 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
2959 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
2960 (BYTE *)&buf, &size);
2961 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2964 CERT_INFO *info = (CERT_INFO *)buf;
2966 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
2967 ok(info->SerialNumber.cbData == 1,
2968 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
2969 ok(*info->SerialNumber.pbData == *serialNum,
2970 "Expected serial number %d, got %d\n", *serialNum,
2971 *info->SerialNumber.pbData);
2972 ok(info->Issuer.cbData == sizeof(encodedCommonName),
2973 "Wrong size %d\n", info->Issuer.cbData);
2974 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
2975 "Unexpected issuer\n");
2976 ok(info->Subject.cbData == sizeof(encodedCommonName),
2977 "Wrong size %d\n", info->Subject.cbData);
2978 ok(!memcmp(info->Subject.pbData, encodedCommonName,
2979 info->Subject.cbData), "Unexpected subject\n");
2980 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
2981 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
2982 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
2983 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
2984 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
2985 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
2986 sizeof(aKey)), "Unexpected public key\n");
2991 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2994 static const BYTE signedBigCert[] = {
2995 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
2996 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
2997 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
2998 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2999 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3000 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3001 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3002 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3003 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3004 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3005 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3006 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3008 static void test_encodeCert(DWORD dwEncoding)
3010 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3011 * also that bigCert is a NULL-terminated string, so don't count its
3012 * last byte (otherwise the signed cert won't decode.)
3014 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3015 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3020 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3021 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
3022 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3025 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3026 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3031 static void test_decodeCert(DWORD dwEncoding)
3037 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3038 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3039 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3042 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3044 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3045 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3046 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3047 "Unexpected cert\n");
3048 ok(info->Signature.cbData == sizeof(hash),
3049 "Wrong signature size %d\n", info->Signature.cbData);
3050 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3051 "Unexpected signature\n");
3054 /* A signed cert decodes as a CERT_INFO too */
3055 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3056 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3057 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3060 CERT_INFO *info = (CERT_INFO *)buf;
3062 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3063 ok(info->SerialNumber.cbData == 1,
3064 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3065 ok(*info->SerialNumber.pbData == *serialNum,
3066 "Expected serial number %d, got %d\n", *serialNum,
3067 *info->SerialNumber.pbData);
3068 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3069 "Wrong size %d\n", info->Issuer.cbData);
3070 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3071 "Unexpected issuer\n");
3072 ok(info->Subject.cbData == sizeof(encodedCommonName),
3073 "Wrong size %d\n", info->Subject.cbData);
3074 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3075 info->Subject.cbData), "Unexpected subject\n");
3080 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3081 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3082 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3083 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3084 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3086 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3087 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3088 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3089 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3090 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3091 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3092 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3093 0x2e, 0x6f, 0x72, 0x67 };
3094 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3095 CRL_REASON_AFFILIATION_CHANGED;
3097 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3099 CRL_DIST_POINTS_INFO info = { 0 };
3100 CRL_DIST_POINT point = { { 0 } };
3101 CERT_ALT_NAME_ENTRY entry = { 0 };
3106 /* Test with an empty info */
3107 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3108 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3109 ok(!ret && GetLastError() == E_INVALIDARG,
3110 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3111 /* Test with one empty dist point */
3112 info.cDistPoint = 1;
3113 info.rgDistPoint = &point;
3114 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3115 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3118 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3119 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3122 /* A dist point with an invalid name */
3123 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3124 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3125 U(entry).pwszURL = (LPWSTR)nihongoURL;
3126 U(point.DistPointName).FullName.cAltEntry = 1;
3127 U(point.DistPointName).FullName.rgAltEntry = &entry;
3128 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3129 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3130 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3131 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3132 /* The first invalid character is at index 7 */
3133 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3134 "Expected invalid char at index 7, got %d\n",
3135 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3136 /* A dist point with (just) a valid name */
3137 U(entry).pwszURL = (LPWSTR)url;
3138 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3139 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3142 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3143 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3146 /* A dist point with (just) reason flags */
3147 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3148 point.ReasonFlags.cbData = sizeof(crlReason);
3149 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3150 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3151 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3154 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3155 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3158 /* A dist point with just an issuer */
3159 point.ReasonFlags.cbData = 0;
3160 point.CRLIssuer.cAltEntry = 1;
3161 point.CRLIssuer.rgAltEntry = &entry;
3162 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3163 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3166 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3167 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3170 /* A dist point with both a name and an issuer */
3171 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3172 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3173 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3176 ok(size == sizeof(distPointWithUrlAndIssuer),
3177 "Wrong size %d\n", size);
3178 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3183 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3188 PCRL_DIST_POINTS_INFO info;
3189 PCRL_DIST_POINT point;
3190 PCERT_ALT_NAME_ENTRY entry;
3192 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3193 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3194 (BYTE *)&buf, &size);
3197 info = (PCRL_DIST_POINTS_INFO)buf;
3198 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3199 "Wrong size %d\n", size);
3200 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3202 point = info->rgDistPoint;
3203 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3204 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3205 point->DistPointName.dwDistPointNameChoice);
3206 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3207 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3210 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3211 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3212 (BYTE *)&buf, &size);
3215 info = (PCRL_DIST_POINTS_INFO)buf;
3216 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3217 "Wrong size %d\n", size);
3218 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3220 point = info->rgDistPoint;
3221 ok(point->DistPointName.dwDistPointNameChoice ==
3222 CRL_DIST_POINT_FULL_NAME,
3223 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3224 point->DistPointName.dwDistPointNameChoice);
3225 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3226 "Expected 1 name entry, got %d\n",
3227 U(point->DistPointName).FullName.cAltEntry);
3228 entry = U(point->DistPointName).FullName.rgAltEntry;
3229 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3230 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3231 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3232 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3233 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3236 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3237 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3238 NULL, (BYTE *)&buf, &size);
3241 info = (PCRL_DIST_POINTS_INFO)buf;
3242 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3243 "Wrong size %d\n", size);
3244 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3246 point = info->rgDistPoint;
3247 ok(point->DistPointName.dwDistPointNameChoice ==
3248 CRL_DIST_POINT_NO_NAME,
3249 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3250 point->DistPointName.dwDistPointNameChoice);
3251 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3252 "Expected reason length\n");
3253 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3254 "Unexpected reason\n");
3255 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3258 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3259 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3260 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3263 info = (PCRL_DIST_POINTS_INFO)buf;
3264 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3265 "Wrong size %d\n", size);
3266 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3268 point = info->rgDistPoint;
3269 ok(point->DistPointName.dwDistPointNameChoice ==
3270 CRL_DIST_POINT_FULL_NAME,
3271 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3272 point->DistPointName.dwDistPointNameChoice);
3273 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3274 "Expected 1 name entry, got %d\n",
3275 U(point->DistPointName).FullName.cAltEntry);
3276 entry = U(point->DistPointName).FullName.rgAltEntry;
3277 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3278 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3279 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3280 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3281 ok(point->CRLIssuer.cAltEntry == 1,
3282 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3283 entry = point->CRLIssuer.rgAltEntry;
3284 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3285 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3286 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3291 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3292 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3293 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3294 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3297 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3302 CRL_ISSUING_DIST_POINT point = { { 0 } };
3303 CERT_ALT_NAME_ENTRY entry;
3305 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3306 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3307 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3309 skip("no X509_ISSUING_DIST_POINT encode support\n");
3312 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3313 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3314 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3315 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3316 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3319 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3320 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3323 /* nonsensical flags */
3324 point.fOnlyContainsUserCerts = TRUE;
3325 point.fOnlyContainsCACerts = TRUE;
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(badFlagsIDP), "Unexpected size %d\n", size);
3332 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3335 /* unimplemented name type */
3336 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3337 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3338 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3339 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3340 ok(!ret && GetLastError() == E_INVALIDARG,
3341 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3343 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3344 U(point.DistPointName).FullName.cAltEntry = 0;
3345 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3346 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3347 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3350 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3351 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3354 /* name with URL entry */
3355 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3356 U(entry).pwszURL = (LPWSTR)url;
3357 U(point.DistPointName).FullName.cAltEntry = 1;
3358 U(point.DistPointName).FullName.rgAltEntry = &entry;
3359 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3360 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3361 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3364 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3365 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3370 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3371 const CERT_ALT_NAME_ENTRY *got)
3373 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3374 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3375 got->dwAltNameChoice);
3376 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3378 switch (got->dwAltNameChoice)
3380 case CERT_ALT_NAME_RFC822_NAME:
3381 case CERT_ALT_NAME_DNS_NAME:
3382 case CERT_ALT_NAME_EDI_PARTY_NAME:
3383 case CERT_ALT_NAME_URL:
3384 case CERT_ALT_NAME_REGISTERED_ID:
3385 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3386 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL), "Unexpected name\n");
3388 case CERT_ALT_NAME_X400_ADDRESS:
3389 case CERT_ALT_NAME_DIRECTORY_NAME:
3390 case CERT_ALT_NAME_IP_ADDRESS:
3391 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3392 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3393 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3394 U(*got).IPAddress.cbData), "Unexpected value\n");
3400 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3401 const CERT_ALT_NAME_INFO *got)
3405 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3406 expected->cAltEntry, got->cAltEntry);
3407 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3408 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3411 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3412 const CRL_DIST_POINT_NAME *got)
3414 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3415 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3416 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3417 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3420 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3421 const CRL_ISSUING_DIST_POINT *got)
3423 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3424 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3425 "Unexpected fOnlyContainsUserCerts\n");
3426 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3427 "Unexpected fOnlyContainsCACerts\n");
3428 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3429 "Unexpected reason flags\n");
3430 ok(got->fIndirectCRL == expected->fIndirectCRL,
3431 "Unexpected fIndirectCRL\n");
3434 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3439 CRL_ISSUING_DIST_POINT point = { { 0 } };
3441 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3442 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3443 (BYTE *)&buf, &size);
3444 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3446 skip("no X509_ISSUING_DIST_POINT decode support\n");
3449 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3452 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3455 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3456 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3457 (BYTE *)&buf, &size);
3458 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3461 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3462 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3465 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3466 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3467 (BYTE *)&buf, &size);
3468 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3471 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3472 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3473 U(point.DistPointName).FullName.cAltEntry = 0;
3474 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3477 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3478 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3479 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3482 CERT_ALT_NAME_ENTRY entry;
3484 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3485 U(entry).pwszURL = (LPWSTR)url;
3486 U(point.DistPointName).FullName.cAltEntry = 1;
3487 U(point.DistPointName).FullName.rgAltEntry = &entry;
3488 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3493 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3494 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3496 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3497 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3498 0x30, 0x30, 0x30, 0x30, 0x5a };
3499 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3500 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3501 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3502 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3504 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3505 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3506 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3507 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3508 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3509 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3510 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3511 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3512 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3513 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3514 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3515 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3516 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3517 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3518 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3519 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3520 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3521 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3522 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3523 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3524 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3525 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3526 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3527 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3528 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3529 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3530 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3531 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3532 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3533 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3534 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3535 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3536 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3537 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3538 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3539 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3540 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3541 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3542 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3543 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3545 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3549 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3551 CRL_INFO info = { 0 };
3552 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3555 /* Test with a V1 CRL */
3556 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3557 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3558 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3561 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3562 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3566 info.dwVersion = CRL_V2;
3567 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3568 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3569 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3572 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3573 v2CRL[1] + 2, size);
3574 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3577 /* v1 CRL with a name */
3578 info.dwVersion = CRL_V1;
3579 info.Issuer.cbData = sizeof(encodedCommonName);
3580 info.Issuer.pbData = (BYTE *)encodedCommonName;
3581 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3582 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3583 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3586 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3587 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3590 /* v1 CRL with a name and a NULL entry pointer */
3592 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3593 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3594 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3595 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3596 /* now set an empty entry */
3597 info.rgCRLEntry = &entry;
3598 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3599 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3602 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3603 "Wrong size %d\n", size);
3604 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3605 "Got unexpected value\n");
3608 /* an entry with a serial number */
3609 entry.SerialNumber.cbData = sizeof(serialNum);
3610 entry.SerialNumber.pbData = (BYTE *)serialNum;
3611 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3612 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3615 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3616 "Wrong size %d\n", size);
3617 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3618 "Got unexpected value\n");
3621 /* an entry with an extension */
3622 entry.cExtension = 1;
3623 entry.rgExtension = &criticalExt;
3624 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3625 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3626 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3629 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3630 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3633 /* a CRL with an extension */
3634 entry.cExtension = 0;
3635 info.cExtension = 1;
3636 info.rgExtension = &criticalExt;
3637 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3638 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3639 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3642 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3643 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3646 /* a v2 CRL with an extension, this time non-critical */
3647 info.dwVersion = CRL_V2;
3648 info.rgExtension = &nonCriticalExt;
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(v2CRLWithExt), "Wrong size %d\n", size);
3655 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3658 /* a v2 CRL with an issuing dist point extension */
3659 ext.pszObjId = oid_issuing_dist_point;
3660 ext.fCritical = TRUE;
3661 ext.Value.cbData = sizeof(urlIDP);
3662 ext.Value.pbData = (LPBYTE)urlIDP;
3663 entry.rgExtension = &ext;
3664 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3665 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3666 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3669 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3670 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3675 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3676 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3677 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3678 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3679 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3680 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3681 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3682 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3683 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3684 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3685 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3686 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3687 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3688 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3689 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3690 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3691 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3692 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3693 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3694 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3695 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3696 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3697 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3698 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3699 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3700 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3701 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3702 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3703 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3704 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3705 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3706 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3707 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3708 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3710 static const BYTE verisignCRLWithLotsOfEntries[] = {
3711 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3712 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3713 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3714 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3715 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3716 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3717 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3718 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3719 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3720 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3721 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3722 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3723 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3724 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3725 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3726 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3727 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3728 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3729 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3730 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3731 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3732 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3733 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3734 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3735 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3736 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3737 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3738 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3739 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3740 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3741 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3742 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3743 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3744 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3745 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3746 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3747 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3748 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3749 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3750 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3751 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3752 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3753 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3754 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3755 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3756 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3757 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3758 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3759 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3760 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3761 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3762 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3763 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3764 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3765 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3766 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3767 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3768 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3769 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3770 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3771 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3772 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3773 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3774 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3775 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3776 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3777 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3778 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3779 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3780 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3781 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3782 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3783 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3784 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3785 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3786 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3787 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3788 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3789 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3790 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3791 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3792 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3793 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3794 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3795 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3796 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3797 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3798 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3799 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3800 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3801 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3802 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3803 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3804 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3805 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3806 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3807 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3808 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3809 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3810 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3811 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3812 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3813 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3814 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3815 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3816 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3817 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3818 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3819 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3820 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3821 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3822 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3823 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3824 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3825 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3826 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3827 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3828 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3829 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3830 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3831 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3832 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3833 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3834 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3835 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3836 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3837 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3838 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3839 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3840 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3841 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3842 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3843 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3844 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3845 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3846 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3847 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3848 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3849 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3850 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3851 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3852 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3853 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3854 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3855 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3856 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3857 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3858 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3859 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3860 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3861 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3862 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3863 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3864 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3865 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3866 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3867 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3868 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3869 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3870 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3871 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3872 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3873 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3874 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3875 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3876 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3877 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3878 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3879 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3880 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3881 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3882 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3883 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3884 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3885 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3886 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3887 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3888 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3889 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3890 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3891 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3892 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
3893 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
3894 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
3895 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
3896 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
3897 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
3898 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
3899 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
3900 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
3901 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
3902 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
3903 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
3904 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
3905 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
3906 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
3907 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
3908 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
3909 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
3910 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
3911 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
3912 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
3913 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
3914 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
3915 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
3916 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
3917 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
3918 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
3919 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
3920 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
3921 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
3922 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
3923 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
3924 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
3925 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
3926 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
3927 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
3928 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
3929 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
3930 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
3931 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
3932 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
3933 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
3934 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
3935 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
3936 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
3937 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
3938 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
3939 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
3940 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
3941 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
3942 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
3943 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
3944 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
3945 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
3946 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
3947 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
3948 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
3949 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
3950 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
3951 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
3952 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
3953 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
3954 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
3955 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
3956 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
3957 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
3958 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
3959 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
3960 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
3961 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
3962 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
3963 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
3964 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
3965 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
3966 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
3967 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
3968 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
3969 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
3970 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
3971 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
3972 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
3973 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
3974 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
3975 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
3976 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
3977 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
3978 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
3979 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
3980 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
3981 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
3982 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
3983 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
3984 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
3985 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
3986 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
3987 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
3988 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
3989 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
3990 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
3991 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
3992 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
3993 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
3994 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
3995 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
3996 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
3997 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
3998 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
3999 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4000 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4001 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4002 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4003 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4004 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4005 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4006 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4007 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4008 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4009 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4010 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4011 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4012 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4013 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4014 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4015 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4016 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4017 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4018 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4019 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4020 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4021 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4022 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4023 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4024 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4025 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4026 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4027 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4028 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4029 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4030 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4031 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4032 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4033 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4034 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4035 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4036 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4037 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4038 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4039 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4040 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4041 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4042 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4043 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4044 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4045 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4046 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4047 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4048 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4049 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4050 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4051 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4052 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4053 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4054 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4055 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4056 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4057 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4058 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4059 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4060 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4061 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4062 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4063 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4064 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4065 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4066 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4067 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4068 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4069 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4070 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4071 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4072 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4073 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4074 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4075 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4076 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4077 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4078 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4079 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4080 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4081 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4082 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4083 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4084 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4085 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4086 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4087 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4088 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4089 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4090 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4091 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4092 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4093 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4094 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4095 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4096 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4097 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4098 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4099 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4100 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4101 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4102 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4103 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4104 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4105 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4106 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4107 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4108 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4109 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4110 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4111 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4112 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4113 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4114 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4115 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4116 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4117 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4118 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4119 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4120 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4121 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4122 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4123 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4124 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4125 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4126 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4127 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4128 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4129 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4130 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4131 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4132 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4133 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4134 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4135 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4136 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4137 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4138 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4139 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4140 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4141 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4142 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4143 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4144 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4145 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4146 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4147 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4148 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4149 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4150 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4151 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4152 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4153 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4154 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4155 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4156 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4157 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4158 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4159 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4160 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4161 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4162 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4163 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4164 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4165 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4166 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4167 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4168 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4169 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4170 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4171 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4172 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4173 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4174 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4175 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4176 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4177 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4178 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4179 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4180 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4181 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4182 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4183 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4184 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4185 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4186 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4187 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4188 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4189 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4190 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4191 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4192 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4193 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4194 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4195 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4196 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4197 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4198 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4199 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4200 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4201 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4202 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4203 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4204 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4205 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4206 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4207 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4208 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4209 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4210 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4211 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4212 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4213 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4214 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4215 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4216 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4217 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4218 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4220 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4222 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4227 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4229 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4230 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4231 (BYTE *)&buf, &size);
4232 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT),
4233 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4235 /* at a minimum, a CRL must contain an issuer: */
4236 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4237 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4238 (BYTE *)&buf, &size);
4239 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4242 CRL_INFO *info = (CRL_INFO *)buf;
4244 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4245 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4247 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4248 "Wrong issuer size %d\n", info->Issuer.cbData);
4249 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4250 "Unexpected issuer\n");
4253 /* check decoding with an empty CRL entry */
4254 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4255 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4256 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4257 todo_wine ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
4258 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4259 /* with a real CRL entry */
4260 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4261 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4262 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4263 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4266 CRL_INFO *info = (CRL_INFO *)buf;
4269 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4270 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4272 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4273 entry = info->rgCRLEntry;
4274 ok(entry->SerialNumber.cbData == 1,
4275 "Expected serial number size 1, got %d\n",
4276 entry->SerialNumber.cbData);
4277 ok(*entry->SerialNumber.pbData == *serialNum,
4278 "Expected serial number %d, got %d\n", *serialNum,
4279 *entry->SerialNumber.pbData);
4280 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4281 "Wrong issuer size %d\n", info->Issuer.cbData);
4282 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4283 "Unexpected issuer\n");
4285 /* a real CRL from verisign that has extensions */
4286 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4287 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4288 NULL, (BYTE *)&buf, &size);
4289 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4292 CRL_INFO *info = (CRL_INFO *)buf;
4295 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4296 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4298 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4299 entry = info->rgCRLEntry;
4300 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4304 /* another real CRL from verisign that has lots of entries */
4305 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4306 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4307 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4308 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4311 CRL_INFO *info = (CRL_INFO *)buf;
4313 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4314 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4316 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4320 /* and finally, with an extension */
4321 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4322 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4323 NULL, (BYTE *)&buf, &size);
4324 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4327 CRL_INFO *info = (CRL_INFO *)buf;
4330 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4331 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4333 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4334 entry = info->rgCRLEntry;
4335 ok(entry->SerialNumber.cbData == 1,
4336 "Expected serial number size 1, got %d\n",
4337 entry->SerialNumber.cbData);
4338 ok(*entry->SerialNumber.pbData == *serialNum,
4339 "Expected serial number %d, got %d\n", *serialNum,
4340 *entry->SerialNumber.pbData);
4341 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4342 "Wrong issuer size %d\n", info->Issuer.cbData);
4343 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4344 "Unexpected issuer\n");
4345 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4348 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4349 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4350 NULL, (BYTE *)&buf, &size);
4351 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4354 CRL_INFO *info = (CRL_INFO *)buf;
4356 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4360 /* And again, with an issuing dist point */
4361 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4362 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4363 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4364 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4367 CRL_INFO *info = (CRL_INFO *)buf;
4369 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4375 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4376 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4377 static const BYTE encodedUsage[] = {
4378 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4379 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4380 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4382 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4387 CERT_ENHKEY_USAGE usage;
4389 /* Test with empty usage */
4390 usage.cUsageIdentifier = 0;
4391 ret = CryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4392 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4393 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4396 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4397 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4400 /* Test with a few usages */
4401 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4402 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
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(encodedUsage), "Wrong size %d\n", size);
4409 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4414 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4420 ret = CryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4421 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4422 (BYTE *)&buf, &size);
4423 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4426 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4428 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4429 "Wrong size %d\n", size);
4430 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4431 usage->cUsageIdentifier);
4434 ret = CryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4435 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4436 (BYTE *)&buf, &size);
4437 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4440 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4443 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4444 "Wrong size %d\n", size);
4445 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4446 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4447 for (i = 0; i < usage->cUsageIdentifier; i++)
4448 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4449 "Expected OID %s, got %s\n", keyUsages[i],
4450 usage->rgpszUsageIdentifier[i]);
4455 static BYTE keyId[] = { 1,2,3,4 };
4456 static const BYTE authorityKeyIdWithId[] = {
4457 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4458 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4459 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4460 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4461 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4463 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4465 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4470 /* Test with empty id */
4471 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4472 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4473 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4476 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4477 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4480 /* With just a key id */
4481 info.KeyId.cbData = sizeof(keyId);
4482 info.KeyId.pbData = keyId;
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(authorityKeyIdWithId), "Unexpected size %d\n", size);
4489 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4492 /* With just an issuer */
4493 info.KeyId.cbData = 0;
4494 info.CertIssuer.cbData = sizeof(encodedCommonName);
4495 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4496 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4497 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4498 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4501 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4503 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4506 /* With just a serial number */
4507 info.CertIssuer.cbData = 0;
4508 info.CertSerialNumber.cbData = sizeof(serialNum);
4509 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4510 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4511 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4512 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4515 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4517 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4522 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4528 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4529 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4530 (BYTE *)&buf, &size);
4531 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4534 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4536 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4538 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4539 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4540 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4543 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4544 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4545 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4546 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4549 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4551 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4553 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4554 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4555 "Unexpected key id\n");
4556 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4557 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4560 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4561 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4562 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4563 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4566 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4568 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4570 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4571 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4572 "Unexpected issuer len\n");
4573 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4574 sizeof(encodedCommonName)), "Unexpected issuer\n");
4575 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4578 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4579 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4580 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4581 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4584 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4586 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4588 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4589 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4590 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4591 "Unexpected serial number len\n");
4592 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4593 "Unexpected serial number\n");
4598 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4599 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4602 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4604 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4605 CERT_ALT_NAME_ENTRY entry = { 0 };
4610 /* Test with empty id */
4611 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4612 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4613 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4616 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4617 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4620 /* With just a key id */
4621 info.KeyId.cbData = sizeof(keyId);
4622 info.KeyId.pbData = keyId;
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(authorityKeyIdWithId), "Unexpected size %d\n",
4630 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4633 /* With a bogus issuer name */
4634 info.KeyId.cbData = 0;
4635 info.AuthorityCertIssuer.cAltEntry = 1;
4636 info.AuthorityCertIssuer.rgAltEntry = &entry;
4637 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4638 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4639 ok(!ret && GetLastError() == E_INVALIDARG,
4640 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4641 /* With an issuer name */
4642 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4643 U(entry).pwszURL = (LPWSTR)url;
4644 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4645 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4646 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4649 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4651 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4652 "Unexpected value\n");
4655 /* With just a serial number */
4656 info.AuthorityCertIssuer.cAltEntry = 0;
4657 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4658 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4659 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4660 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4661 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4664 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4666 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4671 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4677 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4678 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4679 (BYTE *)&buf, &size);
4680 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4683 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4685 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4687 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4688 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4689 "Expected no issuer name entries\n");
4690 ok(info->AuthorityCertSerialNumber.cbData == 0,
4691 "Expected no serial number\n");
4694 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4695 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4696 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4697 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4700 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4702 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4704 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4705 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4706 "Unexpected key id\n");
4707 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4708 "Expected no issuer name entries\n");
4709 ok(info->AuthorityCertSerialNumber.cbData == 0,
4710 "Expected no serial number\n");
4713 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4714 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4715 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4716 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4719 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4721 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4723 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4724 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4725 "Expected 1 issuer entry, got %d\n",
4726 info->AuthorityCertIssuer.cAltEntry);
4727 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4728 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4729 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4730 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4731 url), "Unexpected URL\n");
4732 ok(info->AuthorityCertSerialNumber.cbData == 0,
4733 "Expected no serial number\n");
4736 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4737 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4738 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4739 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4742 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4744 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4746 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4747 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4748 "Expected no issuer name entries\n");
4749 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4750 "Unexpected serial number len\n");
4751 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4752 sizeof(serialNum)), "Unexpected serial number\n");
4757 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
4758 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
4760 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
4762 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
4763 0x03,0x02,0x01,0x01 };
4764 static BYTE bogusDER[] = { 1 };
4766 static void test_encodePKCSContentInfo(DWORD dwEncoding)
4771 CRYPT_CONTENT_INFO info = { 0 };
4772 char oid1[] = "1.2.3";
4774 SetLastError(0xdeadbeef);
4775 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
4776 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4777 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4778 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
4779 SetLastError(0xdeadbeef);
4780 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4781 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4782 ok(!ret && GetLastError() == E_INVALIDARG,
4783 "Expected E_INVALIDARG, got %x\n", GetLastError());
4784 info.pszObjId = oid1;
4785 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4786 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4787 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4790 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
4791 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
4794 info.Content.pbData = bogusDER;
4795 info.Content.cbData = sizeof(bogusDER);
4796 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4797 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4798 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
4801 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
4802 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
4805 info.Content.pbData = (BYTE *)ints[0].encoded;
4806 info.Content.cbData = ints[0].encoded[1] + 2;
4807 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4808 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4811 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
4812 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
4817 static const BYTE indefiniteSignedPKCSContent[] = {
4818 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
4819 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
4820 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
4821 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
4822 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
4823 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
4824 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
4825 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
4826 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
4827 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
4828 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
4829 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
4830 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
4831 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
4832 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
4833 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
4834 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
4835 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
4836 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
4837 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
4838 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
4839 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
4840 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
4841 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
4842 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
4843 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
4844 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
4845 0x00,0x00,0x00,0x00,0x00,0x00 };
4847 static void test_decodePKCSContentInfo(DWORD dwEncoding)
4852 CRYPT_CONTENT_INFO *info;
4854 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4855 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
4856 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4857 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4860 info = (CRYPT_CONTENT_INFO *)buf;
4862 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4864 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
4865 info->Content.cbData);
4868 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4869 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
4870 0, NULL, NULL, &size);
4871 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4872 SetLastError(0xdeadbeef);
4873 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4874 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
4875 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4876 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
4877 * I doubt an app depends on that.
4879 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
4880 GetLastError() == CRYPT_E_ASN1_CORRUPT),
4881 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
4883 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4884 intPKCSContentInfo, sizeof(intPKCSContentInfo),
4885 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4886 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4889 info = (CRYPT_CONTENT_INFO *)buf;
4891 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4893 ok(info->Content.cbData == ints[0].encoded[1] + 2,
4894 "Unexpected size %d\n", info->Content.cbData);
4895 ok(!memcmp(info->Content.pbData, ints[0].encoded,
4896 info->Content.cbData), "Unexpected value\n");
4899 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4900 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
4901 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4902 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4905 info = (CRYPT_CONTENT_INFO *)buf;
4907 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
4908 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
4909 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
4910 info->Content.cbData);
4915 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
4917 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
4919 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
4922 static void test_encodePKCSAttribute(DWORD dwEncoding)
4924 CRYPT_ATTRIBUTE attr = { 0 };
4928 CRYPT_ATTR_BLOB blob;
4929 char oid[] = "1.2.3";
4931 SetLastError(0xdeadbeef);
4932 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
4933 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4934 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4935 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
4936 SetLastError(0xdeadbeef);
4937 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4938 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4939 ok(!ret && GetLastError() == E_INVALIDARG,
4940 "Expected E_INVALIDARG, got %x\n", GetLastError());
4941 attr.pszObjId = oid;
4942 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4943 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4944 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4947 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
4948 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
4951 blob.cbData = sizeof(bogusDER);
4952 blob.pbData = bogusDER;
4954 attr.rgValue = &blob;
4955 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4956 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4957 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4960 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
4961 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
4964 blob.pbData = (BYTE *)ints[0].encoded;
4965 blob.cbData = ints[0].encoded[1] + 2;
4966 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4967 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4970 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
4971 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
4976 static void test_decodePKCSAttribute(DWORD dwEncoding)
4981 CRYPT_ATTRIBUTE *attr;
4983 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
4984 emptyPKCSAttr, sizeof(emptyPKCSAttr),
4985 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4986 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4989 attr = (CRYPT_ATTRIBUTE *)buf;
4991 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4993 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
4996 SetLastError(0xdeadbeef);
4997 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
4998 bogusPKCSAttr, sizeof(bogusPKCSAttr),
4999 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5000 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5001 * I doubt an app depends on that.
5003 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5004 GetLastError() == CRYPT_E_ASN1_CORRUPT),
5005 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5007 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5008 intPKCSAttr, sizeof(intPKCSAttr),
5009 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5010 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5013 attr = (CRYPT_ATTRIBUTE *)buf;
5015 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5017 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5018 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5019 "Unexpected size %d\n", attr->rgValue[0].cbData);
5020 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5021 attr->rgValue[0].cbData), "Unexpected value\n");
5025 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5026 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5027 0x2a,0x03,0x31,0x00 };
5028 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5029 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5031 static void test_encodePKCSAttributes(DWORD dwEncoding)
5033 CRYPT_ATTRIBUTES attributes = { 0 };
5034 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5035 CRYPT_ATTR_BLOB blob;
5039 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5041 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5042 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5043 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5046 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5047 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5050 attributes.cAttr = 1;
5051 attributes.rgAttr = attr;
5052 SetLastError(0xdeadbeef);
5053 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5054 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5055 ok(!ret && GetLastError() == E_INVALIDARG,
5056 "Expected E_INVALIDARG, got %x\n", GetLastError());
5057 attr[0].pszObjId = oid1;
5058 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5059 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5062 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5063 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5066 attr[1].pszObjId = oid2;
5068 attr[1].rgValue = &blob;
5069 blob.pbData = (BYTE *)ints[0].encoded;
5070 blob.cbData = ints[0].encoded[1] + 2;
5071 attributes.cAttr = 2;
5072 ret = CryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5073 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5074 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5077 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5078 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5083 static void test_decodePKCSAttributes(DWORD dwEncoding)
5088 CRYPT_ATTRIBUTES *attributes;
5090 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5091 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5092 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5093 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5096 attributes = (CRYPT_ATTRIBUTES *)buf;
5097 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5101 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5102 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5103 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5104 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5107 attributes = (CRYPT_ATTRIBUTES *)buf;
5108 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5110 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5111 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5112 ok(attributes->rgAttr[0].cValue == 0,
5113 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5116 ret = CryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5117 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5118 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5119 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5122 attributes = (CRYPT_ATTRIBUTES *)buf;
5123 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5125 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5126 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5127 ok(attributes->rgAttr[0].cValue == 0,
5128 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5129 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5130 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5131 ok(attributes->rgAttr[1].cValue == 1,
5132 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5133 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5134 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5135 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5136 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5141 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
5142 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5144 static const BYTE minimalPKCSSigner[] = {
5145 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5146 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5147 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
5148 static const BYTE PKCSSignerWithSerial[] = {
5149 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5150 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5151 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5153 static const BYTE PKCSSignerWithHashAlgo[] = {
5154 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5155 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5156 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5158 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
5159 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5160 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5161 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5162 0x06,0x05,0x00,0x04,0x00 };
5163 static const BYTE PKCSSignerWithHash[] = {
5164 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5165 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5166 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5167 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
5168 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5169 static const BYTE PKCSSignerWithAuthAttr[] = {
5170 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5171 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5172 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
5173 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
5174 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
5175 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
5176 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5178 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
5180 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
5184 CMSG_SIGNER_INFO info = { 0 };
5185 char oid_common_name[] = szOID_COMMON_NAME;
5186 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
5187 (LPBYTE)encodedCommonName };
5188 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
5190 SetLastError(0xdeadbeef);
5191 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5192 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5193 ok(!ret && GetLastError() == E_INVALIDARG,
5194 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5195 /* To be encoded, a signer must have an issuer at least, and the encoding
5196 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
5197 * see decoding tests.)
5199 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
5200 info.Issuer.pbData = encodedCommonNameNoNull;
5201 SetLastError(0xdeadbeef);
5202 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5203 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5204 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5205 ok(!ret && GetLastError() == E_INVALIDARG,
5206 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5209 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5212 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
5213 if (size == sizeof(minimalPKCSSigner))
5214 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
5216 ok(0, "Unexpected value\n");
5220 info.SerialNumber.cbData = sizeof(serialNum);
5221 info.SerialNumber.pbData = (BYTE *)serialNum;
5222 SetLastError(0xdeadbeef);
5223 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5224 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5225 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5226 ok(!ret && GetLastError() == E_INVALIDARG,
5227 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5230 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5233 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
5235 if (size == sizeof(PKCSSignerWithSerial))
5236 ok(!memcmp(buf, PKCSSignerWithSerial, size),
5237 "Unexpected value\n");
5239 ok(0, "Unexpected value\n");
5243 info.HashAlgorithm.pszObjId = oid1;
5244 SetLastError(0xdeadbeef);
5245 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5246 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5247 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5248 ok(!ret && GetLastError() == E_INVALIDARG,
5249 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5252 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5255 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
5257 if (size == sizeof(PKCSSignerWithHashAlgo))
5258 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
5259 "Unexpected value\n");
5261 ok(0, "Unexpected value\n");
5265 info.HashEncryptionAlgorithm.pszObjId = oid2;
5266 SetLastError(0xdeadbeef);
5267 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5268 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5269 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5270 ok(!ret && GetLastError() == E_INVALIDARG,
5271 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5274 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5277 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
5278 "Unexpected size %d\n", size);
5279 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
5280 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
5281 "Unexpected value\n");
5283 ok(0, "Unexpected value\n");
5287 info.EncryptedHash.cbData = sizeof(hash);
5288 info.EncryptedHash.pbData = (BYTE *)hash;
5289 SetLastError(0xdeadbeef);
5290 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5291 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5292 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5293 ok(!ret && GetLastError() == E_INVALIDARG,
5294 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5297 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5300 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
5302 if (size == sizeof(PKCSSignerWithHash))
5303 ok(!memcmp(buf, PKCSSignerWithHash, size),
5304 "Unexpected value\n");
5306 ok(0, "Unexpected value\n");
5310 info.AuthAttrs.cAttr = 1;
5311 info.AuthAttrs.rgAttr = &attr;
5312 SetLastError(0xdeadbeef);
5313 ret = CryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5314 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5315 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5316 ok(!ret && GetLastError() == E_INVALIDARG,
5317 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5320 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5323 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
5325 if (size == sizeof(PKCSSignerWithAuthAttr))
5326 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
5327 "Unexpected value\n");
5329 ok(0, "Unexpected value\n");
5335 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
5340 CMSG_SIGNER_INFO *info;
5342 /* A PKCS signer can't be decoded without a serial number. */
5343 SetLastError(0xdeadbeef);
5344 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5345 minimalPKCSSigner, sizeof(minimalPKCSSigner),
5346 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5347 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
5348 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
5349 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5350 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
5351 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5352 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5355 info = (CMSG_SIGNER_INFO *)buf;
5356 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5358 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5359 "Unexpected size %d\n", info->Issuer.cbData);
5360 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5361 info->Issuer.cbData), "Unexpected value\n");
5362 ok(info->SerialNumber.cbData == sizeof(serialNum),
5363 "Unexpected size %d\n", info->SerialNumber.cbData);
5364 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5365 "Unexpected value\n");
5368 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5369 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
5370 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5373 info = (CMSG_SIGNER_INFO *)buf;
5374 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5376 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5377 "Unexpected size %d\n", info->Issuer.cbData);
5378 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5379 info->Issuer.cbData), "Unexpected value\n");
5380 ok(info->SerialNumber.cbData == sizeof(serialNum),
5381 "Unexpected size %d\n", info->SerialNumber.cbData);
5382 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5383 "Unexpected value\n");
5384 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5385 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5388 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5389 PKCSSignerWithHashAndEncryptionAlgo,
5390 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
5391 NULL, (BYTE *)&buf, &size);
5394 info = (CMSG_SIGNER_INFO *)buf;
5395 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5397 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5398 "Unexpected size %d\n", info->Issuer.cbData);
5399 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5400 info->Issuer.cbData), "Unexpected value\n");
5401 ok(info->SerialNumber.cbData == sizeof(serialNum),
5402 "Unexpected size %d\n", info->SerialNumber.cbData);
5403 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5404 "Unexpected value\n");
5405 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5406 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5407 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
5408 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
5411 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5412 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
5413 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5416 info = (CMSG_SIGNER_INFO *)buf;
5417 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5419 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5420 "Unexpected size %d\n", info->Issuer.cbData);
5421 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5422 info->Issuer.cbData), "Unexpected value\n");
5423 ok(info->SerialNumber.cbData == sizeof(serialNum),
5424 "Unexpected size %d\n", info->SerialNumber.cbData);
5425 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5426 "Unexpected value\n");
5427 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5428 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5429 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
5430 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
5431 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
5432 info->EncryptedHash.cbData);
5433 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
5434 "Unexpected value\n");
5437 ret = CryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5438 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
5439 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5442 info = (CMSG_SIGNER_INFO *)buf;
5443 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
5444 info->AuthAttrs.cAttr);
5445 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
5446 "Expected %s, got %s\n", szOID_COMMON_NAME,
5447 info->AuthAttrs.rgAttr[0].pszObjId);
5448 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
5449 info->AuthAttrs.rgAttr[0].cValue);
5450 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
5451 sizeof(encodedCommonName), "Unexpected size %d\n",
5452 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
5453 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
5454 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
5459 /* Free *pInfo with HeapFree */
5460 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
5467 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
5469 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
5470 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5471 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5472 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
5474 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5475 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5476 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
5478 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5479 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5480 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
5481 0, NULL, NULL, &size);
5482 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5483 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5484 /* Test with no key */
5485 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
5486 0, NULL, NULL, &size);
5487 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
5489 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
5490 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
5493 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
5494 NULL, 0, NULL, NULL, &size);
5495 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
5496 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
5499 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
5500 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
5501 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
5505 /* By default (we passed NULL as the OID) the OID is
5508 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
5509 "Expected %s, got %s\n", szOID_RSA_RSA,
5510 (*pInfo)->Algorithm.pszObjId);
5516 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
5517 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
5518 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
5519 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
5520 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
5521 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
5522 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
5523 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
5524 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
5525 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
5526 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
5527 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
5528 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
5529 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
5530 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
5531 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
5532 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
5533 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
5534 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
5535 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
5536 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
5537 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
5538 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
5539 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
5540 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
5542 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
5546 PCCERT_CONTEXT context;
5549 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
5550 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
5551 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
5552 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
5555 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
5556 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
5557 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
5558 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
5559 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
5560 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
5561 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
5563 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5564 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5565 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
5567 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
5568 CryptDestroyKey(key);
5570 /* Test importing a public key from a certificate context */
5571 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
5572 sizeof(expiredCert));
5573 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
5577 ok(!strcmp(szOID_RSA_RSA,
5578 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
5579 "Expected %s, got %s\n", szOID_RSA_RSA,
5580 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
5581 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
5582 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
5583 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
5584 CryptDestroyKey(key);
5585 CertFreeCertificateContext(context);
5589 static const char cspName[] = "WineCryptTemp";
5591 static void testPortPublicKeyInfo(void)
5595 PCERT_PUBLIC_KEY_INFO info = NULL;
5597 /* Just in case a previous run failed, delete this thing */
5598 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5599 CRYPT_DELETEKEYSET);
5600 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5603 testExportPublicKey(csp, &info);
5604 testImportPublicKey(csp, info);
5606 HeapFree(GetProcessHeap(), 0, info);
5607 CryptReleaseContext(csp, 0);
5608 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5609 CRYPT_DELETEKEYSET);
5614 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
5615 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
5618 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
5620 test_encodeInt(encodings[i]);
5621 test_decodeInt(encodings[i]);
5622 test_encodeEnumerated(encodings[i]);
5623 test_decodeEnumerated(encodings[i]);
5624 test_encodeFiletime(encodings[i]);
5625 test_decodeFiletime(encodings[i]);
5626 test_encodeName(encodings[i]);
5627 test_decodeName(encodings[i]);
5628 test_encodeUnicodeName(encodings[i]);
5629 test_decodeUnicodeName(encodings[i]);
5630 test_encodeNameValue(encodings[i]);
5631 test_decodeNameValue(encodings[i]);
5632 test_encodeUnicodeNameValue(encodings[i]);
5633 test_decodeUnicodeNameValue(encodings[i]);
5634 test_encodeAltName(encodings[i]);
5635 test_decodeAltName(encodings[i]);
5636 test_encodeOctets(encodings[i]);
5637 test_decodeOctets(encodings[i]);
5638 test_encodeBits(encodings[i]);
5639 test_decodeBits(encodings[i]);
5640 test_encodeBasicConstraints(encodings[i]);
5641 test_decodeBasicConstraints(encodings[i]);
5642 test_encodeRsaPublicKey(encodings[i]);
5643 test_decodeRsaPublicKey(encodings[i]);
5644 test_encodeSequenceOfAny(encodings[i]);
5645 test_decodeSequenceOfAny(encodings[i]);
5646 test_encodeExtensions(encodings[i]);
5647 test_decodeExtensions(encodings[i]);
5648 test_encodePublicKeyInfo(encodings[i]);
5649 test_decodePublicKeyInfo(encodings[i]);
5650 test_encodeCertToBeSigned(encodings[i]);
5651 test_decodeCertToBeSigned(encodings[i]);
5652 test_encodeCert(encodings[i]);
5653 test_decodeCert(encodings[i]);
5654 test_encodeCRLDistPoints(encodings[i]);
5655 test_decodeCRLDistPoints(encodings[i]);
5656 test_encodeCRLIssuingDistPoint(encodings[i]);
5657 test_decodeCRLIssuingDistPoint(encodings[i]);
5658 test_encodeCRLToBeSigned(encodings[i]);
5659 test_decodeCRLToBeSigned(encodings[i]);
5660 test_encodeEnhancedKeyUsage(encodings[i]);
5661 test_decodeEnhancedKeyUsage(encodings[i]);
5662 test_encodeAuthorityKeyId(encodings[i]);
5663 test_decodeAuthorityKeyId(encodings[i]);
5664 test_encodeAuthorityKeyId2(encodings[i]);
5665 test_decodeAuthorityKeyId2(encodings[i]);
5666 test_encodePKCSContentInfo(encodings[i]);
5667 test_decodePKCSContentInfo(encodings[i]);
5668 test_encodePKCSAttribute(encodings[i]);
5669 test_decodePKCSAttribute(encodings[i]);
5670 test_encodePKCSAttributes(encodings[i]);
5671 test_decodePKCSAttributes(encodings[i]);
5672 test_encodePKCSSignerInfo(encodings[i]);
5673 test_decodePKCSSignerInfo(encodings[i]);
5675 testPortPublicKeyInfo();