push e8d2f3f1a5d20911a70f6477421a6c3dacf00760
[wine/hacks.git] / dlls / crypt32 / tests / encode.c
blob918f0f069e4bcd23eee4d4ffde81e26b4ba159e6
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, "CryptDecodeObjectEx 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, "CryptEncodeObjectEx 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, "CryptEncodeObjectEx 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 authorityInfoAccessWithUrl[] = {
4779 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4780 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
4781 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
4782 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
4783 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
4784 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
4786 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
4788 static char oid1[] = "1.2.3";
4789 static char oid2[] = "1.5.6";
4790 BOOL ret;
4791 BYTE *buf = NULL;
4792 DWORD size = 0;
4793 CERT_ACCESS_DESCRIPTION accessDescription[2];
4794 CERT_AUTHORITY_INFO_ACCESS aia;
4796 memset(accessDescription, 0, sizeof(accessDescription));
4797 aia.cAccDescr = 0;
4798 aia.rgAccDescr = NULL;
4799 /* Having no access descriptions is allowed */
4800 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4801 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4802 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4803 if (buf)
4805 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
4806 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
4807 LocalFree(buf);
4808 buf = NULL;
4810 /* It can't have an empty access method */
4811 aia.cAccDescr = 1;
4812 aia.rgAccDescr = accessDescription;
4813 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4814 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4815 ok(!ret && GetLastError() == E_INVALIDARG,
4816 "expected E_INVALIDARG, got %08x\n", GetLastError());
4817 /* It can't have an empty location */
4818 accessDescription[0].pszAccessMethod = oid1;
4819 SetLastError(0xdeadbeef);
4820 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4821 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4822 ok(!ret && GetLastError() == E_INVALIDARG,
4823 "expected E_INVALIDARG, got %08x\n", GetLastError());
4824 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4825 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
4826 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4827 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4828 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4829 if (buf)
4831 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
4832 size);
4833 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
4834 "unexpected value\n");
4835 LocalFree(buf);
4836 buf = NULL;
4838 accessDescription[1].pszAccessMethod = oid2;
4839 accessDescription[1].AccessLocation.dwAltNameChoice =
4840 CERT_ALT_NAME_IP_ADDRESS;
4841 U(accessDescription[1].AccessLocation).IPAddress.cbData =
4842 sizeof(encodedIPAddr);
4843 U(accessDescription[1].AccessLocation).IPAddress.pbData =
4844 (LPBYTE)encodedIPAddr;
4845 aia.cAccDescr = 2;
4846 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
4847 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4848 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4849 if (buf)
4851 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
4852 "unexpected size %d\n", size);
4853 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
4854 "unexpected value\n");
4855 LocalFree(buf);
4856 buf = NULL;
4860 static void compareAuthorityInfoAccess(LPCSTR header,
4861 const CERT_AUTHORITY_INFO_ACCESS *expected,
4862 const CERT_AUTHORITY_INFO_ACCESS *got)
4864 DWORD i;
4866 ok(expected->cAccDescr == got->cAccDescr,
4867 "%s: expected %d access descriptions, got %d\n", header,
4868 expected->cAccDescr, got->cAccDescr);
4869 for (i = 0; i < expected->cAccDescr; i++)
4871 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
4872 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
4873 header, i, expected->rgAccDescr[i].pszAccessMethod,
4874 got->rgAccDescr[i].pszAccessMethod);
4875 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
4876 &got->rgAccDescr[i].AccessLocation);
4880 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
4882 static char oid1[] = "1.2.3";
4883 static char oid2[] = "1.5.6";
4884 BOOL ret;
4885 LPBYTE buf = NULL;
4886 DWORD size = 0;
4888 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4889 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4890 (BYTE *)&buf, &size);
4891 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4892 if (buf)
4894 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
4896 compareAuthorityInfoAccess("empty AIA", &aia,
4897 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4898 LocalFree(buf);
4899 buf = NULL;
4901 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4902 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
4903 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
4904 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4905 if (buf)
4907 CERT_ACCESS_DESCRIPTION accessDescription;
4908 CERT_AUTHORITY_INFO_ACCESS aia;
4910 accessDescription.pszAccessMethod = oid1;
4911 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4912 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
4913 aia.cAccDescr = 1;
4914 aia.rgAccDescr = &accessDescription;
4915 compareAuthorityInfoAccess("AIA with URL", &aia,
4916 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4917 LocalFree(buf);
4918 buf = NULL;
4920 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
4921 authorityInfoAccessWithUrlAndIPAddr,
4922 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
4923 NULL, (BYTE *)&buf, &size);
4924 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
4925 if (buf)
4927 CERT_ACCESS_DESCRIPTION accessDescription[2];
4928 CERT_AUTHORITY_INFO_ACCESS aia;
4930 accessDescription[0].pszAccessMethod = oid1;
4931 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
4932 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
4933 accessDescription[1].pszAccessMethod = oid2;
4934 accessDescription[1].AccessLocation.dwAltNameChoice =
4935 CERT_ALT_NAME_IP_ADDRESS;
4936 U(accessDescription[1].AccessLocation).IPAddress.cbData =
4937 sizeof(encodedIPAddr);
4938 U(accessDescription[1].AccessLocation).IPAddress.pbData =
4939 (LPBYTE)encodedIPAddr;
4940 aia.cAccDescr = 2;
4941 aia.rgAccDescr = accessDescription;
4942 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
4943 (CERT_AUTHORITY_INFO_ACCESS *)buf);
4944 LocalFree(buf);
4945 buf = NULL;
4949 static const BYTE emptyCTL[] = {
4950 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
4951 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
4952 static const BYTE emptyCTLWithVersion1[] = {
4953 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
4954 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
4955 static const BYTE ctlWithUsageIdentifier[] = {
4956 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
4957 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
4958 static const BYTE ctlWithListIdentifier[] = {
4959 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
4960 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
4961 static const BYTE ctlWithSequenceNumber[] = {
4962 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
4963 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
4964 static const BYTE ctlWithThisUpdate[] = {
4965 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
4966 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
4967 static const BYTE ctlWithThisAndNextUpdate[] = {
4968 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
4969 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
4970 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
4971 static const BYTE ctlWithAlgId[] = {
4972 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
4973 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
4974 static const BYTE ctlWithBogusEntry[] = {
4975 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
4976 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
4977 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
4978 static const BYTE ctlWithOneEntry[] = {
4979 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
4980 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
4981 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
4982 static const BYTE ctlWithTwoEntries[] = {
4983 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
4984 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
4985 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
4986 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
4987 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
4989 static void test_encodeCTL(DWORD dwEncoding)
4991 static char oid1[] = "1.2.3";
4992 static char oid2[] = "1.5.6";
4993 char *pOid1 = oid1;
4994 BOOL ret;
4995 BYTE *buf = NULL;
4996 DWORD size = 0;
4997 CTL_INFO info;
4998 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
4999 CTL_ENTRY ctlEntry[2];
5000 CRYPT_ATTRIBUTE attr1, attr2;
5001 CRYPT_ATTR_BLOB value1, value2;
5003 memset(&info, 0, sizeof(info));
5004 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5005 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5006 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5007 if (buf)
5009 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5010 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5011 LocalFree(buf);
5012 buf = NULL;
5014 info.dwVersion = 1;
5015 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5016 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5017 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5018 if (buf)
5020 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5021 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5022 LocalFree(buf);
5023 buf = NULL;
5025 info.dwVersion = 0;
5026 info.SubjectUsage.cUsageIdentifier = 1;
5027 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5028 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5029 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5030 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5031 if (buf)
5033 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5034 size);
5035 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5036 LocalFree(buf);
5037 buf = NULL;
5039 info.SubjectUsage.cUsageIdentifier = 0;
5040 info.ListIdentifier.cbData = sizeof(serialNum);
5041 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5042 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5043 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5044 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5045 if (buf)
5047 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5048 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5049 LocalFree(buf);
5050 buf = NULL;
5052 info.ListIdentifier.cbData = 0;
5053 info.SequenceNumber.cbData = sizeof(serialNum);
5054 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5055 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5056 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5057 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5058 if (buf)
5060 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5061 size);
5062 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5063 LocalFree(buf);
5064 buf = NULL;
5066 info.SequenceNumber.cbData = 0;
5067 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5068 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5069 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5070 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5071 if (buf)
5073 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5074 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5075 LocalFree(buf);
5076 buf = NULL;
5078 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5079 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5080 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5081 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5082 if (buf)
5084 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5085 size);
5086 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5087 LocalFree(buf);
5088 buf = NULL;
5090 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5091 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5092 info.SubjectAlgorithm.pszObjId = oid2;
5093 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5094 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5095 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5096 if (buf)
5098 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5099 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5100 LocalFree(buf);
5101 buf = NULL;
5103 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5104 * (see tests below) but it'll encode fine.
5106 info.SubjectAlgorithm.pszObjId = NULL;
5107 value1.cbData = sizeof(serialNum);
5108 value1.pbData = (LPBYTE)serialNum;
5109 attr1.pszObjId = oid1;
5110 attr1.cValue = 1;
5111 attr1.rgValue = &value1;
5112 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5113 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5114 ctlEntry[0].cAttribute = 1;
5115 ctlEntry[0].rgAttribute = &attr1;
5116 info.cCTLEntry = 1;
5117 info.rgCTLEntry = ctlEntry;
5118 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5119 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5120 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5121 if (buf)
5123 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5124 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5125 LocalFree(buf);
5126 buf = NULL;
5128 value1.cbData = sizeof(emptySequence);
5129 value1.pbData = (LPBYTE)emptySequence;
5130 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5131 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5132 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5133 if (buf)
5135 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5136 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5137 LocalFree(buf);
5138 buf = NULL;
5140 value2.cbData = sizeof(encodedIPAddr);
5141 value2.pbData = (LPBYTE)encodedIPAddr;
5142 attr2.pszObjId = oid2;
5143 attr2.cValue = 1;
5144 attr2.rgValue = &value2;
5145 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5146 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5147 ctlEntry[1].cAttribute = 1;
5148 ctlEntry[1].rgAttribute = &attr2;
5149 info.cCTLEntry = 2;
5150 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5151 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5152 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5153 if (buf)
5155 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5156 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5157 LocalFree(buf);
5158 buf = NULL;
5162 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5163 const CTL_INFO *got)
5165 DWORD i, j, k;
5167 ok(expected->dwVersion == got->dwVersion,
5168 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5169 got->dwVersion);
5170 ok(expected->SubjectUsage.cUsageIdentifier ==
5171 got->SubjectUsage.cUsageIdentifier,
5172 "%s: expected %d usage identifiers, got %d\n", header,
5173 expected->SubjectUsage.cUsageIdentifier,
5174 got->SubjectUsage.cUsageIdentifier);
5175 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5176 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5177 got->SubjectUsage.rgpszUsageIdentifier[i]),
5178 "%s[%d]: expected %s, got %s\n", header, i,
5179 expected->SubjectUsage.rgpszUsageIdentifier[i],
5180 got->SubjectUsage.rgpszUsageIdentifier[i]);
5181 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5182 "%s: expected list identifier of %d bytes, got %d\n", header,
5183 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5184 if (expected->ListIdentifier.cbData)
5185 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5186 expected->ListIdentifier.cbData),
5187 "%s: unexpected list identifier value\n", header);
5188 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5189 "%s: expected sequence number of %d bytes, got %d\n", header,
5190 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5191 if (expected->SequenceNumber.cbData)
5192 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5193 expected->SequenceNumber.cbData),
5194 "%s: unexpected sequence number value\n", header);
5195 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5196 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5197 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5198 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5199 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5200 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5201 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5202 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5203 if (expected->SubjectAlgorithm.pszObjId &&
5204 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5205 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5206 expected->SubjectAlgorithm.pszObjId);
5207 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5208 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5209 got->SubjectAlgorithm.pszObjId),
5210 "%s: expected subject algorithm %s, got %s\n", header,
5211 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5212 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5213 got->SubjectAlgorithm.Parameters.cbData,
5214 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5215 expected->SubjectAlgorithm.Parameters.cbData,
5216 got->SubjectAlgorithm.Parameters.cbData);
5217 if (expected->SubjectAlgorithm.Parameters.cbData)
5218 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5219 got->SubjectAlgorithm.Parameters.pbData,
5220 expected->SubjectAlgorithm.Parameters.cbData),
5221 "%s: unexpected subject algorithm parameter value\n", header);
5222 ok(expected->cCTLEntry == got->cCTLEntry,
5223 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5224 got->cCTLEntry);
5225 for (i = 0; i < expected->cCTLEntry; i++)
5227 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5228 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5229 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5230 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5231 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5232 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5233 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5234 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5235 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5236 "%s[%d]: unexpected subject identifier value\n",
5237 header, i);
5238 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5240 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5241 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5242 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5243 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5244 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5245 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5247 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5248 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5249 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5250 header, i, j, k,
5251 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5252 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5253 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5254 ok(!memcmp(
5255 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5256 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5257 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5258 "%s[%d][%d][%d]: unexpected value\n",
5259 header, i, j, k);
5263 ok(expected->cExtension == got->cExtension,
5264 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5265 got->cExtension);
5266 for (i = 0; i < expected->cExtension; i++)
5268 ok(!strcmp(expected->rgExtension[i].pszObjId,
5269 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5270 header, i, expected->rgExtension[i].pszObjId,
5271 got->rgExtension[i].pszObjId);
5272 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5273 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5274 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5275 ok(expected->rgExtension[i].Value.cbData ==
5276 got->rgExtension[i].Value.cbData,
5277 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5278 header, i, expected->rgExtension[i].Value.cbData,
5279 got->rgExtension[i].Value.cbData);
5280 if (expected->rgExtension[i].Value.cbData)
5281 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5282 got->rgExtension[i].Value.pbData,
5283 expected->rgExtension[i].Value.cbData),
5284 "%s[%d]: unexpected extension value\n", header, i);
5288 static const BYTE signedCTL[] = {
5289 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5290 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5291 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5292 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5293 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5294 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5295 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5296 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5297 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5298 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5299 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5300 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5301 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5302 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5303 static const BYTE signedCTLWithCTLInnerContent[] = {
5304 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5305 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5306 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5307 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5308 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5309 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5310 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5311 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5312 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5313 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5314 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5315 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5316 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5317 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5318 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5319 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5320 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5321 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5322 0x57,0x6c,0x0b,0x47,0xb8 };
5324 static void test_decodeCTL(DWORD dwEncoding)
5326 static char oid1[] = "1.2.3";
5327 static char oid2[] = "1.5.6";
5328 static BYTE nullData[] = { 5,0 };
5329 char *pOid1 = oid1;
5330 BOOL ret;
5331 BYTE *buf = NULL;
5332 DWORD size = 0;
5333 CTL_INFO info;
5334 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5335 CTL_ENTRY ctlEntry[2];
5336 CRYPT_ATTRIBUTE attr1, attr2;
5337 CRYPT_ATTR_BLOB value1, value2;
5339 memset(&info, 0, sizeof(info));
5340 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5341 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5342 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5343 if (buf)
5345 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5346 LocalFree(buf);
5347 buf = NULL;
5349 info.dwVersion = 1;
5350 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5351 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf,
5352 &size);
5353 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5354 if (buf)
5356 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5357 LocalFree(buf);
5358 buf = NULL;
5360 info.dwVersion = 0;
5361 info.SubjectUsage.cUsageIdentifier = 1;
5362 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5363 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5364 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5365 (BYTE *)&buf, &size);
5366 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5367 if (buf)
5369 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5370 LocalFree(buf);
5371 buf = NULL;
5373 info.SubjectUsage.cUsageIdentifier = 0;
5374 info.ListIdentifier.cbData = sizeof(serialNum);
5375 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5376 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5377 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5378 (BYTE *)&buf, &size);
5379 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5380 if (buf)
5382 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5383 LocalFree(buf);
5384 buf = NULL;
5386 info.ListIdentifier.cbData = 0;
5387 info.SequenceNumber.cbData = sizeof(serialNum);
5388 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5389 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5390 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL,
5391 (BYTE *)&buf, &size);
5392 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5393 if (buf)
5395 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5396 LocalFree(buf);
5397 buf = NULL;
5399 info.SequenceNumber.cbData = 0;
5400 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5401 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5402 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5403 (BYTE *)&buf, &size);
5404 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5405 if (buf)
5407 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5408 LocalFree(buf);
5409 buf = NULL;
5411 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5412 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5413 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5414 (BYTE *)&buf, &size);
5415 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5416 if (buf)
5418 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5419 LocalFree(buf);
5420 buf = NULL;
5422 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5423 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5424 info.SubjectAlgorithm.pszObjId = oid2;
5425 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5426 info.SubjectAlgorithm.Parameters.pbData = nullData;
5427 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5428 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL,
5429 (BYTE *)&buf, &size);
5430 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5431 if (buf)
5433 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5434 LocalFree(buf);
5435 buf = NULL;
5437 SetLastError(0xdeadbeef);
5438 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5439 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5440 (BYTE *)&buf, &size);
5441 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD || CRYPT_E_ASN1_CORRUPT),
5442 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5443 GetLastError());
5444 info.SubjectAlgorithm.Parameters.cbData = 0;
5445 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5446 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5447 info.SubjectAlgorithm.pszObjId = oid2;
5448 info.SubjectAlgorithm.pszObjId = NULL;
5449 value1.cbData = sizeof(emptySequence);
5450 value1.pbData = (LPBYTE)emptySequence;
5451 attr1.pszObjId = oid1;
5452 attr1.cValue = 1;
5453 attr1.rgValue = &value1;
5454 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5455 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5456 ctlEntry[0].cAttribute = 1;
5457 ctlEntry[0].rgAttribute = &attr1;
5458 info.cCTLEntry = 1;
5459 info.rgCTLEntry = ctlEntry;
5460 SetLastError(0xdeadbeef);
5461 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5462 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL,
5463 (BYTE *)&buf, &size);
5464 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5465 if (buf)
5467 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5468 LocalFree(buf);
5469 buf = NULL;
5471 value2.cbData = sizeof(encodedIPAddr);
5472 value2.pbData = (LPBYTE)encodedIPAddr;
5473 attr2.pszObjId = oid2;
5474 attr2.cValue = 1;
5475 attr2.rgValue = &value2;
5476 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5477 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5478 ctlEntry[1].cAttribute = 1;
5479 ctlEntry[1].rgAttribute = &attr2;
5480 info.cCTLEntry = 2;
5481 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5482 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL,
5483 (BYTE *)&buf, &size);
5484 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5485 if (buf)
5487 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5488 LocalFree(buf);
5489 buf = NULL;
5491 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5492 SetLastError(0xdeadbeef);
5493 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5494 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5495 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
5496 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
5497 SetLastError(0xdeadbeef);
5498 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5499 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5500 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5501 ok(!ret && GetLastError() == CRYPT_E_ASN1_BADTAG,
5502 "expected CRYPT_E_ASN1_BADTAG, got %08x\n", GetLastError());
5505 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5506 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5507 0x03,0,0,0,0,0,0 };
5508 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5509 0xa0,0x01,0x01 };
5510 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5511 0x03,0x02,0x01,0x01 };
5512 static BYTE bogusDER[] = { 1 };
5514 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5516 BOOL ret;
5517 BYTE *buf = NULL;
5518 DWORD size = 0;
5519 CRYPT_CONTENT_INFO info = { 0 };
5520 char oid1[] = "1.2.3";
5522 SetLastError(0xdeadbeef);
5523 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5524 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5525 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5526 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5527 SetLastError(0xdeadbeef);
5528 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5529 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5530 ok(!ret && GetLastError() == E_INVALIDARG,
5531 "Expected E_INVALIDARG, got %x\n", GetLastError());
5532 info.pszObjId = oid1;
5533 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5534 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5535 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5536 if (buf)
5538 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5539 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5540 LocalFree(buf);
5542 info.Content.pbData = bogusDER;
5543 info.Content.cbData = sizeof(bogusDER);
5544 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5545 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5546 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5547 if (buf)
5549 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5550 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5551 LocalFree(buf);
5553 info.Content.pbData = (BYTE *)ints[0].encoded;
5554 info.Content.cbData = ints[0].encoded[1] + 2;
5555 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5556 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5557 if (buf)
5559 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5560 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5561 LocalFree(buf);
5565 static const BYTE indefiniteSignedPKCSContent[] = {
5566 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5567 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5568 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5569 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5570 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5571 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5572 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5573 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5574 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5575 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5576 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5577 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5578 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5579 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5580 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5581 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5582 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5583 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5584 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5585 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5586 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5587 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5588 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5589 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5590 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5591 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5592 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5593 0x00,0x00,0x00,0x00,0x00,0x00 };
5595 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5597 BOOL ret;
5598 LPBYTE buf = NULL;
5599 DWORD size = 0;
5600 CRYPT_CONTENT_INFO *info;
5602 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5603 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5604 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5605 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5606 if (buf)
5608 info = (CRYPT_CONTENT_INFO *)buf;
5610 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5611 info->pszObjId);
5612 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5613 info->Content.cbData);
5614 LocalFree(buf);
5616 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5617 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5618 0, NULL, NULL, &size);
5619 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5620 SetLastError(0xdeadbeef);
5621 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5622 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5623 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5624 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5625 * I doubt an app depends on that.
5627 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5628 GetLastError() == CRYPT_E_ASN1_CORRUPT),
5629 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5630 GetLastError());
5631 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5632 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5633 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5634 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5635 if (buf)
5637 info = (CRYPT_CONTENT_INFO *)buf;
5639 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5640 info->pszObjId);
5641 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5642 "Unexpected size %d\n", info->Content.cbData);
5643 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5644 info->Content.cbData), "Unexpected value\n");
5645 LocalFree(buf);
5647 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5648 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5649 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5650 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5651 if (buf)
5653 info = (CRYPT_CONTENT_INFO *)buf;
5655 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5656 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5657 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5658 info->Content.cbData);
5659 LocalFree(buf);
5663 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5664 0x00 };
5665 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5666 0x01 };
5667 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5668 0x02,0x01,0x01 };
5670 static void test_encodePKCSAttribute(DWORD dwEncoding)
5672 CRYPT_ATTRIBUTE attr = { 0 };
5673 BOOL ret;
5674 LPBYTE buf = NULL;
5675 DWORD size = 0;
5676 CRYPT_ATTR_BLOB blob;
5677 char oid[] = "1.2.3";
5679 SetLastError(0xdeadbeef);
5680 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5681 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5682 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5683 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5684 SetLastError(0xdeadbeef);
5685 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5686 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5687 ok(!ret && GetLastError() == E_INVALIDARG,
5688 "Expected E_INVALIDARG, got %x\n", GetLastError());
5689 attr.pszObjId = oid;
5690 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5691 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5692 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5693 if (buf)
5695 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
5696 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
5697 LocalFree(buf);
5699 blob.cbData = sizeof(bogusDER);
5700 blob.pbData = bogusDER;
5701 attr.cValue = 1;
5702 attr.rgValue = &blob;
5703 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5704 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5705 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5706 if (buf)
5708 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
5709 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
5710 LocalFree(buf);
5712 blob.pbData = (BYTE *)ints[0].encoded;
5713 blob.cbData = ints[0].encoded[1] + 2;
5714 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
5715 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5716 if (buf)
5718 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
5719 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
5720 LocalFree(buf);
5724 static void test_decodePKCSAttribute(DWORD dwEncoding)
5726 BOOL ret;
5727 LPBYTE buf = NULL;
5728 DWORD size = 0;
5729 CRYPT_ATTRIBUTE *attr;
5731 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5732 emptyPKCSAttr, sizeof(emptyPKCSAttr),
5733 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5734 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5735 if (buf)
5737 attr = (CRYPT_ATTRIBUTE *)buf;
5739 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5740 attr->pszObjId);
5741 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
5742 LocalFree(buf);
5744 SetLastError(0xdeadbeef);
5745 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5746 bogusPKCSAttr, sizeof(bogusPKCSAttr),
5747 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5748 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5749 * I doubt an app depends on that.
5751 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5752 GetLastError() == CRYPT_E_ASN1_CORRUPT),
5753 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5754 GetLastError());
5755 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
5756 intPKCSAttr, sizeof(intPKCSAttr),
5757 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5758 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5759 if (buf)
5761 attr = (CRYPT_ATTRIBUTE *)buf;
5763 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5764 attr->pszObjId);
5765 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
5766 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
5767 "Unexpected size %d\n", attr->rgValue[0].cbData);
5768 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
5769 attr->rgValue[0].cbData), "Unexpected value\n");
5770 LocalFree(buf);
5774 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
5775 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
5776 0x2a,0x03,0x31,0x00 };
5777 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
5778 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
5780 static void test_encodePKCSAttributes(DWORD dwEncoding)
5782 CRYPT_ATTRIBUTES attributes = { 0 };
5783 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
5784 CRYPT_ATTR_BLOB blob;
5785 BOOL ret;
5786 LPBYTE buf = NULL;
5787 DWORD size = 0;
5788 char oid1[] = "1.2.3", oid2[] = "1.5.6";
5790 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5791 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5792 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5793 if (buf)
5795 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
5796 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
5797 LocalFree(buf);
5799 attributes.cAttr = 1;
5800 attributes.rgAttr = attr;
5801 SetLastError(0xdeadbeef);
5802 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5803 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5804 ok(!ret && GetLastError() == E_INVALIDARG,
5805 "Expected E_INVALIDARG, got %x\n", GetLastError());
5806 attr[0].pszObjId = oid1;
5807 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5808 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5809 if (buf)
5811 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
5812 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
5813 LocalFree(buf);
5815 attr[1].pszObjId = oid2;
5816 attr[1].cValue = 1;
5817 attr[1].rgValue = &blob;
5818 blob.pbData = (BYTE *)ints[0].encoded;
5819 blob.cbData = ints[0].encoded[1] + 2;
5820 attributes.cAttr = 2;
5821 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
5822 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5823 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5824 if (buf)
5826 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
5827 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
5828 LocalFree(buf);
5832 static void test_decodePKCSAttributes(DWORD dwEncoding)
5834 BOOL ret;
5835 LPBYTE buf = NULL;
5836 DWORD size = 0;
5837 CRYPT_ATTRIBUTES *attributes;
5839 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5840 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
5841 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5842 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5843 if (buf)
5845 attributes = (CRYPT_ATTRIBUTES *)buf;
5846 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
5847 attributes->cAttr);
5848 LocalFree(buf);
5850 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5851 singlePKCSAttributes, sizeof(singlePKCSAttributes),
5852 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5853 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5854 if (buf)
5856 attributes = (CRYPT_ATTRIBUTES *)buf;
5857 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
5858 attributes->cAttr);
5859 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5860 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5861 ok(attributes->rgAttr[0].cValue == 0,
5862 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5863 LocalFree(buf);
5865 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
5866 doublePKCSAttributes, sizeof(doublePKCSAttributes),
5867 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5868 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5869 if (buf)
5871 attributes = (CRYPT_ATTRIBUTES *)buf;
5872 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
5873 attributes->cAttr);
5874 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
5875 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
5876 ok(attributes->rgAttr[0].cValue == 0,
5877 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
5878 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
5879 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
5880 ok(attributes->rgAttr[1].cValue == 1,
5881 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
5882 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
5883 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
5884 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
5885 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
5886 LocalFree(buf);
5890 static const BYTE singleCapability[] = {
5891 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
5892 static const BYTE twoCapabilities[] = {
5893 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
5894 static const BYTE singleCapabilitywithNULL[] = {
5895 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5897 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
5899 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
5900 BOOL ret;
5901 LPBYTE buf = NULL;
5902 DWORD size = 0;
5903 CRYPT_SMIME_CAPABILITY capability[2];
5904 CRYPT_SMIME_CAPABILITIES capabilities;
5906 /* An empty capabilities is allowed */
5907 capabilities.cCapability = 0;
5908 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5909 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5910 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5911 if (buf)
5913 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
5914 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5915 LocalFree(buf);
5917 /* A non-empty capabilities with an empty capability (lacking an OID) is
5918 * not allowed
5920 capability[0].pszObjId = NULL;
5921 capability[0].Parameters.cbData = 0;
5922 capabilities.cCapability = 1;
5923 capabilities.rgCapability = capability;
5924 SetLastError(0xdeadbeef);
5925 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5926 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5927 ok(!ret && GetLastError() == E_INVALIDARG,
5928 "expected E_INVALIDARG, got %08x\n", GetLastError());
5929 capability[0].pszObjId = oid1;
5930 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5931 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5932 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5933 if (buf)
5935 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
5936 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
5937 LocalFree(buf);
5939 capability[1].pszObjId = oid2;
5940 capability[1].Parameters.cbData = 0;
5941 capabilities.cCapability = 2;
5942 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5943 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
5944 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5945 if (buf)
5947 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
5948 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
5949 LocalFree(buf);
5953 static void compareSMimeCapabilities(LPCSTR header,
5954 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
5956 DWORD i;
5958 ok(got->cCapability == expected->cCapability,
5959 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
5960 got->cCapability);
5961 for (i = 0; i < expected->cCapability; i++)
5963 ok(!strcmp(expected->rgCapability[i].pszObjId,
5964 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5965 header, i, expected->rgCapability[i].pszObjId,
5966 got->rgCapability[i].pszObjId);
5967 ok(expected->rgCapability[i].Parameters.cbData ==
5968 got->rgCapability[i].Parameters.cbData,
5969 "%s[%d]: expected %d bytes, got %d\n", header, i,
5970 expected->rgCapability[i].Parameters.cbData,
5971 got->rgCapability[i].Parameters.cbData);
5972 if (expected->rgCapability[i].Parameters.cbData)
5973 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
5974 got->rgCapability[i].Parameters.pbData,
5975 expected->rgCapability[i].Parameters.cbData),
5976 "%s[%d]: unexpected value\n", header, i);
5980 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
5982 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
5983 BOOL ret;
5984 DWORD size = 0;
5985 CRYPT_SMIME_CAPABILITY capability[2];
5986 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
5988 SetLastError(0xdeadbeef);
5989 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
5990 emptySequence, sizeof(emptySequence),
5991 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
5992 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5993 if (ret)
5995 capabilities.cCapability = 0;
5996 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
5997 LocalFree(ptr);
5999 SetLastError(0xdeadbeef);
6000 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6001 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6002 (BYTE *)&ptr, &size);
6003 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6004 if (ret)
6006 capability[0].pszObjId = oid1;
6007 capability[0].Parameters.cbData = 0;
6008 capabilities.cCapability = 1;
6009 capabilities.rgCapability = capability;
6010 compareSMimeCapabilities("single capability", &capabilities, ptr);
6011 LocalFree(ptr);
6013 SetLastError(0xdeadbeef);
6014 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6015 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6016 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&ptr, &size);
6017 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6018 if (ret)
6020 BYTE NULLparam[] = {0x05, 0x00};
6021 capability[0].pszObjId = oid1;
6022 capability[0].Parameters.cbData = 2;
6023 capability[0].Parameters.pbData = NULLparam;
6024 capabilities.cCapability = 1;
6025 capabilities.rgCapability = capability;
6026 compareSMimeCapabilities("single capability with NULL", &capabilities,
6027 ptr);
6028 LocalFree(ptr);
6030 SetLastError(0xdeadbeef);
6031 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6032 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6033 (BYTE *)&ptr, &size);
6034 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6035 if (ret)
6037 capability[0].Parameters.cbData = 0;
6038 capability[1].pszObjId = oid2;
6039 capability[1].Parameters.cbData = 0;
6040 capabilities.cCapability = 2;
6041 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6042 LocalFree(ptr);
6046 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6047 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6048 0x67 };
6049 static const BYTE minimalPKCSSigner[] = {
6050 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6051 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6052 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6053 static const BYTE PKCSSignerWithSerial[] = {
6054 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6055 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6056 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6057 0x00 };
6058 static const BYTE PKCSSignerWithHashAlgo[] = {
6059 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6060 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6061 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6062 0x00,0x04,0x00 };
6063 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6064 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6065 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6066 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6067 0x06,0x05,0x00,0x04,0x00 };
6068 static const BYTE PKCSSignerWithHash[] = {
6069 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6070 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6071 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6072 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6073 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6074 static const BYTE PKCSSignerWithAuthAttr[] = {
6075 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6076 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6077 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6078 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6079 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6080 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6081 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6083 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6085 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6086 BOOL ret;
6087 LPBYTE buf = NULL;
6088 DWORD size = 0;
6089 CMSG_SIGNER_INFO info = { 0 };
6090 char oid_common_name[] = szOID_COMMON_NAME;
6091 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6092 (LPBYTE)encodedCommonName };
6093 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6095 SetLastError(0xdeadbeef);
6096 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6097 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6098 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6100 skip("no PKCS7_SIGNER_INFO encode support\n");
6101 return;
6103 ok(!ret && GetLastError() == E_INVALIDARG,
6104 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6105 /* To be encoded, a signer must have an issuer at least, and the encoding
6106 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6107 * see decoding tests.)
6109 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6110 info.Issuer.pbData = encodedCommonNameNoNull;
6111 SetLastError(0xdeadbeef);
6112 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6113 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6114 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6115 ok(!ret && GetLastError() == E_INVALIDARG,
6116 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6117 else
6119 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6120 if (buf)
6122 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6123 if (size == sizeof(minimalPKCSSigner))
6124 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6125 else
6126 ok(0, "Unexpected value\n");
6127 LocalFree(buf);
6130 info.SerialNumber.cbData = sizeof(serialNum);
6131 info.SerialNumber.pbData = (BYTE *)serialNum;
6132 SetLastError(0xdeadbeef);
6133 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6134 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6135 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6136 ok(!ret && GetLastError() == E_INVALIDARG,
6137 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6138 else
6140 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6141 if (buf)
6143 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6144 size);
6145 if (size == sizeof(PKCSSignerWithSerial))
6146 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6147 "Unexpected value\n");
6148 else
6149 ok(0, "Unexpected value\n");
6150 LocalFree(buf);
6153 info.HashAlgorithm.pszObjId = oid1;
6154 SetLastError(0xdeadbeef);
6155 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6156 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6157 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6158 ok(!ret && GetLastError() == E_INVALIDARG,
6159 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6160 else
6162 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6163 if (buf)
6165 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6166 size);
6167 if (size == sizeof(PKCSSignerWithHashAlgo))
6168 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6169 "Unexpected value\n");
6170 else
6171 ok(0, "Unexpected value\n");
6172 LocalFree(buf);
6175 info.HashEncryptionAlgorithm.pszObjId = oid2;
6176 SetLastError(0xdeadbeef);
6177 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6178 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6179 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6180 ok(!ret && GetLastError() == E_INVALIDARG,
6181 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6182 else
6184 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6185 if (buf)
6187 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6188 "Unexpected size %d\n", size);
6189 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6190 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6191 "Unexpected value\n");
6192 else
6193 ok(0, "Unexpected value\n");
6194 LocalFree(buf);
6197 info.EncryptedHash.cbData = sizeof(hash);
6198 info.EncryptedHash.pbData = (BYTE *)hash;
6199 SetLastError(0xdeadbeef);
6200 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6201 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6202 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6203 ok(!ret && GetLastError() == E_INVALIDARG,
6204 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6205 else
6207 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6208 if (buf)
6210 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6211 size);
6212 if (size == sizeof(PKCSSignerWithHash))
6213 ok(!memcmp(buf, PKCSSignerWithHash, size),
6214 "Unexpected value\n");
6215 else
6216 ok(0, "Unexpected value\n");
6217 LocalFree(buf);
6220 info.AuthAttrs.cAttr = 1;
6221 info.AuthAttrs.rgAttr = &attr;
6222 SetLastError(0xdeadbeef);
6223 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6224 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6225 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6226 ok(!ret && GetLastError() == E_INVALIDARG,
6227 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6228 else
6230 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6231 if (buf)
6233 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6234 size);
6235 if (size == sizeof(PKCSSignerWithAuthAttr))
6236 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6237 "Unexpected value\n");
6238 else
6239 ok(0, "Unexpected value\n");
6240 LocalFree(buf);
6245 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6247 BOOL ret;
6248 LPBYTE buf = NULL;
6249 DWORD size = 0;
6250 CMSG_SIGNER_INFO *info;
6252 /* A PKCS signer can't be decoded without a serial number. */
6253 SetLastError(0xdeadbeef);
6254 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6255 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6256 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6257 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
6258 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6259 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6260 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6261 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6262 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6263 if (buf)
6265 info = (CMSG_SIGNER_INFO *)buf;
6266 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6267 info->dwVersion);
6268 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6269 "Unexpected size %d\n", info->Issuer.cbData);
6270 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6271 info->Issuer.cbData), "Unexpected value\n");
6272 ok(info->SerialNumber.cbData == sizeof(serialNum),
6273 "Unexpected size %d\n", info->SerialNumber.cbData);
6274 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6275 "Unexpected value\n");
6276 LocalFree(buf);
6278 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6279 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6280 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6281 if (buf)
6283 info = (CMSG_SIGNER_INFO *)buf;
6284 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6285 info->dwVersion);
6286 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6287 "Unexpected size %d\n", info->Issuer.cbData);
6288 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6289 info->Issuer.cbData), "Unexpected value\n");
6290 ok(info->SerialNumber.cbData == sizeof(serialNum),
6291 "Unexpected size %d\n", info->SerialNumber.cbData);
6292 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6293 "Unexpected value\n");
6294 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6295 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6296 LocalFree(buf);
6298 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6299 PKCSSignerWithHashAndEncryptionAlgo,
6300 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6301 NULL, (BYTE *)&buf, &size);
6302 if (buf)
6304 info = (CMSG_SIGNER_INFO *)buf;
6305 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6306 info->dwVersion);
6307 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6308 "Unexpected size %d\n", info->Issuer.cbData);
6309 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6310 info->Issuer.cbData), "Unexpected value\n");
6311 ok(info->SerialNumber.cbData == sizeof(serialNum),
6312 "Unexpected size %d\n", info->SerialNumber.cbData);
6313 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6314 "Unexpected value\n");
6315 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6316 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6317 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6318 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6319 LocalFree(buf);
6321 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6322 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6323 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6324 if (buf)
6326 info = (CMSG_SIGNER_INFO *)buf;
6327 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6328 info->dwVersion);
6329 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6330 "Unexpected size %d\n", info->Issuer.cbData);
6331 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6332 info->Issuer.cbData), "Unexpected value\n");
6333 ok(info->SerialNumber.cbData == sizeof(serialNum),
6334 "Unexpected size %d\n", info->SerialNumber.cbData);
6335 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6336 "Unexpected value\n");
6337 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6338 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6339 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6340 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6341 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6342 info->EncryptedHash.cbData);
6343 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6344 "Unexpected value\n");
6345 LocalFree(buf);
6347 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6348 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6349 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6350 if (buf)
6352 info = (CMSG_SIGNER_INFO *)buf;
6353 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6354 info->AuthAttrs.cAttr);
6355 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6356 "Expected %s, got %s\n", szOID_COMMON_NAME,
6357 info->AuthAttrs.rgAttr[0].pszObjId);
6358 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6359 info->AuthAttrs.rgAttr[0].cValue);
6360 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6361 sizeof(encodedCommonName), "Unexpected size %d\n",
6362 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6363 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6364 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6365 LocalFree(buf);
6369 static const BYTE CMSSignerWithKeyId[] = {
6370 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6371 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6373 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6375 BOOL ret;
6376 LPBYTE buf = NULL;
6377 DWORD size = 0;
6378 CMSG_CMS_SIGNER_INFO info = { 0 };
6379 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6381 SetLastError(0xdeadbeef);
6382 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6383 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6384 ok(!ret && GetLastError() == E_INVALIDARG,
6385 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6386 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6387 SetLastError(0xdeadbeef);
6388 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6389 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6390 ok(!ret, "Expected failure, got %d\n", ret);
6391 ok(GetLastError() == E_INVALIDARG,
6392 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6393 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6394 * be a key id or a issuer serial number with at least the issuer set, and
6395 * the encoding must include PKCS_7_ASN_ENCODING.
6396 * (That isn't enough to be decoded, see decoding tests.)
6398 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6399 sizeof(encodedCommonNameNoNull);
6400 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6401 SetLastError(0xdeadbeef);
6402 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6403 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6404 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6405 ok(!ret && GetLastError() == E_INVALIDARG,
6406 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6407 else
6409 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6410 if (buf)
6412 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6413 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6414 LocalFree(buf);
6417 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6418 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6419 SetLastError(0xdeadbeef);
6420 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6421 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6422 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6423 ok(!ret && GetLastError() == E_INVALIDARG,
6424 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6425 else
6427 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6428 if (buf)
6430 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6431 size);
6432 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6433 LocalFree(buf);
6436 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6437 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6438 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6439 SetLastError(0xdeadbeef);
6440 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6441 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6442 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6443 ok(!ret && GetLastError() == E_INVALIDARG,
6444 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6445 else
6447 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6448 if (buf)
6450 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6451 size);
6452 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6453 LocalFree(buf);
6456 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6457 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6458 * (see RFC 3852, section 5.3.)
6460 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6461 U(info.SignerId).HashId.cbData = sizeof(hash);
6462 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6463 SetLastError(0xdeadbeef);
6464 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6465 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6466 ok(!ret && GetLastError() == E_INVALIDARG,
6467 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6468 /* Now with a hash algo */
6469 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6470 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6471 sizeof(encodedCommonNameNoNull);
6472 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6473 info.HashAlgorithm.pszObjId = oid1;
6474 SetLastError(0xdeadbeef);
6475 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6476 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6477 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6478 ok(!ret && GetLastError() == E_INVALIDARG,
6479 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6480 else
6482 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6483 if (buf)
6485 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6486 size);
6487 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6488 "Unexpected value\n");
6489 LocalFree(buf);
6492 info.HashEncryptionAlgorithm.pszObjId = oid2;
6493 SetLastError(0xdeadbeef);
6494 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6495 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6496 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6497 ok(!ret && GetLastError() == E_INVALIDARG,
6498 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6499 else
6501 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6502 if (buf)
6504 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6505 "Unexpected size %d\n", size);
6506 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6507 "Unexpected value\n");
6508 LocalFree(buf);
6511 info.EncryptedHash.cbData = sizeof(hash);
6512 info.EncryptedHash.pbData = (BYTE *)hash;
6513 SetLastError(0xdeadbeef);
6514 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6515 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6516 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6517 ok(!ret && GetLastError() == E_INVALIDARG,
6518 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6519 else
6521 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6522 if (buf)
6524 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6525 size);
6526 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6527 LocalFree(buf);
6532 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6534 BOOL ret;
6535 LPBYTE buf = NULL;
6536 DWORD size = 0;
6537 CMSG_CMS_SIGNER_INFO *info;
6538 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6540 /* A CMS signer can't be decoded without a serial number. */
6541 SetLastError(0xdeadbeef);
6542 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6543 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6544 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6545 ok(!ret && GetLastError() == CRYPT_E_ASN1_CORRUPT,
6546 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6547 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6548 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6549 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6550 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6551 if (buf)
6553 info = (CMSG_CMS_SIGNER_INFO *)buf;
6554 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6555 info->dwVersion);
6556 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6557 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6558 info->SignerId.dwIdChoice);
6559 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6560 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6561 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6562 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6563 encodedCommonNameNoNull,
6564 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6565 "Unexpected value\n");
6566 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6567 sizeof(serialNum), "Unexpected size %d\n",
6568 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6569 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6570 serialNum, sizeof(serialNum)), "Unexpected value\n");
6571 LocalFree(buf);
6573 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6574 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6575 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6576 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6577 if (buf)
6579 info = (CMSG_CMS_SIGNER_INFO *)buf;
6580 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6581 info->dwVersion);
6582 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6583 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6584 info->SignerId.dwIdChoice);
6585 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6586 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6587 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6588 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6589 encodedCommonNameNoNull,
6590 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6591 "Unexpected value\n");
6592 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6593 sizeof(serialNum), "Unexpected size %d\n",
6594 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6595 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6596 serialNum, sizeof(serialNum)), "Unexpected value\n");
6597 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6598 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6599 LocalFree(buf);
6601 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6602 PKCSSignerWithHashAndEncryptionAlgo,
6603 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6604 NULL, (BYTE *)&buf, &size);
6605 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6606 if (buf)
6608 info = (CMSG_CMS_SIGNER_INFO *)buf;
6609 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6610 info->dwVersion);
6611 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6612 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6613 info->SignerId.dwIdChoice);
6614 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6615 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6616 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6617 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6618 encodedCommonNameNoNull,
6619 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6620 "Unexpected value\n");
6621 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6622 sizeof(serialNum), "Unexpected size %d\n",
6623 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6624 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6625 serialNum, sizeof(serialNum)), "Unexpected value\n");
6626 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6627 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6628 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6629 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6630 LocalFree(buf);
6632 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6633 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6634 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6635 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6636 if (buf)
6638 info = (CMSG_CMS_SIGNER_INFO *)buf;
6639 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6640 info->dwVersion);
6641 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6642 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6643 info->SignerId.dwIdChoice);
6644 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6645 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6646 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6647 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6648 encodedCommonNameNoNull,
6649 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6650 "Unexpected value\n");
6651 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6652 sizeof(serialNum), "Unexpected size %d\n",
6653 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6654 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6655 serialNum, sizeof(serialNum)), "Unexpected value\n");
6656 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6657 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6658 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6659 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6660 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6661 info->EncryptedHash.cbData);
6662 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6663 "Unexpected value\n");
6664 LocalFree(buf);
6666 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6667 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
6668 CRYPT_DECODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6669 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6670 if (buf)
6672 info = (CMSG_CMS_SIGNER_INFO *)buf;
6673 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6674 info->dwVersion);
6675 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
6676 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
6677 info->SignerId.dwIdChoice);
6678 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
6679 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
6680 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
6681 "Unexpected value\n");
6682 LocalFree(buf);
6686 static BYTE emptyDNSPermittedConstraints[] = {
6687 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
6688 static BYTE emptyDNSExcludedConstraints[] = {
6689 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
6690 static BYTE DNSExcludedConstraints[] = {
6691 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
6692 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6693 static BYTE permittedAndExcludedConstraints[] = {
6694 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6695 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
6696 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6697 static BYTE permittedAndExcludedWithMinConstraints[] = {
6698 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6699 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
6700 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6701 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
6702 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
6703 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
6704 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
6706 static void test_encodeNameConstraints(DWORD dwEncoding)
6708 BOOL ret;
6709 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
6710 CERT_GENERAL_SUBTREE permitted = { { 0 } };
6711 CERT_GENERAL_SUBTREE excluded = { { 0 } };
6712 LPBYTE buf;
6713 DWORD size;
6715 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6716 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6717 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6719 skip("no X509_NAME_CONSTRAINTS encode support\n");
6720 return;
6722 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6723 if (ret)
6725 ok(size == sizeof(emptySequence), "Unexpected size\n");
6726 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
6727 LocalFree(buf);
6729 constraints.cPermittedSubtree = 1;
6730 constraints.rgPermittedSubtree = &permitted;
6731 SetLastError(0xdeadbeef);
6732 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6733 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6734 ok(!ret && GetLastError() == E_INVALIDARG,
6735 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6736 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6737 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6738 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6739 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6740 if (ret)
6742 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
6743 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
6744 "Unexpected value\n");
6745 LocalFree(buf);
6747 constraints.cPermittedSubtree = 0;
6748 constraints.cExcludedSubtree = 1;
6749 constraints.rgExcludedSubtree = &excluded;
6750 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
6751 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6752 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6753 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6754 if (ret)
6756 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
6757 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
6758 "Unexpected value\n");
6759 LocalFree(buf);
6761 U(excluded.Base).pwszURL = (LPWSTR)url;
6762 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6763 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6764 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6765 if (ret)
6767 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
6768 ok(!memcmp(buf, DNSExcludedConstraints, size),
6769 "Unexpected value\n");
6770 LocalFree(buf);
6772 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
6773 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6774 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6775 constraints.cPermittedSubtree = 1;
6776 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6777 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6778 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6779 if (ret)
6781 ok(size == sizeof(permittedAndExcludedConstraints),
6782 "Unexpected size\n");
6783 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
6784 "Unexpected value\n");
6785 LocalFree(buf);
6787 permitted.dwMinimum = 5;
6788 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6789 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6790 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6791 if (ret)
6793 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
6794 "Unexpected size\n");
6795 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
6796 "Unexpected value\n");
6797 LocalFree(buf);
6799 permitted.fMaximum = TRUE;
6800 permitted.dwMaximum = 3;
6801 SetLastError(0xdeadbeef);
6802 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
6803 CRYPT_ENCODE_ALLOC_FLAG, NULL, (BYTE *)&buf, &size);
6804 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6805 if (ret)
6807 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
6808 "Unexpected size\n");
6809 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
6810 "Unexpected value\n");
6811 LocalFree(buf);
6815 struct EncodedNameConstraints
6817 CRYPT_DATA_BLOB encoded;
6818 CERT_NAME_CONSTRAINTS_INFO constraints;
6821 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
6822 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6823 static CERT_GENERAL_SUBTREE DNSSubtree = {
6824 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
6825 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
6826 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
6827 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
6828 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
6829 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
6830 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
6832 struct EncodedNameConstraints encodedNameConstraints[] = {
6833 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
6834 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
6835 { 1, &emptyDNSSubtree, 0, NULL } },
6836 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
6837 { 0, NULL, 1, &emptyDNSSubtree } },
6838 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
6839 { 0, NULL, 1, &DNSSubtree } },
6840 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
6841 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
6842 { { sizeof(permittedAndExcludedWithMinConstraints),
6843 permittedAndExcludedWithMinConstraints },
6844 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
6845 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
6846 permittedAndExcludedWithMinMaxConstraints },
6847 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
6850 static void test_decodeNameConstraints(DWORD dwEncoding)
6852 BOOL ret;
6853 DWORD i;
6854 CERT_NAME_CONSTRAINTS_INFO *constraints;
6856 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
6857 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6858 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6859 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6860 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6861 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
6862 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
6863 for (i = 0;
6864 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
6865 i++)
6867 DWORD size;
6869 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
6870 encodedNameConstraints[i].encoded.pbData,
6871 encodedNameConstraints[i].encoded.cbData,
6872 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
6873 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6875 skip("no X509_NAME_CONSTRAINTS decode support\n");
6876 return;
6878 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
6879 if (ret)
6881 DWORD j;
6883 if (constraints->cPermittedSubtree !=
6884 encodedNameConstraints[i].constraints.cPermittedSubtree)
6885 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
6886 encodedNameConstraints[i].constraints.cPermittedSubtree,
6887 constraints->cPermittedSubtree);
6888 if (constraints->cPermittedSubtree ==
6889 encodedNameConstraints[i].constraints.cPermittedSubtree)
6891 for (j = 0; j < constraints->cPermittedSubtree; j++)
6893 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
6894 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
6897 if (constraints->cExcludedSubtree !=
6898 encodedNameConstraints[i].constraints.cExcludedSubtree)
6899 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
6900 encodedNameConstraints[i].constraints.cExcludedSubtree,
6901 constraints->cExcludedSubtree);
6902 if (constraints->cExcludedSubtree ==
6903 encodedNameConstraints[i].constraints.cExcludedSubtree)
6905 for (j = 0; j < constraints->cExcludedSubtree; j++)
6907 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
6908 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
6911 LocalFree(constraints);
6916 /* Free *pInfo with HeapFree */
6917 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
6919 BOOL ret;
6920 DWORD size = 0;
6921 HCRYPTKEY key;
6923 /* This crashes
6924 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
6926 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
6927 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6928 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6929 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
6930 &size);
6931 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6932 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6933 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
6934 NULL, &size);
6935 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6936 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6937 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
6938 0, NULL, NULL, &size);
6939 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
6940 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
6941 /* Test with no key */
6942 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
6943 0, NULL, NULL, &size);
6944 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
6945 GetLastError());
6946 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
6947 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
6948 if (ret)
6950 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
6951 NULL, 0, NULL, NULL, &size);
6952 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
6953 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
6954 if (*pInfo)
6956 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
6957 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
6958 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
6959 GetLastError());
6960 if (ret)
6962 /* By default (we passed NULL as the OID) the OID is
6963 * szOID_RSA_RSA.
6965 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
6966 "Expected %s, got %s\n", szOID_RSA_RSA,
6967 (*pInfo)->Algorithm.pszObjId);
6971 CryptDestroyKey(key);
6974 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
6975 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
6976 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
6977 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
6978 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
6979 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
6980 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
6981 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
6982 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
6983 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
6984 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
6985 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
6986 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
6987 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
6988 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
6989 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
6990 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
6991 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
6992 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
6993 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
6994 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
6995 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
6996 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
6997 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
6998 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7000 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7002 BOOL ret;
7003 HCRYPTKEY key;
7004 PCCERT_CONTEXT context;
7005 DWORD dwSize;
7006 ALG_ID ai;
7008 /* These crash
7009 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7010 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7011 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7012 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7013 NULL);
7015 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7016 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7017 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7018 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7019 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7020 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7021 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7022 &key);
7023 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7024 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7026 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7027 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7028 &key);
7029 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7031 dwSize = sizeof(ai);
7032 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7033 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7034 if(ret)
7036 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7037 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7040 CryptDestroyKey(key);
7042 /* Repeat with forced algorithm */
7043 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7044 &key);
7045 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7047 dwSize = sizeof(ai);
7048 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7049 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7050 if(ret)
7052 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7053 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7056 CryptDestroyKey(key);
7058 /* Test importing a public key from a certificate context */
7059 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7060 sizeof(expiredCert));
7061 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7062 GetLastError());
7063 if (context)
7065 ok(!strcmp(szOID_RSA_RSA,
7066 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7067 "Expected %s, got %s\n", szOID_RSA_RSA,
7068 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7069 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7070 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7071 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7072 CryptDestroyKey(key);
7073 CertFreeCertificateContext(context);
7077 static const char cspName[] = "WineCryptTemp";
7079 static void testPortPublicKeyInfo(void)
7081 HCRYPTPROV csp;
7082 BOOL ret;
7083 PCERT_PUBLIC_KEY_INFO info = NULL;
7085 /* Just in case a previous run failed, delete this thing */
7086 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7087 CRYPT_DELETEKEYSET);
7088 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7089 CRYPT_NEWKEYSET);
7091 testExportPublicKey(csp, &info);
7092 testImportPublicKey(csp, info);
7094 HeapFree(GetProcessHeap(), 0, info);
7095 CryptReleaseContext(csp, 0);
7096 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
7097 CRYPT_DELETEKEYSET);
7100 START_TEST(encode)
7102 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
7103 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
7104 HMODULE hCrypt32;
7105 DWORD i;
7107 hCrypt32 = GetModuleHandleA("crypt32.dll");
7108 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
7109 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
7110 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
7112 skip("CryptDecodeObjectEx() is not available\n");
7113 return;
7116 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
7118 test_encodeInt(encodings[i]);
7119 test_decodeInt(encodings[i]);
7120 test_encodeEnumerated(encodings[i]);
7121 test_decodeEnumerated(encodings[i]);
7122 test_encodeFiletime(encodings[i]);
7123 test_decodeFiletime(encodings[i]);
7124 test_encodeName(encodings[i]);
7125 test_decodeName(encodings[i]);
7126 test_encodeUnicodeName(encodings[i]);
7127 test_decodeUnicodeName(encodings[i]);
7128 test_encodeNameValue(encodings[i]);
7129 test_decodeNameValue(encodings[i]);
7130 test_encodeUnicodeNameValue(encodings[i]);
7131 test_decodeUnicodeNameValue(encodings[i]);
7132 test_encodeAltName(encodings[i]);
7133 test_decodeAltName(encodings[i]);
7134 test_encodeOctets(encodings[i]);
7135 test_decodeOctets(encodings[i]);
7136 test_encodeBits(encodings[i]);
7137 test_decodeBits(encodings[i]);
7138 test_encodeBasicConstraints(encodings[i]);
7139 test_decodeBasicConstraints(encodings[i]);
7140 test_encodeRsaPublicKey(encodings[i]);
7141 test_decodeRsaPublicKey(encodings[i]);
7142 test_encodeSequenceOfAny(encodings[i]);
7143 test_decodeSequenceOfAny(encodings[i]);
7144 test_encodeExtensions(encodings[i]);
7145 test_decodeExtensions(encodings[i]);
7146 test_encodePublicKeyInfo(encodings[i]);
7147 test_decodePublicKeyInfo(encodings[i]);
7148 test_encodeCertToBeSigned(encodings[i]);
7149 test_decodeCertToBeSigned(encodings[i]);
7150 test_encodeCert(encodings[i]);
7151 test_decodeCert(encodings[i]);
7152 test_encodeCRLDistPoints(encodings[i]);
7153 test_decodeCRLDistPoints(encodings[i]);
7154 test_encodeCRLIssuingDistPoint(encodings[i]);
7155 test_decodeCRLIssuingDistPoint(encodings[i]);
7156 test_encodeCRLToBeSigned(encodings[i]);
7157 test_decodeCRLToBeSigned(encodings[i]);
7158 test_encodeEnhancedKeyUsage(encodings[i]);
7159 test_decodeEnhancedKeyUsage(encodings[i]);
7160 test_encodeAuthorityKeyId(encodings[i]);
7161 test_decodeAuthorityKeyId(encodings[i]);
7162 test_encodeAuthorityKeyId2(encodings[i]);
7163 test_decodeAuthorityKeyId2(encodings[i]);
7164 test_encodeAuthorityInfoAccess(encodings[i]);
7165 test_decodeAuthorityInfoAccess(encodings[i]);
7166 test_encodeCTL(encodings[i]);
7167 test_decodeCTL(encodings[i]);
7168 test_encodePKCSContentInfo(encodings[i]);
7169 test_decodePKCSContentInfo(encodings[i]);
7170 test_encodePKCSAttribute(encodings[i]);
7171 test_decodePKCSAttribute(encodings[i]);
7172 test_encodePKCSAttributes(encodings[i]);
7173 test_decodePKCSAttributes(encodings[i]);
7174 test_encodePKCSSMimeCapabilities(encodings[i]);
7175 test_decodePKCSSMimeCapabilities(encodings[i]);
7176 test_encodePKCSSignerInfo(encodings[i]);
7177 test_decodePKCSSignerInfo(encodings[i]);
7178 test_encodeCMSSignerInfo(encodings[i]);
7179 test_decodeCMSSignerInfo(encodings[i]);
7180 test_encodeNameConstraints(encodings[i]);
7181 test_decodeNameConstraints(encodings[i]);
7183 testPortPublicKeyInfo();