crypt32: Implement PKCS_CONTENT_INFO encoding/decoding.
[wine/wine64.git] / dlls / crypt32 / tests / encode.c
bloba65560290b9f04512bdbe28d2849b3e96cc7dd31
1 /*
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
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <windef.h>
23 #include <winbase.h>
24 #include <winerror.h>
25 #include <wincrypt.h>
27 #include "wine/test.h"
29 struct encodedInt
31 int val;
32 const BYTE *encoded;
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[] = {
44 { 1, bin1 },
45 { 127, bin2 },
46 { 128, bin3 },
47 { 256, bin4 },
48 { -128, bin5 },
49 { -129, bin6 },
50 { 0xbaddf00d, bin7 },
53 struct encodedBigInt
55 const BYTE *val;
56 const BYTE *encoded;
57 const BYTE *decoded;
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)
86 DWORD bufSize = 0;
87 int i;
88 BOOL ret;
89 CRYPT_INTEGER_BLOB blob;
90 BYTE *buf = NULL;
92 /* CryptEncodeObjectEx with NULL bufSize crashes..
93 ret = CryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
94 NULL);
96 /* check bogus encoding */
97 ret = CryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
98 &bufSize);
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
102 * NTSTATUS.
104 ret = CryptEncodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, NULL, NULL,
105 &bufSize);
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());
117 if (buf)
119 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
120 buf[0]);
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);
125 LocalFree(buf);
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());
136 if (buf)
138 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
139 buf[0]);
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);
144 LocalFree(buf);
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());
160 if (buf)
162 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
163 buf[0]);
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");
169 LocalFree(buf);
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());
183 if (buf)
185 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
186 buf[0]);
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");
192 LocalFree(buf);
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 BYTE *buf = NULL;
204 DWORD bufSize = 0;
205 int i;
206 BOOL ret;
208 /* CryptDecodeObjectEx with NULL bufSize crashes..
209 ret = CryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded,
210 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
212 /* check bogus encoding */
213 ret = CryptDecodeObjectEx(3, X509_INTEGER, (BYTE *)&ints[0].encoded,
214 ints[0].encoded[1] + 2, 0, NULL, NULL, &bufSize);
215 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
216 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
217 /* check with NULL integer buffer */
218 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, 0, NULL, NULL,
219 &bufSize);
220 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
221 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
222 /* check with a valid, but too large, integer */
223 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER, bigInt, bigInt[1] + 2,
224 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
225 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
226 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
227 /* check with a DER-encoded string */
228 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER, testStr, testStr[1] + 2,
229 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
230 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
231 "Expected CRYPT_E_ASN1_BADTAG, got %d\n", GetLastError());
232 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
234 /* When the output buffer is NULL, this always succeeds */
235 SetLastError(0xdeadbeef);
236 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER,
237 ints[i].encoded, ints[i].encoded[1] + 2, 0, NULL, NULL,
238 &bufSize);
239 ok(ret && GetLastError() == NOERROR,
240 "Expected success and NOERROR, got %d\n", GetLastError());
241 ret = CryptDecodeObjectEx(dwEncoding, X509_INTEGER,
242 ints[i].encoded, ints[i].encoded[1] + 2,
243 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
244 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
245 ok(bufSize == sizeof(int), "Wrong size %d\n", bufSize);
246 ok(buf != NULL, "Expected allocated buffer\n");
247 if (buf)
249 ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n",
250 ints[i].val, *(int *)buf);
251 LocalFree(buf);
254 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
256 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
257 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 0, NULL, NULL,
258 &bufSize);
259 ok(ret && GetLastError() == NOERROR,
260 "Expected success and NOERROR, got %d\n", GetLastError());
261 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
262 bigInts[i].encoded, bigInts[i].encoded[1] + 2,
263 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
264 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
265 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
266 ok(buf != NULL, "Expected allocated buffer\n");
267 if (buf)
269 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
271 ok(blob->cbData == strlen((const char*)bigInts[i].decoded),
272 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts[i].decoded),
273 blob->cbData);
274 ok(!memcmp(blob->pbData, bigInts[i].decoded, blob->cbData),
275 "Unexpected value\n");
276 LocalFree(buf);
279 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
281 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
282 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 0, NULL, NULL,
283 &bufSize);
284 ok(ret && GetLastError() == NOERROR,
285 "Expected success and NOERROR, got %d\n", GetLastError());
286 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
287 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2,
288 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
289 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
290 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
291 ok(buf != NULL, "Expected allocated buffer\n");
292 if (buf)
294 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
296 ok(blob->cbData == strlen((const char*)bigUInts[i].val),
297 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts[i].val),
298 blob->cbData);
299 ok(!memcmp(blob->pbData, bigUInts[i].val, blob->cbData),
300 "Unexpected value\n");
301 LocalFree(buf);
304 /* Decode the value 1 with long-form length */
305 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, longForm,
306 sizeof(longForm), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
307 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
308 if (buf)
310 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
311 LocalFree(buf);
313 /* Try to decode some bogus large items */
314 /* The buffer size is smaller than the encoded length, so this should fail
315 * with CRYPT_E_ASN1_EOD if it's being decoded.
316 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit
317 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes.
318 * So this test unfortunately isn't useful.
319 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig,
320 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
321 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
322 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
324 /* This will try to decode the buffer and overflow it, check that it's
325 * caught.
327 if (0)
329 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
330 ret = CryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, bigBogus,
331 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
332 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
333 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
337 static const BYTE bin18[] = {0x0a,0x01,0x01};
338 static const BYTE bin19[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
340 /* These are always encoded unsigned, and aren't constrained to be any
341 * particular value
343 static const struct encodedInt enums[] = {
344 { 1, bin18 },
345 { -128, bin19 },
348 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
349 * X509_ENUMERATED.
351 static const LPCSTR enumeratedTypes[] = { X509_ENUMERATED,
352 szOID_CRL_REASON_CODE };
354 static void test_encodeEnumerated(DWORD dwEncoding)
356 DWORD i, j;
358 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
360 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
362 BOOL ret;
363 BYTE *buf = NULL;
364 DWORD bufSize = 0;
366 ret = CryptEncodeObjectEx(dwEncoding, enumeratedTypes[i],
367 &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
368 &bufSize);
369 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
370 if (buf)
372 ok(buf[0] == 0xa,
373 "Got unexpected type %d for enumerated (expected 0xa)\n",
374 buf[0]);
375 ok(buf[1] == enums[j].encoded[1],
376 "Got length %d, expected %d\n", buf[1], enums[j].encoded[1]);
377 ok(!memcmp(buf + 1, enums[j].encoded + 1,
378 enums[j].encoded[1] + 1),
379 "Encoded value of 0x%08x didn't match expected\n",
380 enums[j].val);
381 LocalFree(buf);
387 static void test_decodeEnumerated(DWORD dwEncoding)
389 DWORD i, j;
391 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
393 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
395 BOOL ret;
396 DWORD bufSize = sizeof(int);
397 int val;
399 ret = CryptDecodeObjectEx(dwEncoding, enumeratedTypes[i],
400 enums[j].encoded, enums[j].encoded[1] + 2, 0, NULL,
401 (BYTE *)&val, &bufSize);
402 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
403 ok(bufSize == sizeof(int),
404 "Got unexpected size %d for enumerated\n", bufSize);
405 ok(val == enums[j].val, "Unexpected value %d, expected %d\n",
406 val, enums[j].val);
411 struct encodedFiletime
413 SYSTEMTIME sysTime;
414 const BYTE *encodedTime;
417 static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType,
418 const struct encodedFiletime *time)
420 FILETIME ft = { 0 };
421 BYTE *buf = NULL;
422 DWORD bufSize = 0;
423 BOOL ret;
425 ret = SystemTimeToFileTime(&time->sysTime, &ft);
426 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
427 ret = CryptEncodeObjectEx(dwEncoding, structType, &ft,
428 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
429 /* years other than 1950-2050 are not allowed for encodings other than
430 * X509_CHOICE_OF_TIME.
432 if (structType == X509_CHOICE_OF_TIME ||
433 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
435 ok(ret, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
436 GetLastError());
437 ok(buf != NULL, "Expected an allocated buffer\n");
438 if (buf)
440 ok(buf[0] == time->encodedTime[0],
441 "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0],
442 buf[0]);
443 ok(buf[1] == time->encodedTime[1], "Expected %d bytes, got %d\n",
444 time->encodedTime[1], bufSize);
445 ok(!memcmp(time->encodedTime + 2, buf + 2, time->encodedTime[1]),
446 "Got unexpected value for time encoding\n");
447 LocalFree(buf);
450 else
451 ok(!ret && GetLastError() == CRYPT_E_BAD_ENCODE,
452 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
455 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
456 const struct encodedFiletime *time)
458 FILETIME ft1 = { 0 }, ft2 = { 0 };
459 DWORD size = sizeof(ft2);
460 BOOL ret;
462 ret = SystemTimeToFileTime(&time->sysTime, &ft1);
463 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
464 ret = CryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
465 time->encodedTime[1] + 2, 0, NULL, &ft2, &size);
466 /* years other than 1950-2050 are not allowed for encodings other than
467 * X509_CHOICE_OF_TIME.
469 if (structType == X509_CHOICE_OF_TIME ||
470 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
472 ok(ret, "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
473 GetLastError());
474 ok(!memcmp(&ft1, &ft2, sizeof(ft1)),
475 "Got unexpected value for time decoding\n");
477 else
478 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
479 "Expected CRYPT_E_ASN1_BADTAG, got 0x%08x\n", GetLastError());
482 static const BYTE bin20[] = {
483 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
484 static const BYTE bin21[] = {
485 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
486 static const BYTE bin22[] = {
487 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
489 static const struct encodedFiletime times[] = {
490 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
491 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
492 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
495 static void test_encodeFiletime(DWORD dwEncoding)
497 DWORD i;
499 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
501 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
502 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
503 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
507 static const BYTE bin23[] = {
508 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
509 static const BYTE bin24[] = {
510 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
511 static const BYTE bin25[] = {
512 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
513 static const BYTE bin26[] = {
514 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
515 static const BYTE bin27[] = {
516 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
517 static const BYTE bin28[] = {
518 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
519 static const BYTE bin29[] = {
520 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
521 static const BYTE bin30[] = {
522 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
523 static const BYTE bin31[] = {
524 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
525 static const BYTE bin32[] = {
526 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
527 static const BYTE bin33[] = {
528 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
529 static const BYTE bin34[] = {
530 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
531 static const BYTE bin35[] = {
532 0x17,0x08, '4','5','0','6','0','6','1','6'};
533 static const BYTE bin36[] = {
534 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
535 static const BYTE bin37[] = {
536 0x18,0x04, '2','1','4','5'};
537 static const BYTE bin38[] = {
538 0x18,0x08, '2','1','4','5','0','6','0','6'};
540 static void test_decodeFiletime(DWORD dwEncoding)
542 static const struct encodedFiletime otherTimes[] = {
543 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
544 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
545 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
546 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
547 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
548 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
549 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
550 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
551 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
552 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
553 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
554 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
556 /* An oddball case that succeeds in Windows, but doesn't seem correct
557 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
559 static const unsigned char *bogusTimes[] = {
560 /* oddly, this succeeds on Windows, with year 2765
561 "\x18" "\x0f" "21r50606161000Z",
563 bin35,
564 bin36,
565 bin37,
566 bin38,
568 DWORD i, size;
569 FILETIME ft1 = { 0 }, ft2 = { 0 };
570 BOOL ret;
572 /* Check bogus length with non-NULL buffer */
573 ret = SystemTimeToFileTime(&times[0].sysTime, &ft1);
574 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
575 size = 1;
576 ret = CryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
577 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
578 ok(!ret && GetLastError() == ERROR_MORE_DATA,
579 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
580 /* Normal tests */
581 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
583 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
584 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
585 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
587 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
589 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
590 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
591 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
593 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
595 size = sizeof(ft1);
596 ret = CryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
597 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
598 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
599 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
603 static const char commonName[] = "Juan Lang";
604 static const char surName[] = "Lang";
606 static const BYTE emptySequence[] = { 0x30, 0 };
607 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
608 static const BYTE twoRDNs[] = {
609 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
610 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
611 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
612 static const BYTE encodedTwoRDNs[] = {
613 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
614 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
615 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
616 0x6e,0x67,0x00,
619 static const BYTE us[] = { 0x55, 0x53 };
620 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
621 0x74, 0x61 };
622 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
623 0x6f, 0x6c, 0x69, 0x73 };
624 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
625 0x76, 0x65, 0x72, 0x73 };
626 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
627 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
628 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
629 0x73, 0x74 };
630 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
631 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
633 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
634 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
636 static CHAR oid_us[] = "2.5.4.6",
637 oid_minnesota[] = "2.5.4.8",
638 oid_minneapolis[] = "2.5.4.7",
639 oid_codeweavers[] = "2.5.4.10",
640 oid_wine[] = "2.5.4.11",
641 oid_localhostAttr[] = "2.5.4.3",
642 oid_aric[] = "1.2.840.113549.1.9.1";
643 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
644 { RDNA(minnesota) },
645 { RDNA(minneapolis) },
646 { RDNA(codeweavers) },
647 { RDNA(wine) },
648 { RDNA(localhostAttr) },
649 { RDNIA5(aric) } };
650 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
651 { RDNA(localhostAttr) },
652 { RDNA(minnesota) },
653 { RDNA(minneapolis) },
654 { RDNA(codeweavers) },
655 { RDNA(wine) },
656 { RDNIA5(aric) } };
658 #undef RDNIA5
659 #undef RDNA
661 static const BYTE encodedRDNAttrs[] = {
662 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
663 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
664 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
665 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
666 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
667 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
668 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
669 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
670 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
671 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
674 static void test_encodeName(DWORD dwEncoding)
676 CERT_RDN_ATTR attrs[2];
677 CERT_RDN rdn;
678 CERT_NAME_INFO info;
679 static CHAR oid_common_name[] = szOID_COMMON_NAME,
680 oid_sur_name[] = szOID_SUR_NAME;
681 BYTE *buf = NULL;
682 DWORD size = 0;
683 BOOL ret;
685 /* Test with NULL pvStructInfo */
686 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
687 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
688 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
689 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
690 /* Test with empty CERT_NAME_INFO */
691 info.cRDN = 0;
692 info.rgRDN = NULL;
693 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
694 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
695 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
696 if (buf)
698 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
699 "Got unexpected encoding for empty name\n");
700 LocalFree(buf);
702 /* Test with bogus CERT_RDN */
703 info.cRDN = 1;
704 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
705 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
706 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
707 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
708 /* Test with empty CERT_RDN */
709 rdn.cRDNAttr = 0;
710 rdn.rgRDNAttr = NULL;
711 info.cRDN = 1;
712 info.rgRDN = &rdn;
713 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
714 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
715 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
716 if (buf)
718 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
719 "Got unexpected encoding for empty RDN array\n");
720 LocalFree(buf);
722 /* Test with bogus attr array */
723 rdn.cRDNAttr = 1;
724 rdn.rgRDNAttr = NULL;
725 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
726 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
727 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
728 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
729 /* oddly, a bogus OID is accepted by Windows XP; not testing.
730 attrs[0].pszObjId = "bogus";
731 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
732 attrs[0].Value.cbData = sizeof(commonName);
733 attrs[0].Value.pbData = (BYTE *)commonName;
734 rdn.cRDNAttr = 1;
735 rdn.rgRDNAttr = attrs;
736 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
737 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
738 ok(!ret, "Expected failure, got success\n");
740 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
741 * the encoded attributes to be swapped.
743 attrs[0].pszObjId = oid_common_name;
744 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
745 attrs[0].Value.cbData = sizeof(commonName);
746 attrs[0].Value.pbData = (BYTE *)commonName;
747 attrs[1].pszObjId = oid_sur_name;
748 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
749 attrs[1].Value.cbData = sizeof(surName);
750 attrs[1].Value.pbData = (BYTE *)surName;
751 rdn.cRDNAttr = 2;
752 rdn.rgRDNAttr = attrs;
753 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
754 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
755 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
756 if (buf)
758 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
759 "Got unexpected encoding for two RDN array\n");
760 LocalFree(buf);
762 /* A name can be "encoded" with previously encoded RDN attrs. */
763 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
764 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
765 attrs[0].Value.cbData = sizeof(twoRDNs);
766 rdn.cRDNAttr = 1;
767 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
768 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
769 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
770 if (buf)
772 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
773 ok(!memcmp(buf, encodedTwoRDNs, size),
774 "Unexpected value for re-endoded two RDN array\n");
775 LocalFree(buf);
777 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
778 rdn.cRDNAttr = 1;
779 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
780 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
781 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
782 ok(!ret && GetLastError() == E_INVALIDARG,
783 "Expected E_INVALIDARG, got %08x\n", GetLastError());
784 /* Test a more complex name */
785 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
786 rdn.rgRDNAttr = (PCERT_RDN_ATTR)rdnAttrs;
787 info.cRDN = 1;
788 info.rgRDN = &rdn;
789 buf = NULL;
790 size = 0;
791 ret = CryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
792 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
793 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
794 if (ret)
796 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
797 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
798 LocalFree(buf);
802 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
803 static WCHAR surNameW[] = { 'L','a','n','g',0 };
805 static const BYTE twoRDNsNoNull[] = {
806 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
807 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
808 0x20,0x4c,0x61,0x6e,0x67 };
809 static const BYTE anyType[] = {
810 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
811 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
812 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
813 0x61,0x4c,0x67,0x6e };
815 static void test_encodeUnicodeName(DWORD dwEncoding)
817 CERT_RDN_ATTR attrs[2];
818 CERT_RDN rdn;
819 CERT_NAME_INFO info;
820 static CHAR oid_common_name[] = szOID_COMMON_NAME,
821 oid_sur_name[] = szOID_SUR_NAME;
822 BYTE *buf = NULL;
823 DWORD size = 0;
824 BOOL ret;
826 /* Test with NULL pvStructInfo */
827 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
828 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
829 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
830 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
831 /* Test with empty CERT_NAME_INFO */
832 info.cRDN = 0;
833 info.rgRDN = NULL;
834 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
835 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
836 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
837 if (buf)
839 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
840 "Got unexpected encoding for empty name\n");
841 LocalFree(buf);
843 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
844 * encoding (the NULL).
846 attrs[0].pszObjId = oid_common_name;
847 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
848 attrs[0].Value.cbData = sizeof(commonNameW);
849 attrs[0].Value.pbData = (BYTE *)commonNameW;
850 rdn.cRDNAttr = 1;
851 rdn.rgRDNAttr = attrs;
852 info.cRDN = 1;
853 info.rgRDN = &rdn;
854 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
855 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
856 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
857 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
858 ok(size == 9, "Unexpected error index %08x\n", size);
859 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
860 * forces the order of the encoded attributes to be swapped.
862 attrs[0].pszObjId = oid_common_name;
863 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
864 attrs[0].Value.cbData = 0;
865 attrs[0].Value.pbData = (BYTE *)commonNameW;
866 attrs[1].pszObjId = oid_sur_name;
867 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
868 attrs[1].Value.cbData = 0;
869 attrs[1].Value.pbData = (BYTE *)surNameW;
870 rdn.cRDNAttr = 2;
871 rdn.rgRDNAttr = attrs;
872 info.cRDN = 1;
873 info.rgRDN = &rdn;
874 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
875 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
876 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
877 if (buf)
879 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
880 "Got unexpected encoding for two RDN array\n");
881 LocalFree(buf);
883 /* A name can be "encoded" with previously encoded RDN attrs. */
884 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
885 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
886 attrs[0].Value.cbData = sizeof(twoRDNs);
887 rdn.cRDNAttr = 1;
888 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
889 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
890 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
891 if (buf)
893 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
894 ok(!memcmp(buf, encodedTwoRDNs, size),
895 "Unexpected value for re-endoded two RDN array\n");
896 LocalFree(buf);
898 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
899 rdn.cRDNAttr = 1;
900 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
901 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
902 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
903 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
904 if (buf)
906 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
907 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
908 LocalFree(buf);
912 static void compareNameValues(const CERT_NAME_VALUE *expected,
913 const CERT_NAME_VALUE *got)
915 ok(got->dwValueType == expected->dwValueType,
916 "Expected string type %d, got %d\n", expected->dwValueType,
917 got->dwValueType);
918 ok(got->Value.cbData == expected->Value.cbData,
919 "String type %d: unexpected data size, got %d, expected %d\n",
920 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
921 if (got->Value.cbData && got->Value.pbData)
922 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
923 min(got->Value.cbData, expected->Value.cbData)),
924 "String type %d: unexpected value\n", expected->dwValueType);
927 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
928 const CERT_RDN_ATTR *got)
930 if (expected->pszObjId && strlen(expected->pszObjId))
932 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
933 expected->pszObjId);
934 if (got->pszObjId)
936 ok(!strcmp(got->pszObjId, expected->pszObjId),
937 "Got unexpected OID %s, expected %s\n", got->pszObjId,
938 expected->pszObjId);
941 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
942 (const CERT_NAME_VALUE *)&got->dwValueType);
945 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
947 ok(got->cRDNAttr == expected->cRDNAttr,
948 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
949 if (got->cRDNAttr)
951 DWORD i;
953 for (i = 0; i < got->cRDNAttr; i++)
954 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
958 static void compareNames(const CERT_NAME_INFO *expected,
959 const CERT_NAME_INFO *got)
961 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
962 expected->cRDN, got->cRDN);
963 if (got->cRDN)
965 DWORD i;
967 for (i = 0; i < got->cRDN; i++)
968 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
972 static void test_decodeName(DWORD dwEncoding)
974 BYTE *buf = NULL;
975 DWORD bufSize = 0;
976 BOOL ret;
977 CERT_RDN rdn;
978 CERT_NAME_INFO info = { 1, &rdn };
980 /* test empty name */
981 bufSize = 0;
982 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
983 emptySequence[1] + 2,
984 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
985 (BYTE *)&buf, &bufSize);
986 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
987 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
988 * decoder works the same way, so only test the count.
990 if (buf)
992 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
993 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
994 "Expected 0 RDNs in empty info, got %d\n",
995 ((CERT_NAME_INFO *)buf)->cRDN);
996 LocalFree(buf);
998 /* test empty RDN */
999 bufSize = 0;
1000 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1001 emptyRDNs[1] + 2,
1002 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1003 (BYTE *)&buf, &bufSize);
1004 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1005 if (buf)
1007 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1009 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1010 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1011 "Got unexpected value for empty RDN\n");
1012 LocalFree(buf);
1014 /* test two RDN attrs */
1015 bufSize = 0;
1016 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1017 twoRDNs[1] + 2,
1018 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1019 (BYTE *)&buf, &bufSize);
1020 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1021 if (buf)
1023 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1024 oid_common_name[] = szOID_COMMON_NAME;
1026 CERT_RDN_ATTR attrs[] = {
1027 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1028 (BYTE *)surName } },
1029 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1030 (BYTE *)commonName } },
1033 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1034 rdn.rgRDNAttr = attrs;
1035 compareNames(&info, (CERT_NAME_INFO *)buf);
1036 LocalFree(buf);
1038 /* And, a slightly more complicated name */
1039 buf = NULL;
1040 bufSize = 0;
1041 ret = CryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1042 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1043 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1044 if (ret)
1046 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1047 rdn.rgRDNAttr = (PCERT_RDN_ATTR)decodedRdnAttrs;
1048 compareNames(&info, (CERT_NAME_INFO *)buf);
1049 LocalFree(buf);
1053 static void test_decodeUnicodeName(DWORD dwEncoding)
1055 BYTE *buf = NULL;
1056 DWORD bufSize = 0;
1057 BOOL ret;
1058 CERT_RDN rdn;
1059 CERT_NAME_INFO info = { 1, &rdn };
1061 /* test empty name */
1062 bufSize = 0;
1063 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1064 emptySequence[1] + 2,
1065 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1066 (BYTE *)&buf, &bufSize);
1067 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1068 if (buf)
1070 ok(bufSize == sizeof(CERT_NAME_INFO),
1071 "Got wrong bufSize %d\n", bufSize);
1072 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1073 "Expected 0 RDNs in empty info, got %d\n",
1074 ((CERT_NAME_INFO *)buf)->cRDN);
1075 LocalFree(buf);
1077 /* test empty RDN */
1078 bufSize = 0;
1079 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1080 emptyRDNs[1] + 2,
1081 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1082 (BYTE *)&buf, &bufSize);
1083 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1084 if (buf)
1086 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1088 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1089 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1090 "Got unexpected value for empty RDN\n");
1091 LocalFree(buf);
1093 /* test two RDN attrs */
1094 bufSize = 0;
1095 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1096 sizeof(twoRDNsNoNull),
1097 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1098 (BYTE *)&buf, &bufSize);
1099 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1100 if (buf)
1102 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1103 oid_common_name[] = szOID_COMMON_NAME;
1105 CERT_RDN_ATTR attrs[] = {
1106 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1107 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1108 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1109 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1112 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1113 rdn.rgRDNAttr = attrs;
1114 compareNames(&info, (CERT_NAME_INFO *)buf);
1115 LocalFree(buf);
1119 struct EncodedNameValue
1121 CERT_NAME_VALUE value;
1122 const BYTE *encoded;
1123 DWORD encodedSize;
1126 static const char bogusIA5[] = "\x80";
1127 static const char bogusPrintable[] = "~";
1128 static const char bogusNumeric[] = "A";
1129 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1130 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1131 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1132 static BYTE octetCommonNameValue[] = {
1133 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1134 static BYTE numericCommonNameValue[] = {
1135 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1136 static BYTE printableCommonNameValue[] = {
1137 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1138 static BYTE t61CommonNameValue[] = {
1139 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1140 static BYTE videotexCommonNameValue[] = {
1141 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1142 static BYTE ia5CommonNameValue[] = {
1143 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1144 static BYTE graphicCommonNameValue[] = {
1145 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1146 static BYTE visibleCommonNameValue[] = {
1147 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1148 static BYTE generalCommonNameValue[] = {
1149 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1150 static BYTE bmpCommonNameValue[] = {
1151 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1152 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1153 static BYTE utf8CommonNameValue[] = {
1154 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1156 static struct EncodedNameValue nameValues[] = {
1157 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1158 octetCommonNameValue, sizeof(octetCommonNameValue) },
1159 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1160 numericCommonNameValue, sizeof(numericCommonNameValue) },
1161 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1162 printableCommonNameValue, sizeof(printableCommonNameValue) },
1163 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1164 t61CommonNameValue, sizeof(t61CommonNameValue) },
1165 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1166 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1167 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1168 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1169 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1170 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1171 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1172 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1173 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1174 generalCommonNameValue, sizeof(generalCommonNameValue) },
1175 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1176 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1177 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1178 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1179 /* The following tests succeed under Windows, but really should fail,
1180 * they contain characters that are illegal for the encoding. I'm
1181 * including them to justify my lazy encoding.
1183 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1184 sizeof(bin42) },
1185 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1186 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1187 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1188 bin44, sizeof(bin44) },
1191 static void test_encodeNameValue(DWORD dwEncoding)
1193 BYTE *buf = NULL;
1194 DWORD size = 0, i;
1195 BOOL ret;
1196 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1198 value.dwValueType = 14;
1199 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1200 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1201 ok(!ret && GetLastError() == CRYPT_E_ASN1_CHOICE,
1202 "Expected CRYPT_E_ASN1_CHOICE, got %08x\n", GetLastError());
1203 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1204 value.Value.pbData = printableCommonNameValue;
1205 value.Value.cbData = sizeof(printableCommonNameValue);
1206 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1207 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1208 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1209 if (buf)
1211 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1212 size);
1213 ok(!memcmp(buf, printableCommonNameValue, size),
1214 "Unexpected encoding\n");
1215 LocalFree(buf);
1217 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1219 ret = CryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1220 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1221 &size);
1222 ok(ret, "Type %d: CryptEncodeObjectEx failed: %08x\n",
1223 nameValues[i].value.dwValueType, GetLastError());
1224 if (buf)
1226 ok(size == nameValues[i].encodedSize,
1227 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1228 ok(!memcmp(buf, nameValues[i].encoded, size),
1229 "Got unexpected encoding\n");
1230 LocalFree(buf);
1235 static void test_decodeNameValue(DWORD dwEncoding)
1237 int i;
1238 BYTE *buf = NULL;
1239 DWORD bufSize = 0;
1240 BOOL ret;
1242 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1244 ret = CryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1245 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1246 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1247 (BYTE *)&buf, &bufSize);
1248 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1249 nameValues[i].value.dwValueType, GetLastError());
1250 if (buf)
1252 compareNameValues(&nameValues[i].value,
1253 (const CERT_NAME_VALUE *)buf);
1254 LocalFree(buf);
1259 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1260 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1261 'h','q','.','o','r','g',0 };
1262 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1263 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1264 0x6f, 0x72, 0x67 };
1265 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1266 0x575b, 0 };
1267 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1268 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1269 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1270 static const BYTE localhost[] = { 127, 0, 0, 1 };
1271 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1272 0x01 };
1274 static void test_encodeAltName(DWORD dwEncoding)
1276 CERT_ALT_NAME_INFO info = { 0 };
1277 CERT_ALT_NAME_ENTRY entry = { 0 };
1278 BYTE *buf = NULL;
1279 DWORD size = 0;
1280 BOOL ret;
1282 /* Test with empty info */
1283 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1284 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1285 if (buf)
1287 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1288 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1289 LocalFree(buf);
1291 /* Test with an empty entry */
1292 info.cAltEntry = 1;
1293 info.rgAltEntry = &entry;
1294 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1295 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1296 ok(!ret && GetLastError() == E_INVALIDARG,
1297 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1298 /* Test with an empty pointer */
1299 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1300 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1301 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1302 if (buf)
1304 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1305 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1306 LocalFree(buf);
1308 /* Test with a real URL */
1309 U(entry).pwszURL = (LPWSTR)url;
1310 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1311 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1312 if (buf)
1314 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1315 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1316 LocalFree(buf);
1318 /* Now with the URL containing an invalid IA5 char */
1319 U(entry).pwszURL = (LPWSTR)nihongoURL;
1320 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1321 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1322 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1323 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1324 /* The first invalid character is at index 7 */
1325 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1326 "Expected invalid char at index 7, got %d\n",
1327 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1328 /* Now with the URL missing a scheme */
1329 U(entry).pwszURL = (LPWSTR)dnsName;
1330 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1331 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1332 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1333 if (buf)
1335 /* This succeeds, but it shouldn't, so don't worry about conforming */
1336 LocalFree(buf);
1338 /* Now with a DNS name */
1339 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1340 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1341 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1342 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1343 if (buf)
1345 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1346 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1347 LocalFree(buf);
1349 /* Test with an IP address */
1350 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1351 U(entry).IPAddress.cbData = sizeof(localhost);
1352 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1353 ret = CryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1354 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1355 if (buf)
1357 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1358 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1359 LocalFree(buf);
1363 static void test_decodeAltName(DWORD dwEncoding)
1365 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1366 0x00, 0x00, 0x01 };
1367 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1368 0x01 };
1369 BOOL ret;
1370 BYTE *buf = NULL;
1371 DWORD bufSize = 0;
1372 CERT_ALT_NAME_INFO *info;
1374 /* Test some bogus ones first */
1375 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1376 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1377 NULL, (BYTE *)&buf, &bufSize);
1378 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1379 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
1380 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1381 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1382 &bufSize);
1383 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
1384 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
1385 /* Now expected cases */
1386 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1387 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1388 &bufSize);
1389 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1390 if (buf)
1392 info = (CERT_ALT_NAME_INFO *)buf;
1394 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1395 info->cAltEntry);
1396 LocalFree(buf);
1398 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1399 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1400 &bufSize);
1401 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1402 if (buf)
1404 info = (CERT_ALT_NAME_INFO *)buf;
1406 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1407 info->cAltEntry);
1408 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1409 "Expected CERT_ALT_NAME_URL, got %d\n",
1410 info->rgAltEntry[0].dwAltNameChoice);
1411 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1412 "Expected empty URL\n");
1413 LocalFree(buf);
1415 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1416 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1417 &bufSize);
1418 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1419 if (buf)
1421 info = (CERT_ALT_NAME_INFO *)buf;
1423 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1424 info->cAltEntry);
1425 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1426 "Expected CERT_ALT_NAME_URL, got %d\n",
1427 info->rgAltEntry[0].dwAltNameChoice);
1428 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1429 LocalFree(buf);
1431 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1432 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1433 &bufSize);
1434 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1435 if (buf)
1437 info = (CERT_ALT_NAME_INFO *)buf;
1439 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1440 info->cAltEntry);
1441 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1442 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1443 info->rgAltEntry[0].dwAltNameChoice);
1444 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1445 "Unexpected DNS name\n");
1446 LocalFree(buf);
1448 ret = CryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1449 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1450 &bufSize);
1451 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1452 if (buf)
1454 info = (CERT_ALT_NAME_INFO *)buf;
1456 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1457 info->cAltEntry);
1458 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1459 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1460 info->rgAltEntry[0].dwAltNameChoice);
1461 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1462 "Unexpected IP address length %d\n",
1463 U(info->rgAltEntry[0]).IPAddress.cbData);
1464 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1465 sizeof(localhost)), "Unexpected IP address value\n");
1466 LocalFree(buf);
1470 struct UnicodeExpectedError
1472 DWORD valueType;
1473 LPCWSTR str;
1474 DWORD errorIndex;
1475 DWORD error;
1478 static const WCHAR oneW[] = { '1',0 };
1479 static const WCHAR aW[] = { 'a',0 };
1480 static const WCHAR quoteW[] = { '"', 0 };
1482 static struct UnicodeExpectedError unicodeErrors[] = {
1483 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1484 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1485 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1486 { 14, oneW, 0, CRYPT_E_ASN1_CHOICE },
1487 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1488 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1489 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1492 struct UnicodeExpectedResult
1494 DWORD valueType;
1495 LPCWSTR str;
1496 CRYPT_DATA_BLOB encoded;
1499 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1500 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1501 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1502 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1503 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1504 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1505 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1506 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1507 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1508 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1509 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1510 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1511 0x5b };
1512 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1513 0x6f,0x5b };
1514 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1515 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1516 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1517 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1519 static struct UnicodeExpectedResult unicodeResults[] = {
1520 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1521 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1522 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1523 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1524 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1525 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1526 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1527 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1528 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1529 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1530 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1531 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1532 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1535 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1536 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1537 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1540 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1542 BYTE *buf = NULL;
1543 DWORD size = 0, i;
1544 BOOL ret;
1545 CERT_NAME_VALUE value;
1547 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1548 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1549 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1550 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1551 /* Have to have a string of some sort */
1552 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1553 value.Value.pbData = NULL;
1554 value.Value.cbData = 0;
1555 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1556 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1557 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1558 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1559 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1560 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1561 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1562 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1563 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1564 value.dwValueType = CERT_RDN_ANY_TYPE;
1565 value.Value.pbData = (LPBYTE)oneW;
1566 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1567 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1568 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1569 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1570 value.Value.cbData = sizeof(oneW);
1571 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1572 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1573 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1574 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1575 /* An encoded string with specified length isn't good enough either */
1576 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1577 value.Value.pbData = oneUniversal;
1578 value.Value.cbData = sizeof(oneUniversal);
1579 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1580 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1581 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1582 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1583 /* More failure checking */
1584 value.Value.cbData = 0;
1585 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1587 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1588 value.dwValueType = unicodeErrors[i].valueType;
1589 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1590 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1591 ok(!ret && GetLastError() == unicodeErrors[i].error,
1592 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1593 unicodeErrors[i].error, GetLastError());
1594 ok(size == unicodeErrors[i].errorIndex,
1595 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1596 size);
1598 /* cbData can be zero if the string is NULL-terminated */
1599 value.Value.cbData = 0;
1600 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1602 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1603 value.dwValueType = unicodeResults[i].valueType;
1604 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1605 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1606 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1607 if (buf)
1609 ok(size == unicodeResults[i].encoded.cbData,
1610 "Value type %d: expected size %d, got %d\n",
1611 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1612 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1613 "Value type %d: unexpected value\n", value.dwValueType);
1614 LocalFree(buf);
1617 /* These "encode," but they do so by truncating each unicode character
1618 * rather than properly encoding it. Kept separate from the proper results,
1619 * because the encoded forms won't decode to their original strings.
1621 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1623 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1624 value.dwValueType = unicodeWeirdness[i].valueType;
1625 ret = CryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1626 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1627 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1628 if (buf)
1630 ok(size == unicodeWeirdness[i].encoded.cbData,
1631 "Value type %d: expected size %d, got %d\n",
1632 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1633 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1634 "Value type %d: unexpected value\n", value.dwValueType);
1635 LocalFree(buf);
1640 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1642 if (n <= 0) return 0;
1643 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1644 return *str1 - *str2;
1647 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1649 DWORD i;
1651 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1653 BYTE *buf = NULL;
1654 BOOL ret;
1655 DWORD size = 0;
1657 ret = CryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1658 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1659 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1660 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1661 if (ret && buf)
1663 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1665 ok(value->dwValueType == unicodeResults[i].valueType,
1666 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1667 value->dwValueType);
1668 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1669 value->Value.cbData / sizeof(WCHAR)),
1670 "Unexpected decoded value for index %d (value type %d)\n", i,
1671 unicodeResults[i].valueType);
1672 LocalFree(buf);
1677 struct encodedOctets
1679 const BYTE *val;
1680 const BYTE *encoded;
1683 static const unsigned char bin46[] = { 'h','i',0 };
1684 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1685 static const unsigned char bin48[] = {
1686 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1687 static const unsigned char bin49[] = {
1688 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1689 static const unsigned char bin50[] = { 0 };
1690 static const unsigned char bin51[] = { 0x04,0x00,0 };
1692 static const struct encodedOctets octets[] = {
1693 { bin46, bin47 },
1694 { bin48, bin49 },
1695 { bin50, bin51 },
1698 static void test_encodeOctets(DWORD dwEncoding)
1700 CRYPT_DATA_BLOB blob;
1701 DWORD i;
1703 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1705 BYTE *buf = NULL;
1706 BOOL ret;
1707 DWORD bufSize = 0;
1709 blob.cbData = strlen((const char*)octets[i].val);
1710 blob.pbData = (BYTE*)octets[i].val;
1711 ret = CryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1712 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1713 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1714 if (buf)
1716 ok(buf[0] == 4,
1717 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1718 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1719 buf[1], octets[i].encoded[1]);
1720 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1721 octets[i].encoded[1] + 1), "Got unexpected value\n");
1722 LocalFree(buf);
1727 static void test_decodeOctets(DWORD dwEncoding)
1729 DWORD i;
1731 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1733 BYTE *buf = NULL;
1734 BOOL ret;
1735 DWORD bufSize = 0;
1737 ret = CryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1738 (BYTE *)octets[i].encoded, octets[i].encoded[1] + 2,
1739 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1740 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1741 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1742 "Expected size >= %d, got %d\n",
1743 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1744 ok(buf != NULL, "Expected allocated buffer\n");
1745 if (buf)
1747 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
1749 if (blob->cbData)
1750 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
1751 "Unexpected value\n");
1752 LocalFree(buf);
1757 static const BYTE bytesToEncode[] = { 0xff, 0xff };
1759 struct encodedBits
1761 DWORD cUnusedBits;
1762 const BYTE *encoded;
1763 DWORD cbDecoded;
1764 const BYTE *decoded;
1767 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
1768 static const unsigned char bin53[] = { 0xff,0xff };
1769 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
1770 static const unsigned char bin55[] = { 0xff,0xfe };
1771 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
1772 static const unsigned char bin57[] = { 0xfe };
1773 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
1775 static const struct encodedBits bits[] = {
1776 /* normal test cases */
1777 { 0, bin52, 2, bin53 },
1778 { 1, bin54, 2, bin55 },
1779 /* strange test case, showing cUnusedBits >= 8 is allowed */
1780 { 9, bin56, 1, bin57 },
1781 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1782 { 17, bin58, 0, NULL },
1785 static void test_encodeBits(DWORD dwEncoding)
1787 DWORD i;
1789 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1791 CRYPT_BIT_BLOB blob;
1792 BOOL ret;
1793 BYTE *buf = NULL;
1794 DWORD bufSize = 0;
1796 blob.cbData = sizeof(bytesToEncode);
1797 blob.pbData = (BYTE *)bytesToEncode;
1798 blob.cUnusedBits = bits[i].cUnusedBits;
1799 ret = CryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
1800 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1801 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1802 if (buf)
1804 ok(bufSize == bits[i].encoded[1] + 2,
1805 "Got unexpected size %d, expected %d\n", bufSize,
1806 bits[i].encoded[1] + 2);
1807 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
1808 "Unexpected value\n");
1809 LocalFree(buf);
1814 static void test_decodeBits(DWORD dwEncoding)
1816 static const BYTE ber[] = "\x03\x02\x01\xff";
1817 static const BYTE berDecoded = 0xfe;
1818 DWORD i;
1819 BOOL ret;
1820 BYTE *buf = NULL;
1821 DWORD bufSize = 0;
1823 /* normal cases */
1824 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1826 ret = CryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
1827 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1828 &bufSize);
1829 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1830 if (buf)
1832 CRYPT_BIT_BLOB *blob;
1834 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
1835 "Got unexpected size %d\n", bufSize);
1836 blob = (CRYPT_BIT_BLOB *)buf;
1837 ok(blob->cbData == bits[i].cbDecoded,
1838 "Got unexpected length %d, expected %d\n", blob->cbData,
1839 bits[i].cbDecoded);
1840 if (blob->cbData && bits[i].cbDecoded)
1841 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
1842 "Unexpected value\n");
1843 LocalFree(buf);
1846 /* special case: check that something that's valid in BER but not in DER
1847 * decodes successfully
1849 ret = CryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
1850 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1851 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1852 if (buf)
1854 CRYPT_BIT_BLOB *blob;
1856 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
1857 "Got unexpected size %d\n", bufSize);
1858 blob = (CRYPT_BIT_BLOB *)buf;
1859 ok(blob->cbData == sizeof(berDecoded),
1860 "Got unexpected length %d\n", blob->cbData);
1861 if (blob->cbData)
1862 ok(*blob->pbData == berDecoded, "Unexpected value\n");
1863 LocalFree(buf);
1867 struct Constraints2
1869 CERT_BASIC_CONSTRAINTS2_INFO info;
1870 const BYTE *encoded;
1873 static const unsigned char bin59[] = { 0x30,0x00 };
1874 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
1875 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
1876 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
1877 static const struct Constraints2 constraints2[] = {
1878 /* empty constraints */
1879 { { FALSE, FALSE, 0}, bin59 },
1880 /* can be a CA */
1881 { { TRUE, FALSE, 0}, bin60 },
1882 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
1883 * but that's not the case
1885 { { FALSE, TRUE, 0}, bin61 },
1886 /* can be a CA and has path length constraints set */
1887 { { TRUE, TRUE, 1}, bin62 },
1890 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
1891 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
1892 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
1893 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
1894 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
1895 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
1896 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
1897 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
1898 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
1899 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
1901 static void test_encodeBasicConstraints(DWORD dwEncoding)
1903 DWORD i, bufSize = 0;
1904 CERT_BASIC_CONSTRAINTS_INFO info;
1905 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
1906 (LPBYTE)encodedDomainName };
1907 BOOL ret;
1908 BYTE *buf = NULL;
1910 /* First test with the simpler info2 */
1911 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
1913 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
1914 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1915 &bufSize);
1916 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1917 if (buf)
1919 ok(bufSize == constraints2[i].encoded[1] + 2,
1920 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
1921 bufSize);
1922 ok(!memcmp(buf, constraints2[i].encoded,
1923 constraints2[i].encoded[1] + 2), "Unexpected value\n");
1924 LocalFree(buf);
1927 /* Now test with more complex basic constraints */
1928 info.SubjectType.cbData = 0;
1929 info.fPathLenConstraint = FALSE;
1930 info.cSubtreesConstraint = 0;
1931 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
1932 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1933 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1934 if (buf)
1936 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
1937 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
1938 "Unexpected value\n");
1939 LocalFree(buf);
1941 /* None of the certs I examined had any subtree constraint, but I test one
1942 * anyway just in case.
1944 info.cSubtreesConstraint = 1;
1945 info.rgSubtreesConstraint = &nameBlob;
1946 ret = CryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
1947 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1948 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1949 if (buf)
1951 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
1952 ok(!memcmp(buf, constraintWithDomainName,
1953 sizeof(constraintWithDomainName)), "Unexpected value\n");
1954 LocalFree(buf);
1956 /* FIXME: test encoding with subject type. */
1959 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
1960 static const unsigned char encodedCommonName[] = {
1961 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1963 static void test_decodeBasicConstraints(DWORD dwEncoding)
1965 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
1966 0xff };
1967 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
1968 DWORD i;
1969 BOOL ret;
1970 BYTE *buf = NULL;
1971 DWORD bufSize = 0;
1973 /* First test with simpler info2 */
1974 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
1976 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
1977 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
1978 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1979 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
1980 GetLastError());
1981 if (buf)
1983 CERT_BASIC_CONSTRAINTS2_INFO *info =
1984 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
1986 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
1987 "Unexpected value for item %d\n", i);
1988 LocalFree(buf);
1991 /* Check with the order of encoded elements inverted */
1992 buf = (PBYTE)1;
1993 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
1994 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1995 &bufSize);
1996 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
1997 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
1998 ok(!buf, "Expected buf to be set to NULL\n");
1999 /* Check with a non-DER bool */
2000 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2001 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2002 (BYTE *)&buf, &bufSize);
2003 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2004 if (buf)
2006 CERT_BASIC_CONSTRAINTS2_INFO *info =
2007 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2009 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2010 LocalFree(buf);
2012 /* Check with a non-basic constraints value */
2013 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2014 (LPBYTE)encodedCommonName, encodedCommonName[1] + 2,
2015 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2016 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2017 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2018 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2019 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2020 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2021 (BYTE *)&buf, &bufSize);
2022 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2023 if (buf)
2025 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2027 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2028 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2029 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2030 LocalFree(buf);
2032 ret = CryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2033 constraintWithDomainName, sizeof(constraintWithDomainName),
2034 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2035 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2036 if (buf)
2038 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2040 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2041 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2042 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2043 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2045 ok(info->rgSubtreesConstraint[0].cbData ==
2046 sizeof(encodedDomainName), "Wrong size %d\n",
2047 info->rgSubtreesConstraint[0].cbData);
2048 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2049 sizeof(encodedDomainName)), "Unexpected value\n");
2051 LocalFree(buf);
2055 /* These are terrible public keys of course, I'm just testing encoding */
2056 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2057 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2058 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2059 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2060 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2061 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2062 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2063 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2065 struct EncodedRSAPubKey
2067 const BYTE *modulus;
2068 size_t modulusLen;
2069 const BYTE *encoded;
2070 size_t decodedModulusLen;
2073 struct EncodedRSAPubKey rsaPubKeys[] = {
2074 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2075 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2076 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2077 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2080 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2082 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2083 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2084 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2085 BOOL ret;
2086 BYTE *buf = NULL;
2087 DWORD bufSize = 0, i;
2089 /* Try with a bogus blob type */
2090 hdr->bType = 2;
2091 hdr->bVersion = CUR_BLOB_VERSION;
2092 hdr->reserved = 0;
2093 hdr->aiKeyAlg = CALG_RSA_KEYX;
2094 rsaPubKey->magic = 0x31415352;
2095 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2096 rsaPubKey->pubexp = 65537;
2097 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2098 sizeof(modulus1));
2100 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2101 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2102 &bufSize);
2103 ok(!ret && GetLastError() == E_INVALIDARG,
2104 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2105 /* Now with a bogus reserved field */
2106 hdr->bType = PUBLICKEYBLOB;
2107 hdr->reserved = 1;
2108 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2109 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2110 &bufSize);
2111 if (buf)
2113 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2114 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2115 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2116 LocalFree(buf);
2118 /* Now with a bogus blob version */
2119 hdr->reserved = 0;
2120 hdr->bVersion = 0;
2121 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2122 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2123 &bufSize);
2124 if (buf)
2126 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2127 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2128 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2129 LocalFree(buf);
2131 /* And with a bogus alg ID */
2132 hdr->bVersion = CUR_BLOB_VERSION;
2133 hdr->aiKeyAlg = CALG_DES;
2134 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2135 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2136 &bufSize);
2137 if (buf)
2139 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2140 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2141 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2142 LocalFree(buf);
2144 /* Check a couple of RSA-related OIDs */
2145 hdr->aiKeyAlg = CALG_RSA_KEYX;
2146 ret = CryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2147 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2148 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2149 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2150 ret = CryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2151 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2152 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2153 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2154 /* Finally, all valid */
2155 hdr->aiKeyAlg = CALG_RSA_KEYX;
2156 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2158 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2159 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2160 ret = CryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2161 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2162 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2163 if (buf)
2165 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2166 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2167 bufSize);
2168 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2169 "Unexpected value\n");
2170 LocalFree(buf);
2175 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2177 DWORD i;
2178 LPBYTE buf = NULL;
2179 DWORD bufSize = 0;
2180 BOOL ret;
2182 /* Try with a bad length */
2183 ret = CryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2184 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2185 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2186 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2187 "Expected CRYPT_E_ASN1_EOD, got %08x\n", CRYPT_E_ASN1_EOD);
2188 /* Try with a couple of RSA-related OIDs */
2189 ret = CryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2190 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2191 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2192 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2193 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2194 ret = CryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2195 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2196 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2197 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2198 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2199 /* Now try success cases */
2200 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2202 bufSize = 0;
2203 ret = CryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2204 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2205 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2206 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2207 if (buf)
2209 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2210 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2212 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2213 rsaPubKeys[i].decodedModulusLen,
2214 "Wrong size %d\n", bufSize);
2215 ok(hdr->bType == PUBLICKEYBLOB,
2216 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2217 hdr->bType);
2218 ok(hdr->bVersion == CUR_BLOB_VERSION,
2219 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2220 CUR_BLOB_VERSION, hdr->bVersion);
2221 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2222 hdr->reserved);
2223 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2224 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2225 ok(rsaPubKey->magic == 0x31415352,
2226 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2227 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2228 "Wrong bit len %d\n", rsaPubKey->bitlen);
2229 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2230 rsaPubKey->pubexp);
2231 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2232 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2233 "Unexpected modulus\n");
2234 LocalFree(buf);
2239 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2240 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2241 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2243 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2244 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2245 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2246 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2248 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2250 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2251 CRYPT_SEQUENCE_OF_ANY seq;
2252 DWORD i;
2253 BOOL ret;
2254 BYTE *buf = NULL;
2255 DWORD bufSize = 0;
2257 /* Encode a homogenous sequence */
2258 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2260 blobs[i].cbData = ints[i].encoded[1] + 2;
2261 blobs[i].pbData = (BYTE *)ints[i].encoded;
2263 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2264 seq.rgValue = blobs;
2266 ret = CryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2267 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2268 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2269 if (buf)
2271 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2272 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2273 LocalFree(buf);
2275 /* Change the type of the first element in the sequence, and give it
2276 * another go
2278 blobs[0].cbData = times[0].encodedTime[1] + 2;
2279 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2280 ret = CryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2281 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2282 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2283 if (buf)
2285 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2286 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2287 "Unexpected value\n");
2288 LocalFree(buf);
2292 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2294 BOOL ret;
2295 BYTE *buf = NULL;
2296 DWORD bufSize = 0;
2298 ret = CryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2299 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2300 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2301 if (buf)
2303 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2304 DWORD i;
2306 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2307 "Wrong elements %d\n", seq->cValue);
2308 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2310 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2311 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2312 seq->rgValue[i].cbData);
2313 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2314 ints[i].encoded[1] + 2), "Unexpected value\n");
2316 LocalFree(buf);
2318 ret = CryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2319 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2320 &bufSize);
2321 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2322 if (buf)
2324 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2326 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2327 "Wrong elements %d\n", seq->cValue);
2328 /* Just check the first element since it's all that changed */
2329 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2330 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2331 seq->rgValue[0].cbData);
2332 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2333 times[0].encodedTime[1] + 2), "Unexpected value\n");
2334 LocalFree(buf);
2338 struct encodedExtensions
2340 CERT_EXTENSIONS exts;
2341 const BYTE *encoded;
2344 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2345 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2346 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2347 static CERT_EXTENSION criticalExt =
2348 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2349 static CERT_EXTENSION nonCriticalExt =
2350 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2352 static const BYTE ext0[] = { 0x30,0x00 };
2353 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2354 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2355 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2356 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2358 static const struct encodedExtensions exts[] = {
2359 { { 0, NULL }, ext0 },
2360 { { 1, &criticalExt }, ext1 },
2361 { { 1, &nonCriticalExt }, ext2 },
2364 static void test_encodeExtensions(DWORD dwEncoding)
2366 DWORD i;
2368 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2370 BOOL ret;
2371 BYTE *buf = NULL;
2372 DWORD bufSize = 0;
2374 ret = CryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2375 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2376 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2377 if (buf)
2379 ok(bufSize == exts[i].encoded[1] + 2,
2380 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2381 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2382 "Unexpected value\n");
2383 LocalFree(buf);
2388 static void test_decodeExtensions(DWORD dwEncoding)
2390 DWORD i;
2392 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2394 BOOL ret;
2395 BYTE *buf = NULL;
2396 DWORD bufSize = 0;
2398 ret = CryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2399 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2400 NULL, (BYTE *)&buf, &bufSize);
2401 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2402 if (buf)
2404 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2405 DWORD j;
2407 ok(ext->cExtension == exts[i].exts.cExtension,
2408 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2409 ext->cExtension);
2410 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2412 ok(!strcmp(ext->rgExtension[j].pszObjId,
2413 exts[i].exts.rgExtension[j].pszObjId),
2414 "Expected OID %s, got %s\n",
2415 exts[i].exts.rgExtension[j].pszObjId,
2416 ext->rgExtension[j].pszObjId);
2417 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2418 exts[i].exts.rgExtension[j].Value.pbData,
2419 exts[i].exts.rgExtension[j].Value.cbData),
2420 "Unexpected value\n");
2422 LocalFree(buf);
2427 /* MS encodes public key info with a NULL if the algorithm identifier's
2428 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2429 * it encodes them by omitting the algorithm parameters. This latter approach
2430 * seems more correct, so accept either form.
2432 struct encodedPublicKey
2434 CERT_PUBLIC_KEY_INFO info;
2435 const BYTE *encoded;
2436 const BYTE *encodedNoNull;
2437 CERT_PUBLIC_KEY_INFO decoded;
2440 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2441 0xe, 0xf };
2442 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2444 static const unsigned char bin64[] = {
2445 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2446 static const unsigned char bin65[] = {
2447 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2448 static const unsigned char bin66[] = {
2449 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2450 static const unsigned char bin67[] = {
2451 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2452 static const unsigned char bin68[] = {
2453 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2454 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2455 static const unsigned char bin69[] = {
2456 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2457 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2458 static const unsigned char bin70[] = {
2459 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2460 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2461 0x0f};
2462 static const unsigned char bin71[] = {
2463 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2464 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2465 0x0f};
2466 static unsigned char bin72[] = { 0x05,0x00};
2468 static CHAR oid_bogus[] = "1.2.3",
2469 oid_rsa[] = szOID_RSA;
2471 static const struct encodedPublicKey pubKeys[] = {
2472 /* with a bogus OID */
2473 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2474 bin64, bin65,
2475 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2476 /* some normal keys */
2477 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2478 bin66, bin67,
2479 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2480 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2481 bin68, bin69,
2482 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2483 /* with add'l parameters--note they must be DER-encoded */
2484 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2485 (BYTE *)aKey, 0 } },
2486 bin70, bin71,
2487 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2488 (BYTE *)aKey, 0 } } },
2491 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2493 DWORD i;
2495 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2497 BOOL ret;
2498 BYTE *buf = NULL;
2499 DWORD bufSize = 0;
2501 ret = CryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2502 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2503 &bufSize);
2504 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2505 if (buf)
2507 ok(bufSize == pubKeys[i].encoded[1] + 2 ||
2508 bufSize == pubKeys[i].encodedNoNull[1] + 2,
2509 "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
2510 pubKeys[i].encodedNoNull[1] + 2, bufSize);
2511 if (bufSize == pubKeys[i].encoded[1] + 2)
2512 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2513 "Unexpected value\n");
2514 else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
2515 ok(!memcmp(buf, pubKeys[i].encodedNoNull,
2516 pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
2517 LocalFree(buf);
2522 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2523 const CERT_PUBLIC_KEY_INFO *got)
2525 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2526 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2527 got->Algorithm.pszObjId);
2528 ok(expected->Algorithm.Parameters.cbData ==
2529 got->Algorithm.Parameters.cbData,
2530 "Expected parameters of %d bytes, got %d\n",
2531 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2532 if (expected->Algorithm.Parameters.cbData)
2533 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2534 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2535 "Unexpected algorithm parameters\n");
2536 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2537 "Expected public key of %d bytes, got %d\n",
2538 expected->PublicKey.cbData, got->PublicKey.cbData);
2539 if (expected->PublicKey.cbData)
2540 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2541 got->PublicKey.cbData), "Unexpected public key value\n");
2544 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2546 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2547 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2548 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2549 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2550 DWORD i;
2551 BOOL ret;
2552 BYTE *buf = NULL;
2553 DWORD bufSize = 0;
2555 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2557 /* The NULL form decodes to the decoded member */
2558 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2559 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2560 NULL, (BYTE *)&buf, &bufSize);
2561 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2562 if (buf)
2564 comparePublicKeyInfo(&pubKeys[i].decoded,
2565 (CERT_PUBLIC_KEY_INFO *)buf);
2566 LocalFree(buf);
2568 /* The non-NULL form decodes to the original */
2569 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2570 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2571 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2572 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2573 if (buf)
2575 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2576 LocalFree(buf);
2579 /* Test with bogus (not valid DER) parameters */
2580 ret = CryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2581 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2582 NULL, (BYTE *)&buf, &bufSize);
2583 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2584 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2587 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2588 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2589 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2590 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2591 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2592 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2593 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2594 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2595 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2596 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2597 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2598 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2599 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2600 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2601 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2602 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2603 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2604 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2605 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2606 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2607 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2608 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2609 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2610 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2611 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2612 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2613 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2614 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2615 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2616 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2617 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2618 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2619 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2620 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2621 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2622 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2623 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2624 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2625 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2627 static const BYTE serialNum[] = { 0x01 };
2629 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2631 BOOL ret;
2632 BYTE *buf = NULL;
2633 DWORD size = 0;
2634 CERT_INFO info = { 0 };
2636 /* Test with NULL pvStructInfo */
2637 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2638 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2639 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2640 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2641 /* Test with a V1 cert */
2642 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2643 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2644 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2645 if (buf)
2647 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2648 v1Cert[1] + 2, size);
2649 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2650 LocalFree(buf);
2652 /* Test v2 cert */
2653 info.dwVersion = CERT_V2;
2654 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2655 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2656 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2657 if (buf)
2659 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2660 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2661 LocalFree(buf);
2663 /* Test v3 cert */
2664 info.dwVersion = CERT_V3;
2665 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2666 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2667 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2668 if (buf)
2670 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2671 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2672 LocalFree(buf);
2674 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2675 * API doesn't prevent it)
2677 info.dwVersion = CERT_V1;
2678 info.cExtension = 1;
2679 info.rgExtension = &criticalExt;
2680 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2681 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2682 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2683 if (buf)
2685 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2686 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2687 LocalFree(buf);
2689 /* test v1 cert with a serial number */
2690 info.SerialNumber.cbData = sizeof(serialNum);
2691 info.SerialNumber.pbData = (BYTE *)serialNum;
2692 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2693 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2694 if (buf)
2696 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2697 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2698 LocalFree(buf);
2700 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2701 info.Issuer.cbData = sizeof(encodedCommonName);
2702 info.Issuer.pbData = (BYTE *)encodedCommonName;
2703 info.Subject.cbData = sizeof(encodedCommonName);
2704 info.Subject.pbData = (BYTE *)encodedCommonName;
2705 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2706 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2707 if (buf)
2709 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
2710 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
2711 LocalFree(buf);
2713 /* for now, I let more interesting tests be done for each subcomponent,
2714 * rather than retesting them all here.
2718 static void test_decodeCertToBeSigned(DWORD dwEncoding)
2720 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
2721 v1CertWithConstraints, v1CertWithSerial };
2722 BOOL ret;
2723 BYTE *buf = NULL;
2724 DWORD size = 0, i;
2726 /* Test with NULL pbEncoded */
2727 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
2728 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2729 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2730 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2731 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
2732 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2733 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2734 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2735 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
2736 * minimum a cert must have a non-zero serial number, an issuer, and a
2737 * subject.
2739 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
2741 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
2742 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2743 (BYTE *)&buf, &size);
2744 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT),
2745 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2747 /* Now check with serial number, subject and issuer specified */
2748 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
2749 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2750 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2751 if (buf)
2753 CERT_INFO *info = (CERT_INFO *)buf;
2755 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
2756 ok(info->SerialNumber.cbData == 1,
2757 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
2758 ok(*info->SerialNumber.pbData == *serialNum,
2759 "Expected serial number %d, got %d\n", *serialNum,
2760 *info->SerialNumber.pbData);
2761 ok(info->Issuer.cbData == sizeof(encodedCommonName),
2762 "Wrong size %d\n", info->Issuer.cbData);
2763 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
2764 "Unexpected issuer\n");
2765 ok(info->Subject.cbData == sizeof(encodedCommonName),
2766 "Wrong size %d\n", info->Subject.cbData);
2767 ok(!memcmp(info->Subject.pbData, encodedCommonName,
2768 info->Subject.cbData), "Unexpected subject\n");
2769 LocalFree(buf);
2773 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2774 0xe, 0xf };
2776 static const BYTE signedBigCert[] = {
2777 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
2778 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
2779 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
2780 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2781 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2782 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
2783 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
2784 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
2785 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
2786 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2787 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
2788 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
2790 static void test_encodeCert(DWORD dwEncoding)
2792 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
2793 * also that bigCert is a NULL-terminated string, so don't count its
2794 * last byte (otherwise the signed cert won't decode.)
2796 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
2797 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
2798 BOOL ret;
2799 BYTE *buf = NULL;
2800 DWORD bufSize = 0;
2802 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
2803 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2804 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2805 if (buf)
2807 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
2808 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
2809 LocalFree(buf);
2813 static void test_decodeCert(DWORD dwEncoding)
2815 BOOL ret;
2816 BYTE *buf = NULL;
2817 DWORD size = 0;
2819 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
2820 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2821 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2822 if (buf)
2824 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
2826 ok(info->ToBeSigned.cbData == sizeof(bigCert),
2827 "Wrong cert size %d\n", info->ToBeSigned.cbData);
2828 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
2829 "Unexpected cert\n");
2830 ok(info->Signature.cbData == sizeof(hash),
2831 "Wrong signature size %d\n", info->Signature.cbData);
2832 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
2833 "Unexpected signature\n");
2834 LocalFree(buf);
2836 /* A signed cert decodes as a CERT_INFO too */
2837 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
2838 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2839 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2840 if (buf)
2842 CERT_INFO *info = (CERT_INFO *)buf;
2844 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
2845 ok(info->SerialNumber.cbData == 1,
2846 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
2847 ok(*info->SerialNumber.pbData == *serialNum,
2848 "Expected serial number %d, got %d\n", *serialNum,
2849 *info->SerialNumber.pbData);
2850 ok(info->Issuer.cbData == sizeof(encodedCommonName),
2851 "Wrong size %d\n", info->Issuer.cbData);
2852 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
2853 "Unexpected issuer\n");
2854 ok(info->Subject.cbData == sizeof(encodedCommonName),
2855 "Wrong size %d\n", info->Subject.cbData);
2856 ok(!memcmp(info->Subject.pbData, encodedCommonName,
2857 info->Subject.cbData), "Unexpected subject\n");
2858 LocalFree(buf);
2862 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
2863 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
2864 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
2865 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
2866 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
2867 0x00, 0x03 };
2868 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
2869 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
2870 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
2871 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
2872 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
2873 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
2874 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
2875 0x2e, 0x6f, 0x72, 0x67 };
2876 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
2877 CRL_REASON_AFFILIATION_CHANGED;
2879 static void test_encodeCRLDistPoints(DWORD dwEncoding)
2881 CRL_DIST_POINTS_INFO info = { 0 };
2882 CRL_DIST_POINT point = { { 0 } };
2883 CERT_ALT_NAME_ENTRY entry = { 0 };
2884 BOOL ret;
2885 BYTE *buf = NULL;
2886 DWORD size = 0;
2888 /* Test with an empty info */
2889 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
2890 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2891 ok(!ret && GetLastError() == E_INVALIDARG,
2892 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2893 /* Test with one empty dist point */
2894 info.cDistPoint = 1;
2895 info.rgDistPoint = &point;
2896 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
2897 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2898 if (buf)
2900 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
2901 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
2902 LocalFree(buf);
2904 /* A dist point with an invalid name */
2905 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
2906 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
2907 U(entry).pwszURL = (LPWSTR)nihongoURL;
2908 U(point.DistPointName).FullName.cAltEntry = 1;
2909 U(point.DistPointName).FullName.rgAltEntry = &entry;
2910 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
2911 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2912 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
2913 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
2914 /* The first invalid character is at index 7 */
2915 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
2916 "Expected invalid char at index 7, got %d\n",
2917 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
2918 /* A dist point with (just) a valid name */
2919 U(entry).pwszURL = (LPWSTR)url;
2920 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
2921 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2922 if (buf)
2924 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
2925 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
2926 LocalFree(buf);
2928 /* A dist point with (just) reason flags */
2929 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
2930 point.ReasonFlags.cbData = sizeof(crlReason);
2931 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
2932 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
2933 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2934 if (buf)
2936 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
2937 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
2938 LocalFree(buf);
2940 /* A dist point with just an issuer */
2941 point.ReasonFlags.cbData = 0;
2942 point.CRLIssuer.cAltEntry = 1;
2943 point.CRLIssuer.rgAltEntry = &entry;
2944 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
2945 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2946 if (buf)
2948 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
2949 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
2950 LocalFree(buf);
2952 /* A dist point with both a name and an issuer */
2953 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
2954 ret = CryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
2955 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2956 if (buf)
2958 ok(size == sizeof(distPointWithUrlAndIssuer),
2959 "Wrong size %d\n", size);
2960 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
2961 LocalFree(buf);
2965 static void test_decodeCRLDistPoints(DWORD dwEncoding)
2967 BOOL ret;
2968 BYTE *buf = NULL;
2969 DWORD size = 0;
2970 PCRL_DIST_POINTS_INFO info;
2971 PCRL_DIST_POINT point;
2972 PCERT_ALT_NAME_ENTRY entry;
2974 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
2975 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2976 (BYTE *)&buf, &size);
2977 if (ret)
2979 info = (PCRL_DIST_POINTS_INFO)buf;
2980 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
2981 "Wrong size %d\n", size);
2982 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
2983 info->cDistPoint);
2984 point = info->rgDistPoint;
2985 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
2986 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
2987 point->DistPointName.dwDistPointNameChoice);
2988 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
2989 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
2990 LocalFree(buf);
2992 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
2993 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2994 (BYTE *)&buf, &size);
2995 if (ret)
2997 info = (PCRL_DIST_POINTS_INFO)buf;
2998 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
2999 "Wrong size %d\n", size);
3000 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3001 info->cDistPoint);
3002 point = info->rgDistPoint;
3003 ok(point->DistPointName.dwDistPointNameChoice ==
3004 CRL_DIST_POINT_FULL_NAME,
3005 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3006 point->DistPointName.dwDistPointNameChoice);
3007 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3008 "Expected 1 name entry, got %d\n",
3009 U(point->DistPointName).FullName.cAltEntry);
3010 entry = U(point->DistPointName).FullName.rgAltEntry;
3011 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3012 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3013 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3014 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3015 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3016 LocalFree(buf);
3018 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3019 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3020 NULL, (BYTE *)&buf, &size);
3021 if (ret)
3023 info = (PCRL_DIST_POINTS_INFO)buf;
3024 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3025 "Wrong size %d\n", size);
3026 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3027 info->cDistPoint);
3028 point = info->rgDistPoint;
3029 ok(point->DistPointName.dwDistPointNameChoice ==
3030 CRL_DIST_POINT_NO_NAME,
3031 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3032 point->DistPointName.dwDistPointNameChoice);
3033 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3034 "Expected reason length\n");
3035 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3036 "Unexpected reason\n");
3037 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3038 LocalFree(buf);
3040 ret = CryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3041 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3042 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3043 if (ret)
3045 info = (PCRL_DIST_POINTS_INFO)buf;
3046 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3047 "Wrong size %d\n", size);
3048 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3049 info->cDistPoint);
3050 point = info->rgDistPoint;
3051 ok(point->DistPointName.dwDistPointNameChoice ==
3052 CRL_DIST_POINT_FULL_NAME,
3053 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3054 point->DistPointName.dwDistPointNameChoice);
3055 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3056 "Expected 1 name entry, got %d\n",
3057 U(point->DistPointName).FullName.cAltEntry);
3058 entry = U(point->DistPointName).FullName.rgAltEntry;
3059 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3060 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3061 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3062 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3063 ok(point->CRLIssuer.cAltEntry == 1,
3064 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3065 entry = point->CRLIssuer.rgAltEntry;
3066 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3067 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3068 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3069 LocalFree(buf);
3073 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3074 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3075 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3076 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3077 0x67 };
3079 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3081 BOOL ret;
3082 BYTE *buf = NULL;
3083 DWORD size = 0;
3084 CRL_ISSUING_DIST_POINT point = { { 0 } };
3085 CERT_ALT_NAME_ENTRY entry;
3087 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3088 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3089 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3090 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3091 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3092 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3093 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3094 if (buf)
3096 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3097 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3098 LocalFree(buf);
3100 /* nonsensical flags */
3101 point.fOnlyContainsUserCerts = TRUE;
3102 point.fOnlyContainsCACerts = TRUE;
3103 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3104 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3105 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3106 if (buf)
3108 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3109 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3110 LocalFree(buf);
3112 /* unimplemented name type */
3113 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3114 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3115 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3116 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3117 ok(!ret && GetLastError() == E_INVALIDARG,
3118 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3119 /* empty name */
3120 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3121 U(point.DistPointName).FullName.cAltEntry = 0;
3122 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3123 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3124 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3125 if (buf)
3127 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3128 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3129 LocalFree(buf);
3131 /* name with URL entry */
3132 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3133 U(entry).pwszURL = (LPWSTR)url;
3134 U(point.DistPointName).FullName.cAltEntry = 1;
3135 U(point.DistPointName).FullName.rgAltEntry = &entry;
3136 ret = CryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3137 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3138 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3139 if (buf)
3141 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3142 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3143 LocalFree(buf);
3147 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3148 const CERT_ALT_NAME_ENTRY *got)
3150 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3151 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3152 got->dwAltNameChoice);
3153 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3155 switch (got->dwAltNameChoice)
3157 case CERT_ALT_NAME_RFC822_NAME:
3158 case CERT_ALT_NAME_DNS_NAME:
3159 case CERT_ALT_NAME_EDI_PARTY_NAME:
3160 case CERT_ALT_NAME_URL:
3161 case CERT_ALT_NAME_REGISTERED_ID:
3162 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3163 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL), "Unexpected name\n");
3164 break;
3165 case CERT_ALT_NAME_X400_ADDRESS:
3166 case CERT_ALT_NAME_DIRECTORY_NAME:
3167 case CERT_ALT_NAME_IP_ADDRESS:
3168 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3169 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3170 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3171 U(*got).IPAddress.cbData), "Unexpected value\n");
3172 break;
3177 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3178 const CERT_ALT_NAME_INFO *got)
3180 DWORD i;
3182 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3183 expected->cAltEntry, got->cAltEntry);
3184 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3185 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3188 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3189 const CRL_DIST_POINT_NAME *got)
3191 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3192 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3193 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3194 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3197 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3198 const CRL_ISSUING_DIST_POINT *got)
3200 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3201 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3202 "Unexpected fOnlyContainsUserCerts\n");
3203 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3204 "Unexpected fOnlyContainsCACerts\n");
3205 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3206 "Unexpected reason flags\n");
3207 ok(got->fIndirectCRL == expected->fIndirectCRL,
3208 "Unexpected fIndirectCRL\n");
3211 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3213 BOOL ret;
3214 BYTE *buf = NULL;
3215 DWORD size = 0;
3216 CRL_ISSUING_DIST_POINT point = { { 0 } };
3218 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3219 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3220 (BYTE *)&buf, &size);
3221 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3222 if (ret)
3224 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3225 LocalFree(buf);
3227 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3228 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3229 (BYTE *)&buf, &size);
3230 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3231 if (ret)
3233 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3234 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3235 LocalFree(buf);
3237 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3238 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3239 (BYTE *)&buf, &size);
3240 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3241 if (ret)
3243 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3244 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3245 U(point.DistPointName).FullName.cAltEntry = 0;
3246 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3247 LocalFree(buf);
3249 ret = CryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3250 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3251 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3252 if (ret)
3254 CERT_ALT_NAME_ENTRY entry;
3256 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3257 U(entry).pwszURL = (LPWSTR)url;
3258 U(point.DistPointName).FullName.cAltEntry = 1;
3259 U(point.DistPointName).FullName.rgAltEntry = &entry;
3260 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3261 LocalFree(buf);
3265 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3266 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3267 0x30, 0x5a };
3268 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3269 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3270 0x30, 0x30, 0x30, 0x30, 0x5a };
3271 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3272 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3273 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3274 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3275 0x5a };
3276 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3277 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3278 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3279 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3280 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3281 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3282 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3283 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3284 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3285 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3286 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3287 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3288 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3289 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3290 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3291 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3292 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3293 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3294 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3295 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3296 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3297 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3298 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3299 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3300 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3301 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3302 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3303 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3304 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3305 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3306 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3307 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3308 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3309 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3310 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3311 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3312 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3313 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3314 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3315 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3317 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3319 BOOL ret;
3320 BYTE *buf = NULL;
3321 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3322 DWORD size = 0;
3323 CRL_INFO info = { 0 };
3324 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3325 CERT_EXTENSION ext;
3327 /* Test with a V1 CRL */
3328 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3329 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3330 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3331 if (buf)
3333 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3334 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3335 LocalFree(buf);
3337 /* Test v2 CRL */
3338 info.dwVersion = CRL_V2;
3339 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3340 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3341 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3342 if (buf)
3344 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3345 v2CRL[1] + 2, size);
3346 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3347 LocalFree(buf);
3349 /* v1 CRL with a name */
3350 info.dwVersion = CRL_V1;
3351 info.Issuer.cbData = sizeof(encodedCommonName);
3352 info.Issuer.pbData = (BYTE *)encodedCommonName;
3353 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3354 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3355 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3356 if (buf)
3358 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3359 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3360 LocalFree(buf);
3362 /* v1 CRL with a name and a NULL entry pointer */
3363 info.cCRLEntry = 1;
3364 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3365 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3366 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3367 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3368 /* now set an empty entry */
3369 info.rgCRLEntry = &entry;
3370 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3371 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3372 if (buf)
3374 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3375 "Wrong size %d\n", size);
3376 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3377 "Got unexpected value\n");
3378 LocalFree(buf);
3380 /* an entry with a serial number */
3381 entry.SerialNumber.cbData = sizeof(serialNum);
3382 entry.SerialNumber.pbData = (BYTE *)serialNum;
3383 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3384 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3385 if (buf)
3387 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3388 "Wrong size %d\n", size);
3389 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3390 "Got unexpected value\n");
3391 LocalFree(buf);
3393 /* an entry with an extension */
3394 entry.cExtension = 1;
3395 entry.rgExtension = &criticalExt;
3396 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3397 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3398 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3399 if (buf)
3401 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3402 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3403 LocalFree(buf);
3405 /* a CRL with an extension */
3406 entry.cExtension = 0;
3407 info.cExtension = 1;
3408 info.rgExtension = &criticalExt;
3409 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3410 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3411 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3412 if (buf)
3414 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3415 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3416 LocalFree(buf);
3418 /* a v2 CRL with an extension, this time non-critical */
3419 info.dwVersion = CRL_V2;
3420 info.rgExtension = &nonCriticalExt;
3421 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3422 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3423 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3424 if (buf)
3426 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3427 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3428 LocalFree(buf);
3430 /* a v2 CRL with an issuing dist point extension */
3431 ext.pszObjId = oid_issuing_dist_point;
3432 ext.fCritical = TRUE;
3433 ext.Value.cbData = sizeof(urlIDP);
3434 ext.Value.pbData = (LPBYTE)urlIDP;
3435 entry.rgExtension = &ext;
3436 ret = CryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3437 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3438 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3439 if (buf)
3441 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3442 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3443 LocalFree(buf);
3447 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3448 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3449 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3450 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3451 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3452 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3453 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3454 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3455 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3456 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3457 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3458 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3459 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3460 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3461 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3462 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3463 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3464 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3465 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3466 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3467 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3468 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3469 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3470 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3471 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3472 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3473 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3474 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3475 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3476 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3477 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3478 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3479 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3480 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3481 0xcd };
3482 static const BYTE verisignCRLWithLotsOfEntries[] = {
3483 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3484 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3485 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3486 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3487 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3488 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3489 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3490 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3491 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3492 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3493 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3494 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3495 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3496 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3497 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3498 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3499 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3500 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3501 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3502 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3503 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3504 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3505 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3506 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3507 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3508 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3509 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3510 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3511 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3512 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3513 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3514 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3515 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3516 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3517 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3518 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3519 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3520 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3521 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3522 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3523 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3524 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3525 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3526 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3527 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3528 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3529 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3530 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3531 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3532 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3533 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3534 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3535 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3536 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3537 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3538 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3539 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3540 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3541 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3542 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3543 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3544 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3545 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3546 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3547 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3548 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3549 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3550 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3551 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3552 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3553 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3554 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3555 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3556 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3557 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3558 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3559 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3560 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3561 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3562 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3563 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3564 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3565 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3566 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3567 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3568 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3569 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3570 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3571 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3572 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3573 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3574 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3575 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3576 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3577 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3578 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3579 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3580 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3581 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3582 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3583 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3584 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3585 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3586 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3587 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3588 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3589 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3590 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3591 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3592 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3593 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3594 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3595 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3596 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3597 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3598 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3599 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3600 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3601 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3602 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3603 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3604 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3605 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3606 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3607 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3608 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3609 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3610 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3611 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3612 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3613 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3614 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3615 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3616 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3617 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3618 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3619 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3620 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3621 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3622 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3623 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3624 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3625 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3626 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3627 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3628 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3629 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3630 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3631 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3632 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3633 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3634 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3635 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3636 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3637 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3638 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3639 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3640 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3641 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3642 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3643 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3644 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3645 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3646 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3647 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3648 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3649 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3650 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3651 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3652 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3653 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3654 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3655 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3656 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3657 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3658 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3659 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3660 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3661 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3662 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3663 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3664 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
3665 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
3666 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
3667 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
3668 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
3669 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
3670 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
3671 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
3672 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
3673 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
3674 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
3675 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
3676 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
3677 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
3678 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
3679 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
3680 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
3681 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
3682 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
3683 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
3684 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
3685 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
3686 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
3687 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
3688 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
3689 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
3690 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
3691 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
3692 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
3693 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
3694 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
3695 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
3696 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
3697 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
3698 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
3699 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
3700 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
3701 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
3702 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
3703 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
3704 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
3705 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
3706 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
3707 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
3708 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
3709 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
3710 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
3711 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
3712 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
3713 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
3714 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
3715 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
3716 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
3717 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
3718 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
3719 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
3720 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
3721 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
3722 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
3723 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
3724 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
3725 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
3726 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
3727 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
3728 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
3729 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
3730 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
3731 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
3732 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
3733 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
3734 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
3735 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
3736 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
3737 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
3738 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
3739 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
3740 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
3741 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
3742 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
3743 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
3744 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
3745 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
3746 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
3747 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
3748 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
3749 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
3750 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
3751 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
3752 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
3753 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
3754 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
3755 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
3756 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
3757 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
3758 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
3759 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
3760 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
3761 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
3762 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
3763 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
3764 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
3765 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
3766 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
3767 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
3768 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
3769 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
3770 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
3771 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
3772 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
3773 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
3774 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
3775 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
3776 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
3777 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
3778 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
3779 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
3780 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
3781 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
3782 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
3783 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
3784 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
3785 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
3786 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
3787 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
3788 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
3789 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
3790 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
3791 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
3792 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
3793 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
3794 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
3795 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
3796 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
3797 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
3798 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
3799 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
3800 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
3801 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
3802 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
3803 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
3804 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
3805 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
3806 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
3807 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
3808 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
3809 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
3810 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
3811 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
3812 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
3813 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
3814 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
3815 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
3816 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
3817 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
3818 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
3819 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
3820 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
3821 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
3822 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
3823 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
3824 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
3825 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
3826 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
3827 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
3828 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
3829 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
3830 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
3831 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
3832 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
3833 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
3834 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
3835 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
3836 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
3837 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
3838 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
3839 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
3840 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
3841 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
3842 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
3843 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
3844 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
3845 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
3846 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
3847 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
3848 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
3849 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
3850 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
3851 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
3852 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
3853 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
3854 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
3855 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
3856 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
3857 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
3858 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
3859 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
3860 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
3861 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
3862 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
3863 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
3864 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
3865 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
3866 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
3867 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
3868 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
3869 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
3870 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
3871 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
3872 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
3873 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
3874 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
3875 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
3876 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
3877 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
3878 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
3879 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
3880 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
3881 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
3882 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
3883 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
3884 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
3885 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
3886 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
3887 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
3888 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
3889 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
3890 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
3891 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
3892 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
3893 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
3894 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
3895 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
3896 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
3897 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
3898 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
3899 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
3900 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
3901 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
3902 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
3903 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
3904 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
3905 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
3906 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
3907 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
3908 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
3909 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
3910 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
3911 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
3912 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
3913 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
3914 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
3915 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
3916 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
3917 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
3918 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
3919 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
3920 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
3921 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
3922 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
3923 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
3924 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
3925 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
3926 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
3927 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
3928 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
3929 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
3930 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
3931 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
3932 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
3933 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
3934 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
3935 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
3936 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
3937 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
3938 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
3939 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
3940 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
3941 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
3942 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
3943 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
3944 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
3945 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
3946 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
3947 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
3948 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
3949 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
3950 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
3951 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
3952 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
3953 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
3954 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
3955 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
3956 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
3957 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
3958 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
3959 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
3960 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
3961 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
3962 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
3963 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
3964 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
3965 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
3966 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
3967 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
3968 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
3969 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
3970 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
3971 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
3972 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
3973 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
3974 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
3975 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
3976 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
3977 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
3978 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
3979 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
3980 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
3981 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
3982 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
3983 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
3984 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
3985 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
3986 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
3987 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
3988 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
3989 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
3990 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
3992 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
3994 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
3995 BOOL ret;
3996 BYTE *buf = NULL;
3997 DWORD size = 0, i;
3999 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4001 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4002 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4003 (BYTE *)&buf, &size);
4004 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT),
4005 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4007 /* at a minimum, a CRL must contain an issuer: */
4008 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4009 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4010 (BYTE *)&buf, &size);
4011 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4012 if (buf)
4014 CRL_INFO *info = (CRL_INFO *)buf;
4016 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4017 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4018 info->cCRLEntry);
4019 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4020 "Wrong issuer size %d\n", info->Issuer.cbData);
4021 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4022 "Unexpected issuer\n");
4023 LocalFree(buf);
4025 /* check decoding with an empty CRL entry */
4026 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4027 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4028 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4029 todo_wine ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
4030 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4031 /* with a real CRL entry */
4032 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4033 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4034 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4035 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4036 if (buf)
4038 CRL_INFO *info = (CRL_INFO *)buf;
4039 CRL_ENTRY *entry;
4041 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4042 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4043 info->cCRLEntry);
4044 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4045 entry = info->rgCRLEntry;
4046 ok(entry->SerialNumber.cbData == 1,
4047 "Expected serial number size 1, got %d\n",
4048 entry->SerialNumber.cbData);
4049 ok(*entry->SerialNumber.pbData == *serialNum,
4050 "Expected serial number %d, got %d\n", *serialNum,
4051 *entry->SerialNumber.pbData);
4052 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4053 "Wrong issuer size %d\n", info->Issuer.cbData);
4054 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4055 "Unexpected issuer\n");
4057 /* a real CRL from verisign that has extensions */
4058 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4059 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4060 NULL, (BYTE *)&buf, &size);
4061 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4062 if (buf)
4064 CRL_INFO *info = (CRL_INFO *)buf;
4065 CRL_ENTRY *entry;
4067 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4068 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4069 info->cCRLEntry);
4070 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4071 entry = info->rgCRLEntry;
4072 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4073 info->cExtension);
4074 LocalFree(buf);
4076 /* another real CRL from verisign that has lots of entries */
4077 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4078 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4079 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4080 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4081 if (buf)
4083 CRL_INFO *info = (CRL_INFO *)buf;
4085 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4086 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4087 info->cCRLEntry);
4088 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4089 info->cExtension);
4090 LocalFree(buf);
4092 /* and finally, with an extension */
4093 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4094 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4095 NULL, (BYTE *)&buf, &size);
4096 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4097 if (buf)
4099 CRL_INFO *info = (CRL_INFO *)buf;
4100 CRL_ENTRY *entry;
4102 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4103 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4104 info->cCRLEntry);
4105 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4106 entry = info->rgCRLEntry;
4107 ok(entry->SerialNumber.cbData == 1,
4108 "Expected serial number size 1, got %d\n",
4109 entry->SerialNumber.cbData);
4110 ok(*entry->SerialNumber.pbData == *serialNum,
4111 "Expected serial number %d, got %d\n", *serialNum,
4112 *entry->SerialNumber.pbData);
4113 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4114 "Wrong issuer size %d\n", info->Issuer.cbData);
4115 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4116 "Unexpected issuer\n");
4117 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4118 info->cExtension);
4120 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4121 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4122 NULL, (BYTE *)&buf, &size);
4123 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4124 if (buf)
4126 CRL_INFO *info = (CRL_INFO *)buf;
4128 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4129 info->cExtension);
4130 LocalFree(buf);
4132 /* And again, with an issuing dist point */
4133 ret = CryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4134 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4135 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4136 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4137 if (buf)
4139 CRL_INFO *info = (CRL_INFO *)buf;
4141 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4142 info->cExtension);
4143 LocalFree(buf);
4147 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4148 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4149 static const BYTE encodedUsage[] = {
4150 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4151 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4152 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4154 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4156 BOOL ret;
4157 BYTE *buf = NULL;
4158 DWORD size = 0;
4159 CERT_ENHKEY_USAGE usage;
4161 /* Test with empty usage */
4162 usage.cUsageIdentifier = 0;
4163 ret = CryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4164 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4165 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4166 if (buf)
4168 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4169 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4170 LocalFree(buf);
4172 /* Test with a few usages */
4173 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4174 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4175 ret = CryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4176 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4177 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4178 if (buf)
4180 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4181 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4182 LocalFree(buf);
4186 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4188 BOOL ret;
4189 LPBYTE buf = NULL;
4190 DWORD size = 0;
4192 ret = CryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4193 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4194 (BYTE *)&buf, &size);
4195 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4196 if (buf)
4198 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4200 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4201 "Wrong size %d\n", size);
4202 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4203 usage->cUsageIdentifier);
4204 LocalFree(buf);
4206 ret = CryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4207 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4208 (BYTE *)&buf, &size);
4209 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4210 if (buf)
4212 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4213 DWORD i;
4215 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4216 "Wrong size %d\n", size);
4217 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4218 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4219 for (i = 0; i < usage->cUsageIdentifier; i++)
4220 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4221 "Expected OID %s, got %s\n", keyUsages[i],
4222 usage->rgpszUsageIdentifier[i]);
4223 LocalFree(buf);
4227 static const BYTE authorityKeyIdWithId[] = { 0x30,0x03,0x80,0x01,0x01 };
4228 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4229 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4230 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4231 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4233 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4235 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4236 BOOL ret;
4237 BYTE *buf = NULL;
4238 DWORD size = 0;
4240 /* Test with empty id */
4241 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4242 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4243 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4244 if (buf)
4246 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4247 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4248 LocalFree(buf);
4250 /* With just a key id */
4251 info.KeyId.cbData = sizeof(serialNum);
4252 info.KeyId.pbData = (BYTE *)serialNum;
4253 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4254 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4255 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4256 if (buf)
4258 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4259 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4260 LocalFree(buf);
4262 /* With just an issuer */
4263 info.KeyId.cbData = 0;
4264 info.CertIssuer.cbData = sizeof(encodedCommonName);
4265 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4266 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4267 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4268 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4269 if (buf)
4271 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4272 size);
4273 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4274 LocalFree(buf);
4276 /* With just a serial number */
4277 info.CertIssuer.cbData = 0;
4278 info.CertSerialNumber.cbData = sizeof(serialNum);
4279 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4280 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4281 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4282 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4283 if (buf)
4285 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4286 size);
4287 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4288 LocalFree(buf);
4292 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4294 BOOL ret;
4295 LPBYTE buf = NULL;
4296 DWORD size = 0;
4298 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4299 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4300 (BYTE *)&buf, &size);
4301 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4302 if (buf)
4304 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4306 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4307 size);
4308 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4309 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4310 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4311 LocalFree(buf);
4313 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4314 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4315 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4316 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4317 if (buf)
4319 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4321 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4322 size);
4323 ok(info->KeyId.cbData == sizeof(serialNum), "Unexpected key id len\n");
4324 ok(!memcmp(info->KeyId.pbData, serialNum, sizeof(serialNum)),
4325 "Unexpected key id\n");
4326 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4327 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4328 LocalFree(buf);
4330 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4331 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4332 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4333 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4334 if (buf)
4336 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4338 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4339 size);
4340 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4341 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4342 "Unexpected issuer len\n");
4343 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4344 sizeof(encodedCommonName)), "Unexpected issuer\n");
4345 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4346 LocalFree(buf);
4348 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4349 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4350 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4351 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4352 if (buf)
4354 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4356 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4357 size);
4358 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4359 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4360 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4361 "Unexpected serial number len\n");
4362 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4363 "Unexpected serial number\n");
4364 LocalFree(buf);
4368 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4369 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4370 0x6f,0x72,0x67 };
4372 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4374 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4375 CERT_ALT_NAME_ENTRY entry = { 0 };
4376 BOOL ret;
4377 BYTE *buf = NULL;
4378 DWORD size = 0;
4380 /* Test with empty id */
4381 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4382 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4383 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4384 if (buf)
4386 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4387 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4388 LocalFree(buf);
4390 /* With just a key id */
4391 info.KeyId.cbData = sizeof(serialNum);
4392 info.KeyId.pbData = (BYTE *)serialNum;
4393 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4394 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4395 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4396 if (buf)
4398 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4399 size);
4400 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4401 LocalFree(buf);
4403 /* With a bogus issuer name */
4404 info.KeyId.cbData = 0;
4405 info.AuthorityCertIssuer.cAltEntry = 1;
4406 info.AuthorityCertIssuer.rgAltEntry = &entry;
4407 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4408 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4409 ok(!ret && GetLastError() == E_INVALIDARG,
4410 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4411 /* With an issuer name */
4412 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4413 entry.pwszURL = (LPWSTR)url;
4414 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4415 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4416 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4417 if (buf)
4419 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4420 size);
4421 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4422 "Unexpected value\n");
4423 LocalFree(buf);
4425 /* With just a serial number */
4426 info.AuthorityCertIssuer.cAltEntry = 0;
4427 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4428 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4429 ret = CryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4430 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4431 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4432 if (buf)
4434 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4435 size);
4436 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4437 LocalFree(buf);
4441 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4443 BOOL ret;
4444 LPBYTE buf = NULL;
4445 DWORD size = 0;
4447 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4448 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4449 (BYTE *)&buf, &size);
4450 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4451 if (buf)
4453 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4455 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4456 size);
4457 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4458 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4459 "Expected no issuer name entries\n");
4460 ok(info->AuthorityCertSerialNumber.cbData == 0,
4461 "Expected no serial number\n");
4462 LocalFree(buf);
4464 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4465 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4466 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4467 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4468 if (buf)
4470 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4472 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4473 size);
4474 ok(info->KeyId.cbData == sizeof(serialNum), "Unexpected key id len\n");
4475 ok(!memcmp(info->KeyId.pbData, serialNum, sizeof(serialNum)),
4476 "Unexpected key id\n");
4477 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4478 "Expected no issuer name entries\n");
4479 ok(info->AuthorityCertSerialNumber.cbData == 0,
4480 "Expected no serial number\n");
4481 LocalFree(buf);
4483 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4484 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4485 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4486 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4487 if (buf)
4489 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4491 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4492 size);
4493 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4494 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4495 "Expected 1 issuer entry, got %d\n",
4496 info->AuthorityCertIssuer.cAltEntry);
4497 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4498 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4499 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4500 ok(!lstrcmpW(info->AuthorityCertIssuer.rgAltEntry[0].pwszURL,
4501 url), "Unexpected URL\n");
4502 ok(info->AuthorityCertSerialNumber.cbData == 0,
4503 "Expected no serial number\n");
4504 LocalFree(buf);
4506 ret = CryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4507 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4508 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4509 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4510 if (buf)
4512 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4514 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4515 size);
4516 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4517 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4518 "Expected no issuer name entries\n");
4519 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4520 "Unexpected serial number len\n");
4521 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4522 sizeof(serialNum)), "Unexpected serial number\n");
4523 LocalFree(buf);
4527 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
4528 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
4529 0xa0,0x01,0x01 };
4530 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
4531 0x03,0x02,0x01,0x01 };
4532 static BYTE bogusDER[] = { 1 };
4534 static void test_encodePKCSContentInfo(DWORD dwEncoding)
4536 BOOL ret;
4537 BYTE *buf = NULL;
4538 DWORD size = 0;
4539 CRYPT_CONTENT_INFO info = { 0 };
4540 char oid1[] = "1.2.3";
4542 SetLastError(0xdeadbeef);
4543 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
4544 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4545 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4546 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
4547 SetLastError(0xdeadbeef);
4548 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4549 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4550 ok(!ret && GetLastError() == E_INVALIDARG,
4551 "Expected E_INVALIDARG, got %x\n", GetLastError());
4552 info.pszObjId = oid1;
4553 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4554 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4555 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4556 if (buf)
4558 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
4559 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
4560 LocalFree(buf);
4562 info.Content.pbData = bogusDER;
4563 info.Content.cbData = sizeof(bogusDER);
4564 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4565 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4566 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
4567 if (buf)
4569 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
4570 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
4571 LocalFree(buf);
4573 info.Content.pbData = (BYTE *)ints[0].encoded;
4574 info.Content.cbData = ints[0].encoded[1] + 2;
4575 ret = CryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4576 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4577 if (buf)
4579 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
4580 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
4581 LocalFree(buf);
4585 static void test_decodePKCSContentInfo(DWORD dwEncoding)
4587 BOOL ret;
4588 LPBYTE buf = NULL;
4589 DWORD size = 0;
4590 CRYPT_CONTENT_INFO *info;
4592 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4593 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
4594 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4595 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4596 if (buf)
4598 info = (CRYPT_CONTENT_INFO *)buf;
4600 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4601 info->pszObjId);
4602 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
4603 info->Content.cbData);
4604 LocalFree(buf);
4606 SetLastError(0xdeadbeef);
4607 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4608 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
4609 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4610 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
4611 * I doubt an app depends on that.
4613 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
4614 GetLastError() == CRYPT_E_ASN1_CORRUPT),
4615 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
4616 GetLastError());
4617 ret = CryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4618 intPKCSContentInfo, sizeof(intPKCSContentInfo),
4619 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4620 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4621 if (buf)
4623 info = (CRYPT_CONTENT_INFO *)buf;
4625 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4626 info->pszObjId);
4627 ok(info->Content.cbData == ints[0].encoded[1] + 2,
4628 "Unexpected size %d\n", info->Content.cbData);
4629 ok(!memcmp(info->Content.pbData, ints[0].encoded,
4630 info->Content.cbData), "Unexpected value\n");
4634 /* Free *pInfo with HeapFree */
4635 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
4637 BOOL ret;
4638 DWORD size = 0;
4639 HCRYPTKEY key;
4641 /* This crashes
4642 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
4644 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
4645 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4646 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
4647 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
4648 &size);
4649 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4650 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
4651 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
4652 NULL, &size);
4653 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4654 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
4655 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
4656 0, NULL, NULL, &size);
4657 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4658 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
4659 /* Test with no key */
4660 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
4661 0, NULL, NULL, &size);
4662 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
4663 GetLastError());
4664 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
4665 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
4666 if (ret)
4668 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
4669 NULL, 0, NULL, NULL, &size);
4670 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
4671 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
4672 if (*pInfo)
4674 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
4675 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
4676 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
4677 GetLastError());
4678 if (ret)
4680 /* By default (we passed NULL as the OID) the OID is
4681 * szOID_RSA_RSA.
4683 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
4684 "Expected %s, got %s\n", szOID_RSA_RSA,
4685 (*pInfo)->Algorithm.pszObjId);
4691 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
4692 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
4693 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
4694 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
4695 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
4696 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
4697 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
4698 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
4699 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
4700 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
4701 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
4702 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
4703 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
4704 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
4705 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
4706 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
4707 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
4708 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
4709 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
4710 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
4711 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
4712 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
4713 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
4714 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
4715 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
4717 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
4719 BOOL ret;
4720 HCRYPTKEY key;
4721 PCCERT_CONTEXT context;
4723 /* These crash
4724 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
4725 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
4726 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
4727 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
4728 NULL);
4730 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
4731 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
4732 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
4733 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
4734 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
4735 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
4736 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
4737 &key);
4738 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
4739 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
4740 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
4741 &key);
4742 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
4743 CryptDestroyKey(key);
4745 /* Test importing a public key from a certificate context */
4746 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
4747 sizeof(expiredCert));
4748 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
4749 GetLastError());
4750 if (context)
4752 ok(!strcmp(szOID_RSA_RSA,
4753 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
4754 "Expected %s, got %s\n", szOID_RSA_RSA,
4755 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
4756 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
4757 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
4758 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
4759 CryptDestroyKey(key);
4760 CertFreeCertificateContext(context);
4764 static const char cspName[] = "WineCryptTemp";
4766 static void testPortPublicKeyInfo(void)
4768 HCRYPTPROV csp;
4769 BOOL ret;
4770 PCERT_PUBLIC_KEY_INFO info = NULL;
4772 /* Just in case a previous run failed, delete this thing */
4773 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
4774 CRYPT_DELETEKEYSET);
4775 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
4776 CRYPT_NEWKEYSET);
4778 testExportPublicKey(csp, &info);
4779 testImportPublicKey(csp, info);
4781 HeapFree(GetProcessHeap(), 0, info);
4782 CryptReleaseContext(csp, 0);
4783 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
4784 CRYPT_DELETEKEYSET);
4787 START_TEST(encode)
4789 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
4790 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
4791 DWORD i;
4793 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
4795 test_encodeInt(encodings[i]);
4796 test_decodeInt(encodings[i]);
4797 test_encodeEnumerated(encodings[i]);
4798 test_decodeEnumerated(encodings[i]);
4799 test_encodeFiletime(encodings[i]);
4800 test_decodeFiletime(encodings[i]);
4801 test_encodeName(encodings[i]);
4802 test_decodeName(encodings[i]);
4803 test_encodeUnicodeName(encodings[i]);
4804 test_decodeUnicodeName(encodings[i]);
4805 test_encodeNameValue(encodings[i]);
4806 test_decodeNameValue(encodings[i]);
4807 test_encodeUnicodeNameValue(encodings[i]);
4808 test_decodeUnicodeNameValue(encodings[i]);
4809 test_encodeAltName(encodings[i]);
4810 test_decodeAltName(encodings[i]);
4811 test_encodeOctets(encodings[i]);
4812 test_decodeOctets(encodings[i]);
4813 test_encodeBits(encodings[i]);
4814 test_decodeBits(encodings[i]);
4815 test_encodeBasicConstraints(encodings[i]);
4816 test_decodeBasicConstraints(encodings[i]);
4817 test_encodeRsaPublicKey(encodings[i]);
4818 test_decodeRsaPublicKey(encodings[i]);
4819 test_encodeSequenceOfAny(encodings[i]);
4820 test_decodeSequenceOfAny(encodings[i]);
4821 test_encodeExtensions(encodings[i]);
4822 test_decodeExtensions(encodings[i]);
4823 test_encodePublicKeyInfo(encodings[i]);
4824 test_decodePublicKeyInfo(encodings[i]);
4825 test_encodeCertToBeSigned(encodings[i]);
4826 test_decodeCertToBeSigned(encodings[i]);
4827 test_encodeCert(encodings[i]);
4828 test_decodeCert(encodings[i]);
4829 test_encodeCRLDistPoints(encodings[i]);
4830 test_decodeCRLDistPoints(encodings[i]);
4831 test_encodeCRLIssuingDistPoint(encodings[i]);
4832 test_decodeCRLIssuingDistPoint(encodings[i]);
4833 test_encodeCRLToBeSigned(encodings[i]);
4834 test_decodeCRLToBeSigned(encodings[i]);
4835 test_encodeEnhancedKeyUsage(encodings[i]);
4836 test_decodeEnhancedKeyUsage(encodings[i]);
4837 test_encodeAuthorityKeyId(encodings[i]);
4838 test_decodeAuthorityKeyId(encodings[i]);
4839 test_encodeAuthorityKeyId2(encodings[i]);
4840 test_decodeAuthorityKeyId2(encodings[i]);
4841 test_encodePKCSContentInfo(encodings[i]);
4842 test_decodePKCSContentInfo(encodings[i]);
4844 testPortPublicKeyInfo();