push 514b285b0c98f6a7a84c63e51c3091a87ae6d177
[wine/hacks.git] / dlls / crypt32 / tests / encode.c
blobd6bcf61238fc1c57bdf9df4166a3aa5d3ac3ad71
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 const BYTE singleCapability[] = {
5164 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
5165 static const BYTE twoCapabilities[] = {
5166 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
5167 static const BYTE singleCapabilitywithNULL[] = {
5168 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5170 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
5172 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
5173 BOOL ret;
5174 LPBYTE buf = NULL;
5175 DWORD size = 0;
5176 CRYPT_SMIME_CAPABILITY capability[2];
5177 CRYPT_SMIME_CAPABILITIES capabilities;
5179 /* An empty capabilities is allowed */
5180 capabilities.cCapability = 0;
5181 ret = CryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5182 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5183 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5184 if (buf)
5186 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
5187 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5188 LocalFree(buf);
5190 /* A non-empty capabilities with an empty capability (lacking an OID) is
5191 * not allowed
5193 capability[0].pszObjId = NULL;
5194 capability[0].Parameters.cbData = 0;
5195 capabilities.cCapability = 1;
5196 capabilities.rgCapability = capability;
5197 SetLastError(0xdeadbeef);
5198 ret = CryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5199 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5200 ok(!ret && GetLastError() == E_INVALIDARG,
5201 "expected E_INVALIDARG, got %08x\n", GetLastError());
5202 capability[0].pszObjId = oid1;
5203 ret = CryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5204 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5205 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5206 if (buf)
5208 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
5209 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
5210 LocalFree(buf);
5212 capability[1].pszObjId = oid2;
5213 capability[1].Parameters.cbData = 0;
5214 capabilities.cCapability = 2;
5215 ret = CryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5216 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5217 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5218 if (buf)
5220 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
5221 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
5222 LocalFree(buf);
5226 static void compareSMimeCapabilities(LPCSTR header,
5227 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
5229 DWORD i;
5231 ok(got->cCapability == expected->cCapability,
5232 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
5233 got->cCapability);
5234 for (i = 0; i < expected->cCapability; i++)
5236 ok(!strcmp(expected->rgCapability[i].pszObjId,
5237 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5238 header, i, expected->rgCapability[i].pszObjId,
5239 got->rgCapability[i].pszObjId);
5240 ok(expected->rgCapability[i].Parameters.cbData ==
5241 got->rgCapability[i].Parameters.cbData,
5242 "%s[%d]: expected %d bytes, got %d\n", header, i,
5243 expected->rgCapability[i].Parameters.cbData,
5244 got->rgCapability[i].Parameters.cbData);
5245 if (expected->rgCapability[i].Parameters.cbData)
5246 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
5247 got->rgCapability[i].Parameters.pbData,
5248 expected->rgCapability[i].Parameters.cbData),
5249 "%s[%d]: unexpected value\n", header, i);
5253 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
5255 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
5256 BOOL ret;
5257 DWORD size = 0;
5258 CRYPT_SMIME_CAPABILITY capability[2];
5259 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
5261 SetLastError(0xdeadbeef);
5262 ret = CryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5263 emptySequence, sizeof(emptySequence),
5264 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
5265 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5266 if (ret)
5268 capabilities.cCapability = 0;
5269 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
5270 LocalFree(ptr);
5272 SetLastError(0xdeadbeef);
5273 ret = CryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5274 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
5275 (BYTE *)&ptr, &size);
5276 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5277 if (ret)
5279 capability[0].pszObjId = oid1;
5280 capability[0].Parameters.cbData = 0;
5281 capabilities.cCapability = 1;
5282 capabilities.rgCapability = capability;
5283 compareSMimeCapabilities("single capability", &capabilities, ptr);
5284 LocalFree(ptr);
5286 SetLastError(0xdeadbeef);
5287 ret = CryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5288 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
5289 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
5290 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5291 if (ret)
5293 BYTE NULLparam[] = {0x05, 0x00};
5294 capability[0].pszObjId = oid1;
5295 capability[0].Parameters.cbData = 2;
5296 capability[0].Parameters.pbData = NULLparam;
5297 capabilities.cCapability = 1;
5298 capabilities.rgCapability = capability;
5299 compareSMimeCapabilities("single capability with NULL", &capabilities,
5300 ptr);
5301 LocalFree(ptr);
5303 SetLastError(0xdeadbeef);
5304 ret = CryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5305 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
5306 (BYTE *)&ptr, &size);
5307 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5308 if (ret)
5310 capability[0].Parameters.cbData = 0;
5311 capability[1].pszObjId = oid2;
5312 capability[1].Parameters.cbData = 0;
5313 capabilities.cCapability = 2;
5314 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
5315 LocalFree(ptr);
5319 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
5320 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5321 0x67 };
5322 static const BYTE minimalPKCSSigner[] = {
5323 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5324 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5325 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
5326 static const BYTE PKCSSignerWithSerial[] = {
5327 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5328 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5329 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5330 0x00 };
5331 static const BYTE PKCSSignerWithHashAlgo[] = {
5332 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5333 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5334 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5335 0x00,0x04,0x00 };
5336 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
5337 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5338 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5339 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5340 0x06,0x05,0x00,0x04,0x00 };
5341 static const BYTE PKCSSignerWithHash[] = {
5342 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5343 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5344 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
5345 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
5346 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5347 static const BYTE PKCSSignerWithAuthAttr[] = {
5348 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
5349 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
5350 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
5351 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
5352 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
5353 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
5354 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
5356 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
5358 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
5359 BOOL ret;
5360 LPBYTE buf = NULL;
5361 DWORD size = 0;
5362 CMSG_SIGNER_INFO info = { 0 };
5363 char oid_common_name[] = szOID_COMMON_NAME;
5364 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
5365 (LPBYTE)encodedCommonName };
5366 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
5368 SetLastError(0xdeadbeef);
5369 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5370 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5371 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
5373 skip("no PKCS7_SIGNER_INFO encode support\n");
5374 return;
5376 ok(!ret && GetLastError() == E_INVALIDARG,
5377 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5378 /* To be encoded, a signer must have an issuer at least, and the encoding
5379 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
5380 * see decoding tests.)
5382 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
5383 info.Issuer.pbData = encodedCommonNameNoNull;
5384 SetLastError(0xdeadbeef);
5385 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5386 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5387 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5388 ok(!ret && GetLastError() == E_INVALIDARG,
5389 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5390 else
5392 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5393 if (buf)
5395 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
5396 if (size == sizeof(minimalPKCSSigner))
5397 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
5398 else
5399 ok(0, "Unexpected value\n");
5400 LocalFree(buf);
5403 info.SerialNumber.cbData = sizeof(serialNum);
5404 info.SerialNumber.pbData = (BYTE *)serialNum;
5405 SetLastError(0xdeadbeef);
5406 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5407 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5408 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5409 ok(!ret && GetLastError() == E_INVALIDARG,
5410 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5411 else
5413 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5414 if (buf)
5416 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
5417 size);
5418 if (size == sizeof(PKCSSignerWithSerial))
5419 ok(!memcmp(buf, PKCSSignerWithSerial, size),
5420 "Unexpected value\n");
5421 else
5422 ok(0, "Unexpected value\n");
5423 LocalFree(buf);
5426 info.HashAlgorithm.pszObjId = oid1;
5427 SetLastError(0xdeadbeef);
5428 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5429 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5430 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5431 ok(!ret && GetLastError() == E_INVALIDARG,
5432 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5433 else
5435 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5436 if (buf)
5438 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
5439 size);
5440 if (size == sizeof(PKCSSignerWithHashAlgo))
5441 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
5442 "Unexpected value\n");
5443 else
5444 ok(0, "Unexpected value\n");
5445 LocalFree(buf);
5448 info.HashEncryptionAlgorithm.pszObjId = oid2;
5449 SetLastError(0xdeadbeef);
5450 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5451 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5452 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5453 ok(!ret && GetLastError() == E_INVALIDARG,
5454 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5455 else
5457 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5458 if (buf)
5460 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
5461 "Unexpected size %d\n", size);
5462 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
5463 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
5464 "Unexpected value\n");
5465 else
5466 ok(0, "Unexpected value\n");
5467 LocalFree(buf);
5470 info.EncryptedHash.cbData = sizeof(hash);
5471 info.EncryptedHash.pbData = (BYTE *)hash;
5472 SetLastError(0xdeadbeef);
5473 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5474 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5475 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5476 ok(!ret && GetLastError() == E_INVALIDARG,
5477 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5478 else
5480 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5481 if (buf)
5483 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
5484 size);
5485 if (size == sizeof(PKCSSignerWithHash))
5486 ok(!memcmp(buf, PKCSSignerWithHash, size),
5487 "Unexpected value\n");
5488 else
5489 ok(0, "Unexpected value\n");
5490 LocalFree(buf);
5493 info.AuthAttrs.cAttr = 1;
5494 info.AuthAttrs.rgAttr = &attr;
5495 SetLastError(0xdeadbeef);
5496 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
5497 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5498 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5499 ok(!ret && GetLastError() == E_INVALIDARG,
5500 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5501 else
5503 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5504 if (buf)
5506 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
5507 size);
5508 if (size == sizeof(PKCSSignerWithAuthAttr))
5509 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
5510 "Unexpected value\n");
5511 else
5512 ok(0, "Unexpected value\n");
5513 LocalFree(buf);
5518 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
5520 BOOL ret;
5521 LPBYTE buf = NULL;
5522 DWORD size = 0;
5523 CMSG_SIGNER_INFO *info;
5525 /* A PKCS signer can't be decoded without a serial number. */
5526 SetLastError(0xdeadbeef);
5527 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5528 minimalPKCSSigner, sizeof(minimalPKCSSigner),
5529 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5530 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
5531 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
5532 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5533 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
5534 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5535 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5536 if (buf)
5538 info = (CMSG_SIGNER_INFO *)buf;
5539 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5540 info->dwVersion);
5541 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5542 "Unexpected size %d\n", info->Issuer.cbData);
5543 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5544 info->Issuer.cbData), "Unexpected value\n");
5545 ok(info->SerialNumber.cbData == sizeof(serialNum),
5546 "Unexpected size %d\n", info->SerialNumber.cbData);
5547 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5548 "Unexpected value\n");
5549 LocalFree(buf);
5551 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5552 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
5553 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5554 if (buf)
5556 info = (CMSG_SIGNER_INFO *)buf;
5557 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5558 info->dwVersion);
5559 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5560 "Unexpected size %d\n", info->Issuer.cbData);
5561 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5562 info->Issuer.cbData), "Unexpected value\n");
5563 ok(info->SerialNumber.cbData == sizeof(serialNum),
5564 "Unexpected size %d\n", info->SerialNumber.cbData);
5565 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5566 "Unexpected value\n");
5567 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5568 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5569 LocalFree(buf);
5571 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5572 PKCSSignerWithHashAndEncryptionAlgo,
5573 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
5574 NULL, (BYTE *)&buf, &size);
5575 if (buf)
5577 info = (CMSG_SIGNER_INFO *)buf;
5578 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5579 info->dwVersion);
5580 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5581 "Unexpected size %d\n", info->Issuer.cbData);
5582 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5583 info->Issuer.cbData), "Unexpected value\n");
5584 ok(info->SerialNumber.cbData == sizeof(serialNum),
5585 "Unexpected size %d\n", info->SerialNumber.cbData);
5586 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5587 "Unexpected value\n");
5588 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5589 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5590 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
5591 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
5592 LocalFree(buf);
5594 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5595 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
5596 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5597 if (buf)
5599 info = (CMSG_SIGNER_INFO *)buf;
5600 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5601 info->dwVersion);
5602 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
5603 "Unexpected size %d\n", info->Issuer.cbData);
5604 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
5605 info->Issuer.cbData), "Unexpected value\n");
5606 ok(info->SerialNumber.cbData == sizeof(serialNum),
5607 "Unexpected size %d\n", info->SerialNumber.cbData);
5608 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
5609 "Unexpected value\n");
5610 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
5611 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
5612 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
5613 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
5614 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
5615 info->EncryptedHash.cbData);
5616 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
5617 "Unexpected value\n");
5618 LocalFree(buf);
5620 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
5621 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
5622 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5623 if (buf)
5625 info = (CMSG_SIGNER_INFO *)buf;
5626 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
5627 info->AuthAttrs.cAttr);
5628 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
5629 "Expected %s, got %s\n", szOID_COMMON_NAME,
5630 info->AuthAttrs.rgAttr[0].pszObjId);
5631 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
5632 info->AuthAttrs.rgAttr[0].cValue);
5633 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
5634 sizeof(encodedCommonName), "Unexpected size %d\n",
5635 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
5636 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
5637 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
5638 LocalFree(buf);
5642 static const BYTE CMSSignerWithKeyId[] = {
5643 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
5644 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
5646 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
5648 BOOL ret;
5649 LPBYTE buf = NULL;
5650 DWORD size = 0;
5651 CMSG_CMS_SIGNER_INFO info = { 0 };
5652 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
5654 SetLastError(0xdeadbeef);
5655 ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
5656 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5657 ok(!ret && GetLastError() == E_INVALIDARG,
5658 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5659 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5660 SetLastError(0xdeadbeef);
5661 ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
5662 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5663 ok(!ret && GetLastError() == E_INVALIDARG,
5664 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5665 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
5666 * be a key id or a issuer serial number with at least the issuer set, and
5667 * the encoding must include PKCS_7_ASN_ENCODING.
5668 * (That isn't enough to be decoded, see decoding tests.)
5670 info.SignerId.IssuerSerialNumber.Issuer.cbData =
5671 sizeof(encodedCommonNameNoNull);
5672 info.SignerId.IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
5673 SetLastError(0xdeadbeef);
5674 ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
5675 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5676 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5677 ok(!ret && GetLastError() == E_INVALIDARG,
5678 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5679 else
5681 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5682 if (buf)
5684 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
5685 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
5686 LocalFree(buf);
5689 info.SignerId.IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
5690 info.SignerId.IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
5691 SetLastError(0xdeadbeef);
5692 ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
5693 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5694 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5695 ok(!ret && GetLastError() == E_INVALIDARG,
5696 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5697 else
5699 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5700 if (buf)
5702 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
5703 size);
5704 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
5705 LocalFree(buf);
5708 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
5709 info.SignerId.KeyId.cbData = sizeof(serialNum);
5710 info.SignerId.KeyId.pbData = (BYTE *)serialNum;
5711 SetLastError(0xdeadbeef);
5712 ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
5713 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5714 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5715 ok(!ret && GetLastError() == E_INVALIDARG,
5716 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5717 else
5719 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5720 if (buf)
5722 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
5723 size);
5724 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
5725 LocalFree(buf);
5728 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
5729 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
5730 * (see RFC 3852, section 5.3.)
5732 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
5733 info.SignerId.HashId.cbData = sizeof(hash);
5734 info.SignerId.HashId.pbData = (BYTE *)hash;
5735 SetLastError(0xdeadbeef);
5736 ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
5737 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5738 ok(!ret && GetLastError() == E_INVALIDARG,
5739 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5740 /* Now with a hash algo */
5741 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
5742 info.SignerId.IssuerSerialNumber.Issuer.cbData =
5743 sizeof(encodedCommonNameNoNull);
5744 info.SignerId.IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
5745 info.HashAlgorithm.pszObjId = oid1;
5746 SetLastError(0xdeadbeef);
5747 ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
5748 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5749 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5750 ok(!ret && GetLastError() == E_INVALIDARG,
5751 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5752 else
5754 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5755 if (buf)
5757 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
5758 size);
5759 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
5760 "Unexpected value\n");
5761 LocalFree(buf);
5764 info.HashEncryptionAlgorithm.pszObjId = oid2;
5765 SetLastError(0xdeadbeef);
5766 ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
5767 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5768 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5769 ok(!ret && GetLastError() == E_INVALIDARG,
5770 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5771 else
5773 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5774 if (buf)
5776 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
5777 "Unexpected size %d\n", size);
5778 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
5779 "Unexpected value\n");
5780 LocalFree(buf);
5783 info.EncryptedHash.cbData = sizeof(hash);
5784 info.EncryptedHash.pbData = (BYTE *)hash;
5785 SetLastError(0xdeadbeef);
5786 ret = CryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
5787 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5788 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
5789 ok(!ret && GetLastError() == E_INVALIDARG,
5790 "Expected E_INVALIDARG, got %08x\n", GetLastError());
5791 else
5793 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5794 if (buf)
5796 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
5797 size);
5798 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
5799 LocalFree(buf);
5804 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
5806 BOOL ret;
5807 LPBYTE buf = NULL;
5808 DWORD size = 0;
5809 CMSG_CMS_SIGNER_INFO *info;
5810 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
5812 /* A CMS signer can't be decoded without a serial number. */
5813 SetLastError(0xdeadbeef);
5814 ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
5815 minimalPKCSSigner, sizeof(minimalPKCSSigner),
5816 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5817 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
5818 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
5819 ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
5820 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
5821 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5822 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5823 if (buf)
5825 info = (CMSG_CMS_SIGNER_INFO *)buf;
5826 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5827 info->dwVersion);
5828 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
5829 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
5830 info->SignerId.dwIdChoice);
5831 ok(info->SignerId.IssuerSerialNumber.Issuer.cbData ==
5832 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
5833 info->SignerId.IssuerSerialNumber.Issuer.cbData);
5834 ok(!memcmp(info->SignerId.IssuerSerialNumber.Issuer.pbData,
5835 encodedCommonNameNoNull,
5836 info->SignerId.IssuerSerialNumber.Issuer.cbData),
5837 "Unexpected value\n");
5838 ok(info->SignerId.IssuerSerialNumber.SerialNumber.cbData ==
5839 sizeof(serialNum), "Unexpected size %d\n",
5840 info->SignerId.IssuerSerialNumber.SerialNumber.cbData);
5841 ok(!memcmp(info->SignerId.IssuerSerialNumber.SerialNumber.pbData,
5842 serialNum, sizeof(serialNum)), "Unexpected value\n");
5843 LocalFree(buf);
5845 ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
5846 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
5847 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5848 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5849 if (buf)
5851 info = (CMSG_CMS_SIGNER_INFO *)buf;
5852 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5853 info->dwVersion);
5854 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
5855 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
5856 info->SignerId.dwIdChoice);
5857 ok(info->SignerId.IssuerSerialNumber.Issuer.cbData ==
5858 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
5859 info->SignerId.IssuerSerialNumber.Issuer.cbData);
5860 ok(!memcmp(info->SignerId.IssuerSerialNumber.Issuer.pbData,
5861 encodedCommonNameNoNull,
5862 info->SignerId.IssuerSerialNumber.Issuer.cbData),
5863 "Unexpected value\n");
5864 ok(info->SignerId.IssuerSerialNumber.SerialNumber.cbData ==
5865 sizeof(serialNum), "Unexpected size %d\n",
5866 info->SignerId.IssuerSerialNumber.SerialNumber.cbData);
5867 ok(!memcmp(info->SignerId.IssuerSerialNumber.SerialNumber.pbData,
5868 serialNum, sizeof(serialNum)), "Unexpected value\n");
5869 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
5870 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
5871 LocalFree(buf);
5873 ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
5874 PKCSSignerWithHashAndEncryptionAlgo,
5875 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
5876 NULL, (BYTE *)&buf, &size);
5877 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5878 if (buf)
5880 info = (CMSG_CMS_SIGNER_INFO *)buf;
5881 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5882 info->dwVersion);
5883 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
5884 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
5885 info->SignerId.dwIdChoice);
5886 ok(info->SignerId.IssuerSerialNumber.Issuer.cbData ==
5887 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
5888 info->SignerId.IssuerSerialNumber.Issuer.cbData);
5889 ok(!memcmp(info->SignerId.IssuerSerialNumber.Issuer.pbData,
5890 encodedCommonNameNoNull,
5891 info->SignerId.IssuerSerialNumber.Issuer.cbData),
5892 "Unexpected value\n");
5893 ok(info->SignerId.IssuerSerialNumber.SerialNumber.cbData ==
5894 sizeof(serialNum), "Unexpected size %d\n",
5895 info->SignerId.IssuerSerialNumber.SerialNumber.cbData);
5896 ok(!memcmp(info->SignerId.IssuerSerialNumber.SerialNumber.pbData,
5897 serialNum, sizeof(serialNum)), "Unexpected value\n");
5898 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
5899 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
5900 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
5901 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
5902 LocalFree(buf);
5904 ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
5905 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
5906 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5907 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5908 if (buf)
5910 info = (CMSG_CMS_SIGNER_INFO *)buf;
5911 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5912 info->dwVersion);
5913 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
5914 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
5915 info->SignerId.dwIdChoice);
5916 ok(info->SignerId.IssuerSerialNumber.Issuer.cbData ==
5917 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
5918 info->SignerId.IssuerSerialNumber.Issuer.cbData);
5919 ok(!memcmp(info->SignerId.IssuerSerialNumber.Issuer.pbData,
5920 encodedCommonNameNoNull,
5921 info->SignerId.IssuerSerialNumber.Issuer.cbData),
5922 "Unexpected value\n");
5923 ok(info->SignerId.IssuerSerialNumber.SerialNumber.cbData ==
5924 sizeof(serialNum), "Unexpected size %d\n",
5925 info->SignerId.IssuerSerialNumber.SerialNumber.cbData);
5926 ok(!memcmp(info->SignerId.IssuerSerialNumber.SerialNumber.pbData,
5927 serialNum, sizeof(serialNum)), "Unexpected value\n");
5928 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
5929 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
5930 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
5931 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
5932 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
5933 info->EncryptedHash.cbData);
5934 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
5935 "Unexpected value\n");
5936 LocalFree(buf);
5938 ret = CryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
5939 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
5940 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5941 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5942 if (buf)
5944 info = (CMSG_CMS_SIGNER_INFO *)buf;
5945 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
5946 info->dwVersion);
5947 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
5948 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
5949 info->SignerId.dwIdChoice);
5950 ok(info->SignerId.KeyId.cbData == sizeof(serialNum),
5951 "Unexpected size %d\n", info->SignerId.KeyId.cbData);
5952 ok(!memcmp(info->SignerId.KeyId.pbData, serialNum, sizeof(serialNum)),
5953 "Unexpected value\n");
5954 LocalFree(buf);
5958 static BYTE emptyDNSPermittedConstraints[] = {
5959 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
5960 static BYTE emptyDNSExcludedConstraints[] = {
5961 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
5962 static BYTE DNSExcludedConstraints[] = {
5963 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
5964 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5965 static BYTE permittedAndExcludedConstraints[] = {
5966 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5967 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
5968 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5969 static BYTE permittedAndExcludedWithMinConstraints[] = {
5970 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5971 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
5972 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5973 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
5974 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
5975 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
5976 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5978 static void test_encodeNameConstraints(DWORD dwEncoding)
5980 BOOL ret;
5981 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
5982 CERT_GENERAL_SUBTREE permitted = { { 0 } };
5983 CERT_GENERAL_SUBTREE excluded = { { 0 } };
5984 LPBYTE buf;
5985 DWORD size;
5987 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
5988 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5989 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
5991 skip("no X509_NAME_CONSTRAINTS encode support\n");
5992 return;
5994 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5995 if (ret)
5997 ok(size == sizeof(emptySequence), "Unexpected size\n");
5998 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
5999 LocalFree(buf);
6001 constraints.cPermittedSubtree = 1;
6002 constraints.rgPermittedSubtree = &permitted;
6003 SetLastError(0xdeadbeef);
6004 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6005 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6006 ok(!ret && GetLastError() == E_INVALIDARG,
6007 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6008 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6009 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6010 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6011 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6012 if (ret)
6014 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
6015 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
6016 "Unexpected value\n");
6017 LocalFree(buf);
6019 constraints.cPermittedSubtree = 0;
6020 constraints.cExcludedSubtree = 1;
6021 constraints.rgExcludedSubtree = &excluded;
6022 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6023 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6024 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6025 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6026 if (ret)
6028 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
6029 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
6030 "Unexpected value\n");
6031 LocalFree(buf);
6033 U(excluded.Base).pwszURL = (LPWSTR)url;
6034 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6035 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6036 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6037 if (ret)
6039 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
6040 ok(!memcmp(buf, DNSExcludedConstraints, size),
6041 "Unexpected value\n");
6042 LocalFree(buf);
6044 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
6045 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6046 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6047 constraints.cPermittedSubtree = 1;
6048 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6049 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6050 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6051 if (ret)
6053 ok(size == sizeof(permittedAndExcludedConstraints),
6054 "Unexpected size\n");
6055 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
6056 "Unexpected value\n");
6057 LocalFree(buf);
6059 permitted.dwMinimum = 5;
6060 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6061 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6062 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6063 if (ret)
6065 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
6066 "Unexpected size\n");
6067 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
6068 "Unexpected value\n");
6069 LocalFree(buf);
6071 permitted.fMaximum = TRUE;
6072 permitted.dwMaximum = 3;
6073 SetLastError(0xdeadbeef);
6074 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6075 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6076 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6077 if (ret)
6079 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
6080 "Unexpected size\n");
6081 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
6082 "Unexpected value\n");
6083 LocalFree(buf);
6087 struct EncodedNameConstraints
6089 CRYPT_DATA_BLOB encoded;
6090 CERT_NAME_CONSTRAINTS_INFO constraints;
6093 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
6094 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6095 static CERT_GENERAL_SUBTREE DNSSubtree = {
6096 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6097 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
6098 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
6099 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
6100 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
6101 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
6102 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
6104 struct EncodedNameConstraints encodedNameConstraints[] = {
6105 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
6106 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
6107 { 1, &emptyDNSSubtree, 0, NULL } },
6108 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
6109 { 0, NULL, 1, &emptyDNSSubtree } },
6110 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
6111 { 0, NULL, 1, &DNSSubtree } },
6112 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
6113 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
6114 { { sizeof(permittedAndExcludedWithMinConstraints),
6115 permittedAndExcludedWithMinConstraints },
6116 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
6117 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
6118 permittedAndExcludedWithMinMaxConstraints },
6119 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
6122 static void test_decodeNameConstraints(DWORD dwEncoding)
6124 BOOL ret;
6125 DWORD i;
6126 CERT_NAME_CONSTRAINTS_INFO *constraints;
6128 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
6129 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6130 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6131 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6132 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6133 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6134 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6135 for (i = 0;
6136 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
6137 i++)
6139 DWORD size;
6141 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
6142 encodedNameConstraints[i].encoded.pbData,
6143 encodedNameConstraints[i].encoded.cbData,
6144 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
6145 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6147 skip("no X509_NAME_CONSTRAINTS decode support\n");
6148 return;
6150 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
6151 if (ret)
6153 DWORD j;
6155 if (constraints->cPermittedSubtree !=
6156 encodedNameConstraints[i].constraints.cPermittedSubtree)
6157 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
6158 encodedNameConstraints[i].constraints.cPermittedSubtree,
6159 constraints->cPermittedSubtree);
6160 if (constraints->cPermittedSubtree ==
6161 encodedNameConstraints[i].constraints.cPermittedSubtree)
6163 for (j = 0; j < constraints->cPermittedSubtree; j++)
6165 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
6166 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
6169 if (constraints->cExcludedSubtree !=
6170 encodedNameConstraints[i].constraints.cExcludedSubtree)
6171 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
6172 encodedNameConstraints[i].constraints.cExcludedSubtree,
6173 constraints->cExcludedSubtree);
6174 if (constraints->cExcludedSubtree ==
6175 encodedNameConstraints[i].constraints.cExcludedSubtree)
6177 for (j = 0; j < constraints->cExcludedSubtree; j++)
6179 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
6180 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
6183 LocalFree(constraints);
6188 /* Free *pInfo with HeapFree */
6189 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
6191 BOOL ret;
6192 DWORD size = 0;
6193 HCRYPTKEY key;
6195 /* This crashes
6196 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
6198 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
6199 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6200 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6201 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
6202 &size);
6203 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6204 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6205 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
6206 NULL, &size);
6207 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6208 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6209 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
6210 0, NULL, NULL, &size);
6211 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6212 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6213 /* Test with no key */
6214 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
6215 0, NULL, NULL, &size);
6216 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
6217 GetLastError());
6218 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
6219 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
6220 if (ret)
6222 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
6223 NULL, 0, NULL, NULL, &size);
6224 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
6225 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
6226 if (*pInfo)
6228 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
6229 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
6230 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
6231 GetLastError());
6232 if (ret)
6234 /* By default (we passed NULL as the OID) the OID is
6235 * szOID_RSA_RSA.
6237 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
6238 "Expected %s, got %s\n", szOID_RSA_RSA,
6239 (*pInfo)->Algorithm.pszObjId);
6243 CryptDestroyKey(key);
6246 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
6247 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
6248 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
6249 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
6250 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
6251 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
6252 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
6253 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
6254 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
6255 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
6256 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
6257 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
6258 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
6259 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
6260 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
6261 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
6262 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
6263 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
6264 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
6265 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
6266 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
6267 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
6268 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
6269 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
6270 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
6272 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
6274 BOOL ret;
6275 HCRYPTKEY key;
6276 PCCERT_CONTEXT context;
6277 DWORD dwSize;
6278 ALG_ID ai;
6280 /* These crash
6281 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
6282 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
6283 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
6284 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
6285 NULL);
6287 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
6288 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
6289 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
6290 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
6291 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
6292 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
6293 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
6294 &key);
6295 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6296 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6298 /* Export key with standard algorithm (CALG_RSA_KEYX) */
6299 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
6300 &key);
6301 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
6303 dwSize = sizeof(ai);
6304 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
6305 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
6306 if(ret)
6308 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
6309 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
6312 CryptDestroyKey(key);
6314 /* Repeat with forced algorithm */
6315 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
6316 &key);
6317 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
6319 dwSize = sizeof(ai);
6320 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
6321 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
6322 if(ret)
6324 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
6325 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
6328 CryptDestroyKey(key);
6330 /* Test importing a public key from a certificate context */
6331 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
6332 sizeof(expiredCert));
6333 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
6334 GetLastError());
6335 if (context)
6337 ok(!strcmp(szOID_RSA_RSA,
6338 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
6339 "Expected %s, got %s\n", szOID_RSA_RSA,
6340 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
6341 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
6342 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
6343 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
6344 CryptDestroyKey(key);
6345 CertFreeCertificateContext(context);
6349 static const char cspName[] = "WineCryptTemp";
6351 static void testPortPublicKeyInfo(void)
6353 HCRYPTPROV csp;
6354 BOOL ret;
6355 PCERT_PUBLIC_KEY_INFO info = NULL;
6357 /* Just in case a previous run failed, delete this thing */
6358 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
6359 CRYPT_DELETEKEYSET);
6360 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
6361 CRYPT_NEWKEYSET);
6363 testExportPublicKey(csp, &info);
6364 testImportPublicKey(csp, info);
6366 HeapFree(GetProcessHeap(), 0, info);
6367 CryptReleaseContext(csp, 0);
6368 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
6369 CRYPT_DELETEKEYSET);
6372 START_TEST(encode)
6374 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
6375 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
6376 HMODULE hCrypt32;
6377 DWORD i;
6379 hCrypt32 = GetModuleHandleA("crypt32.dll");
6380 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
6381 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
6382 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
6384 skip("CryptDecodeObjectEx() is not available\n");
6385 return;
6388 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
6390 test_encodeInt(encodings[i]);
6391 test_decodeInt(encodings[i]);
6392 test_encodeEnumerated(encodings[i]);
6393 test_decodeEnumerated(encodings[i]);
6394 test_encodeFiletime(encodings[i]);
6395 test_decodeFiletime(encodings[i]);
6396 test_encodeName(encodings[i]);
6397 test_decodeName(encodings[i]);
6398 test_encodeUnicodeName(encodings[i]);
6399 test_decodeUnicodeName(encodings[i]);
6400 test_encodeNameValue(encodings[i]);
6401 test_decodeNameValue(encodings[i]);
6402 test_encodeUnicodeNameValue(encodings[i]);
6403 test_decodeUnicodeNameValue(encodings[i]);
6404 test_encodeAltName(encodings[i]);
6405 test_decodeAltName(encodings[i]);
6406 test_encodeOctets(encodings[i]);
6407 test_decodeOctets(encodings[i]);
6408 test_encodeBits(encodings[i]);
6409 test_decodeBits(encodings[i]);
6410 test_encodeBasicConstraints(encodings[i]);
6411 test_decodeBasicConstraints(encodings[i]);
6412 test_encodeRsaPublicKey(encodings[i]);
6413 test_decodeRsaPublicKey(encodings[i]);
6414 test_encodeSequenceOfAny(encodings[i]);
6415 test_decodeSequenceOfAny(encodings[i]);
6416 test_encodeExtensions(encodings[i]);
6417 test_decodeExtensions(encodings[i]);
6418 test_encodePublicKeyInfo(encodings[i]);
6419 test_decodePublicKeyInfo(encodings[i]);
6420 test_encodeCertToBeSigned(encodings[i]);
6421 test_decodeCertToBeSigned(encodings[i]);
6422 test_encodeCert(encodings[i]);
6423 test_decodeCert(encodings[i]);
6424 test_encodeCRLDistPoints(encodings[i]);
6425 test_decodeCRLDistPoints(encodings[i]);
6426 test_encodeCRLIssuingDistPoint(encodings[i]);
6427 test_decodeCRLIssuingDistPoint(encodings[i]);
6428 test_encodeCRLToBeSigned(encodings[i]);
6429 test_decodeCRLToBeSigned(encodings[i]);
6430 test_encodeEnhancedKeyUsage(encodings[i]);
6431 test_decodeEnhancedKeyUsage(encodings[i]);
6432 test_encodeAuthorityKeyId(encodings[i]);
6433 test_decodeAuthorityKeyId(encodings[i]);
6434 test_encodeAuthorityKeyId2(encodings[i]);
6435 test_decodeAuthorityKeyId2(encodings[i]);
6436 test_encodePKCSContentInfo(encodings[i]);
6437 test_decodePKCSContentInfo(encodings[i]);
6438 test_encodePKCSAttribute(encodings[i]);
6439 test_decodePKCSAttribute(encodings[i]);
6440 test_encodePKCSAttributes(encodings[i]);
6441 test_decodePKCSAttributes(encodings[i]);
6442 test_encodePKCSSMimeCapabilities(encodings[i]);
6443 test_decodePKCSSMimeCapabilities(encodings[i]);
6444 test_encodePKCSSignerInfo(encodings[i]);
6445 test_decodePKCSSignerInfo(encodings[i]);
6446 test_encodeCMSSignerInfo(encodings[i]);
6447 test_decodeCMSSignerInfo(encodings[i]);
6448 test_encodeNameConstraints(encodings[i]);
6449 test_decodeNameConstraints(encodings[i]);
6451 testPortPublicKeyInfo();