push 7d59f97ddb2317e6350cdd96ee6bc6e63ea046f4
[wine/hacks.git] / dlls / crypt32 / tests / encode.c
blob49e495592f2cebd55135a12e8b29d55c7f16a5ca
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"
30 static BOOL (WINAPI *pCryptDecodeObjectEx)(DWORD,LPCSTR,const BYTE*,DWORD,DWORD,PCRYPT_DECODE_PARA,void*,DWORD*);
31 static BOOL (WINAPI *pCryptEncodeObjectEx)(DWORD,LPCSTR,const void*,DWORD,PCRYPT_ENCODE_PARA,void*,DWORD*);
33 struct encodedInt
35 int val;
36 const BYTE *encoded;
39 static const BYTE bin1[] = {0x02,0x01,0x01};
40 static const BYTE bin2[] = {0x02,0x01,0x7f};
41 static const BYTE bin3[] = {0x02,0x02,0x00,0x80};
42 static const BYTE bin4[] = {0x02,0x02,0x01,0x00};
43 static const BYTE bin5[] = {0x02,0x01,0x80};
44 static const BYTE bin6[] = {0x02,0x02,0xff,0x7f};
45 static const BYTE bin7[] = {0x02,0x04,0xba,0xdd,0xf0,0x0d};
47 static const struct encodedInt ints[] = {
48 { 1, bin1 },
49 { 127, bin2 },
50 { 128, bin3 },
51 { 256, bin4 },
52 { -128, bin5 },
53 { -129, bin6 },
54 { 0xbaddf00d, bin7 },
57 struct encodedBigInt
59 const BYTE *val;
60 const BYTE *encoded;
61 const BYTE *decoded;
64 static const BYTE bin8[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
65 static const BYTE bin9[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
66 static const BYTE bin10[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
68 static const BYTE bin11[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
69 static const BYTE bin12[] = {0x02,0x09,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
70 static const BYTE bin13[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0};
72 static const struct encodedBigInt bigInts[] = {
73 { bin8, bin9, bin10 },
74 { bin11, bin12, bin13 },
77 static const BYTE bin14[] = {0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
78 static const BYTE bin15[] = {0x02,0x0a,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0};
79 static const BYTE bin16[] = {0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0xff,0xff,0xff,0};
80 static const BYTE bin17[] = {0x02,0x0c,0x00,0xff,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0};
82 /* Decoded is the same as original, so don't bother storing a separate copy */
83 static const struct encodedBigInt bigUInts[] = {
84 { bin14, bin15, NULL },
85 { bin16, bin17, NULL },
88 static void test_encodeInt(DWORD dwEncoding)
90 DWORD bufSize = 0;
91 int i;
92 BOOL ret;
93 CRYPT_INTEGER_BLOB blob;
94 BYTE *buf = NULL;
96 /* CryptEncodeObjectEx with NULL bufSize crashes..
97 ret = pCryptEncodeObjectEx(3, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
98 NULL);
100 /* check bogus encoding */
101 ret = pCryptEncodeObjectEx(0, X509_INTEGER, &ints[0].val, 0, NULL, NULL,
102 &bufSize);
103 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
104 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
105 /* check with NULL integer buffer. Windows XP incorrectly returns an
106 * NTSTATUS.
108 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, NULL, NULL,
109 &bufSize);
110 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
111 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
112 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
114 /* encode as normal integer */
115 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 0,
116 NULL, NULL, &bufSize);
117 ok(ret, "Expected success, got %d\n", GetLastError());
118 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val,
119 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
120 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
121 if (buf)
123 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
124 buf[0]);
125 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
126 buf[1], ints[i].encoded[1]);
127 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
128 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
129 LocalFree(buf);
131 /* encode as multibyte integer */
132 blob.cbData = sizeof(ints[i].val);
133 blob.pbData = (BYTE *)&ints[i].val;
134 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
135 0, NULL, NULL, &bufSize);
136 ok(ret, "Expected success, got %d\n", GetLastError());
137 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
138 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
139 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
140 if (buf)
142 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
143 buf[0]);
144 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
145 buf[1], ints[i].encoded[1]);
146 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
147 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
148 LocalFree(buf);
151 /* encode a couple bigger ints, just to show it's little-endian and leading
152 * sign bytes are dropped
154 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
156 blob.cbData = strlen((const char*)bigInts[i].val);
157 blob.pbData = (BYTE *)bigInts[i].val;
158 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
159 0, NULL, NULL, &bufSize);
160 ok(ret, "Expected success, got %d\n", GetLastError());
161 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
162 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
163 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
164 if (buf)
166 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
167 buf[0]);
168 ok(buf[1] == bigInts[i].encoded[1], "Got length %d, expected %d\n",
169 buf[1], bigInts[i].encoded[1]);
170 ok(!memcmp(buf + 1, bigInts[i].encoded + 1,
171 bigInts[i].encoded[1] + 1),
172 "Encoded value didn't match expected\n");
173 LocalFree(buf);
176 /* and, encode some uints */
177 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
179 blob.cbData = strlen((const char*)bigUInts[i].val);
180 blob.pbData = (BYTE*)bigUInts[i].val;
181 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
182 0, NULL, NULL, &bufSize);
183 ok(ret, "Expected success, got %d\n", GetLastError());
184 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
185 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
186 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
187 if (buf)
189 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
190 buf[0]);
191 ok(buf[1] == bigUInts[i].encoded[1], "Got length %d, expected %d\n",
192 buf[1], bigUInts[i].encoded[1]);
193 ok(!memcmp(buf + 1, bigUInts[i].encoded + 1,
194 bigUInts[i].encoded[1] + 1),
195 "Encoded value didn't match expected\n");
196 LocalFree(buf);
201 static void test_decodeInt(DWORD dwEncoding)
203 static const BYTE bigInt[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff };
204 static const BYTE testStr[] = { 0x16, 4, 't', 'e', 's', 't' };
205 static const BYTE longForm[] = { 2, 0x81, 0x01, 0x01 };
206 static const BYTE bigBogus[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 };
207 static const BYTE extraBytes[] = { 2, 1, 1, 0, 0, 0, 0 };
208 BYTE *buf = NULL;
209 DWORD bufSize = 0;
210 int i;
211 BOOL ret;
213 /* CryptDecodeObjectEx with NULL bufSize crashes..
214 ret = pCryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded,
215 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
217 /* check bogus encoding */
218 ret = pCryptDecodeObjectEx(3, X509_INTEGER, (BYTE *)&ints[0].encoded,
219 ints[0].encoded[1] + 2, 0, NULL, NULL, &bufSize);
220 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
221 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
222 /* check with NULL integer buffer */
223 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, 0, NULL, NULL,
224 &bufSize);
225 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
226 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
227 /* check with a valid, but too large, integer */
228 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, bigInt, bigInt[1] + 2,
229 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
230 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
231 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
232 /* check with a DER-encoded string */
233 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, testStr, testStr[1] + 2,
234 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
235 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
236 "Expected CRYPT_E_ASN1_BADTAG, got %d\n", GetLastError());
237 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
239 /* When the output buffer is NULL, this always succeeds */
240 SetLastError(0xdeadbeef);
241 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
242 ints[i].encoded, ints[i].encoded[1] + 2, 0, NULL, NULL,
243 &bufSize);
244 ok(ret && GetLastError() == NOERROR,
245 "Expected success and NOERROR, got %d\n", GetLastError());
246 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
247 ints[i].encoded, ints[i].encoded[1] + 2,
248 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
249 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
250 ok(bufSize == sizeof(int), "Wrong size %d\n", bufSize);
251 ok(buf != NULL, "Expected allocated buffer\n");
252 if (buf)
254 ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n",
255 ints[i].val, *(int *)buf);
256 LocalFree(buf);
259 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
261 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
262 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 0, NULL, NULL,
263 &bufSize);
264 ok(ret && GetLastError() == NOERROR,
265 "Expected success and NOERROR, got %d\n", GetLastError());
266 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
267 bigInts[i].encoded, bigInts[i].encoded[1] + 2,
268 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
269 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
270 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
271 ok(buf != NULL, "Expected allocated buffer\n");
272 if (buf)
274 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
276 ok(blob->cbData == strlen((const char*)bigInts[i].decoded),
277 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts[i].decoded),
278 blob->cbData);
279 ok(!memcmp(blob->pbData, bigInts[i].decoded, blob->cbData),
280 "Unexpected value\n");
281 LocalFree(buf);
284 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
286 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
287 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 0, NULL, NULL,
288 &bufSize);
289 ok(ret && GetLastError() == NOERROR,
290 "Expected success and NOERROR, got %d\n", GetLastError());
291 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
292 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2,
293 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
294 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
295 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
296 ok(buf != NULL, "Expected allocated buffer\n");
297 if (buf)
299 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
301 ok(blob->cbData == strlen((const char*)bigUInts[i].val),
302 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts[i].val),
303 blob->cbData);
304 ok(!memcmp(blob->pbData, bigUInts[i].val, blob->cbData),
305 "Unexpected value\n");
306 LocalFree(buf);
309 /* Decode the value 1 with long-form length */
310 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, longForm,
311 sizeof(longForm), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
312 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
313 if (buf)
315 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
316 LocalFree(buf);
318 /* check with extra bytes at the end */
319 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, extraBytes,
320 sizeof(extraBytes), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
321 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
322 if (buf)
324 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
325 LocalFree(buf);
327 /* Try to decode some bogus large items */
328 /* The buffer size is smaller than the encoded length, so this should fail
329 * with CRYPT_E_ASN1_EOD if it's being decoded.
330 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit
331 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes.
332 * So this test unfortunately isn't useful.
333 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig,
334 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
335 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
336 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
338 /* This will try to decode the buffer and overflow it, check that it's
339 * caught.
341 if (0)
343 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
344 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, bigBogus,
345 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
346 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
347 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
351 static const BYTE bin18[] = {0x0a,0x01,0x01};
352 static const BYTE bin19[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
354 /* These are always encoded unsigned, and aren't constrained to be any
355 * particular value
357 static const struct encodedInt enums[] = {
358 { 1, bin18 },
359 { -128, bin19 },
362 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
363 * X509_ENUMERATED.
365 static const LPCSTR enumeratedTypes[] = { X509_ENUMERATED,
366 szOID_CRL_REASON_CODE };
368 static void test_encodeEnumerated(DWORD dwEncoding)
370 DWORD i, j;
372 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
374 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
376 BOOL ret;
377 BYTE *buf = NULL;
378 DWORD bufSize = 0;
380 ret = pCryptEncodeObjectEx(dwEncoding, enumeratedTypes[i],
381 &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
382 &bufSize);
383 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
384 if (buf)
386 ok(buf[0] == 0xa,
387 "Got unexpected type %d for enumerated (expected 0xa)\n",
388 buf[0]);
389 ok(buf[1] == enums[j].encoded[1],
390 "Got length %d, expected %d\n", buf[1], enums[j].encoded[1]);
391 ok(!memcmp(buf + 1, enums[j].encoded + 1,
392 enums[j].encoded[1] + 1),
393 "Encoded value of 0x%08x didn't match expected\n",
394 enums[j].val);
395 LocalFree(buf);
401 static void test_decodeEnumerated(DWORD dwEncoding)
403 DWORD i, j;
405 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
407 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
409 BOOL ret;
410 DWORD bufSize = sizeof(int);
411 int val;
413 ret = pCryptDecodeObjectEx(dwEncoding, enumeratedTypes[i],
414 enums[j].encoded, enums[j].encoded[1] + 2, 0, NULL,
415 (BYTE *)&val, &bufSize);
416 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
417 ok(bufSize == sizeof(int),
418 "Got unexpected size %d for enumerated\n", bufSize);
419 ok(val == enums[j].val, "Unexpected value %d, expected %d\n",
420 val, enums[j].val);
425 struct encodedFiletime
427 SYSTEMTIME sysTime;
428 const BYTE *encodedTime;
431 static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType,
432 const struct encodedFiletime *time)
434 FILETIME ft = { 0 };
435 BYTE *buf = NULL;
436 DWORD bufSize = 0;
437 BOOL ret;
439 ret = SystemTimeToFileTime(&time->sysTime, &ft);
440 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
441 ret = pCryptEncodeObjectEx(dwEncoding, structType, &ft,
442 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
443 /* years other than 1950-2050 are not allowed for encodings other than
444 * X509_CHOICE_OF_TIME.
446 if (structType == X509_CHOICE_OF_TIME ||
447 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
449 ok(ret, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
450 GetLastError());
451 ok(buf != NULL, "Expected an allocated buffer\n");
452 if (buf)
454 ok(buf[0] == time->encodedTime[0],
455 "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0],
456 buf[0]);
457 ok(buf[1] == time->encodedTime[1], "Expected %d bytes, got %d\n",
458 time->encodedTime[1], bufSize);
459 ok(!memcmp(time->encodedTime + 2, buf + 2, time->encodedTime[1]),
460 "Got unexpected value for time encoding\n");
461 LocalFree(buf);
464 else
465 ok(!ret && GetLastError() == CRYPT_E_BAD_ENCODE,
466 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
469 static const char *printSystemTime(const SYSTEMTIME *st)
471 static char buf[25];
473 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay,
474 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
475 return buf;
478 static const char *printFileTime(const FILETIME *ft)
480 static char buf[25];
481 SYSTEMTIME st;
483 FileTimeToSystemTime(ft, &st);
484 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay,
485 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
486 return buf;
489 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got)
491 SYSTEMTIME st;
493 FileTimeToSystemTime(got, &st);
494 ok(expected->wYear == st.wYear &&
495 expected->wMonth == st.wMonth &&
496 expected->wDay == st.wDay &&
497 expected->wHour == st.wHour &&
498 expected->wMinute == st.wMinute &&
499 expected->wSecond == st.wSecond &&
500 abs(expected->wMilliseconds - st.wMilliseconds) <= 1,
501 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
502 printSystemTime(expected), printFileTime(got));
505 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
506 const struct encodedFiletime *time)
508 FILETIME ft = { 0 };
509 DWORD size = sizeof(ft);
510 BOOL ret;
512 ret = pCryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
513 time->encodedTime[1] + 2, 0, NULL, &ft, &size);
514 /* years other than 1950-2050 are not allowed for encodings other than
515 * X509_CHOICE_OF_TIME.
517 if (structType == X509_CHOICE_OF_TIME ||
518 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
520 ok(ret, "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
521 GetLastError());
522 compareTime(&time->sysTime, &ft);
524 else
525 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
526 "Expected CRYPT_E_ASN1_BADTAG, got 0x%08x\n", GetLastError());
529 static const BYTE bin20[] = {
530 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
531 static const BYTE bin21[] = {
532 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
533 static const BYTE bin22[] = {
534 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
536 static const struct encodedFiletime times[] = {
537 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
538 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
539 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
542 static void test_encodeFiletime(DWORD dwEncoding)
544 DWORD i;
546 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
548 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
549 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
550 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
554 static const BYTE bin23[] = {
555 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
556 static const BYTE bin24[] = {
557 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
558 static const BYTE bin25[] = {
559 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
560 static const BYTE bin26[] = {
561 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
562 static const BYTE bin27[] = {
563 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
564 static const BYTE bin28[] = {
565 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
566 static const BYTE bin29[] = {
567 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
568 static const BYTE bin30[] = {
569 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
570 static const BYTE bin31[] = {
571 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
572 static const BYTE bin32[] = {
573 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
574 static const BYTE bin33[] = {
575 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
576 static const BYTE bin34[] = {
577 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
578 static const BYTE bin35[] = {
579 0x17,0x08, '4','5','0','6','0','6','1','6'};
580 static const BYTE bin36[] = {
581 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
582 static const BYTE bin37[] = {
583 0x18,0x04, '2','1','4','5'};
584 static const BYTE bin38[] = {
585 0x18,0x08, '2','1','4','5','0','6','0','6'};
587 static void test_decodeFiletime(DWORD dwEncoding)
589 static const struct encodedFiletime otherTimes[] = {
590 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
591 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
592 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
593 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
594 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
595 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
596 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
597 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
598 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
599 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
600 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
601 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
603 /* An oddball case that succeeds in Windows, but doesn't seem correct
604 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
606 static const unsigned char *bogusTimes[] = {
607 /* oddly, this succeeds on Windows, with year 2765
608 "\x18" "\x0f" "21r50606161000Z",
610 bin35,
611 bin36,
612 bin37,
613 bin38,
615 DWORD i, size;
616 FILETIME ft1 = { 0 }, ft2 = { 0 };
617 BOOL ret;
619 /* Check bogus length with non-NULL buffer */
620 ret = SystemTimeToFileTime(&times[0].sysTime, &ft1);
621 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
622 size = 1;
623 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
624 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
625 ok(!ret && GetLastError() == ERROR_MORE_DATA,
626 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
627 /* Normal tests */
628 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
630 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
631 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
632 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
634 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
636 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
637 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
638 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
640 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
642 size = sizeof(ft1);
643 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
644 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
645 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
646 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
650 static const char commonName[] = "Juan Lang";
651 static const char surName[] = "Lang";
653 static const BYTE emptySequence[] = { 0x30, 0 };
654 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
655 static const BYTE twoRDNs[] = {
656 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
657 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
658 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
659 static const BYTE encodedTwoRDNs[] = {
660 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
661 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
662 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
663 0x6e,0x67,0x00,
666 static const BYTE us[] = { 0x55, 0x53 };
667 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
668 0x74, 0x61 };
669 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
670 0x6f, 0x6c, 0x69, 0x73 };
671 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
672 0x76, 0x65, 0x72, 0x73 };
673 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
674 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
675 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
676 0x73, 0x74 };
677 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
678 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
680 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
681 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
683 static CHAR oid_us[] = "2.5.4.6",
684 oid_minnesota[] = "2.5.4.8",
685 oid_minneapolis[] = "2.5.4.7",
686 oid_codeweavers[] = "2.5.4.10",
687 oid_wine[] = "2.5.4.11",
688 oid_localhostAttr[] = "2.5.4.3",
689 oid_aric[] = "1.2.840.113549.1.9.1";
690 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
691 { RDNA(minnesota) },
692 { RDNA(minneapolis) },
693 { RDNA(codeweavers) },
694 { RDNA(wine) },
695 { RDNA(localhostAttr) },
696 { RDNIA5(aric) } };
697 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
698 { RDNA(localhostAttr) },
699 { RDNA(minnesota) },
700 { RDNA(minneapolis) },
701 { RDNA(codeweavers) },
702 { RDNA(wine) },
703 { RDNIA5(aric) } };
705 #undef RDNIA5
706 #undef RDNA
708 static const BYTE encodedRDNAttrs[] = {
709 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
710 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
711 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
712 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
713 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
714 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
715 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
716 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
717 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
718 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
721 static void test_encodeName(DWORD dwEncoding)
723 CERT_RDN_ATTR attrs[2];
724 CERT_RDN rdn;
725 CERT_NAME_INFO info;
726 static CHAR oid_common_name[] = szOID_COMMON_NAME,
727 oid_sur_name[] = szOID_SUR_NAME;
728 BYTE *buf = NULL;
729 DWORD size = 0;
730 BOOL ret;
732 /* Test with NULL pvStructInfo */
733 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
734 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
735 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
736 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
737 /* Test with empty CERT_NAME_INFO */
738 info.cRDN = 0;
739 info.rgRDN = NULL;
740 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
741 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
742 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
743 if (buf)
745 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
746 "Got unexpected encoding for empty name\n");
747 LocalFree(buf);
749 /* Test with bogus CERT_RDN */
750 info.cRDN = 1;
751 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
752 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
753 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
754 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
755 /* Test with empty CERT_RDN */
756 rdn.cRDNAttr = 0;
757 rdn.rgRDNAttr = NULL;
758 info.cRDN = 1;
759 info.rgRDN = &rdn;
760 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
761 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
762 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
763 if (buf)
765 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
766 "Got unexpected encoding for empty RDN array\n");
767 LocalFree(buf);
769 /* Test with bogus attr array */
770 rdn.cRDNAttr = 1;
771 rdn.rgRDNAttr = NULL;
772 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
773 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
774 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
775 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
776 /* oddly, a bogus OID is accepted by Windows XP; not testing.
777 attrs[0].pszObjId = "bogus";
778 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
779 attrs[0].Value.cbData = sizeof(commonName);
780 attrs[0].Value.pbData = (BYTE *)commonName;
781 rdn.cRDNAttr = 1;
782 rdn.rgRDNAttr = attrs;
783 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
784 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
785 ok(!ret, "Expected failure, got success\n");
787 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
788 * the encoded attributes to be swapped.
790 attrs[0].pszObjId = oid_common_name;
791 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
792 attrs[0].Value.cbData = sizeof(commonName);
793 attrs[0].Value.pbData = (BYTE *)commonName;
794 attrs[1].pszObjId = oid_sur_name;
795 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
796 attrs[1].Value.cbData = sizeof(surName);
797 attrs[1].Value.pbData = (BYTE *)surName;
798 rdn.cRDNAttr = 2;
799 rdn.rgRDNAttr = attrs;
800 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
801 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
802 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
803 if (buf)
805 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
806 "Got unexpected encoding for two RDN array\n");
807 LocalFree(buf);
809 /* A name can be "encoded" with previously encoded RDN attrs. */
810 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
811 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
812 attrs[0].Value.cbData = sizeof(twoRDNs);
813 rdn.cRDNAttr = 1;
814 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
815 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
816 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
817 if (buf)
819 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
820 ok(!memcmp(buf, encodedTwoRDNs, size),
821 "Unexpected value for re-endoded two RDN array\n");
822 LocalFree(buf);
824 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
825 rdn.cRDNAttr = 1;
826 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
827 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
828 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
829 ok(!ret && GetLastError() == E_INVALIDARG,
830 "Expected E_INVALIDARG, got %08x\n", GetLastError());
831 /* Test a more complex name */
832 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
833 rdn.rgRDNAttr = (PCERT_RDN_ATTR)rdnAttrs;
834 info.cRDN = 1;
835 info.rgRDN = &rdn;
836 buf = NULL;
837 size = 0;
838 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
839 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
840 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
841 if (ret)
843 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
844 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
845 LocalFree(buf);
849 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
850 static WCHAR surNameW[] = { 'L','a','n','g',0 };
852 static const BYTE twoRDNsNoNull[] = {
853 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
854 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
855 0x20,0x4c,0x61,0x6e,0x67 };
856 static const BYTE anyType[] = {
857 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
858 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
859 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
860 0x61,0x4c,0x67,0x6e };
862 static void test_encodeUnicodeName(DWORD dwEncoding)
864 CERT_RDN_ATTR attrs[2];
865 CERT_RDN rdn;
866 CERT_NAME_INFO info;
867 static CHAR oid_common_name[] = szOID_COMMON_NAME,
868 oid_sur_name[] = szOID_SUR_NAME;
869 BYTE *buf = NULL;
870 DWORD size = 0;
871 BOOL ret;
873 /* Test with NULL pvStructInfo */
874 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
875 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
876 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
877 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
878 /* Test with empty CERT_NAME_INFO */
879 info.cRDN = 0;
880 info.rgRDN = NULL;
881 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
882 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
883 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
884 if (buf)
886 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
887 "Got unexpected encoding for empty name\n");
888 LocalFree(buf);
890 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
891 * encoding (the NULL).
893 attrs[0].pszObjId = oid_common_name;
894 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
895 attrs[0].Value.cbData = sizeof(commonNameW);
896 attrs[0].Value.pbData = (BYTE *)commonNameW;
897 rdn.cRDNAttr = 1;
898 rdn.rgRDNAttr = attrs;
899 info.cRDN = 1;
900 info.rgRDN = &rdn;
901 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
902 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
903 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
904 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
905 ok(size == 9, "Unexpected error index %08x\n", size);
906 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
907 * forces the order of the encoded attributes to be swapped.
909 attrs[0].pszObjId = oid_common_name;
910 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
911 attrs[0].Value.cbData = 0;
912 attrs[0].Value.pbData = (BYTE *)commonNameW;
913 attrs[1].pszObjId = oid_sur_name;
914 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
915 attrs[1].Value.cbData = 0;
916 attrs[1].Value.pbData = (BYTE *)surNameW;
917 rdn.cRDNAttr = 2;
918 rdn.rgRDNAttr = attrs;
919 info.cRDN = 1;
920 info.rgRDN = &rdn;
921 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
922 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
923 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
924 if (buf)
926 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
927 "Got unexpected encoding for two RDN array\n");
928 LocalFree(buf);
930 /* A name can be "encoded" with previously encoded RDN attrs. */
931 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
932 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
933 attrs[0].Value.cbData = sizeof(twoRDNs);
934 rdn.cRDNAttr = 1;
935 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
936 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
937 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
938 if (buf)
940 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
941 ok(!memcmp(buf, encodedTwoRDNs, size),
942 "Unexpected value for re-endoded two RDN array\n");
943 LocalFree(buf);
945 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
946 rdn.cRDNAttr = 1;
947 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
948 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
949 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
950 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
951 if (buf)
953 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
954 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
955 LocalFree(buf);
959 static void compareNameValues(const CERT_NAME_VALUE *expected,
960 const CERT_NAME_VALUE *got)
962 ok(got->dwValueType == expected->dwValueType,
963 "Expected string type %d, got %d\n", expected->dwValueType,
964 got->dwValueType);
965 ok(got->Value.cbData == expected->Value.cbData,
966 "String type %d: unexpected data size, got %d, expected %d\n",
967 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
968 if (got->Value.cbData && got->Value.pbData)
969 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
970 min(got->Value.cbData, expected->Value.cbData)),
971 "String type %d: unexpected value\n", expected->dwValueType);
974 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
975 const CERT_RDN_ATTR *got)
977 if (expected->pszObjId && strlen(expected->pszObjId))
979 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
980 expected->pszObjId);
981 if (got->pszObjId)
983 ok(!strcmp(got->pszObjId, expected->pszObjId),
984 "Got unexpected OID %s, expected %s\n", got->pszObjId,
985 expected->pszObjId);
988 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
989 (const CERT_NAME_VALUE *)&got->dwValueType);
992 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
994 ok(got->cRDNAttr == expected->cRDNAttr,
995 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
996 if (got->cRDNAttr)
998 DWORD i;
1000 for (i = 0; i < got->cRDNAttr; i++)
1001 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1005 static void compareNames(const CERT_NAME_INFO *expected,
1006 const CERT_NAME_INFO *got)
1008 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
1009 expected->cRDN, got->cRDN);
1010 if (got->cRDN)
1012 DWORD i;
1014 for (i = 0; i < got->cRDN; i++)
1015 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1019 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1020 static const BYTE twoRDNsExtraBytes[] = {
1021 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1022 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1023 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1025 static void test_decodeName(DWORD dwEncoding)
1027 BYTE *buf = NULL;
1028 DWORD bufSize = 0;
1029 BOOL ret;
1030 CERT_RDN rdn;
1031 CERT_NAME_INFO info = { 1, &rdn };
1033 /* test empty name */
1034 bufSize = 0;
1035 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1036 emptySequence[1] + 2,
1037 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1038 (BYTE *)&buf, &bufSize);
1039 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1040 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1041 * decoder works the same way, so only test the count.
1043 if (buf)
1045 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1046 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1047 "Expected 0 RDNs in empty info, got %d\n",
1048 ((CERT_NAME_INFO *)buf)->cRDN);
1049 LocalFree(buf);
1051 /* test empty name with indefinite-length encoding */
1052 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1053 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1054 (BYTE *)&buf, &bufSize);
1055 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1056 if (ret)
1058 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1059 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1060 "Expected 0 RDNs in empty info, got %d\n",
1061 ((CERT_NAME_INFO *)buf)->cRDN);
1062 LocalFree(buf);
1064 /* test empty RDN */
1065 bufSize = 0;
1066 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1067 emptyRDNs[1] + 2,
1068 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1069 (BYTE *)&buf, &bufSize);
1070 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1071 if (buf)
1073 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1075 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1076 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1077 "Got unexpected value for empty RDN\n");
1078 LocalFree(buf);
1080 /* test two RDN attrs */
1081 bufSize = 0;
1082 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1083 twoRDNs[1] + 2,
1084 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1085 (BYTE *)&buf, &bufSize);
1086 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1087 if (buf)
1089 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1090 oid_common_name[] = szOID_COMMON_NAME;
1092 CERT_RDN_ATTR attrs[] = {
1093 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1094 (BYTE *)surName } },
1095 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1096 (BYTE *)commonName } },
1099 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1100 rdn.rgRDNAttr = attrs;
1101 compareNames(&info, (CERT_NAME_INFO *)buf);
1102 LocalFree(buf);
1104 /* test that two RDN attrs with extra bytes succeeds */
1105 bufSize = 0;
1106 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1107 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1108 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1109 /* And, a slightly more complicated name */
1110 buf = NULL;
1111 bufSize = 0;
1112 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1113 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1114 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1115 if (ret)
1117 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1118 rdn.rgRDNAttr = (PCERT_RDN_ATTR)decodedRdnAttrs;
1119 compareNames(&info, (CERT_NAME_INFO *)buf);
1120 LocalFree(buf);
1124 static void test_decodeUnicodeName(DWORD dwEncoding)
1126 BYTE *buf = NULL;
1127 DWORD bufSize = 0;
1128 BOOL ret;
1129 CERT_RDN rdn;
1130 CERT_NAME_INFO info = { 1, &rdn };
1132 /* test empty name */
1133 bufSize = 0;
1134 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1135 emptySequence[1] + 2,
1136 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1137 (BYTE *)&buf, &bufSize);
1138 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1139 if (buf)
1141 ok(bufSize == sizeof(CERT_NAME_INFO),
1142 "Got wrong bufSize %d\n", bufSize);
1143 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1144 "Expected 0 RDNs in empty info, got %d\n",
1145 ((CERT_NAME_INFO *)buf)->cRDN);
1146 LocalFree(buf);
1148 /* test empty RDN */
1149 bufSize = 0;
1150 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1151 emptyRDNs[1] + 2,
1152 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1153 (BYTE *)&buf, &bufSize);
1154 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1155 if (buf)
1157 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1159 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1160 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1161 "Got unexpected value for empty RDN\n");
1162 LocalFree(buf);
1164 /* test two RDN attrs */
1165 bufSize = 0;
1166 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1167 sizeof(twoRDNsNoNull),
1168 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1169 (BYTE *)&buf, &bufSize);
1170 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1171 if (buf)
1173 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1174 oid_common_name[] = szOID_COMMON_NAME;
1176 CERT_RDN_ATTR attrs[] = {
1177 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1178 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1179 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1180 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1183 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1184 rdn.rgRDNAttr = attrs;
1185 compareNames(&info, (CERT_NAME_INFO *)buf);
1186 LocalFree(buf);
1190 struct EncodedNameValue
1192 CERT_NAME_VALUE value;
1193 const BYTE *encoded;
1194 DWORD encodedSize;
1197 static const char bogusIA5[] = "\x80";
1198 static const char bogusPrintable[] = "~";
1199 static const char bogusNumeric[] = "A";
1200 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1201 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1202 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1203 static BYTE octetCommonNameValue[] = {
1204 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1205 static BYTE numericCommonNameValue[] = {
1206 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1207 static BYTE printableCommonNameValue[] = {
1208 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1209 static BYTE t61CommonNameValue[] = {
1210 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1211 static BYTE videotexCommonNameValue[] = {
1212 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1213 static BYTE ia5CommonNameValue[] = {
1214 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1215 static BYTE graphicCommonNameValue[] = {
1216 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1217 static BYTE visibleCommonNameValue[] = {
1218 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1219 static BYTE generalCommonNameValue[] = {
1220 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1221 static BYTE bmpCommonNameValue[] = {
1222 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1223 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1224 static BYTE utf8CommonNameValue[] = {
1225 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1227 static struct EncodedNameValue nameValues[] = {
1228 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1229 octetCommonNameValue, sizeof(octetCommonNameValue) },
1230 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1231 numericCommonNameValue, sizeof(numericCommonNameValue) },
1232 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1233 printableCommonNameValue, sizeof(printableCommonNameValue) },
1234 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1235 t61CommonNameValue, sizeof(t61CommonNameValue) },
1236 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1237 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1238 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1239 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1240 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1241 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1242 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1243 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1244 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1245 generalCommonNameValue, sizeof(generalCommonNameValue) },
1246 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1247 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1248 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1249 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1250 /* The following tests succeed under Windows, but really should fail,
1251 * they contain characters that are illegal for the encoding. I'm
1252 * including them to justify my lazy encoding.
1254 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1255 sizeof(bin42) },
1256 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1257 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1258 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1259 bin44, sizeof(bin44) },
1262 static void test_encodeNameValue(DWORD dwEncoding)
1264 BYTE *buf = NULL;
1265 DWORD size = 0, i;
1266 BOOL ret;
1267 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1269 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1270 value.Value.pbData = printableCommonNameValue;
1271 value.Value.cbData = sizeof(printableCommonNameValue);
1272 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1273 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1274 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1275 if (buf)
1277 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1278 size);
1279 ok(!memcmp(buf, printableCommonNameValue, size),
1280 "Unexpected encoding\n");
1281 LocalFree(buf);
1283 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1285 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1286 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1287 &size);
1288 ok(ret, "Type %d: CryptEncodeObjectEx failed: %08x\n",
1289 nameValues[i].value.dwValueType, GetLastError());
1290 if (buf)
1292 ok(size == nameValues[i].encodedSize,
1293 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1294 ok(!memcmp(buf, nameValues[i].encoded, size),
1295 "Got unexpected encoding\n");
1296 LocalFree(buf);
1301 static void test_decodeNameValue(DWORD dwEncoding)
1303 int i;
1304 BYTE *buf = NULL;
1305 DWORD bufSize = 0;
1306 BOOL ret;
1308 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1310 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1311 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1312 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1313 (BYTE *)&buf, &bufSize);
1314 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1315 nameValues[i].value.dwValueType, GetLastError());
1316 if (buf)
1318 compareNameValues(&nameValues[i].value,
1319 (const CERT_NAME_VALUE *)buf);
1320 LocalFree(buf);
1325 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1326 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1327 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1328 'h','q','.','o','r','g',0 };
1329 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1330 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1331 0x6f, 0x72, 0x67 };
1332 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1333 0x575b, 0 };
1334 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1335 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1336 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1337 static const BYTE localhost[] = { 127, 0, 0, 1 };
1338 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1339 0x01 };
1340 static const unsigned char encodedCommonName[] = {
1341 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1342 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1343 static const BYTE encodedDirectoryName[] = {
1344 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1345 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1347 static void test_encodeAltName(DWORD dwEncoding)
1349 CERT_ALT_NAME_INFO info = { 0 };
1350 CERT_ALT_NAME_ENTRY entry = { 0 };
1351 BYTE *buf = NULL;
1352 DWORD size = 0;
1353 BOOL ret;
1354 char oid[] = "1.2.3";
1356 /* Test with empty info */
1357 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1358 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1359 if (buf)
1361 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1362 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1363 LocalFree(buf);
1365 /* Test with an empty entry */
1366 info.cAltEntry = 1;
1367 info.rgAltEntry = &entry;
1368 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1369 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1370 ok(!ret && GetLastError() == E_INVALIDARG,
1371 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1372 /* Test with an empty pointer */
1373 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1374 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1375 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1376 if (buf)
1378 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1379 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1380 LocalFree(buf);
1382 /* Test with a real URL */
1383 U(entry).pwszURL = (LPWSTR)url;
1384 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1385 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1386 if (buf)
1388 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1389 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1390 LocalFree(buf);
1392 /* Now with the URL containing an invalid IA5 char */
1393 U(entry).pwszURL = (LPWSTR)nihongoURL;
1394 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1395 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1396 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1397 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1398 /* The first invalid character is at index 7 */
1399 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1400 "Expected invalid char at index 7, got %d\n",
1401 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1402 /* Now with the URL missing a scheme */
1403 U(entry).pwszURL = (LPWSTR)dnsName;
1404 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1405 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1406 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1407 if (buf)
1409 /* This succeeds, but it shouldn't, so don't worry about conforming */
1410 LocalFree(buf);
1412 /* Now with a DNS name */
1413 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1414 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1415 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1416 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1417 if (buf)
1419 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1420 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1421 LocalFree(buf);
1423 /* Test with an IP address */
1424 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1425 U(entry).IPAddress.cbData = sizeof(localhost);
1426 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1427 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1428 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1429 if (buf)
1431 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1432 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1433 LocalFree(buf);
1435 /* Test with OID */
1436 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1437 U(entry).pszRegisteredID = oid;
1438 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1439 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1440 if (buf)
1442 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1443 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1444 LocalFree(buf);
1446 /* Test with directory name */
1447 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1448 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1449 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1450 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1451 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1452 if (buf)
1454 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1455 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1456 LocalFree(buf);
1460 static void test_decodeAltName(DWORD dwEncoding)
1462 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1463 0x00, 0x00, 0x01 };
1464 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1465 0x01 };
1466 BOOL ret;
1467 BYTE *buf = NULL;
1468 DWORD bufSize = 0;
1469 CERT_ALT_NAME_INFO *info;
1471 /* Test some bogus ones first */
1472 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1473 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1474 NULL, (BYTE *)&buf, &bufSize);
1475 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
1476 "Expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
1477 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1478 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1479 &bufSize);
1480 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
1481 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
1482 /* Now expected cases */
1483 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1484 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1485 &bufSize);
1486 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1487 if (buf)
1489 info = (CERT_ALT_NAME_INFO *)buf;
1491 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1492 info->cAltEntry);
1493 LocalFree(buf);
1495 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1496 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1497 &bufSize);
1498 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1499 if (buf)
1501 info = (CERT_ALT_NAME_INFO *)buf;
1503 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1504 info->cAltEntry);
1505 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1506 "Expected CERT_ALT_NAME_URL, got %d\n",
1507 info->rgAltEntry[0].dwAltNameChoice);
1508 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1509 "Expected empty URL\n");
1510 LocalFree(buf);
1512 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1513 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1514 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1515 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1516 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1517 &bufSize);
1518 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1519 if (buf)
1521 info = (CERT_ALT_NAME_INFO *)buf;
1523 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1524 info->cAltEntry);
1525 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1526 "Expected CERT_ALT_NAME_URL, got %d\n",
1527 info->rgAltEntry[0].dwAltNameChoice);
1528 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1529 LocalFree(buf);
1531 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1532 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1533 &bufSize);
1534 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1535 if (buf)
1537 info = (CERT_ALT_NAME_INFO *)buf;
1539 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1540 info->cAltEntry);
1541 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1542 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1543 info->rgAltEntry[0].dwAltNameChoice);
1544 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1545 "Unexpected DNS name\n");
1546 LocalFree(buf);
1548 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1549 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1550 &bufSize);
1551 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1552 if (buf)
1554 info = (CERT_ALT_NAME_INFO *)buf;
1556 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1557 info->cAltEntry);
1558 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1559 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1560 info->rgAltEntry[0].dwAltNameChoice);
1561 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1562 "Unexpected IP address length %d\n",
1563 U(info->rgAltEntry[0]).IPAddress.cbData);
1564 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1565 sizeof(localhost)), "Unexpected IP address value\n");
1566 LocalFree(buf);
1568 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1569 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1570 &bufSize);
1571 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1572 if (buf)
1574 info = (CERT_ALT_NAME_INFO *)buf;
1576 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1577 info->cAltEntry);
1578 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1579 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1580 info->rgAltEntry[0].dwAltNameChoice);
1581 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1582 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1583 LocalFree(buf);
1585 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1586 encodedDirectoryName, sizeof(encodedDirectoryName),
1587 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1588 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1589 if (buf)
1591 info = (CERT_ALT_NAME_INFO *)buf;
1593 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1594 info->cAltEntry);
1595 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1596 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1597 info->rgAltEntry[0].dwAltNameChoice);
1598 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1599 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1600 U(info->rgAltEntry[0]).DirectoryName.cbData);
1601 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1602 encodedCommonName, sizeof(encodedCommonName)),
1603 "Unexpected directory name value\n");
1604 LocalFree(buf);
1608 struct UnicodeExpectedError
1610 DWORD valueType;
1611 LPCWSTR str;
1612 DWORD errorIndex;
1613 DWORD error;
1616 static const WCHAR oneW[] = { '1',0 };
1617 static const WCHAR aW[] = { 'a',0 };
1618 static const WCHAR quoteW[] = { '"', 0 };
1620 static struct UnicodeExpectedError unicodeErrors[] = {
1621 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1622 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1623 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1624 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1625 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1626 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1629 struct UnicodeExpectedResult
1631 DWORD valueType;
1632 LPCWSTR str;
1633 CRYPT_DATA_BLOB encoded;
1636 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1637 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1638 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1639 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1640 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1641 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1642 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1643 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1644 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1645 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1646 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1647 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1648 0x5b };
1649 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1650 0x6f,0x5b };
1651 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1652 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1653 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1654 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1656 static struct UnicodeExpectedResult unicodeResults[] = {
1657 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1658 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1659 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1660 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1661 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1662 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1663 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1664 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1665 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1666 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1667 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1668 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1669 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1672 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1673 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1674 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1677 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1679 BYTE *buf = NULL;
1680 DWORD size = 0, i;
1681 BOOL ret;
1682 CERT_NAME_VALUE value;
1684 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1685 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1686 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1687 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1688 /* Have to have a string of some sort */
1689 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1690 value.Value.pbData = NULL;
1691 value.Value.cbData = 0;
1692 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1693 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1694 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1695 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1696 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1697 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1698 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1699 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1700 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1701 value.dwValueType = CERT_RDN_ANY_TYPE;
1702 value.Value.pbData = (LPBYTE)oneW;
1703 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1704 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1705 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1706 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1707 value.Value.cbData = sizeof(oneW);
1708 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1709 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1710 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1711 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1712 /* An encoded string with specified length isn't good enough either */
1713 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1714 value.Value.pbData = oneUniversal;
1715 value.Value.cbData = sizeof(oneUniversal);
1716 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1717 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1718 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1719 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1720 /* More failure checking */
1721 value.Value.cbData = 0;
1722 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1724 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1725 value.dwValueType = unicodeErrors[i].valueType;
1726 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1727 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1728 ok(!ret && GetLastError() == unicodeErrors[i].error,
1729 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1730 unicodeErrors[i].error, GetLastError());
1731 ok(size == unicodeErrors[i].errorIndex,
1732 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1733 size);
1735 /* cbData can be zero if the string is NULL-terminated */
1736 value.Value.cbData = 0;
1737 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1739 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1740 value.dwValueType = unicodeResults[i].valueType;
1741 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1742 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1743 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1744 if (buf)
1746 ok(size == unicodeResults[i].encoded.cbData,
1747 "Value type %d: expected size %d, got %d\n",
1748 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1749 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1750 "Value type %d: unexpected value\n", value.dwValueType);
1751 LocalFree(buf);
1754 /* These "encode," but they do so by truncating each unicode character
1755 * rather than properly encoding it. Kept separate from the proper results,
1756 * because the encoded forms won't decode to their original strings.
1758 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1760 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1761 value.dwValueType = unicodeWeirdness[i].valueType;
1762 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1763 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1764 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1765 if (buf)
1767 ok(size == unicodeWeirdness[i].encoded.cbData,
1768 "Value type %d: expected size %d, got %d\n",
1769 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1770 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1771 "Value type %d: unexpected value\n", value.dwValueType);
1772 LocalFree(buf);
1777 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1779 if (n <= 0) return 0;
1780 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1781 return *str1 - *str2;
1784 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1786 DWORD i;
1788 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1790 BYTE *buf = NULL;
1791 BOOL ret;
1792 DWORD size = 0;
1794 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1795 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1796 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
1797 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1798 if (ret && buf)
1800 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1802 ok(value->dwValueType == unicodeResults[i].valueType,
1803 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1804 value->dwValueType);
1805 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1806 value->Value.cbData / sizeof(WCHAR)),
1807 "Unexpected decoded value for index %d (value type %d)\n", i,
1808 unicodeResults[i].valueType);
1809 LocalFree(buf);
1814 struct encodedOctets
1816 const BYTE *val;
1817 const BYTE *encoded;
1820 static const unsigned char bin46[] = { 'h','i',0 };
1821 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1822 static const unsigned char bin48[] = {
1823 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1824 static const unsigned char bin49[] = {
1825 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1826 static const unsigned char bin50[] = { 0 };
1827 static const unsigned char bin51[] = { 0x04,0x00,0 };
1829 static const struct encodedOctets octets[] = {
1830 { bin46, bin47 },
1831 { bin48, bin49 },
1832 { bin50, bin51 },
1835 static void test_encodeOctets(DWORD dwEncoding)
1837 CRYPT_DATA_BLOB blob;
1838 DWORD i;
1840 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1842 BYTE *buf = NULL;
1843 BOOL ret;
1844 DWORD bufSize = 0;
1846 blob.cbData = strlen((const char*)octets[i].val);
1847 blob.pbData = (BYTE*)octets[i].val;
1848 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1849 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1850 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1851 if (buf)
1853 ok(buf[0] == 4,
1854 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
1855 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
1856 buf[1], octets[i].encoded[1]);
1857 ok(!memcmp(buf + 1, octets[i].encoded + 1,
1858 octets[i].encoded[1] + 1), "Got unexpected value\n");
1859 LocalFree(buf);
1864 static void test_decodeOctets(DWORD dwEncoding)
1866 DWORD i;
1868 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1870 BYTE *buf = NULL;
1871 BOOL ret;
1872 DWORD bufSize = 0;
1874 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
1875 (BYTE *)octets[i].encoded, octets[i].encoded[1] + 2,
1876 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1877 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1878 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
1879 "Expected size >= %d, got %d\n",
1880 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
1881 ok(buf != NULL, "Expected allocated buffer\n");
1882 if (buf)
1884 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
1886 if (blob->cbData)
1887 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
1888 "Unexpected value\n");
1889 LocalFree(buf);
1894 static const BYTE bytesToEncode[] = { 0xff, 0xff };
1896 struct encodedBits
1898 DWORD cUnusedBits;
1899 const BYTE *encoded;
1900 DWORD cbDecoded;
1901 const BYTE *decoded;
1904 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
1905 static const unsigned char bin53[] = { 0xff,0xff };
1906 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
1907 static const unsigned char bin55[] = { 0xff,0xfe };
1908 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
1909 static const unsigned char bin57[] = { 0xfe };
1910 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
1912 static const struct encodedBits bits[] = {
1913 /* normal test cases */
1914 { 0, bin52, 2, bin53 },
1915 { 1, bin54, 2, bin55 },
1916 /* strange test case, showing cUnusedBits >= 8 is allowed */
1917 { 9, bin56, 1, bin57 },
1918 /* even stranger test case, showing cUnusedBits > cbData * 8 is allowed */
1919 { 17, bin58, 0, NULL },
1922 static void test_encodeBits(DWORD dwEncoding)
1924 DWORD i;
1926 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1928 CRYPT_BIT_BLOB blob;
1929 BOOL ret;
1930 BYTE *buf = NULL;
1931 DWORD bufSize = 0;
1933 blob.cbData = sizeof(bytesToEncode);
1934 blob.pbData = (BYTE *)bytesToEncode;
1935 blob.cUnusedBits = bits[i].cUnusedBits;
1936 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
1937 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1938 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1939 if (buf)
1941 ok(bufSize == bits[i].encoded[1] + 2,
1942 "Got unexpected size %d, expected %d\n", bufSize,
1943 bits[i].encoded[1] + 2);
1944 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
1945 "Unexpected value\n");
1946 LocalFree(buf);
1951 static void test_decodeBits(DWORD dwEncoding)
1953 static const BYTE ber[] = "\x03\x02\x01\xff";
1954 static const BYTE berDecoded = 0xfe;
1955 DWORD i;
1956 BOOL ret;
1957 BYTE *buf = NULL;
1958 DWORD bufSize = 0;
1960 /* normal cases */
1961 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
1963 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
1964 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
1965 &bufSize);
1966 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1967 if (buf)
1969 CRYPT_BIT_BLOB *blob;
1971 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
1972 "Got unexpected size %d\n", bufSize);
1973 blob = (CRYPT_BIT_BLOB *)buf;
1974 ok(blob->cbData == bits[i].cbDecoded,
1975 "Got unexpected length %d, expected %d\n", blob->cbData,
1976 bits[i].cbDecoded);
1977 if (blob->cbData && bits[i].cbDecoded)
1978 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
1979 "Unexpected value\n");
1980 LocalFree(buf);
1983 /* special case: check that something that's valid in BER but not in DER
1984 * decodes successfully
1986 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
1987 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
1988 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1989 if (buf)
1991 CRYPT_BIT_BLOB *blob;
1993 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
1994 "Got unexpected size %d\n", bufSize);
1995 blob = (CRYPT_BIT_BLOB *)buf;
1996 ok(blob->cbData == sizeof(berDecoded),
1997 "Got unexpected length %d\n", blob->cbData);
1998 if (blob->cbData)
1999 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2000 LocalFree(buf);
2004 struct Constraints2
2006 CERT_BASIC_CONSTRAINTS2_INFO info;
2007 const BYTE *encoded;
2010 static const unsigned char bin59[] = { 0x30,0x00 };
2011 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2012 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2013 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2014 static const struct Constraints2 constraints2[] = {
2015 /* empty constraints */
2016 { { FALSE, FALSE, 0}, bin59 },
2017 /* can be a CA */
2018 { { TRUE, FALSE, 0}, bin60 },
2019 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2020 * but that's not the case
2022 { { FALSE, TRUE, 0}, bin61 },
2023 /* can be a CA and has path length constraints set */
2024 { { TRUE, TRUE, 1}, bin62 },
2027 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2028 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2029 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2030 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2031 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2032 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2033 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2034 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2035 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2036 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2038 static void test_encodeBasicConstraints(DWORD dwEncoding)
2040 DWORD i, bufSize = 0;
2041 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2042 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2043 (LPBYTE)encodedDomainName };
2044 BOOL ret;
2045 BYTE *buf = NULL;
2047 /* First test with the simpler info2 */
2048 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2050 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2051 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2052 &bufSize);
2053 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2054 if (buf)
2056 ok(bufSize == constraints2[i].encoded[1] + 2,
2057 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2058 bufSize);
2059 ok(!memcmp(buf, constraints2[i].encoded,
2060 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2061 LocalFree(buf);
2064 /* Now test with more complex basic constraints */
2065 info.SubjectType.cbData = 0;
2066 info.fPathLenConstraint = FALSE;
2067 info.cSubtreesConstraint = 0;
2068 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2069 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2070 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2071 if (buf)
2073 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2074 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2075 "Unexpected value\n");
2076 LocalFree(buf);
2078 /* None of the certs I examined had any subtree constraint, but I test one
2079 * anyway just in case.
2081 info.cSubtreesConstraint = 1;
2082 info.rgSubtreesConstraint = &nameBlob;
2083 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2084 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2085 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2086 if (buf)
2088 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2089 ok(!memcmp(buf, constraintWithDomainName,
2090 sizeof(constraintWithDomainName)), "Unexpected value\n");
2091 LocalFree(buf);
2093 /* FIXME: test encoding with subject type. */
2096 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2098 static void test_decodeBasicConstraints(DWORD dwEncoding)
2100 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2101 0xff };
2102 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2103 DWORD i;
2104 BOOL ret;
2105 BYTE *buf = NULL;
2106 DWORD bufSize = 0;
2108 /* First test with simpler info2 */
2109 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2111 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2112 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2113 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2114 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2115 GetLastError());
2116 if (buf)
2118 CERT_BASIC_CONSTRAINTS2_INFO *info =
2119 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2121 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2122 "Unexpected value for item %d\n", i);
2123 LocalFree(buf);
2126 /* Check with the order of encoded elements inverted */
2127 buf = (PBYTE)1;
2128 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2129 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2130 &bufSize);
2131 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2132 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2133 ok(!buf, "Expected buf to be set to NULL\n");
2134 /* Check with a non-DER bool */
2135 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2136 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2137 (BYTE *)&buf, &bufSize);
2138 ok(ret, "pCryptDecodeObjectEx failed: %08x\n", GetLastError());
2139 if (buf)
2141 CERT_BASIC_CONSTRAINTS2_INFO *info =
2142 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2144 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2145 LocalFree(buf);
2147 /* Check with a non-basic constraints value */
2148 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2149 (LPBYTE)encodedCommonName, encodedCommonName[1] + 2,
2150 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2151 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2152 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2153 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2154 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2155 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2156 (BYTE *)&buf, &bufSize);
2157 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2158 if (buf)
2160 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2162 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2163 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2164 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2165 LocalFree(buf);
2167 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2168 constraintWithDomainName, sizeof(constraintWithDomainName),
2169 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2170 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2171 if (buf)
2173 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2175 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2176 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2177 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2178 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2180 ok(info->rgSubtreesConstraint[0].cbData ==
2181 sizeof(encodedDomainName), "Wrong size %d\n",
2182 info->rgSubtreesConstraint[0].cbData);
2183 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2184 sizeof(encodedDomainName)), "Unexpected value\n");
2186 LocalFree(buf);
2190 /* These are terrible public keys of course, I'm just testing encoding */
2191 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2192 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2193 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2194 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2195 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2196 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2197 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2198 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2200 struct EncodedRSAPubKey
2202 const BYTE *modulus;
2203 size_t modulusLen;
2204 const BYTE *encoded;
2205 size_t decodedModulusLen;
2208 struct EncodedRSAPubKey rsaPubKeys[] = {
2209 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2210 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2211 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2212 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2215 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2217 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2218 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2219 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2220 BOOL ret;
2221 BYTE *buf = NULL;
2222 DWORD bufSize = 0, i;
2224 /* Try with a bogus blob type */
2225 hdr->bType = 2;
2226 hdr->bVersion = CUR_BLOB_VERSION;
2227 hdr->reserved = 0;
2228 hdr->aiKeyAlg = CALG_RSA_KEYX;
2229 rsaPubKey->magic = 0x31415352;
2230 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2231 rsaPubKey->pubexp = 65537;
2232 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2233 sizeof(modulus1));
2235 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2236 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2237 &bufSize);
2238 ok(!ret && GetLastError() == E_INVALIDARG,
2239 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2240 /* Now with a bogus reserved field */
2241 hdr->bType = PUBLICKEYBLOB;
2242 hdr->reserved = 1;
2243 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2244 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2245 &bufSize);
2246 if (buf)
2248 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2249 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2250 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2251 LocalFree(buf);
2253 /* Now with a bogus blob version */
2254 hdr->reserved = 0;
2255 hdr->bVersion = 0;
2256 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2257 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2258 &bufSize);
2259 if (buf)
2261 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2262 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2263 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2264 LocalFree(buf);
2266 /* And with a bogus alg ID */
2267 hdr->bVersion = CUR_BLOB_VERSION;
2268 hdr->aiKeyAlg = CALG_DES;
2269 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2270 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2271 &bufSize);
2272 if (buf)
2274 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2275 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2276 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2277 LocalFree(buf);
2279 /* Check a couple of RSA-related OIDs */
2280 hdr->aiKeyAlg = CALG_RSA_KEYX;
2281 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2282 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2283 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2284 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2285 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2286 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2287 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2288 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2289 /* Finally, all valid */
2290 hdr->aiKeyAlg = CALG_RSA_KEYX;
2291 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2293 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2294 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2295 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2296 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2297 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2298 if (buf)
2300 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2301 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2302 bufSize);
2303 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2304 "Unexpected value\n");
2305 LocalFree(buf);
2310 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2312 DWORD i;
2313 LPBYTE buf = NULL;
2314 DWORD bufSize = 0;
2315 BOOL ret;
2317 /* Try with a bad length */
2318 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2319 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2320 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2321 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2322 "Expected CRYPT_E_ASN1_EOD, got %08x\n", CRYPT_E_ASN1_EOD);
2323 /* Try with a couple of RSA-related OIDs */
2324 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2325 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2326 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2327 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2328 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2329 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2330 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2331 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2332 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2333 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2334 /* Now try success cases */
2335 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2337 bufSize = 0;
2338 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2339 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2340 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2341 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2342 if (buf)
2344 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2345 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2347 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2348 rsaPubKeys[i].decodedModulusLen,
2349 "Wrong size %d\n", bufSize);
2350 ok(hdr->bType == PUBLICKEYBLOB,
2351 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2352 hdr->bType);
2353 ok(hdr->bVersion == CUR_BLOB_VERSION,
2354 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2355 CUR_BLOB_VERSION, hdr->bVersion);
2356 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2357 hdr->reserved);
2358 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2359 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2360 ok(rsaPubKey->magic == 0x31415352,
2361 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2362 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2363 "Wrong bit len %d\n", rsaPubKey->bitlen);
2364 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2365 rsaPubKey->pubexp);
2366 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2367 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2368 "Unexpected modulus\n");
2369 LocalFree(buf);
2374 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2375 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2376 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2378 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2379 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2380 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2381 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2383 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2385 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2386 CRYPT_SEQUENCE_OF_ANY seq;
2387 DWORD i;
2388 BOOL ret;
2389 BYTE *buf = NULL;
2390 DWORD bufSize = 0;
2392 /* Encode a homogeneous sequence */
2393 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2395 blobs[i].cbData = ints[i].encoded[1] + 2;
2396 blobs[i].pbData = (BYTE *)ints[i].encoded;
2398 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2399 seq.rgValue = blobs;
2401 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2402 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2403 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2404 if (buf)
2406 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2407 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2408 LocalFree(buf);
2410 /* Change the type of the first element in the sequence, and give it
2411 * another go
2413 blobs[0].cbData = times[0].encodedTime[1] + 2;
2414 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2415 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2416 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2417 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2418 if (buf)
2420 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2421 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2422 "Unexpected value\n");
2423 LocalFree(buf);
2427 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2429 BOOL ret;
2430 BYTE *buf = NULL;
2431 DWORD bufSize = 0;
2433 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2434 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2435 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2436 if (buf)
2438 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2439 DWORD i;
2441 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2442 "Wrong elements %d\n", seq->cValue);
2443 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2445 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2446 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2447 seq->rgValue[i].cbData);
2448 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2449 ints[i].encoded[1] + 2), "Unexpected value\n");
2451 LocalFree(buf);
2453 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2454 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2455 &bufSize);
2456 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2457 if (buf)
2459 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2461 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2462 "Wrong elements %d\n", seq->cValue);
2463 /* Just check the first element since it's all that changed */
2464 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2465 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2466 seq->rgValue[0].cbData);
2467 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2468 times[0].encodedTime[1] + 2), "Unexpected value\n");
2469 LocalFree(buf);
2473 struct encodedExtensions
2475 CERT_EXTENSIONS exts;
2476 const BYTE *encoded;
2479 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2480 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2481 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2482 static CERT_EXTENSION criticalExt =
2483 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2484 static CERT_EXTENSION nonCriticalExt =
2485 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2487 static const BYTE ext0[] = { 0x30,0x00 };
2488 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2489 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2490 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2491 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2493 static const struct encodedExtensions exts[] = {
2494 { { 0, NULL }, ext0 },
2495 { { 1, &criticalExt }, ext1 },
2496 { { 1, &nonCriticalExt }, ext2 },
2499 static void test_encodeExtensions(DWORD dwEncoding)
2501 DWORD i;
2503 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2505 BOOL ret;
2506 BYTE *buf = NULL;
2507 DWORD bufSize = 0;
2509 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2510 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2511 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2512 if (buf)
2514 ok(bufSize == exts[i].encoded[1] + 2,
2515 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2516 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2517 "Unexpected value\n");
2518 LocalFree(buf);
2523 static void test_decodeExtensions(DWORD dwEncoding)
2525 DWORD i;
2527 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2529 BOOL ret;
2530 BYTE *buf = NULL;
2531 DWORD bufSize = 0;
2533 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2534 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2535 NULL, (BYTE *)&buf, &bufSize);
2536 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2537 if (buf)
2539 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2540 DWORD j;
2542 ok(ext->cExtension == exts[i].exts.cExtension,
2543 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2544 ext->cExtension);
2545 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2547 ok(!strcmp(ext->rgExtension[j].pszObjId,
2548 exts[i].exts.rgExtension[j].pszObjId),
2549 "Expected OID %s, got %s\n",
2550 exts[i].exts.rgExtension[j].pszObjId,
2551 ext->rgExtension[j].pszObjId);
2552 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2553 exts[i].exts.rgExtension[j].Value.pbData,
2554 exts[i].exts.rgExtension[j].Value.cbData),
2555 "Unexpected value\n");
2557 LocalFree(buf);
2562 /* MS encodes public key info with a NULL if the algorithm identifier's
2563 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2564 * it encodes them by omitting the algorithm parameters. This latter approach
2565 * seems more correct, so accept either form.
2567 struct encodedPublicKey
2569 CERT_PUBLIC_KEY_INFO info;
2570 const BYTE *encoded;
2571 const BYTE *encodedNoNull;
2572 CERT_PUBLIC_KEY_INFO decoded;
2575 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2576 0xe, 0xf };
2577 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2579 static const unsigned char bin64[] = {
2580 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2581 static const unsigned char bin65[] = {
2582 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2583 static const unsigned char bin66[] = {
2584 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2585 static const unsigned char bin67[] = {
2586 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2587 static const unsigned char bin68[] = {
2588 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2589 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2590 static const unsigned char bin69[] = {
2591 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2592 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2593 static const unsigned char bin70[] = {
2594 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2595 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2596 0x0f};
2597 static const unsigned char bin71[] = {
2598 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2599 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2600 0x0f};
2601 static unsigned char bin72[] = { 0x05,0x00};
2603 static CHAR oid_bogus[] = "1.2.3",
2604 oid_rsa[] = szOID_RSA;
2606 static const struct encodedPublicKey pubKeys[] = {
2607 /* with a bogus OID */
2608 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2609 bin64, bin65,
2610 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2611 /* some normal keys */
2612 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2613 bin66, bin67,
2614 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2615 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2616 bin68, bin69,
2617 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2618 /* with add'l parameters--note they must be DER-encoded */
2619 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2620 (BYTE *)aKey, 0 } },
2621 bin70, bin71,
2622 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2623 (BYTE *)aKey, 0 } } },
2626 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2628 DWORD i;
2630 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2632 BOOL ret;
2633 BYTE *buf = NULL;
2634 DWORD bufSize = 0;
2636 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2637 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
2638 &bufSize);
2639 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2640 if (buf)
2642 ok(bufSize == pubKeys[i].encoded[1] + 2 ||
2643 bufSize == pubKeys[i].encodedNoNull[1] + 2,
2644 "Expected %d or %d bytes, got %d\n", pubKeys[i].encoded[1] + 2,
2645 pubKeys[i].encodedNoNull[1] + 2, bufSize);
2646 if (bufSize == pubKeys[i].encoded[1] + 2)
2647 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2648 "Unexpected value\n");
2649 else if (bufSize == pubKeys[i].encodedNoNull[1] + 2)
2650 ok(!memcmp(buf, pubKeys[i].encodedNoNull,
2651 pubKeys[i].encodedNoNull[1] + 2), "Unexpected value\n");
2652 LocalFree(buf);
2657 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2658 const CERT_PUBLIC_KEY_INFO *got)
2660 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2661 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2662 got->Algorithm.pszObjId);
2663 ok(expected->Algorithm.Parameters.cbData ==
2664 got->Algorithm.Parameters.cbData,
2665 "Expected parameters of %d bytes, got %d\n",
2666 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2667 if (expected->Algorithm.Parameters.cbData)
2668 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2669 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2670 "Unexpected algorithm parameters\n");
2671 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2672 "Expected public key of %d bytes, got %d\n",
2673 expected->PublicKey.cbData, got->PublicKey.cbData);
2674 if (expected->PublicKey.cbData)
2675 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2676 got->PublicKey.cbData), "Unexpected public key value\n");
2679 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2681 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2682 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2683 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2684 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2685 DWORD i;
2686 BOOL ret;
2687 BYTE *buf = NULL;
2688 DWORD bufSize = 0;
2690 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2692 /* The NULL form decodes to the decoded member */
2693 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2694 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2695 NULL, (BYTE *)&buf, &bufSize);
2696 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2697 if (buf)
2699 comparePublicKeyInfo(&pubKeys[i].decoded,
2700 (CERT_PUBLIC_KEY_INFO *)buf);
2701 LocalFree(buf);
2703 /* The non-NULL form decodes to the original */
2704 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2705 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2706 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
2707 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2708 if (buf)
2710 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2711 LocalFree(buf);
2714 /* Test with bogus (not valid DER) parameters */
2715 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2716 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2717 NULL, (BYTE *)&buf, &bufSize);
2718 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
2719 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
2722 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2723 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2724 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2725 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2726 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2727 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2728 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2729 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2730 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2731 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2732 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2733 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2734 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2735 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2736 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2737 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2738 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2739 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2740 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2741 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2742 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2743 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2744 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2745 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2746 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2747 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2748 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2749 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2750 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2751 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2752 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2753 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2754 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2755 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2756 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2757 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2758 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2759 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2760 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2761 static const BYTE v1CertWithPubKey[] = {
2762 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2763 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2764 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2765 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2766 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2767 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2768 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2769 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2770 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2771 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2772 0x01,0x01 };
2773 static const BYTE v1CertWithPubKeyNoNull[] = {
2774 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2775 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2776 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2777 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2778 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2779 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2780 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2781 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2782 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2783 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2784 static const BYTE v1CertWithSubjectKeyId[] = {
2785 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2786 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2787 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2788 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2789 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2790 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2791 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2792 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2793 0x4c,0x61,0x6e,0x67,0x00 };
2795 static const BYTE serialNum[] = { 0x01 };
2797 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2799 BOOL ret;
2800 BYTE *buf = NULL;
2801 DWORD size = 0;
2802 CERT_INFO info = { 0 };
2803 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2804 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2805 CERT_EXTENSION ext;
2807 /* Test with NULL pvStructInfo */
2808 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2809 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2810 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2811 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2812 /* Test with a V1 cert */
2813 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2814 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2815 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2816 if (buf)
2818 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
2819 v1Cert[1] + 2, size);
2820 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
2821 LocalFree(buf);
2823 /* Test v2 cert */
2824 info.dwVersion = CERT_V2;
2825 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2826 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2827 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2828 if (buf)
2830 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
2831 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
2832 LocalFree(buf);
2834 /* Test v3 cert */
2835 info.dwVersion = CERT_V3;
2836 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2837 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2838 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2839 if (buf)
2841 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
2842 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
2843 LocalFree(buf);
2845 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
2846 * API doesn't prevent it)
2848 info.dwVersion = CERT_V1;
2849 info.cExtension = 1;
2850 info.rgExtension = &criticalExt;
2851 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2852 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2853 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2854 if (buf)
2856 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
2857 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
2858 LocalFree(buf);
2860 /* test v1 cert with a serial number */
2861 info.SerialNumber.cbData = sizeof(serialNum);
2862 info.SerialNumber.pbData = (BYTE *)serialNum;
2863 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2864 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2865 if (buf)
2867 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
2868 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
2869 LocalFree(buf);
2871 /* Test v1 cert with an issuer name, a subject name, and a serial number */
2872 info.Issuer.cbData = sizeof(encodedCommonName);
2873 info.Issuer.pbData = (BYTE *)encodedCommonName;
2874 info.Subject.cbData = sizeof(encodedCommonName);
2875 info.Subject.pbData = (BYTE *)encodedCommonName;
2876 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2877 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2878 if (buf)
2880 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
2881 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
2882 LocalFree(buf);
2884 /* Add a public key */
2885 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
2886 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
2887 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
2888 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2889 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2890 if (buf)
2892 ok(size == sizeof(v1CertWithPubKey) ||
2893 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
2894 if (size == sizeof(v1CertWithPubKey))
2895 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
2896 else if (size == sizeof(v1CertWithPubKeyNoNull))
2897 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
2898 "Got unexpected value\n");
2899 LocalFree(buf);
2901 /* Remove the public key, and add a subject key identifier extension */
2902 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
2903 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
2904 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
2905 ext.pszObjId = oid_subject_key_identifier;
2906 ext.fCritical = FALSE;
2907 ext.Value.cbData = sizeof(octetCommonNameValue);
2908 ext.Value.pbData = (BYTE *)octetCommonNameValue;
2909 info.cExtension = 1;
2910 info.rgExtension = &ext;
2911 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
2912 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2913 if (buf)
2915 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
2916 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
2917 LocalFree(buf);
2921 static void test_decodeCertToBeSigned(DWORD dwEncoding)
2923 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert,
2924 v1CertWithConstraints, v1CertWithSerial };
2925 BOOL ret;
2926 BYTE *buf = NULL;
2927 DWORD size = 0, i;
2929 /* Test with NULL pbEncoded */
2930 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
2931 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2932 ok(!ret && GetLastError() == CRYPT_E_ASN1_EOD,
2933 "Expected CRYPT_E_ASN1_EOD, got %08x\n", GetLastError());
2934 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
2935 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2936 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2937 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
2938 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT, because at a
2939 * minimum a cert must have a non-zero serial number, an issuer, and a
2940 * subject.
2942 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
2944 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
2945 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2946 (BYTE *)&buf, &size);
2947 ok(!ret, "Expected failure\n");
2949 /* Now check with serial number, subject and issuer specified */
2950 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
2951 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
2952 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2953 if (buf)
2955 CERT_INFO *info = (CERT_INFO *)buf;
2957 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
2958 ok(info->SerialNumber.cbData == 1,
2959 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
2960 ok(*info->SerialNumber.pbData == *serialNum,
2961 "Expected serial number %d, got %d\n", *serialNum,
2962 *info->SerialNumber.pbData);
2963 ok(info->Issuer.cbData == sizeof(encodedCommonName),
2964 "Wrong size %d\n", info->Issuer.cbData);
2965 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
2966 "Unexpected issuer\n");
2967 ok(info->Subject.cbData == sizeof(encodedCommonName),
2968 "Wrong size %d\n", info->Subject.cbData);
2969 ok(!memcmp(info->Subject.pbData, encodedCommonName,
2970 info->Subject.cbData), "Unexpected subject\n");
2971 LocalFree(buf);
2973 /* Check again with pub key specified */
2974 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
2975 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
2976 (BYTE *)&buf, &size);
2977 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2978 if (buf)
2980 CERT_INFO *info = (CERT_INFO *)buf;
2982 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
2983 ok(info->SerialNumber.cbData == 1,
2984 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
2985 ok(*info->SerialNumber.pbData == *serialNum,
2986 "Expected serial number %d, got %d\n", *serialNum,
2987 *info->SerialNumber.pbData);
2988 ok(info->Issuer.cbData == sizeof(encodedCommonName),
2989 "Wrong size %d\n", info->Issuer.cbData);
2990 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
2991 "Unexpected issuer\n");
2992 ok(info->Subject.cbData == sizeof(encodedCommonName),
2993 "Wrong size %d\n", info->Subject.cbData);
2994 ok(!memcmp(info->Subject.pbData, encodedCommonName,
2995 info->Subject.cbData), "Unexpected subject\n");
2996 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
2997 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
2998 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
2999 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3000 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3001 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3002 sizeof(aKey)), "Unexpected public key\n");
3003 LocalFree(buf);
3007 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3008 0xe, 0xf };
3010 static const BYTE signedBigCert[] = {
3011 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3012 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3013 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3014 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3015 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3016 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3017 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3018 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3019 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3020 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3021 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3022 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3024 static void test_encodeCert(DWORD dwEncoding)
3026 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3027 * also that bigCert is a NULL-terminated string, so don't count its
3028 * last byte (otherwise the signed cert won't decode.)
3030 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3031 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3032 BOOL ret;
3033 BYTE *buf = NULL;
3034 DWORD bufSize = 0;
3036 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3037 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &bufSize);
3038 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3039 if (buf)
3041 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3042 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3043 LocalFree(buf);
3047 static void test_decodeCert(DWORD dwEncoding)
3049 BOOL ret;
3050 BYTE *buf = NULL;
3051 DWORD size = 0;
3053 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3054 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3055 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3056 if (buf)
3058 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3060 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3061 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3062 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3063 "Unexpected cert\n");
3064 ok(info->Signature.cbData == sizeof(hash),
3065 "Wrong signature size %d\n", info->Signature.cbData);
3066 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3067 "Unexpected signature\n");
3068 LocalFree(buf);
3070 /* A signed cert decodes as a CERT_INFO too */
3071 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3072 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3073 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3074 if (buf)
3076 CERT_INFO *info = (CERT_INFO *)buf;
3078 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3079 ok(info->SerialNumber.cbData == 1,
3080 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3081 ok(*info->SerialNumber.pbData == *serialNum,
3082 "Expected serial number %d, got %d\n", *serialNum,
3083 *info->SerialNumber.pbData);
3084 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3085 "Wrong size %d\n", info->Issuer.cbData);
3086 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3087 "Unexpected issuer\n");
3088 ok(info->Subject.cbData == sizeof(encodedCommonName),
3089 "Wrong size %d\n", info->Subject.cbData);
3090 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3091 info->Subject.cbData), "Unexpected subject\n");
3092 LocalFree(buf);
3096 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3097 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3098 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3099 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3100 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3101 0x00, 0x03 };
3102 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3103 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3104 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3105 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3106 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3107 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3108 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3109 0x2e, 0x6f, 0x72, 0x67 };
3110 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3111 CRL_REASON_AFFILIATION_CHANGED;
3113 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3115 CRL_DIST_POINTS_INFO info = { 0 };
3116 CRL_DIST_POINT point = { { 0 } };
3117 CERT_ALT_NAME_ENTRY entry = { 0 };
3118 BOOL ret;
3119 BYTE *buf = NULL;
3120 DWORD size = 0;
3122 /* Test with an empty info */
3123 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3124 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3125 ok(!ret && GetLastError() == E_INVALIDARG,
3126 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3127 /* Test with one empty dist point */
3128 info.cDistPoint = 1;
3129 info.rgDistPoint = &point;
3130 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3131 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3132 if (buf)
3134 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3135 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3136 LocalFree(buf);
3138 /* A dist point with an invalid name */
3139 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3140 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3141 U(entry).pwszURL = (LPWSTR)nihongoURL;
3142 U(point.DistPointName).FullName.cAltEntry = 1;
3143 U(point.DistPointName).FullName.rgAltEntry = &entry;
3144 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3145 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3146 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3147 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3148 /* The first invalid character is at index 7 */
3149 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3150 "Expected invalid char at index 7, got %d\n",
3151 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3152 /* A dist point with (just) a valid name */
3153 U(entry).pwszURL = (LPWSTR)url;
3154 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3155 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3156 if (buf)
3158 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3159 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3160 LocalFree(buf);
3162 /* A dist point with (just) reason flags */
3163 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3164 point.ReasonFlags.cbData = sizeof(crlReason);
3165 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3166 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3167 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3168 if (buf)
3170 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3171 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3172 LocalFree(buf);
3174 /* A dist point with just an issuer */
3175 point.ReasonFlags.cbData = 0;
3176 point.CRLIssuer.cAltEntry = 1;
3177 point.CRLIssuer.rgAltEntry = &entry;
3178 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3179 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3180 if (buf)
3182 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3183 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3184 LocalFree(buf);
3186 /* A dist point with both a name and an issuer */
3187 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3188 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3189 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3190 if (buf)
3192 ok(size == sizeof(distPointWithUrlAndIssuer),
3193 "Wrong size %d\n", size);
3194 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3195 LocalFree(buf);
3199 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3201 BOOL ret;
3202 BYTE *buf = NULL;
3203 DWORD size = 0;
3204 PCRL_DIST_POINTS_INFO info;
3205 PCRL_DIST_POINT point;
3206 PCERT_ALT_NAME_ENTRY entry;
3208 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3209 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3210 (BYTE *)&buf, &size);
3211 if (ret)
3213 info = (PCRL_DIST_POINTS_INFO)buf;
3214 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3215 "Wrong size %d\n", size);
3216 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3217 info->cDistPoint);
3218 point = info->rgDistPoint;
3219 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3220 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3221 point->DistPointName.dwDistPointNameChoice);
3222 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3223 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3224 LocalFree(buf);
3226 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3227 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3228 (BYTE *)&buf, &size);
3229 if (ret)
3231 info = (PCRL_DIST_POINTS_INFO)buf;
3232 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3233 "Wrong size %d\n", size);
3234 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3235 info->cDistPoint);
3236 point = info->rgDistPoint;
3237 ok(point->DistPointName.dwDistPointNameChoice ==
3238 CRL_DIST_POINT_FULL_NAME,
3239 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3240 point->DistPointName.dwDistPointNameChoice);
3241 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3242 "Expected 1 name entry, got %d\n",
3243 U(point->DistPointName).FullName.cAltEntry);
3244 entry = U(point->DistPointName).FullName.rgAltEntry;
3245 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3246 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3247 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3248 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3249 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3250 LocalFree(buf);
3252 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3253 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3254 NULL, (BYTE *)&buf, &size);
3255 if (ret)
3257 info = (PCRL_DIST_POINTS_INFO)buf;
3258 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3259 "Wrong size %d\n", size);
3260 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3261 info->cDistPoint);
3262 point = info->rgDistPoint;
3263 ok(point->DistPointName.dwDistPointNameChoice ==
3264 CRL_DIST_POINT_NO_NAME,
3265 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3266 point->DistPointName.dwDistPointNameChoice);
3267 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3268 "Expected reason length\n");
3269 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3270 "Unexpected reason\n");
3271 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3272 LocalFree(buf);
3274 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3275 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3276 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3277 if (ret)
3279 info = (PCRL_DIST_POINTS_INFO)buf;
3280 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3281 "Wrong size %d\n", size);
3282 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3283 info->cDistPoint);
3284 point = info->rgDistPoint;
3285 ok(point->DistPointName.dwDistPointNameChoice ==
3286 CRL_DIST_POINT_FULL_NAME,
3287 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3288 point->DistPointName.dwDistPointNameChoice);
3289 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3290 "Expected 1 name entry, got %d\n",
3291 U(point->DistPointName).FullName.cAltEntry);
3292 entry = U(point->DistPointName).FullName.rgAltEntry;
3293 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3294 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3295 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3296 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3297 ok(point->CRLIssuer.cAltEntry == 1,
3298 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3299 entry = point->CRLIssuer.rgAltEntry;
3300 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3301 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3302 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3303 LocalFree(buf);
3307 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3308 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3309 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3310 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3311 0x67 };
3313 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3315 BOOL ret;
3316 BYTE *buf = NULL;
3317 DWORD size = 0;
3318 CRL_ISSUING_DIST_POINT point = { { 0 } };
3319 CERT_ALT_NAME_ENTRY entry;
3321 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3322 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3323 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3325 skip("no X509_ISSUING_DIST_POINT encode support\n");
3326 return;
3328 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3329 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3330 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3331 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3332 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3333 if (buf)
3335 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3336 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3337 LocalFree(buf);
3339 /* nonsensical flags */
3340 point.fOnlyContainsUserCerts = TRUE;
3341 point.fOnlyContainsCACerts = TRUE;
3342 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3343 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3344 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3345 if (buf)
3347 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3348 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3349 LocalFree(buf);
3351 /* unimplemented name type */
3352 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3353 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3354 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3355 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3356 ok(!ret && GetLastError() == E_INVALIDARG,
3357 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3358 /* empty name */
3359 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3360 U(point.DistPointName).FullName.cAltEntry = 0;
3361 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3362 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3363 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3364 if (buf)
3366 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3367 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3368 LocalFree(buf);
3370 /* name with URL entry */
3371 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3372 U(entry).pwszURL = (LPWSTR)url;
3373 U(point.DistPointName).FullName.cAltEntry = 1;
3374 U(point.DistPointName).FullName.rgAltEntry = &entry;
3375 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3376 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3377 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3378 if (buf)
3380 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3381 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3382 LocalFree(buf);
3386 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3387 const CERT_ALT_NAME_ENTRY *got)
3389 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3390 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3391 got->dwAltNameChoice);
3392 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3394 switch (got->dwAltNameChoice)
3396 case CERT_ALT_NAME_RFC822_NAME:
3397 case CERT_ALT_NAME_DNS_NAME:
3398 case CERT_ALT_NAME_EDI_PARTY_NAME:
3399 case CERT_ALT_NAME_URL:
3400 case CERT_ALT_NAME_REGISTERED_ID:
3401 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3402 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3403 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3404 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3405 "Unexpected name\n");
3406 break;
3407 case CERT_ALT_NAME_X400_ADDRESS:
3408 case CERT_ALT_NAME_DIRECTORY_NAME:
3409 case CERT_ALT_NAME_IP_ADDRESS:
3410 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3411 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3412 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3413 U(*got).IPAddress.cbData), "Unexpected value\n");
3414 break;
3419 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3420 const CERT_ALT_NAME_INFO *got)
3422 DWORD i;
3424 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3425 expected->cAltEntry, got->cAltEntry);
3426 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3427 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3430 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3431 const CRL_DIST_POINT_NAME *got)
3433 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3434 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3435 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3436 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3439 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3440 const CRL_ISSUING_DIST_POINT *got)
3442 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3443 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3444 "Unexpected fOnlyContainsUserCerts\n");
3445 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3446 "Unexpected fOnlyContainsCACerts\n");
3447 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3448 "Unexpected reason flags\n");
3449 ok(got->fIndirectCRL == expected->fIndirectCRL,
3450 "Unexpected fIndirectCRL\n");
3453 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3455 BOOL ret;
3456 BYTE *buf = NULL;
3457 DWORD size = 0;
3458 CRL_ISSUING_DIST_POINT point = { { 0 } };
3460 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3461 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3462 (BYTE *)&buf, &size);
3463 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3465 skip("no X509_ISSUING_DIST_POINT decode support\n");
3466 return;
3468 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3469 if (ret)
3471 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3472 LocalFree(buf);
3474 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3475 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3476 (BYTE *)&buf, &size);
3477 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3478 if (ret)
3480 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3481 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3482 LocalFree(buf);
3484 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3485 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3486 (BYTE *)&buf, &size);
3487 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3488 if (ret)
3490 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3491 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3492 U(point.DistPointName).FullName.cAltEntry = 0;
3493 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3494 LocalFree(buf);
3496 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3497 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3498 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3499 if (ret)
3501 CERT_ALT_NAME_ENTRY entry;
3503 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3504 U(entry).pwszURL = (LPWSTR)url;
3505 U(point.DistPointName).FullName.cAltEntry = 1;
3506 U(point.DistPointName).FullName.rgAltEntry = &entry;
3507 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3508 LocalFree(buf);
3512 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3513 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3514 0x30, 0x5a };
3515 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3516 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3517 0x30, 0x30, 0x30, 0x30, 0x5a };
3518 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3519 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3520 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3521 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3522 0x5a };
3523 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3524 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3525 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3526 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3527 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3528 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3529 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3530 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3531 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3532 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3533 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3534 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3535 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3536 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3537 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3538 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3539 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3540 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3541 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3542 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3543 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3544 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3545 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3546 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3547 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3548 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3549 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3550 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3551 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3552 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3553 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3554 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3555 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3556 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3557 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3558 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3559 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3560 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3561 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3562 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3564 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3566 BOOL ret;
3567 BYTE *buf = NULL;
3568 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3569 DWORD size = 0;
3570 CRL_INFO info = { 0 };
3571 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3572 CERT_EXTENSION ext;
3574 /* Test with a V1 CRL */
3575 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3576 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3577 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3578 if (buf)
3580 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3581 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3582 LocalFree(buf);
3584 /* Test v2 CRL */
3585 info.dwVersion = CRL_V2;
3586 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3587 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3588 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3589 if (buf)
3591 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3592 v2CRL[1] + 2, size);
3593 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3594 LocalFree(buf);
3596 /* v1 CRL with a name */
3597 info.dwVersion = CRL_V1;
3598 info.Issuer.cbData = sizeof(encodedCommonName);
3599 info.Issuer.pbData = (BYTE *)encodedCommonName;
3600 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3601 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3602 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3603 if (buf)
3605 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3606 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3607 LocalFree(buf);
3609 /* v1 CRL with a name and a NULL entry pointer */
3610 info.cCRLEntry = 1;
3611 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3612 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3613 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3614 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3615 /* now set an empty entry */
3616 info.rgCRLEntry = &entry;
3617 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3618 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3619 if (buf)
3621 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3622 "Wrong size %d\n", size);
3623 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3624 "Got unexpected value\n");
3625 LocalFree(buf);
3627 /* an entry with a serial number */
3628 entry.SerialNumber.cbData = sizeof(serialNum);
3629 entry.SerialNumber.pbData = (BYTE *)serialNum;
3630 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3631 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3632 if (buf)
3634 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3635 "Wrong size %d\n", size);
3636 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3637 "Got unexpected value\n");
3638 LocalFree(buf);
3640 /* an entry with an extension */
3641 entry.cExtension = 1;
3642 entry.rgExtension = &criticalExt;
3643 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3644 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3645 ok(ret, "pCryptEncodeObjectEx failed: %08x\n", GetLastError());
3646 if (buf)
3648 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3649 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3650 LocalFree(buf);
3652 /* a CRL with an extension */
3653 entry.cExtension = 0;
3654 info.cExtension = 1;
3655 info.rgExtension = &criticalExt;
3656 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3657 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3658 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3659 if (buf)
3661 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3662 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3663 LocalFree(buf);
3665 /* a v2 CRL with an extension, this time non-critical */
3666 info.dwVersion = CRL_V2;
3667 info.rgExtension = &nonCriticalExt;
3668 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3669 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3670 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3671 if (buf)
3673 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3674 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3675 LocalFree(buf);
3677 /* a v2 CRL with an issuing dist point extension */
3678 ext.pszObjId = oid_issuing_dist_point;
3679 ext.fCritical = TRUE;
3680 ext.Value.cbData = sizeof(urlIDP);
3681 ext.Value.pbData = (LPBYTE)urlIDP;
3682 entry.rgExtension = &ext;
3683 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3684 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
3685 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3686 if (buf)
3688 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3689 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3690 LocalFree(buf);
3694 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3695 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
3696 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
3697 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
3698 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
3699 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
3700 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
3701 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
3702 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
3703 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
3704 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
3705 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
3706 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
3707 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
3708 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
3709 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
3710 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
3711 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
3712 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
3713 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
3714 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
3715 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
3716 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
3717 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
3718 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
3719 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
3720 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
3721 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
3722 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
3723 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
3724 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
3725 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
3726 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
3727 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
3728 0xcd };
3729 static const BYTE verisignCRLWithLotsOfEntries[] = {
3730 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
3731 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
3732 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
3733 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
3734 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
3735 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
3736 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
3737 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
3738 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
3739 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
3740 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
3741 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
3742 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
3743 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
3744 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
3745 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
3746 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3747 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
3748 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
3749 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3750 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
3751 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
3752 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
3753 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
3754 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
3755 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
3756 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
3757 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
3758 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
3759 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
3760 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
3761 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
3762 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
3763 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3764 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
3765 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
3766 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
3767 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
3768 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
3769 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
3770 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
3771 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
3772 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
3773 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
3774 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
3775 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
3776 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
3777 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
3778 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
3779 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
3780 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
3781 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
3782 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
3783 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
3784 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3785 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
3786 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
3787 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
3788 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
3789 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
3790 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
3791 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
3792 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
3793 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
3794 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
3795 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
3796 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
3797 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
3798 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
3799 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
3800 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
3801 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
3802 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
3803 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
3804 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
3805 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
3806 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
3807 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
3808 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
3809 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
3810 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
3811 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
3812 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
3813 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
3814 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
3815 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
3816 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
3817 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
3818 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
3819 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
3820 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
3821 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
3822 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
3823 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
3824 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
3825 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
3826 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
3827 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
3828 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
3829 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
3830 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
3831 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
3832 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
3833 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
3834 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
3835 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
3836 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
3837 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
3838 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
3839 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
3840 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
3841 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
3842 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
3843 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
3844 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
3845 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
3846 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
3847 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
3848 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
3849 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
3850 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
3851 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
3852 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
3853 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
3854 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
3855 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
3856 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
3857 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
3858 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
3859 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
3860 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
3861 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
3862 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
3863 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
3864 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
3865 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
3866 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
3867 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
3868 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
3869 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
3870 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
3871 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
3872 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
3873 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
3874 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
3875 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
3876 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
3877 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
3878 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
3879 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
3880 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
3881 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
3882 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
3883 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
3884 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
3885 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
3886 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
3887 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
3888 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
3889 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
3890 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
3891 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
3892 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
3893 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
3894 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
3895 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
3896 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
3897 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
3898 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
3899 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
3900 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
3901 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
3902 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
3903 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
3904 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
3905 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
3906 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
3907 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
3908 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
3909 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
3910 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
3911 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
3912 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
3913 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
3914 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
3915 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
3916 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
3917 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
3918 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
3919 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
3920 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
3921 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
3922 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
3923 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
3924 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
3925 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
3926 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
3927 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
3928 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
3929 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
3930 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
3931 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
3932 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
3933 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
3934 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
3935 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
3936 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
3937 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
3938 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
3939 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
3940 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
3941 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
3942 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
3943 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
3944 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
3945 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
3946 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
3947 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
3948 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
3949 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
3950 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
3951 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
3952 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
3953 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
3954 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
3955 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
3956 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
3957 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
3958 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
3959 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
3960 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
3961 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
3962 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
3963 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
3964 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
3965 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
3966 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
3967 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
3968 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
3969 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
3970 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
3971 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
3972 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
3973 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
3974 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
3975 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
3976 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
3977 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
3978 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
3979 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
3980 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
3981 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
3982 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
3983 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
3984 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
3985 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
3986 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
3987 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
3988 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
3989 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
3990 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
3991 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
3992 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
3993 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
3994 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
3995 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
3996 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
3997 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
3998 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
3999 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4000 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4001 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4002 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4003 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4004 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4005 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4006 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4007 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4008 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4009 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4010 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4011 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4012 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4013 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4014 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4015 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4016 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4017 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4018 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4019 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4020 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4021 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4022 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4023 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4024 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4025 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4026 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4027 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4028 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4029 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4030 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4031 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4032 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4033 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4034 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4035 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4036 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4037 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4038 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4039 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4040 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4041 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4042 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4043 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4044 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4045 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4046 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4047 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4048 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4049 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4050 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4051 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4052 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4053 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4054 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4055 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4056 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4057 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4058 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4059 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4060 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4061 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4062 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4063 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4064 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4065 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4066 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4067 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4068 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4069 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4070 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4071 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4072 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4073 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4074 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4075 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4076 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4077 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4078 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4079 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4080 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4081 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4082 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4083 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4084 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4085 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4086 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4087 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4088 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4089 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4090 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4091 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4092 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4093 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4094 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4095 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4096 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4097 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4098 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4099 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4100 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4101 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4102 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4103 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4104 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4105 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4106 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4107 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4108 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4109 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4110 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4111 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4112 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4113 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4114 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4115 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4116 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4117 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4118 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4119 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4120 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4121 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4122 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4123 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4124 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4125 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4126 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4127 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4128 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4129 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4130 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4131 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4132 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4133 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4134 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4135 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4136 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4137 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4138 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4139 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4140 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4141 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4142 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4143 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4144 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4145 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4146 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4147 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4148 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4149 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4150 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4151 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4152 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4153 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4154 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4155 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4156 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4157 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4158 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4159 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4160 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4161 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4162 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4163 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4164 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4165 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4166 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4167 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4168 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4169 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4170 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4171 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4172 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4173 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4174 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4175 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4176 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4177 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4178 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4179 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4180 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4181 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4182 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4183 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4184 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4185 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4186 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4187 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4188 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4189 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4190 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4191 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4192 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4193 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4194 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4195 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4196 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4197 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4198 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4199 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4200 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4201 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4202 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4203 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4204 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4205 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4206 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4207 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4208 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4209 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4210 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4211 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4212 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4213 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4214 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4215 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4216 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4217 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4218 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4219 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4220 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4221 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4222 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4223 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4224 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4225 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4226 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4227 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4228 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4229 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4230 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4231 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4232 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4233 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4234 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4235 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4236 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4237 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4239 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4241 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4242 BOOL ret;
4243 BYTE *buf = NULL;
4244 DWORD size = 0, i;
4246 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4248 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4249 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4250 (BYTE *)&buf, &size);
4251 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT),
4252 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4254 /* at a minimum, a CRL must contain an issuer: */
4255 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4256 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4257 (BYTE *)&buf, &size);
4258 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4259 if (buf)
4261 CRL_INFO *info = (CRL_INFO *)buf;
4263 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4264 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4265 info->cCRLEntry);
4266 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4267 "Wrong issuer size %d\n", info->Issuer.cbData);
4268 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4269 "Unexpected issuer\n");
4270 LocalFree(buf);
4272 /* check decoding with an empty CRL entry */
4273 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4274 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4275 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4276 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
4277 "Expected CRYPT_E_ASN1_CORRUPT, got %08x\n", GetLastError());
4278 /* with a real CRL entry */
4279 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4280 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4281 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4282 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4283 if (buf)
4285 CRL_INFO *info = (CRL_INFO *)buf;
4286 CRL_ENTRY *entry;
4288 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4289 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4290 info->cCRLEntry);
4291 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4292 entry = info->rgCRLEntry;
4293 ok(entry->SerialNumber.cbData == 1,
4294 "Expected serial number size 1, got %d\n",
4295 entry->SerialNumber.cbData);
4296 ok(*entry->SerialNumber.pbData == *serialNum,
4297 "Expected serial number %d, got %d\n", *serialNum,
4298 *entry->SerialNumber.pbData);
4299 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4300 "Wrong issuer size %d\n", info->Issuer.cbData);
4301 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4302 "Unexpected issuer\n");
4303 LocalFree(buf);
4305 /* a real CRL from verisign that has extensions */
4306 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4307 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4308 NULL, (BYTE *)&buf, &size);
4309 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4310 if (buf)
4312 CRL_INFO *info = (CRL_INFO *)buf;
4313 CRL_ENTRY *entry;
4315 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4316 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4317 info->cCRLEntry);
4318 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4319 entry = info->rgCRLEntry;
4320 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4321 info->cExtension);
4322 LocalFree(buf);
4324 /* another real CRL from verisign that has lots of entries */
4325 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4326 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4327 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4328 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4329 if (buf)
4331 CRL_INFO *info = (CRL_INFO *)buf;
4333 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4334 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4335 info->cCRLEntry);
4336 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4337 info->cExtension);
4338 LocalFree(buf);
4340 /* and finally, with an extension */
4341 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4342 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4343 NULL, (BYTE *)&buf, &size);
4344 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4345 if (buf)
4347 CRL_INFO *info = (CRL_INFO *)buf;
4348 CRL_ENTRY *entry;
4350 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4351 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4352 info->cCRLEntry);
4353 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4354 entry = info->rgCRLEntry;
4355 ok(entry->SerialNumber.cbData == 1,
4356 "Expected serial number size 1, got %d\n",
4357 entry->SerialNumber.cbData);
4358 ok(*entry->SerialNumber.pbData == *serialNum,
4359 "Expected serial number %d, got %d\n", *serialNum,
4360 *entry->SerialNumber.pbData);
4361 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4362 "Wrong issuer size %d\n", info->Issuer.cbData);
4363 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4364 "Unexpected issuer\n");
4365 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4366 info->cExtension);
4367 LocalFree(buf);
4369 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4370 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4371 NULL, (BYTE *)&buf, &size);
4372 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4373 if (buf)
4375 CRL_INFO *info = (CRL_INFO *)buf;
4377 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4378 info->cExtension);
4379 LocalFree(buf);
4381 /* And again, with an issuing dist point */
4382 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4383 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4384 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4385 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4386 if (buf)
4388 CRL_INFO *info = (CRL_INFO *)buf;
4390 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4391 info->cExtension);
4392 LocalFree(buf);
4396 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4397 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4398 static const BYTE encodedUsage[] = {
4399 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4400 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4401 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4403 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4405 BOOL ret;
4406 BYTE *buf = NULL;
4407 DWORD size = 0;
4408 CERT_ENHKEY_USAGE usage;
4410 /* Test with empty usage */
4411 usage.cUsageIdentifier = 0;
4412 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4413 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4414 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4415 if (buf)
4417 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4418 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4419 LocalFree(buf);
4421 /* Test with a few usages */
4422 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4423 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4424 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4425 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4426 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4427 if (buf)
4429 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4430 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4431 LocalFree(buf);
4435 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4437 BOOL ret;
4438 LPBYTE buf = NULL;
4439 DWORD size = 0;
4441 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4442 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4443 (BYTE *)&buf, &size);
4444 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4445 if (buf)
4447 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4449 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4450 "Wrong size %d\n", size);
4451 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4452 usage->cUsageIdentifier);
4453 LocalFree(buf);
4455 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4456 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4457 (BYTE *)&buf, &size);
4458 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4459 if (buf)
4461 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4462 DWORD i;
4464 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4465 "Wrong size %d\n", size);
4466 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4467 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4468 for (i = 0; i < usage->cUsageIdentifier; i++)
4469 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4470 "Expected OID %s, got %s\n", keyUsages[i],
4471 usage->rgpszUsageIdentifier[i]);
4472 LocalFree(buf);
4476 static BYTE keyId[] = { 1,2,3,4 };
4477 static const BYTE authorityKeyIdWithId[] = {
4478 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4479 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4480 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4481 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4482 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4484 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4486 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4487 BOOL ret;
4488 BYTE *buf = NULL;
4489 DWORD size = 0;
4491 /* Test with empty id */
4492 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4493 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4494 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4495 if (buf)
4497 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4498 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4499 LocalFree(buf);
4501 /* With just a key id */
4502 info.KeyId.cbData = sizeof(keyId);
4503 info.KeyId.pbData = keyId;
4504 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4505 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4506 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4507 if (buf)
4509 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4510 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4511 LocalFree(buf);
4513 /* With just an issuer */
4514 info.KeyId.cbData = 0;
4515 info.CertIssuer.cbData = sizeof(encodedCommonName);
4516 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4517 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4518 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4519 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4520 if (buf)
4522 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4523 size);
4524 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4525 LocalFree(buf);
4527 /* With just a serial number */
4528 info.CertIssuer.cbData = 0;
4529 info.CertSerialNumber.cbData = sizeof(serialNum);
4530 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4531 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4532 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4533 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4534 if (buf)
4536 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4537 size);
4538 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4539 LocalFree(buf);
4543 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4545 BOOL ret;
4546 LPBYTE buf = NULL;
4547 DWORD size = 0;
4549 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4550 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4551 (BYTE *)&buf, &size);
4552 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4553 if (buf)
4555 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4557 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4558 size);
4559 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4560 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4561 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4562 LocalFree(buf);
4564 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4565 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4566 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4567 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4568 if (buf)
4570 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4572 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4573 size);
4574 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4575 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4576 "Unexpected key id\n");
4577 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4578 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4579 LocalFree(buf);
4581 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4582 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4583 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4584 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4585 if (buf)
4587 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4589 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4590 size);
4591 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4592 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4593 "Unexpected issuer len\n");
4594 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4595 sizeof(encodedCommonName)), "Unexpected issuer\n");
4596 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4597 LocalFree(buf);
4599 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4600 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4601 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4602 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4603 if (buf)
4605 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4607 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4608 size);
4609 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4610 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4611 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4612 "Unexpected serial number len\n");
4613 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4614 "Unexpected serial number\n");
4615 LocalFree(buf);
4619 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4620 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4621 0x6f,0x72,0x67 };
4623 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4625 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4626 CERT_ALT_NAME_ENTRY entry = { 0 };
4627 BOOL ret;
4628 BYTE *buf = NULL;
4629 DWORD size = 0;
4631 /* Test with empty id */
4632 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4633 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4634 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4635 if (buf)
4637 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4638 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4639 LocalFree(buf);
4641 /* With just a key id */
4642 info.KeyId.cbData = sizeof(keyId);
4643 info.KeyId.pbData = keyId;
4644 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4645 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4646 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4647 if (buf)
4649 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4650 size);
4651 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4652 LocalFree(buf);
4654 /* With a bogus issuer name */
4655 info.KeyId.cbData = 0;
4656 info.AuthorityCertIssuer.cAltEntry = 1;
4657 info.AuthorityCertIssuer.rgAltEntry = &entry;
4658 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4659 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4660 ok(!ret && GetLastError() == E_INVALIDARG,
4661 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4662 /* With an issuer name */
4663 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4664 U(entry).pwszURL = (LPWSTR)url;
4665 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4666 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4667 ok(ret, "pCryptEncodeObjectEx failed: %08x\n", GetLastError());
4668 if (buf)
4670 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4671 size);
4672 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4673 "Unexpected value\n");
4674 LocalFree(buf);
4676 /* With just a serial number */
4677 info.AuthorityCertIssuer.cAltEntry = 0;
4678 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4679 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4680 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4681 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4682 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4683 if (buf)
4685 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4686 size);
4687 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4688 LocalFree(buf);
4692 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
4694 BOOL ret;
4695 LPBYTE buf = NULL;
4696 DWORD size = 0;
4698 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4699 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4700 (BYTE *)&buf, &size);
4701 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4702 if (buf)
4704 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4706 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4707 size);
4708 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4709 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4710 "Expected no issuer name entries\n");
4711 ok(info->AuthorityCertSerialNumber.cbData == 0,
4712 "Expected no serial number\n");
4713 LocalFree(buf);
4715 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4716 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4717 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4718 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4719 if (buf)
4721 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4723 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4724 size);
4725 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4726 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4727 "Unexpected key id\n");
4728 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4729 "Expected no issuer name entries\n");
4730 ok(info->AuthorityCertSerialNumber.cbData == 0,
4731 "Expected no serial number\n");
4732 LocalFree(buf);
4734 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4735 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
4736 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4737 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4738 if (buf)
4740 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4742 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4743 size);
4744 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4745 ok(info->AuthorityCertIssuer.cAltEntry == 1,
4746 "Expected 1 issuer entry, got %d\n",
4747 info->AuthorityCertIssuer.cAltEntry);
4748 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
4749 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
4750 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
4751 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
4752 url), "Unexpected URL\n");
4753 ok(info->AuthorityCertSerialNumber.cbData == 0,
4754 "Expected no serial number\n");
4755 LocalFree(buf);
4757 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
4758 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4759 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4760 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4761 if (buf)
4763 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
4765 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
4766 size);
4767 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4768 ok(info->AuthorityCertIssuer.cAltEntry == 0,
4769 "Expected no issuer name entries\n");
4770 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
4771 "Unexpected serial number len\n");
4772 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
4773 sizeof(serialNum)), "Unexpected serial number\n");
4774 LocalFree(buf);
4778 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
4779 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
4780 0x03,0,0,0,0,0,0 };
4781 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
4782 0xa0,0x01,0x01 };
4783 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
4784 0x03,0x02,0x01,0x01 };
4785 static BYTE bogusDER[] = { 1 };
4787 static void test_encodePKCSContentInfo(DWORD dwEncoding)
4789 BOOL ret;
4790 BYTE *buf = NULL;
4791 DWORD size = 0;
4792 CRYPT_CONTENT_INFO info = { 0 };
4793 char oid1[] = "1.2.3";
4795 SetLastError(0xdeadbeef);
4796 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
4797 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4798 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4799 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
4800 SetLastError(0xdeadbeef);
4801 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4802 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4803 ok(!ret && GetLastError() == E_INVALIDARG,
4804 "Expected E_INVALIDARG, got %x\n", GetLastError());
4805 info.pszObjId = oid1;
4806 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4807 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4808 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4809 if (buf)
4811 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
4812 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
4813 LocalFree(buf);
4815 info.Content.pbData = bogusDER;
4816 info.Content.cbData = sizeof(bogusDER);
4817 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4818 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4819 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
4820 if (buf)
4822 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
4823 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
4824 LocalFree(buf);
4826 info.Content.pbData = (BYTE *)ints[0].encoded;
4827 info.Content.cbData = ints[0].encoded[1] + 2;
4828 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
4829 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4830 if (buf)
4832 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
4833 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
4834 LocalFree(buf);
4838 static const BYTE indefiniteSignedPKCSContent[] = {
4839 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
4840 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
4841 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
4842 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
4843 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
4844 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
4845 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
4846 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
4847 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
4848 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
4849 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
4850 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
4851 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
4852 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
4853 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
4854 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
4855 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
4856 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
4857 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
4858 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
4859 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
4860 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
4861 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
4862 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
4863 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
4864 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
4865 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
4866 0x00,0x00,0x00,0x00,0x00,0x00 };
4868 static void test_decodePKCSContentInfo(DWORD dwEncoding)
4870 BOOL ret;
4871 LPBYTE buf = NULL;
4872 DWORD size = 0;
4873 CRYPT_CONTENT_INFO *info;
4875 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4876 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
4877 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4878 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4879 if (buf)
4881 info = (CRYPT_CONTENT_INFO *)buf;
4883 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4884 info->pszObjId);
4885 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
4886 info->Content.cbData);
4887 LocalFree(buf);
4889 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4890 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
4891 0, NULL, NULL, &size);
4892 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4893 SetLastError(0xdeadbeef);
4894 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4895 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
4896 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4897 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
4898 * I doubt an app depends on that.
4900 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
4901 GetLastError() == CRYPT_E_ASN1_CORRUPT),
4902 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
4903 GetLastError());
4904 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4905 intPKCSContentInfo, sizeof(intPKCSContentInfo),
4906 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4907 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4908 if (buf)
4910 info = (CRYPT_CONTENT_INFO *)buf;
4912 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
4913 info->pszObjId);
4914 ok(info->Content.cbData == ints[0].encoded[1] + 2,
4915 "Unexpected size %d\n", info->Content.cbData);
4916 ok(!memcmp(info->Content.pbData, ints[0].encoded,
4917 info->Content.cbData), "Unexpected value\n");
4918 LocalFree(buf);
4920 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
4921 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
4922 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4923 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4924 if (buf)
4926 info = (CRYPT_CONTENT_INFO *)buf;
4928 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
4929 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
4930 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
4931 info->Content.cbData);
4932 LocalFree(buf);
4936 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
4937 0x00 };
4938 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
4939 0x01 };
4940 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
4941 0x02,0x01,0x01 };
4943 static void test_encodePKCSAttribute(DWORD dwEncoding)
4945 CRYPT_ATTRIBUTE attr = { 0 };
4946 BOOL ret;
4947 LPBYTE buf = NULL;
4948 DWORD size = 0;
4949 CRYPT_ATTR_BLOB blob;
4950 char oid[] = "1.2.3";
4952 SetLastError(0xdeadbeef);
4953 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
4954 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4955 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
4956 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
4957 SetLastError(0xdeadbeef);
4958 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4959 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4960 ok(!ret && GetLastError() == E_INVALIDARG,
4961 "Expected E_INVALIDARG, got %x\n", GetLastError());
4962 attr.pszObjId = oid;
4963 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4964 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4965 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4966 if (buf)
4968 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
4969 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
4970 LocalFree(buf);
4972 blob.cbData = sizeof(bogusDER);
4973 blob.pbData = bogusDER;
4974 attr.cValue = 1;
4975 attr.rgValue = &blob;
4976 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4977 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4978 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
4979 if (buf)
4981 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
4982 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
4983 LocalFree(buf);
4985 blob.pbData = (BYTE *)ints[0].encoded;
4986 blob.cbData = ints[0].encoded[1] + 2;
4987 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
4988 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4989 if (buf)
4991 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
4992 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
4993 LocalFree(buf);
4997 static void test_decodePKCSAttribute(DWORD dwEncoding)
4999 BOOL ret;
5000 LPBYTE buf = NULL;
5001 DWORD size = 0;
5002 CRYPT_ATTRIBUTE *attr;
5004 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5005 emptyPKCSAttr, sizeof(emptyPKCSAttr),
5006 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5007 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5008 if (buf)
5010 attr = (CRYPT_ATTRIBUTE *)buf;
5012 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5013 attr->pszObjId);
5014 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5015 LocalFree(buf);
5017 SetLastError(0xdeadbeef);
5018 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5019 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5020 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5021 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5022 * I doubt an app depends on that.
5024 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5025 GetLastError() == CRYPT_E_ASN1_CORRUPT),
5026 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5027 GetLastError());
5028 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5029 intPKCSAttr, sizeof(intPKCSAttr),
5030 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5031 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5032 if (buf)
5034 attr = (CRYPT_ATTRIBUTE *)buf;
5036 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5037 attr->pszObjId);
5038 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5039 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5040 "Unexpected size %d\n", attr->rgValue[0].cbData);
5041 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5042 attr->rgValue[0].cbData), "Unexpected value\n");
5043 LocalFree(buf);
5047 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5048 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5049 0x2a,0x03,0x31,0x00 };
5050 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5051 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5053 static void test_encodePKCSAttributes(DWORD dwEncoding)
5055 CRYPT_ATTRIBUTES attributes = { 0 };
5056 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5057 CRYPT_ATTR_BLOB blob;
5058 BOOL ret;
5059 LPBYTE buf = NULL;
5060 DWORD size = 0;
5061 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5063 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5064 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5065 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5066 if (buf)
5068 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5069 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5070 LocalFree(buf);
5072 attributes.cAttr = 1;
5073 attributes.rgAttr = attr;
5074 SetLastError(0xdeadbeef);
5075 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5076 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5077 ok(!ret && GetLastError() == E_INVALIDARG,
5078 "Expected E_INVALIDARG, got %x\n", GetLastError());
5079 attr[0].pszObjId = oid1;
5080 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5081 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5082 if (buf)
5084 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5085 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5086 LocalFree(buf);
5088 attr[1].pszObjId = oid2;
5089 attr[1].cValue = 1;
5090 attr[1].rgValue = &blob;
5091 blob.pbData = (BYTE *)ints[0].encoded;
5092 blob.cbData = ints[0].encoded[1] + 2;
5093 attributes.cAttr = 2;
5094 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5095 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5096 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5097 if (buf)
5099 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5100 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5101 LocalFree(buf);
5105 static void test_decodePKCSAttributes(DWORD dwEncoding)
5107 BOOL ret;
5108 LPBYTE buf = NULL;
5109 DWORD size = 0;
5110 CRYPT_ATTRIBUTES *attributes;
5112 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5113 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5114 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5115 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5116 if (buf)
5118 attributes = (CRYPT_ATTRIBUTES *)buf;
5119 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5120 attributes->cAttr);
5121 LocalFree(buf);
5123 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5124 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5125 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5126 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5127 if (buf)
5129 attributes = (CRYPT_ATTRIBUTES *)buf;
5130 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5131 attributes->cAttr);
5132 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5133 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5134 ok(attributes->rgAttr[0].cValue == 0,
5135 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5136 LocalFree(buf);
5138 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5139 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5140 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5141 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5142 if (buf)
5144 attributes = (CRYPT_ATTRIBUTES *)buf;
5145 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5146 attributes->cAttr);
5147 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5148 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5149 ok(attributes->rgAttr[0].cValue == 0,
5150 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5151 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5152 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5153 ok(attributes->rgAttr[1].cValue == 1,
5154 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5155 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5156 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5157 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5158 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5159 LocalFree(buf);
5163 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
5164 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5165 0x67 };
5166 static const BYTE minimalPKCSSigner[] = {
5167 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5168 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5169 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
5170 static const BYTE PKCSSignerWithSerial[] = {
5171 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5172 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5173 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5174 0x00 };
5175 static const BYTE PKCSSignerWithHashAlgo[] = {
5176 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5177 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5178 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5179 0x00,0x04,0x00 };
5180 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
5181 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5182 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5183 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5184 0x06,0x05,0x00,0x04,0x00 };
5185 static const BYTE PKCSSignerWithHash[] = {
5186 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5187 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5188 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5189 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
5190 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5191 static const BYTE PKCSSignerWithAuthAttr[] = {
5192 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5193 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5194 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
5195 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
5196 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
5197 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
5198 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5200 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
5202 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
5203 BOOL ret;
5204 LPBYTE buf = NULL;
5205 DWORD size = 0;
5206 CMSG_SIGNER_INFO info = { 0 };
5207 char oid_common_name[] = szOID_COMMON_NAME;
5208 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
5209 (LPBYTE)encodedCommonName };
5210 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
5212 SetLastError(0xdeadbeef);
5213 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5214 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5215 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
5217 skip("no PKCS7_SIGNER_INFO encode support\n");
5218 return;
5220 ok(!ret && GetLastError() == E_INVALIDARG,
5221 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5222 /* To be encoded, a signer must have an issuer at least, and the encoding
5223 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
5224 * see decoding tests.)
5226 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
5227 info.Issuer.pbData = encodedCommonNameNoNull;
5228 SetLastError(0xdeadbeef);
5229 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5230 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5231 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5232 ok(!ret && GetLastError() == E_INVALIDARG,
5233 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5234 else
5236 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5237 if (buf)
5239 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
5240 if (size == sizeof(minimalPKCSSigner))
5241 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
5242 else
5243 ok(0, "Unexpected value\n");
5244 LocalFree(buf);
5247 info.SerialNumber.cbData = sizeof(serialNum);
5248 info.SerialNumber.pbData = (BYTE *)serialNum;
5249 SetLastError(0xdeadbeef);
5250 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5251 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5252 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5253 ok(!ret && GetLastError() == E_INVALIDARG,
5254 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5255 else
5257 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5258 if (buf)
5260 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
5261 size);
5262 if (size == sizeof(PKCSSignerWithSerial))
5263 ok(!memcmp(buf, PKCSSignerWithSerial, size),
5264 "Unexpected value\n");
5265 else
5266 ok(0, "Unexpected value\n");
5267 LocalFree(buf);
5270 info.HashAlgorithm.pszObjId = oid1;
5271 SetLastError(0xdeadbeef);
5272 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5273 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5274 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5275 ok(!ret && GetLastError() == E_INVALIDARG,
5276 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5277 else
5279 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5280 if (buf)
5282 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
5283 size);
5284 if (size == sizeof(PKCSSignerWithHashAlgo))
5285 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
5286 "Unexpected value\n");
5287 else
5288 ok(0, "Unexpected value\n");
5289 LocalFree(buf);
5292 info.HashEncryptionAlgorithm.pszObjId = oid2;
5293 SetLastError(0xdeadbeef);
5294 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5295 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5296 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5297 ok(!ret && GetLastError() == E_INVALIDARG,
5298 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5299 else
5301 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5302 if (buf)
5304 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
5305 "Unexpected size %d\n", size);
5306 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
5307 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
5308 "Unexpected value\n");
5309 else
5310 ok(0, "Unexpected value\n");
5311 LocalFree(buf);
5314 info.EncryptedHash.cbData = sizeof(hash);
5315 info.EncryptedHash.pbData = (BYTE *)hash;
5316 SetLastError(0xdeadbeef);
5317 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5318 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5319 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5320 ok(!ret && GetLastError() == E_INVALIDARG,
5321 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5322 else
5324 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5325 if (buf)
5327 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
5328 size);
5329 if (size == sizeof(PKCSSignerWithHash))
5330 ok(!memcmp(buf, PKCSSignerWithHash, size),
5331 "Unexpected value\n");
5332 else
5333 ok(0, "Unexpected value\n");
5334 LocalFree(buf);
5337 info.AuthAttrs.cAttr = 1;
5338 info.AuthAttrs.rgAttr = &attr;
5339 SetLastError(0xdeadbeef);
5340 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5341 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5342 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5343 ok(!ret && GetLastError() == E_INVALIDARG,
5344 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5345 else
5347 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5348 if (buf)
5350 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
5351 size);
5352 if (size == sizeof(PKCSSignerWithAuthAttr))
5353 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
5354 "Unexpected value\n");
5355 else
5356 ok(0, "Unexpected value\n");
5357 LocalFree(buf);
5362 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
5364 BOOL ret;
5365 LPBYTE buf = NULL;
5366 DWORD size = 0;
5367 CMSG_SIGNER_INFO *info;
5369 /* A PKCS signer can't be decoded without a serial number. */
5370 SetLastError(0xdeadbeef);
5371 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5372 minimalPKCSSigner, sizeof(minimalPKCSSigner),
5373 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5374 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
5375 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
5376 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5377 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
5378 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5379 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5380 if (buf)
5382 info = (CMSG_SIGNER_INFO *)buf;
5383 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5384 info->dwVersion);
5385 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5386 "Unexpected size %d\n", info->Issuer.cbData);
5387 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5388 info->Issuer.cbData), "Unexpected value\n");
5389 ok(info->SerialNumber.cbData == sizeof(serialNum),
5390 "Unexpected size %d\n", info->SerialNumber.cbData);
5391 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5392 "Unexpected value\n");
5393 LocalFree(buf);
5395 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5396 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
5397 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5398 if (buf)
5400 info = (CMSG_SIGNER_INFO *)buf;
5401 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5402 info->dwVersion);
5403 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5404 "Unexpected size %d\n", info->Issuer.cbData);
5405 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5406 info->Issuer.cbData), "Unexpected value\n");
5407 ok(info->SerialNumber.cbData == sizeof(serialNum),
5408 "Unexpected size %d\n", info->SerialNumber.cbData);
5409 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5410 "Unexpected value\n");
5411 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5412 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5413 LocalFree(buf);
5415 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5416 PKCSSignerWithHashAndEncryptionAlgo,
5417 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
5418 NULL, (BYTE *)&buf, &size);
5419 if (buf)
5421 info = (CMSG_SIGNER_INFO *)buf;
5422 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5423 info->dwVersion);
5424 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5425 "Unexpected size %d\n", info->Issuer.cbData);
5426 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5427 info->Issuer.cbData), "Unexpected value\n");
5428 ok(info->SerialNumber.cbData == sizeof(serialNum),
5429 "Unexpected size %d\n", info->SerialNumber.cbData);
5430 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5431 "Unexpected value\n");
5432 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5433 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5434 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
5435 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
5436 LocalFree(buf);
5438 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5439 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
5440 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5441 if (buf)
5443 info = (CMSG_SIGNER_INFO *)buf;
5444 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5445 info->dwVersion);
5446 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5447 "Unexpected size %d\n", info->Issuer.cbData);
5448 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5449 info->Issuer.cbData), "Unexpected value\n");
5450 ok(info->SerialNumber.cbData == sizeof(serialNum),
5451 "Unexpected size %d\n", info->SerialNumber.cbData);
5452 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5453 "Unexpected value\n");
5454 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5455 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5456 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
5457 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
5458 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
5459 info->EncryptedHash.cbData);
5460 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
5461 "Unexpected value\n");
5462 LocalFree(buf);
5464 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5465 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
5466 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5467 if (buf)
5469 info = (CMSG_SIGNER_INFO *)buf;
5470 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
5471 info->AuthAttrs.cAttr);
5472 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
5473 "Expected %s, got %s\n", szOID_COMMON_NAME,
5474 info->AuthAttrs.rgAttr[0].pszObjId);
5475 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
5476 info->AuthAttrs.rgAttr[0].cValue);
5477 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
5478 sizeof(encodedCommonName), "Unexpected size %d\n",
5479 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
5480 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
5481 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
5482 LocalFree(buf);
5486 static BYTE emptyDNSPermittedConstraints[] = {
5487 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
5488 static BYTE emptyDNSExcludedConstraints[] = {
5489 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
5490 static BYTE DNSExcludedConstraints[] = {
5491 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
5492 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5493 static BYTE permittedAndExcludedConstraints[] = {
5494 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5495 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
5496 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5497 static BYTE permittedAndExcludedWithMinConstraints[] = {
5498 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5499 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
5500 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5501 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
5502 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5503 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
5504 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5506 static void test_encodeNameConstraints(DWORD dwEncoding)
5508 BOOL ret;
5509 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
5510 CERT_GENERAL_SUBTREE permitted = { { 0 } };
5511 CERT_GENERAL_SUBTREE excluded = { { 0 } };
5512 LPBYTE buf;
5513 DWORD size;
5515 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5516 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5517 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
5519 skip("no X509_NAME_CONSTRAINTS encode support\n");
5520 return;
5522 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5523 if (ret)
5525 ok(size == sizeof(emptySequence), "Unexpected size\n");
5526 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
5527 LocalFree(buf);
5529 constraints.cPermittedSubtree = 1;
5530 constraints.rgPermittedSubtree = &permitted;
5531 SetLastError(0xdeadbeef);
5532 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5533 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5534 ok(!ret && GetLastError() == E_INVALIDARG,
5535 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5536 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
5537 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5538 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5539 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5540 if (ret)
5542 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
5543 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
5544 "Unexpected value\n");
5545 LocalFree(buf);
5547 constraints.cPermittedSubtree = 0;
5548 constraints.cExcludedSubtree = 1;
5549 constraints.rgExcludedSubtree = &excluded;
5550 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
5551 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5552 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5553 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5554 if (ret)
5556 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
5557 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
5558 "Unexpected value\n");
5559 LocalFree(buf);
5561 U(excluded.Base).pwszURL = (LPWSTR)url;
5562 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5563 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5564 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5565 if (ret)
5567 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
5568 ok(!memcmp(buf, DNSExcludedConstraints, size),
5569 "Unexpected value\n");
5570 LocalFree(buf);
5572 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
5573 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
5574 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
5575 constraints.cPermittedSubtree = 1;
5576 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5577 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5578 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5579 if (ret)
5581 ok(size == sizeof(permittedAndExcludedConstraints),
5582 "Unexpected size\n");
5583 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
5584 "Unexpected value\n");
5585 LocalFree(buf);
5587 permitted.dwMinimum = 5;
5588 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5589 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5590 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5591 if (ret)
5593 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
5594 "Unexpected size\n");
5595 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
5596 "Unexpected value\n");
5597 LocalFree(buf);
5599 permitted.fMaximum = TRUE;
5600 permitted.dwMaximum = 3;
5601 SetLastError(0xdeadbeef);
5602 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5603 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5604 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5605 if (ret)
5607 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
5608 "Unexpected size\n");
5609 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
5610 "Unexpected value\n");
5611 LocalFree(buf);
5615 struct EncodedNameConstraints
5617 CRYPT_DATA_BLOB encoded;
5618 CERT_NAME_CONSTRAINTS_INFO constraints;
5621 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
5622 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
5623 static CERT_GENERAL_SUBTREE DNSSubtree = {
5624 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
5625 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
5626 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
5627 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
5628 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
5629 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
5630 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
5632 struct EncodedNameConstraints encodedNameConstraints[] = {
5633 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
5634 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
5635 { 1, &emptyDNSSubtree, 0, NULL } },
5636 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
5637 { 0, NULL, 1, &emptyDNSSubtree } },
5638 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
5639 { 0, NULL, 1, &DNSSubtree } },
5640 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
5641 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
5642 { { sizeof(permittedAndExcludedWithMinConstraints),
5643 permittedAndExcludedWithMinConstraints },
5644 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
5645 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
5646 permittedAndExcludedWithMinMaxConstraints },
5647 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
5650 static void test_decodeNameConstraints(DWORD dwEncoding)
5652 BOOL ret;
5653 DWORD i;
5654 CERT_NAME_CONSTRAINTS_INFO *constraints;
5656 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
5657 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
5658 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
5659 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
5660 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
5661 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
5662 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
5663 for (i = 0;
5664 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
5665 i++)
5667 DWORD size;
5669 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
5670 encodedNameConstraints[i].encoded.pbData,
5671 encodedNameConstraints[i].encoded.cbData,
5672 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
5673 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
5675 skip("no X509_NAME_CONSTRAINTS decode support\n");
5676 return;
5678 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
5679 if (ret)
5681 DWORD j;
5683 if (constraints->cPermittedSubtree !=
5684 encodedNameConstraints[i].constraints.cPermittedSubtree)
5685 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
5686 encodedNameConstraints[i].constraints.cPermittedSubtree,
5687 constraints->cPermittedSubtree);
5688 if (constraints->cPermittedSubtree ==
5689 encodedNameConstraints[i].constraints.cPermittedSubtree)
5691 for (j = 0; j < constraints->cPermittedSubtree; j++)
5693 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
5694 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
5697 if (constraints->cExcludedSubtree !=
5698 encodedNameConstraints[i].constraints.cExcludedSubtree)
5699 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
5700 encodedNameConstraints[i].constraints.cExcludedSubtree,
5701 constraints->cExcludedSubtree);
5702 if (constraints->cExcludedSubtree ==
5703 encodedNameConstraints[i].constraints.cExcludedSubtree)
5705 for (j = 0; j < constraints->cExcludedSubtree; j++)
5707 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
5708 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
5711 LocalFree(constraints);
5716 /* Free *pInfo with HeapFree */
5717 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
5719 BOOL ret;
5720 DWORD size = 0;
5721 HCRYPTKEY key;
5723 /* This crashes
5724 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
5726 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
5727 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5728 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5729 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
5730 &size);
5731 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5732 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5733 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
5734 NULL, &size);
5735 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5736 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5737 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
5738 0, NULL, NULL, &size);
5739 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5740 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5741 /* Test with no key */
5742 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
5743 0, NULL, NULL, &size);
5744 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
5745 GetLastError());
5746 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
5747 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
5748 if (ret)
5750 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
5751 NULL, 0, NULL, NULL, &size);
5752 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
5753 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
5754 if (*pInfo)
5756 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
5757 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
5758 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
5759 GetLastError());
5760 if (ret)
5762 /* By default (we passed NULL as the OID) the OID is
5763 * szOID_RSA_RSA.
5765 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
5766 "Expected %s, got %s\n", szOID_RSA_RSA,
5767 (*pInfo)->Algorithm.pszObjId);
5771 CryptDestroyKey(key);
5774 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
5775 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
5776 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
5777 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
5778 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
5779 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
5780 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
5781 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
5782 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
5783 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
5784 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
5785 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
5786 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
5787 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
5788 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
5789 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
5790 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
5791 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
5792 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
5793 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
5794 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
5795 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
5796 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
5797 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
5798 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
5800 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
5802 BOOL ret;
5803 HCRYPTKEY key;
5804 PCCERT_CONTEXT context;
5805 DWORD dwSize;
5806 ALG_ID ai;
5808 /* These crash
5809 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
5810 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
5811 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
5812 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
5813 NULL);
5815 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
5816 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
5817 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
5818 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
5819 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
5820 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
5821 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
5822 &key);
5823 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
5824 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
5826 /* Export key with standard algorithm (CALG_RSA_KEYX) */
5827 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
5828 &key);
5829 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
5831 dwSize = sizeof(ai);
5832 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
5833 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
5834 if(ret)
5836 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
5837 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
5840 CryptDestroyKey(key);
5842 /* Repeat with forced algorithm */
5843 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
5844 &key);
5845 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
5847 dwSize = sizeof(ai);
5848 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
5849 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
5850 if(ret)
5852 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
5853 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
5856 CryptDestroyKey(key);
5858 /* Test importing a public key from a certificate context */
5859 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
5860 sizeof(expiredCert));
5861 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
5862 GetLastError());
5863 if (context)
5865 ok(!strcmp(szOID_RSA_RSA,
5866 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
5867 "Expected %s, got %s\n", szOID_RSA_RSA,
5868 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
5869 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
5870 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
5871 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
5872 CryptDestroyKey(key);
5873 CertFreeCertificateContext(context);
5877 static const char cspName[] = "WineCryptTemp";
5879 static void testPortPublicKeyInfo(void)
5881 HCRYPTPROV csp;
5882 BOOL ret;
5883 PCERT_PUBLIC_KEY_INFO info = NULL;
5885 /* Just in case a previous run failed, delete this thing */
5886 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5887 CRYPT_DELETEKEYSET);
5888 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5889 CRYPT_NEWKEYSET);
5891 testExportPublicKey(csp, &info);
5892 testImportPublicKey(csp, info);
5894 HeapFree(GetProcessHeap(), 0, info);
5895 CryptReleaseContext(csp, 0);
5896 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
5897 CRYPT_DELETEKEYSET);
5900 START_TEST(encode)
5902 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
5903 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
5904 HMODULE hCrypt32;
5905 DWORD i;
5907 hCrypt32 = GetModuleHandleA("crypt32.dll");
5908 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
5909 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
5910 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
5912 skip("CryptDecodeObjectEx() is not available\n");
5913 return;
5916 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
5918 test_encodeInt(encodings[i]);
5919 test_decodeInt(encodings[i]);
5920 test_encodeEnumerated(encodings[i]);
5921 test_decodeEnumerated(encodings[i]);
5922 test_encodeFiletime(encodings[i]);
5923 test_decodeFiletime(encodings[i]);
5924 test_encodeName(encodings[i]);
5925 test_decodeName(encodings[i]);
5926 test_encodeUnicodeName(encodings[i]);
5927 test_decodeUnicodeName(encodings[i]);
5928 test_encodeNameValue(encodings[i]);
5929 test_decodeNameValue(encodings[i]);
5930 test_encodeUnicodeNameValue(encodings[i]);
5931 test_decodeUnicodeNameValue(encodings[i]);
5932 test_encodeAltName(encodings[i]);
5933 test_decodeAltName(encodings[i]);
5934 test_encodeOctets(encodings[i]);
5935 test_decodeOctets(encodings[i]);
5936 test_encodeBits(encodings[i]);
5937 test_decodeBits(encodings[i]);
5938 test_encodeBasicConstraints(encodings[i]);
5939 test_decodeBasicConstraints(encodings[i]);
5940 test_encodeRsaPublicKey(encodings[i]);
5941 test_decodeRsaPublicKey(encodings[i]);
5942 test_encodeSequenceOfAny(encodings[i]);
5943 test_decodeSequenceOfAny(encodings[i]);
5944 test_encodeExtensions(encodings[i]);
5945 test_decodeExtensions(encodings[i]);
5946 test_encodePublicKeyInfo(encodings[i]);
5947 test_decodePublicKeyInfo(encodings[i]);
5948 test_encodeCertToBeSigned(encodings[i]);
5949 test_decodeCertToBeSigned(encodings[i]);
5950 test_encodeCert(encodings[i]);
5951 test_decodeCert(encodings[i]);
5952 test_encodeCRLDistPoints(encodings[i]);
5953 test_decodeCRLDistPoints(encodings[i]);
5954 test_encodeCRLIssuingDistPoint(encodings[i]);
5955 test_decodeCRLIssuingDistPoint(encodings[i]);
5956 test_encodeCRLToBeSigned(encodings[i]);
5957 test_decodeCRLToBeSigned(encodings[i]);
5958 test_encodeEnhancedKeyUsage(encodings[i]);
5959 test_decodeEnhancedKeyUsage(encodings[i]);
5960 test_encodeAuthorityKeyId(encodings[i]);
5961 test_decodeAuthorityKeyId(encodings[i]);
5962 test_encodeAuthorityKeyId2(encodings[i]);
5963 test_decodeAuthorityKeyId2(encodings[i]);
5964 test_encodePKCSContentInfo(encodings[i]);
5965 test_decodePKCSContentInfo(encodings[i]);
5966 test_encodePKCSAttribute(encodings[i]);
5967 test_decodePKCSAttribute(encodings[i]);
5968 test_encodePKCSAttributes(encodings[i]);
5969 test_decodePKCSAttributes(encodings[i]);
5970 test_encodePKCSSignerInfo(encodings[i]);
5971 test_decodePKCSSignerInfo(encodings[i]);
5972 test_encodeNameConstraints(encodings[i]);
5973 test_decodeNameConstraints(encodings[i]);
5975 testPortPublicKeyInfo();