push 5bc4839baba05cc4333240c25295b8dd6e351557
[wine/hacks.git] / dlls / crypt32 / tests / encode.c
blobf2fc7275a55b85506590f83602e69547e3169bce
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 if (0)
107 /* check with NULL integer buffer. Windows XP incorrectly returns an
108 * NTSTATUS (crashes on win9x).
110 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, NULL, NULL,
111 &bufSize);
112 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
113 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
115 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
117 /* encode as normal integer */
118 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 0,
119 NULL, NULL, &bufSize);
120 ok(ret, "Expected success, got %d\n", GetLastError());
121 ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val,
122 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
123 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
124 if (buf)
126 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
127 buf[0]);
128 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
129 buf[1], ints[i].encoded[1]);
130 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
131 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
132 LocalFree(buf);
134 /* encode as multibyte integer */
135 blob.cbData = sizeof(ints[i].val);
136 blob.pbData = (BYTE *)&ints[i].val;
137 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
138 0, NULL, NULL, &bufSize);
139 ok(ret, "Expected success, got %d\n", GetLastError());
140 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
141 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
142 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
143 if (buf)
145 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
146 buf[0]);
147 ok(buf[1] == ints[i].encoded[1], "Got length %d, expected %d\n",
148 buf[1], ints[i].encoded[1]);
149 ok(!memcmp(buf + 1, ints[i].encoded + 1, ints[i].encoded[1] + 1),
150 "Encoded value of 0x%08x didn't match expected\n", ints[i].val);
151 LocalFree(buf);
154 /* encode a couple bigger ints, just to show it's little-endian and leading
155 * sign bytes are dropped
157 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
159 blob.cbData = strlen((const char*)bigInts[i].val);
160 blob.pbData = (BYTE *)bigInts[i].val;
161 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
162 0, NULL, NULL, &bufSize);
163 ok(ret, "Expected success, got %d\n", GetLastError());
164 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, &blob,
165 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
166 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
167 if (buf)
169 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
170 buf[0]);
171 ok(buf[1] == bigInts[i].encoded[1], "Got length %d, expected %d\n",
172 buf[1], bigInts[i].encoded[1]);
173 ok(!memcmp(buf + 1, bigInts[i].encoded + 1,
174 bigInts[i].encoded[1] + 1),
175 "Encoded value didn't match expected\n");
176 LocalFree(buf);
179 /* and, encode some uints */
180 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
182 blob.cbData = strlen((const char*)bigUInts[i].val);
183 blob.pbData = (BYTE*)bigUInts[i].val;
184 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
185 0, NULL, NULL, &bufSize);
186 ok(ret, "Expected success, got %d\n", GetLastError());
187 ret = pCryptEncodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT, &blob,
188 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
189 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
190 if (buf)
192 ok(buf[0] == 2, "Got unexpected type %d for integer (expected 2)\n",
193 buf[0]);
194 ok(buf[1] == bigUInts[i].encoded[1], "Got length %d, expected %d\n",
195 buf[1], bigUInts[i].encoded[1]);
196 ok(!memcmp(buf + 1, bigUInts[i].encoded + 1,
197 bigUInts[i].encoded[1] + 1),
198 "Encoded value didn't match expected\n");
199 LocalFree(buf);
204 static void test_decodeInt(DWORD dwEncoding)
206 static const BYTE bigInt[] = { 2, 5, 0xff, 0xfe, 0xff, 0xfe, 0xff };
207 static const BYTE testStr[] = { 0x16, 4, 't', 'e', 's', 't' };
208 static const BYTE longForm[] = { 2, 0x81, 0x01, 0x01 };
209 static const BYTE bigBogus[] = { 0x02, 0x84, 0x01, 0xff, 0xff, 0xf9 };
210 static const BYTE extraBytes[] = { 2, 1, 1, 0, 0, 0, 0 };
211 BYTE *buf = NULL;
212 DWORD bufSize = 0;
213 int i;
214 BOOL ret;
216 /* CryptDecodeObjectEx with NULL bufSize crashes..
217 ret = pCryptDecodeObjectEx(3, X509_INTEGER, &ints[0].encoded,
218 ints[0].encoded[1] + 2, 0, NULL, NULL, NULL);
220 /* check bogus encoding */
221 ret = pCryptDecodeObjectEx(3, X509_INTEGER, (BYTE *)&ints[0].encoded,
222 ints[0].encoded[1] + 2, 0, NULL, NULL, &bufSize);
223 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
224 "Expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
225 /* check with NULL integer buffer */
226 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, NULL, 0, 0, NULL, NULL,
227 &bufSize);
228 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
229 GetLastError() == OSS_BAD_ARG /* Win9x */),
230 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
231 /* check with a valid, but too large, integer */
232 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, bigInt, bigInt[1] + 2,
233 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
234 ok((!ret && GetLastError() == CRYPT_E_ASN1_LARGE) ||
235 broken(ret) /* Win9x */,
236 "Expected CRYPT_E_ASN1_LARGE, got %d\n", GetLastError());
237 /* check with a DER-encoded string */
238 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, testStr, testStr[1] + 2,
239 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
240 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
241 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
242 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
243 GetLastError());
244 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
246 /* When the output buffer is NULL, this always succeeds */
247 SetLastError(0xdeadbeef);
248 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
249 ints[i].encoded, ints[i].encoded[1] + 2, 0, NULL, NULL,
250 &bufSize);
251 ok(ret && GetLastError() == NOERROR,
252 "Expected success and NOERROR, got %d\n", GetLastError());
253 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER,
254 ints[i].encoded, ints[i].encoded[1] + 2,
255 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
256 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
257 ok(bufSize == sizeof(int), "Wrong size %d\n", bufSize);
258 ok(buf != NULL, "Expected allocated buffer\n");
259 if (buf)
261 ok(!memcmp(buf, &ints[i].val, bufSize), "Expected %d, got %d\n",
262 ints[i].val, *(int *)buf);
263 LocalFree(buf);
266 for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
268 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
269 bigInts[i].encoded, bigInts[i].encoded[1] + 2, 0, NULL, NULL,
270 &bufSize);
271 ok(ret && GetLastError() == NOERROR,
272 "Expected success and NOERROR, got %d\n", GetLastError());
273 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
274 bigInts[i].encoded, bigInts[i].encoded[1] + 2,
275 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
276 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
277 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
278 ok(buf != NULL, "Expected allocated buffer\n");
279 if (buf)
281 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
283 ok(blob->cbData == strlen((const char*)bigInts[i].decoded),
284 "Expected len %d, got %d\n", lstrlenA((const char*)bigInts[i].decoded),
285 blob->cbData);
286 ok(!memcmp(blob->pbData, bigInts[i].decoded, blob->cbData),
287 "Unexpected value\n");
288 LocalFree(buf);
291 for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
293 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
294 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 0, NULL, NULL,
295 &bufSize);
296 ok(ret && GetLastError() == NOERROR,
297 "Expected success and NOERROR, got %d\n", GetLastError());
298 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
299 bigUInts[i].encoded, bigUInts[i].encoded[1] + 2,
300 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
301 ok(ret, "CryptDecodeObjectEx failed: %d\n", GetLastError());
302 ok(bufSize >= sizeof(CRYPT_INTEGER_BLOB), "Wrong size %d\n", bufSize);
303 ok(buf != NULL, "Expected allocated buffer\n");
304 if (buf)
306 CRYPT_INTEGER_BLOB *blob = (CRYPT_INTEGER_BLOB *)buf;
308 ok(blob->cbData == strlen((const char*)bigUInts[i].val),
309 "Expected len %d, got %d\n", lstrlenA((const char*)bigUInts[i].val),
310 blob->cbData);
311 ok(!memcmp(blob->pbData, bigUInts[i].val, blob->cbData),
312 "Unexpected value\n");
313 LocalFree(buf);
316 /* Decode the value 1 with long-form length */
317 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, longForm,
318 sizeof(longForm), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
319 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
320 if (buf)
322 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
323 LocalFree(buf);
325 /* check with extra bytes at the end */
326 ret = pCryptDecodeObjectEx(dwEncoding, X509_INTEGER, extraBytes,
327 sizeof(extraBytes), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
328 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
329 if (buf)
331 ok(*(int *)buf == 1, "Expected 1, got %d\n", *(int *)buf);
332 LocalFree(buf);
334 /* Try to decode some bogus large items */
335 /* The buffer size is smaller than the encoded length, so this should fail
336 * with CRYPT_E_ASN1_EOD if it's being decoded.
337 * Under XP it fails with CRYPT_E_ASN1_LARGE, which means there's a limit
338 * on the size decoded, but in ME it fails with CRYPT_E_ASN1_EOD or crashes.
339 * So this test unfortunately isn't useful.
340 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, tooBig,
341 0x7fffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
342 ok(!ret && GetLastError() == CRYPT_E_ASN1_LARGE,
343 "Expected CRYPT_E_ASN1_LARGE, got %08x\n", GetLastError());
345 /* This will try to decode the buffer and overflow it, check that it's
346 * caught.
348 if (0)
350 /* a large buffer isn't guaranteed to crash, it depends on memory allocation order */
351 ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER, bigBogus,
352 0x01ffffff, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
353 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
354 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
358 static const BYTE bin18[] = {0x0a,0x01,0x01};
359 static const BYTE bin19[] = {0x0a,0x05,0x00,0xff,0xff,0xff,0x80};
361 /* These are always encoded unsigned, and aren't constrained to be any
362 * particular value
364 static const struct encodedInt enums[] = {
365 { 1, bin18 },
366 { -128, bin19 },
369 /* X509_CRL_REASON_CODE is also an enumerated type, but it's #defined to
370 * X509_ENUMERATED.
372 static const LPCSTR enumeratedTypes[] = { X509_ENUMERATED,
373 szOID_CRL_REASON_CODE };
375 static void test_encodeEnumerated(DWORD dwEncoding)
377 DWORD i, j;
379 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
381 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
383 BOOL ret;
384 BYTE *buf = NULL;
385 DWORD bufSize = 0;
387 ret = pCryptEncodeObjectEx(dwEncoding, enumeratedTypes[i],
388 &enums[j].val, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
389 &bufSize);
390 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
391 if (buf)
393 ok(buf[0] == 0xa,
394 "Got unexpected type %d for enumerated (expected 0xa)\n",
395 buf[0]);
396 ok(buf[1] == enums[j].encoded[1],
397 "Got length %d, expected %d\n", buf[1], enums[j].encoded[1]);
398 ok(!memcmp(buf + 1, enums[j].encoded + 1,
399 enums[j].encoded[1] + 1),
400 "Encoded value of 0x%08x didn't match expected\n",
401 enums[j].val);
402 LocalFree(buf);
408 static void test_decodeEnumerated(DWORD dwEncoding)
410 DWORD i, j;
412 for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
414 for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
416 BOOL ret;
417 DWORD bufSize = sizeof(int);
418 int val;
420 ret = pCryptDecodeObjectEx(dwEncoding, enumeratedTypes[i],
421 enums[j].encoded, enums[j].encoded[1] + 2, 0, NULL,
422 &val, &bufSize);
423 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
424 ok(bufSize == sizeof(int),
425 "Got unexpected size %d for enumerated\n", bufSize);
426 ok(val == enums[j].val, "Unexpected value %d, expected %d\n",
427 val, enums[j].val);
432 struct encodedFiletime
434 SYSTEMTIME sysTime;
435 const BYTE *encodedTime;
438 static void testTimeEncoding(DWORD dwEncoding, LPCSTR structType,
439 const struct encodedFiletime *time)
441 FILETIME ft = { 0 };
442 BYTE *buf = NULL;
443 DWORD bufSize = 0;
444 BOOL ret;
446 ret = SystemTimeToFileTime(&time->sysTime, &ft);
447 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
448 ret = pCryptEncodeObjectEx(dwEncoding, structType, &ft,
449 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
450 /* years other than 1950-2050 are not allowed for encodings other than
451 * X509_CHOICE_OF_TIME.
453 if (structType == X509_CHOICE_OF_TIME ||
454 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
456 ok(ret, "CryptEncodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
457 GetLastError());
458 ok(buf != NULL, "Expected an allocated buffer\n");
459 if (buf)
461 ok(buf[0] == time->encodedTime[0],
462 "Expected type 0x%02x, got 0x%02x\n", time->encodedTime[0],
463 buf[0]);
464 ok(buf[1] == time->encodedTime[1], "Expected %d bytes, got %d\n",
465 time->encodedTime[1], bufSize);
466 ok(!memcmp(time->encodedTime + 2, buf + 2, time->encodedTime[1]),
467 "Got unexpected value for time encoding\n");
468 LocalFree(buf);
471 else
472 ok((!ret && GetLastError() == CRYPT_E_BAD_ENCODE) ||
473 broken(GetLastError() == ERROR_SUCCESS),
474 "Expected CRYPT_E_BAD_ENCODE, got 0x%08x\n", GetLastError());
477 static const char *printSystemTime(const SYSTEMTIME *st)
479 static char buf[25];
481 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st->wMonth, st->wDay,
482 st->wYear, st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
483 return buf;
486 static const char *printFileTime(const FILETIME *ft)
488 static char buf[25];
489 SYSTEMTIME st;
491 FileTimeToSystemTime(ft, &st);
492 sprintf(buf, "%02d-%02d-%04d %02d:%02d:%02d.%03d", st.wMonth, st.wDay,
493 st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
494 return buf;
497 static void compareTime(const SYSTEMTIME *expected, const FILETIME *got)
499 SYSTEMTIME st;
501 FileTimeToSystemTime(got, &st);
502 ok((expected->wYear == st.wYear &&
503 expected->wMonth == st.wMonth &&
504 expected->wDay == st.wDay &&
505 expected->wHour == st.wHour &&
506 expected->wMinute == st.wMinute &&
507 expected->wSecond == st.wSecond &&
508 abs(expected->wMilliseconds - st.wMilliseconds) <= 1) ||
509 /* Some Windows systems only seem to be accurate in their time decoding to
510 * within about an hour.
512 broken(expected->wYear == st.wYear &&
513 expected->wMonth == st.wMonth &&
514 expected->wDay == st.wDay &&
515 abs(expected->wHour - st.wHour) <= 1),
516 "Got unexpected value for time decoding:\nexpected %s, got %s\n",
517 printSystemTime(expected), printFileTime(got));
520 static void testTimeDecoding(DWORD dwEncoding, LPCSTR structType,
521 const struct encodedFiletime *time)
523 FILETIME ft = { 0 };
524 DWORD size = sizeof(ft);
525 BOOL ret;
527 ret = pCryptDecodeObjectEx(dwEncoding, structType, time->encodedTime,
528 time->encodedTime[1] + 2, 0, NULL, &ft, &size);
529 /* years other than 1950-2050 are not allowed for encodings other than
530 * X509_CHOICE_OF_TIME.
532 if (structType == X509_CHOICE_OF_TIME ||
533 (time->sysTime.wYear >= 1950 && time->sysTime.wYear <= 2050))
535 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
536 "CryptDecodeObjectEx failed: %d (0x%08x)\n", GetLastError(),
537 GetLastError());
538 if (ret)
539 compareTime(&time->sysTime, &ft);
541 else
542 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
543 GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
544 "Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
545 GetLastError());
548 static const BYTE bin20[] = {
549 0x17,0x0d,'0','5','0','6','0','6','1','6','1','0','0','0','Z'};
550 static const BYTE bin21[] = {
551 0x18,0x0f,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
552 static const BYTE bin22[] = {
553 0x18,0x0f,'2','1','4','5','0','6','0','6','1','6','1','0','0','0','Z'};
555 static const struct encodedFiletime times[] = {
556 { { 2005, 6, 1, 6, 16, 10, 0, 0 }, bin20 },
557 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin21 },
558 { { 2145, 6, 1, 6, 16, 10, 0, 0 }, bin22 },
561 static void test_encodeFiletime(DWORD dwEncoding)
563 DWORD i;
565 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
567 testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
568 testTimeEncoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
569 testTimeEncoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
573 static const BYTE bin23[] = {
574 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','0','0','0','Z'};
575 static const BYTE bin24[] = {
576 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','.','9','9','9','Z'};
577 static const BYTE bin25[] = {
578 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','+','0','1','0','0'};
579 static const BYTE bin26[] = {
580 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','0','0'};
581 static const BYTE bin27[] = {
582 0x18,0x13,'1','9','4','5','0','6','0','6','1','6','1','0','0','0','-','0','1','1','5'};
583 static const BYTE bin28[] = {
584 0x18,0x0a,'2','1','4','5','0','6','0','6','1','6'};
585 static const BYTE bin29[] = {
586 0x17,0x0a,'4','5','0','6','0','6','1','6','1','0'};
587 static const BYTE bin30[] = {
588 0x17,0x0b,'4','5','0','6','0','6','1','6','1','0','Z'};
589 static const BYTE bin31[] = {
590 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','+','0','1'};
591 static const BYTE bin32[] = {
592 0x17,0x0d,'4','5','0','6','0','6','1','6','1','0','-','0','1'};
593 static const BYTE bin33[] = {
594 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','+','0','1','0','0'};
595 static const BYTE bin34[] = {
596 0x17,0x0f,'4','5','0','6','0','6','1','6','1','0','-','0','1','0','0'};
597 static const BYTE bin35[] = {
598 0x17,0x08, '4','5','0','6','0','6','1','6'};
599 static const BYTE bin36[] = {
600 0x18,0x0f, 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','Z'};
601 static const BYTE bin37[] = {
602 0x18,0x04, '2','1','4','5'};
603 static const BYTE bin38[] = {
604 0x18,0x08, '2','1','4','5','0','6','0','6'};
606 static void test_decodeFiletime(DWORD dwEncoding)
608 static const struct encodedFiletime otherTimes[] = {
609 { { 1945, 6, 1, 6, 16, 10, 0, 0 }, bin23 },
610 { { 1945, 6, 1, 6, 16, 10, 0, 999 }, bin24 },
611 { { 1945, 6, 1, 6, 17, 10, 0, 0 }, bin25 },
612 { { 1945, 6, 1, 6, 15, 10, 0, 0 }, bin26 },
613 { { 1945, 6, 1, 6, 14, 55, 0, 0 }, bin27 },
614 { { 2145, 6, 1, 6, 16, 0, 0, 0 }, bin28 },
615 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin29 },
616 { { 2045, 6, 1, 6, 16, 10, 0, 0 }, bin30 },
617 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin31 },
618 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin32 },
619 { { 2045, 6, 1, 6, 17, 10, 0, 0 }, bin33 },
620 { { 2045, 6, 1, 6, 15, 10, 0, 0 }, bin34 },
622 /* An oddball case that succeeds in Windows, but doesn't seem correct
623 { { 2145, 6, 1, 2, 11, 31, 0, 0 }, "\x18" "\x13" "21450606161000-9999" },
625 static const unsigned char *bogusTimes[] = {
626 /* oddly, this succeeds on Windows, with year 2765
627 "\x18" "\x0f" "21r50606161000Z",
629 bin35,
630 bin36,
631 bin37,
632 bin38,
634 DWORD i, size;
635 FILETIME ft1 = { 0 }, ft2 = { 0 };
636 BOOL ret;
638 /* Check bogus length with non-NULL buffer */
639 ret = SystemTimeToFileTime(&times[0].sysTime, &ft1);
640 ok(ret, "SystemTimeToFileTime failed: %d\n", GetLastError());
641 size = 1;
642 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
643 times[0].encodedTime, times[0].encodedTime[1] + 2, 0, NULL, &ft2, &size);
644 ok(!ret && GetLastError() == ERROR_MORE_DATA,
645 "Expected ERROR_MORE_DATA, got %d\n", GetLastError());
646 /* Normal tests */
647 for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
649 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &times[i]);
650 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &times[i]);
651 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &times[i]);
653 for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
655 testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
656 testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
657 testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
659 for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
661 size = sizeof(ft1);
662 ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
663 bogusTimes[i], bogusTimes[i][1] + 2, 0, NULL, &ft1, &size);
664 ok((!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
665 GetLastError() == OSS_DATA_ERROR /* Win9x */)) ||
666 broken(ret), /* Win9x and NT4 for bin38 */
667 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
668 GetLastError());
672 static const char commonName[] = "Juan Lang";
673 static const char surName[] = "Lang";
675 static const BYTE emptySequence[] = { 0x30, 0 };
676 static const BYTE emptyRDNs[] = { 0x30, 0x02, 0x31, 0 };
677 static const BYTE twoRDNs[] = {
678 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
679 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
680 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0};
681 static const BYTE encodedTwoRDNs[] = {
682 0x30,0x2e,0x31,0x2c,0x30,0x2a,0x06,0x03,0x55,0x04,0x03,0x30,0x23,0x31,0x21,
683 0x30,0x0c,0x06,0x03,0x55,0x04,0x04,0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,
684 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
685 0x6e,0x67,0x00,
688 static const BYTE us[] = { 0x55, 0x53 };
689 static const BYTE minnesota[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x73, 0x6f,
690 0x74, 0x61 };
691 static const BYTE minneapolis[] = { 0x4d, 0x69, 0x6e, 0x6e, 0x65, 0x61, 0x70,
692 0x6f, 0x6c, 0x69, 0x73 };
693 static const BYTE codeweavers[] = { 0x43, 0x6f, 0x64, 0x65, 0x57, 0x65, 0x61,
694 0x76, 0x65, 0x72, 0x73 };
695 static const BYTE wine[] = { 0x57, 0x69, 0x6e, 0x65, 0x20, 0x44, 0x65, 0x76,
696 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74 };
697 static const BYTE localhostAttr[] = { 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
698 0x73, 0x74 };
699 static const BYTE aric[] = { 0x61, 0x72, 0x69, 0x63, 0x40, 0x63, 0x6f, 0x64,
700 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63, 0x6f, 0x6d };
702 #define RDNA(arr) oid_ ## arr, CERT_RDN_PRINTABLE_STRING, { sizeof(arr), (LPBYTE)arr }
703 #define RDNIA5(arr) oid_ ## arr, CERT_RDN_IA5_STRING, { sizeof(arr), (LPBYTE)arr }
705 static CHAR oid_us[] = "2.5.4.6",
706 oid_minnesota[] = "2.5.4.8",
707 oid_minneapolis[] = "2.5.4.7",
708 oid_codeweavers[] = "2.5.4.10",
709 oid_wine[] = "2.5.4.11",
710 oid_localhostAttr[] = "2.5.4.3",
711 oid_aric[] = "1.2.840.113549.1.9.1";
712 static CERT_RDN_ATTR rdnAttrs[] = { { RDNA(us) },
713 { RDNA(minnesota) },
714 { RDNA(minneapolis) },
715 { RDNA(codeweavers) },
716 { RDNA(wine) },
717 { RDNA(localhostAttr) },
718 { RDNIA5(aric) } };
719 static CERT_RDN_ATTR decodedRdnAttrs[] = { { RDNA(us) },
720 { RDNA(localhostAttr) },
721 { RDNA(minnesota) },
722 { RDNA(minneapolis) },
723 { RDNA(codeweavers) },
724 { RDNA(wine) },
725 { RDNIA5(aric) } };
727 #undef RDNIA5
728 #undef RDNA
730 static const BYTE encodedRDNAttrs[] = {
731 0x30,0x81,0x96,0x31,0x81,0x93,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
732 0x53,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x6c,0x6f,0x63,0x61,0x6c,0x68,
733 0x6f,0x73,0x74,0x30,0x10,0x06,0x03,0x55,0x04,0x08,0x13,0x09,0x4d,0x69,0x6e,0x6e,
734 0x65,0x73,0x6f,0x74,0x61,0x30,0x12,0x06,0x03,0x55,0x04,0x07,0x13,0x0b,0x4d,0x69,
735 0x6e,0x6e,0x65,0x61,0x70,0x6f,0x6c,0x69,0x73,0x30,0x12,0x06,0x03,0x55,0x04,0x0a,
736 0x13,0x0b,0x43,0x6f,0x64,0x65,0x57,0x65,0x61,0x76,0x65,0x72,0x73,0x30,0x17,0x06,
737 0x03,0x55,0x04,0x0b,0x13,0x10,0x57,0x69,0x6e,0x65,0x20,0x44,0x65,0x76,0x65,0x6c,
738 0x6f,0x70,0x6d,0x65,0x6e,0x74,0x30,0x21,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
739 0x01,0x09,0x01,0x16,0x14,0x61,0x72,0x69,0x63,0x40,0x63,0x6f,0x64,0x65,0x77,0x65,
740 0x61,0x76,0x65,0x72,0x73,0x2e,0x63,0x6f,0x6d
743 static void test_encodeName(DWORD dwEncoding)
745 CERT_RDN_ATTR attrs[2];
746 CERT_RDN rdn;
747 CERT_NAME_INFO info;
748 static CHAR oid_common_name[] = szOID_COMMON_NAME,
749 oid_sur_name[] = szOID_SUR_NAME;
750 BYTE *buf = NULL;
751 DWORD size = 0;
752 BOOL ret;
754 if (0)
756 /* Test with NULL pvStructInfo (crashes on win9x) */
757 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, NULL,
758 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
759 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
760 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
762 /* Test with empty CERT_NAME_INFO */
763 info.cRDN = 0;
764 info.rgRDN = NULL;
765 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
766 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
767 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
768 if (buf)
770 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
771 "Got unexpected encoding for empty name\n");
772 LocalFree(buf);
774 if (0)
776 /* Test with bogus CERT_RDN (crashes on win9x) */
777 info.cRDN = 1;
778 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
779 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
780 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
781 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
783 /* Test with empty CERT_RDN */
784 rdn.cRDNAttr = 0;
785 rdn.rgRDNAttr = NULL;
786 info.cRDN = 1;
787 info.rgRDN = &rdn;
788 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
789 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
790 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
791 if (buf)
793 ok(!memcmp(buf, emptyRDNs, sizeof(emptyRDNs)),
794 "Got unexpected encoding for empty RDN array\n");
795 LocalFree(buf);
797 if (0)
799 /* Test with bogus attr array (crashes on win9x) */
800 rdn.cRDNAttr = 1;
801 rdn.rgRDNAttr = NULL;
802 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
803 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
804 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
805 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
807 /* oddly, a bogus OID is accepted by Windows XP; not testing.
808 attrs[0].pszObjId = "bogus";
809 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
810 attrs[0].Value.cbData = sizeof(commonName);
811 attrs[0].Value.pbData = commonName;
812 rdn.cRDNAttr = 1;
813 rdn.rgRDNAttr = attrs;
814 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
815 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
816 ok(!ret, "Expected failure, got success\n");
818 /* Check with two CERT_RDN_ATTRs. Note DER encoding forces the order of
819 * the encoded attributes to be swapped.
821 attrs[0].pszObjId = oid_common_name;
822 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
823 attrs[0].Value.cbData = sizeof(commonName);
824 attrs[0].Value.pbData = (BYTE *)commonName;
825 attrs[1].pszObjId = oid_sur_name;
826 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
827 attrs[1].Value.cbData = sizeof(surName);
828 attrs[1].Value.pbData = (BYTE *)surName;
829 rdn.cRDNAttr = 2;
830 rdn.rgRDNAttr = attrs;
831 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
832 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
833 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
834 if (buf)
836 ok(!memcmp(buf, twoRDNs, sizeof(twoRDNs)),
837 "Got unexpected encoding for two RDN array\n");
838 LocalFree(buf);
840 /* A name can be "encoded" with previously encoded RDN attrs. */
841 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
842 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
843 attrs[0].Value.cbData = sizeof(twoRDNs);
844 rdn.cRDNAttr = 1;
845 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
846 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
847 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
848 if (buf)
850 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
851 ok(!memcmp(buf, encodedTwoRDNs, size),
852 "Unexpected value for re-endoded two RDN array\n");
853 LocalFree(buf);
855 /* CERT_RDN_ANY_TYPE is too vague for X509_NAMEs, check the return */
856 rdn.cRDNAttr = 1;
857 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
858 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME, &info,
859 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
860 ok(!ret && GetLastError() == E_INVALIDARG,
861 "Expected E_INVALIDARG, got %08x\n", GetLastError());
862 /* Test a more complex name */
863 rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
864 rdn.rgRDNAttr = rdnAttrs;
865 info.cRDN = 1;
866 info.rgRDN = &rdn;
867 buf = NULL;
868 size = 0;
869 ret = pCryptEncodeObjectEx(X509_ASN_ENCODING, X509_NAME, &info,
870 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
871 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
872 if (ret)
874 ok(size == sizeof(encodedRDNAttrs), "Wrong size %d\n", size);
875 ok(!memcmp(buf, encodedRDNAttrs, size), "Unexpected value\n");
876 LocalFree(buf);
880 static WCHAR commonNameW[] = { 'J','u','a','n',' ','L','a','n','g',0 };
881 static WCHAR surNameW[] = { 'L','a','n','g',0 };
883 static const BYTE twoRDNsNoNull[] = {
884 0x30,0x21,0x31,0x1f,0x30,0x0b,0x06,0x03,0x55,0x04,0x04,0x13,0x04,0x4c,0x61,
885 0x6e,0x67,0x30,0x10,0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,
886 0x20,0x4c,0x61,0x6e,0x67 };
887 static const BYTE anyType[] = {
888 0x30,0x2f,0x31,0x2d,0x30,0x2b,0x06,0x03,0x55,0x04,0x03,0x1e,0x24,0x23,0x30,
889 0x21,0x31,0x0c,0x30,0x03,0x06,0x04,0x55,0x13,0x04,0x4c,0x05,0x6e,0x61,0x00,
890 0x67,0x11,0x30,0x03,0x06,0x04,0x55,0x13,0x03,0x4a,0x0a,0x61,0x75,0x20,0x6e,
891 0x61,0x4c,0x67,0x6e };
893 static void test_encodeUnicodeName(DWORD dwEncoding)
895 CERT_RDN_ATTR attrs[2];
896 CERT_RDN rdn;
897 CERT_NAME_INFO info;
898 static CHAR oid_common_name[] = szOID_COMMON_NAME,
899 oid_sur_name[] = szOID_SUR_NAME;
900 BYTE *buf = NULL;
901 DWORD size = 0;
902 BOOL ret;
904 if (0)
906 /* Test with NULL pvStructInfo (crashes on win9x) */
907 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, NULL,
908 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
909 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
910 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
912 /* Test with empty CERT_NAME_INFO */
913 info.cRDN = 0;
914 info.rgRDN = NULL;
915 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
916 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
917 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
918 if (buf)
920 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
921 "Got unexpected encoding for empty name\n");
922 LocalFree(buf);
924 /* Check with one CERT_RDN_ATTR, that has an invalid character for the
925 * encoding (the NULL).
927 attrs[0].pszObjId = oid_common_name;
928 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
929 attrs[0].Value.cbData = sizeof(commonNameW);
930 attrs[0].Value.pbData = (BYTE *)commonNameW;
931 rdn.cRDNAttr = 1;
932 rdn.rgRDNAttr = attrs;
933 info.cRDN = 1;
934 info.rgRDN = &rdn;
935 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
936 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
937 ok(!ret && GetLastError() == CRYPT_E_INVALID_PRINTABLE_STRING,
938 "Expected CRYPT_E_INVALID_PRINTABLE_STRING, got %08x\n", GetLastError());
939 ok(size == 9, "Unexpected error index %08x\n", size);
940 /* Check with two NULL-terminated CERT_RDN_ATTRs. Note DER encoding
941 * forces the order of the encoded attributes to be swapped.
943 attrs[0].pszObjId = oid_common_name;
944 attrs[0].dwValueType = CERT_RDN_PRINTABLE_STRING;
945 attrs[0].Value.cbData = 0;
946 attrs[0].Value.pbData = (BYTE *)commonNameW;
947 attrs[1].pszObjId = oid_sur_name;
948 attrs[1].dwValueType = CERT_RDN_PRINTABLE_STRING;
949 attrs[1].Value.cbData = 0;
950 attrs[1].Value.pbData = (BYTE *)surNameW;
951 rdn.cRDNAttr = 2;
952 rdn.rgRDNAttr = attrs;
953 info.cRDN = 1;
954 info.rgRDN = &rdn;
955 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
956 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
957 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
958 if (buf)
960 ok(!memcmp(buf, twoRDNsNoNull, sizeof(twoRDNsNoNull)),
961 "Got unexpected encoding for two RDN array\n");
962 LocalFree(buf);
964 /* A name can be "encoded" with previously encoded RDN attrs. */
965 attrs[0].dwValueType = CERT_RDN_ENCODED_BLOB;
966 attrs[0].Value.pbData = (LPBYTE)twoRDNs;
967 attrs[0].Value.cbData = sizeof(twoRDNs);
968 rdn.cRDNAttr = 1;
969 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
970 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
971 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
972 if (buf)
974 ok(size == sizeof(encodedTwoRDNs), "Unexpected size %d\n", size);
975 ok(!memcmp(buf, encodedTwoRDNs, size),
976 "Unexpected value for re-endoded two RDN array\n");
977 LocalFree(buf);
979 /* Unicode names infer the type for CERT_RDN_ANY_TYPE */
980 rdn.cRDNAttr = 1;
981 attrs[0].dwValueType = CERT_RDN_ANY_TYPE;
982 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME, &info,
983 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
984 todo_wine ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
985 if (buf)
987 ok(size == sizeof(anyType), "Unexpected size %d\n", size);
988 ok(!memcmp(buf, anyType, size), "Unexpected value\n");
989 LocalFree(buf);
993 static void compareNameValues(const CERT_NAME_VALUE *expected,
994 const CERT_NAME_VALUE *got)
996 if (expected->dwValueType == CERT_RDN_UTF8_STRING &&
997 got->dwValueType == CERT_RDN_ENCODED_BLOB)
999 win_skip("Can't handle CERT_RDN_UTF8_STRING\n");
1000 return;
1003 ok(got->dwValueType == expected->dwValueType,
1004 "Expected string type %d, got %d\n", expected->dwValueType,
1005 got->dwValueType);
1006 ok(got->Value.cbData == expected->Value.cbData,
1007 "String type %d: unexpected data size, got %d, expected %d\n",
1008 expected->dwValueType, got->Value.cbData, expected->Value.cbData);
1009 if (got->Value.cbData && got->Value.pbData)
1010 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1011 min(got->Value.cbData, expected->Value.cbData)),
1012 "String type %d: unexpected value\n", expected->dwValueType);
1015 static void compareRDNAttrs(const CERT_RDN_ATTR *expected,
1016 const CERT_RDN_ATTR *got)
1018 if (expected->pszObjId && strlen(expected->pszObjId))
1020 ok(got->pszObjId != NULL, "Expected OID %s, got NULL\n",
1021 expected->pszObjId);
1022 if (got->pszObjId)
1024 ok(!strcmp(got->pszObjId, expected->pszObjId),
1025 "Got unexpected OID %s, expected %s\n", got->pszObjId,
1026 expected->pszObjId);
1029 compareNameValues((const CERT_NAME_VALUE *)&expected->dwValueType,
1030 (const CERT_NAME_VALUE *)&got->dwValueType);
1033 static void compareRDNs(const CERT_RDN *expected, const CERT_RDN *got)
1035 ok(got->cRDNAttr == expected->cRDNAttr,
1036 "Expected %d RDN attrs, got %d\n", expected->cRDNAttr, got->cRDNAttr);
1037 if (got->cRDNAttr)
1039 DWORD i;
1041 for (i = 0; i < got->cRDNAttr; i++)
1042 compareRDNAttrs(&expected->rgRDNAttr[i], &got->rgRDNAttr[i]);
1046 static void compareNames(const CERT_NAME_INFO *expected,
1047 const CERT_NAME_INFO *got)
1049 ok(got->cRDN == expected->cRDN, "Expected %d RDNs, got %d\n",
1050 expected->cRDN, got->cRDN);
1051 if (got->cRDN)
1053 DWORD i;
1055 for (i = 0; i < got->cRDN; i++)
1056 compareRDNs(&expected->rgRDN[i], &got->rgRDN[i]);
1060 static const BYTE emptyIndefiniteSequence[] = { 0x30,0x80,0x00,0x00 };
1061 static const BYTE twoRDNsExtraBytes[] = {
1062 0x30,0x23,0x31,0x21,0x30,0x0c,0x06,0x03,0x55,0x04,0x04,
1063 0x13,0x05,0x4c,0x61,0x6e,0x67,0x00,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1064 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0,0,0,0,0,0};
1066 static void test_decodeName(DWORD dwEncoding)
1068 BYTE *buf = NULL;
1069 DWORD bufSize = 0;
1070 BOOL ret;
1071 CERT_RDN rdn;
1072 CERT_NAME_INFO info = { 1, &rdn };
1074 /* test empty name */
1075 bufSize = 0;
1076 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptySequence,
1077 emptySequence[1] + 2,
1078 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1079 &buf, &bufSize);
1080 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1081 /* Interestingly, in Windows, if cRDN is 0, rgRGN may not be NULL. My
1082 * decoder works the same way, so only test the count.
1084 if (buf)
1086 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1087 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1088 "Expected 0 RDNs in empty info, got %d\n",
1089 ((CERT_NAME_INFO *)buf)->cRDN);
1090 LocalFree(buf);
1092 /* test empty name with indefinite-length encoding */
1093 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyIndefiniteSequence,
1094 sizeof(emptyIndefiniteSequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
1095 &buf, &bufSize);
1096 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1097 if (ret)
1099 ok(bufSize == sizeof(CERT_NAME_INFO), "Wrong bufSize %d\n", bufSize);
1100 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1101 "Expected 0 RDNs in empty info, got %d\n",
1102 ((CERT_NAME_INFO *)buf)->cRDN);
1103 LocalFree(buf);
1105 /* test empty RDN */
1106 bufSize = 0;
1107 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, emptyRDNs,
1108 emptyRDNs[1] + 2,
1109 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1110 &buf, &bufSize);
1111 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1112 if (buf)
1114 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1116 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1117 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1118 "Got unexpected value for empty RDN\n");
1119 LocalFree(buf);
1121 /* test two RDN attrs */
1122 bufSize = 0;
1123 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNs,
1124 twoRDNs[1] + 2,
1125 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1126 &buf, &bufSize);
1127 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1128 if (buf)
1130 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1131 oid_common_name[] = szOID_COMMON_NAME;
1133 CERT_RDN_ATTR attrs[] = {
1134 { oid_sur_name, CERT_RDN_PRINTABLE_STRING, { sizeof(surName),
1135 (BYTE *)surName } },
1136 { oid_common_name, CERT_RDN_PRINTABLE_STRING, { sizeof(commonName),
1137 (BYTE *)commonName } },
1140 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1141 rdn.rgRDNAttr = attrs;
1142 compareNames(&info, (CERT_NAME_INFO *)buf);
1143 LocalFree(buf);
1145 /* test that two RDN attrs with extra bytes succeeds */
1146 bufSize = 0;
1147 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME, twoRDNsExtraBytes,
1148 sizeof(twoRDNsExtraBytes), 0, NULL, NULL, &bufSize);
1149 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1150 /* And, a slightly more complicated name */
1151 buf = NULL;
1152 bufSize = 0;
1153 ret = pCryptDecodeObjectEx(X509_ASN_ENCODING, X509_NAME, encodedRDNAttrs,
1154 sizeof(encodedRDNAttrs), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1155 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1156 if (ret)
1158 rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
1159 rdn.rgRDNAttr = decodedRdnAttrs;
1160 compareNames(&info, (CERT_NAME_INFO *)buf);
1161 LocalFree(buf);
1165 static void test_decodeUnicodeName(DWORD dwEncoding)
1167 BYTE *buf = NULL;
1168 DWORD bufSize = 0;
1169 BOOL ret;
1170 CERT_RDN rdn;
1171 CERT_NAME_INFO info = { 1, &rdn };
1173 /* test empty name */
1174 bufSize = 0;
1175 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptySequence,
1176 emptySequence[1] + 2,
1177 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1178 &buf, &bufSize);
1179 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1180 if (buf)
1182 ok(bufSize == sizeof(CERT_NAME_INFO),
1183 "Got wrong bufSize %d\n", bufSize);
1184 ok(((CERT_NAME_INFO *)buf)->cRDN == 0,
1185 "Expected 0 RDNs in empty info, got %d\n",
1186 ((CERT_NAME_INFO *)buf)->cRDN);
1187 LocalFree(buf);
1189 /* test empty RDN */
1190 bufSize = 0;
1191 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, emptyRDNs,
1192 emptyRDNs[1] + 2,
1193 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1194 &buf, &bufSize);
1195 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1196 if (buf)
1198 CERT_NAME_INFO *info = (CERT_NAME_INFO *)buf;
1200 ok(bufSize == sizeof(CERT_NAME_INFO) + sizeof(CERT_RDN) &&
1201 info->cRDN == 1 && info->rgRDN && info->rgRDN[0].cRDNAttr == 0,
1202 "Got unexpected value for empty RDN\n");
1203 LocalFree(buf);
1205 /* test two RDN attrs */
1206 bufSize = 0;
1207 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME, twoRDNsNoNull,
1208 sizeof(twoRDNsNoNull),
1209 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1210 &buf, &bufSize);
1211 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1212 if (buf)
1214 static CHAR oid_sur_name[] = szOID_SUR_NAME,
1215 oid_common_name[] = szOID_COMMON_NAME;
1217 CERT_RDN_ATTR attrs[] = {
1218 { oid_sur_name, CERT_RDN_PRINTABLE_STRING,
1219 { lstrlenW(surNameW) * sizeof(WCHAR), (BYTE *)surNameW } },
1220 { oid_common_name, CERT_RDN_PRINTABLE_STRING,
1221 { lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
1224 rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
1225 rdn.rgRDNAttr = attrs;
1226 compareNames(&info, (CERT_NAME_INFO *)buf);
1227 LocalFree(buf);
1231 struct EncodedNameValue
1233 CERT_NAME_VALUE value;
1234 const BYTE *encoded;
1235 DWORD encodedSize;
1238 static const char bogusIA5[] = "\x80";
1239 static const char bogusPrintable[] = "~";
1240 static const char bogusNumeric[] = "A";
1241 static const BYTE bin42[] = { 0x16,0x02,0x80,0x00 };
1242 static const BYTE bin43[] = { 0x13,0x02,0x7e,0x00 };
1243 static const BYTE bin44[] = { 0x12,0x02,0x41,0x00 };
1244 static BYTE octetCommonNameValue[] = {
1245 0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1246 static BYTE numericCommonNameValue[] = {
1247 0x12,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1248 static BYTE printableCommonNameValue[] = {
1249 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1250 static BYTE t61CommonNameValue[] = {
1251 0x14,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1252 static BYTE videotexCommonNameValue[] = {
1253 0x15,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1254 static BYTE ia5CommonNameValue[] = {
1255 0x16,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1256 static BYTE graphicCommonNameValue[] = {
1257 0x19,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1258 static BYTE visibleCommonNameValue[] = {
1259 0x1a,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1260 static BYTE generalCommonNameValue[] = {
1261 0x1b,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1262 static BYTE bmpCommonNameValue[] = {
1263 0x1e,0x14,0x00,0x4a,0x00,0x75,0x00,0x61,0x00,0x6e,0x00,0x20,0x00,0x4c,0x00,
1264 0x61,0x00,0x6e,0x00,0x67,0x00,0x00 };
1265 static BYTE utf8CommonNameValue[] = {
1266 0x0c,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1267 static char embedded_null[] = "foo\0com";
1268 static BYTE ia5EmbeddedNull[] = {
1269 0x16,0x07,0x66,0x6f,0x6f,0x00,0x63,0x6f,0x6d };
1271 static struct EncodedNameValue nameValues[] = {
1272 { { CERT_RDN_OCTET_STRING, { sizeof(commonName), (BYTE *)commonName } },
1273 octetCommonNameValue, sizeof(octetCommonNameValue) },
1274 { { CERT_RDN_NUMERIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1275 numericCommonNameValue, sizeof(numericCommonNameValue) },
1276 { { CERT_RDN_PRINTABLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1277 printableCommonNameValue, sizeof(printableCommonNameValue) },
1278 { { CERT_RDN_T61_STRING, { sizeof(commonName), (BYTE *)commonName } },
1279 t61CommonNameValue, sizeof(t61CommonNameValue) },
1280 { { CERT_RDN_VIDEOTEX_STRING, { sizeof(commonName), (BYTE *)commonName } },
1281 videotexCommonNameValue, sizeof(videotexCommonNameValue) },
1282 { { CERT_RDN_IA5_STRING, { sizeof(commonName), (BYTE *)commonName } },
1283 ia5CommonNameValue, sizeof(ia5CommonNameValue) },
1284 { { CERT_RDN_GRAPHIC_STRING, { sizeof(commonName), (BYTE *)commonName } },
1285 graphicCommonNameValue, sizeof(graphicCommonNameValue) },
1286 { { CERT_RDN_VISIBLE_STRING, { sizeof(commonName), (BYTE *)commonName } },
1287 visibleCommonNameValue, sizeof(visibleCommonNameValue) },
1288 { { CERT_RDN_GENERAL_STRING, { sizeof(commonName), (BYTE *)commonName } },
1289 generalCommonNameValue, sizeof(generalCommonNameValue) },
1290 { { CERT_RDN_BMP_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1291 bmpCommonNameValue, sizeof(bmpCommonNameValue) },
1292 { { CERT_RDN_UTF8_STRING, { sizeof(commonNameW), (BYTE *)commonNameW } },
1293 utf8CommonNameValue, sizeof(utf8CommonNameValue) },
1294 /* The following tests succeed under Windows, but really should fail,
1295 * they contain characters that are illegal for the encoding. I'm
1296 * including them to justify my lazy encoding.
1298 { { CERT_RDN_IA5_STRING, { sizeof(bogusIA5), (BYTE *)bogusIA5 } }, bin42,
1299 sizeof(bin42) },
1300 { { CERT_RDN_PRINTABLE_STRING, { sizeof(bogusPrintable),
1301 (BYTE *)bogusPrintable } }, bin43, sizeof(bin43) },
1302 { { CERT_RDN_NUMERIC_STRING, { sizeof(bogusNumeric), (BYTE *)bogusNumeric } },
1303 bin44, sizeof(bin44) },
1305 /* This is kept separate, because the decoding doesn't return to the original
1306 * value.
1308 static struct EncodedNameValue embeddedNullNameValue = {
1309 { CERT_RDN_IA5_STRING, { sizeof(embedded_null) - 1, (BYTE *)embedded_null } },
1310 ia5EmbeddedNull, sizeof(ia5EmbeddedNull) };
1312 static void test_encodeNameValue(DWORD dwEncoding)
1314 BYTE *buf = NULL;
1315 DWORD size = 0, i;
1316 BOOL ret;
1317 CERT_NAME_VALUE value = { 0, { 0, NULL } };
1319 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1320 value.Value.pbData = printableCommonNameValue;
1321 value.Value.cbData = sizeof(printableCommonNameValue);
1322 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE, &value,
1323 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1324 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1325 if (buf)
1327 ok(size == sizeof(printableCommonNameValue), "Unexpected size %d\n",
1328 size);
1329 ok(!memcmp(buf, printableCommonNameValue, size),
1330 "Unexpected encoding\n");
1331 LocalFree(buf);
1333 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1335 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1336 &nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1337 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */,
1338 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1339 nameValues[i].value.dwValueType, GetLastError());
1340 if (ret)
1342 ok(size == nameValues[i].encodedSize,
1343 "Expected size %d, got %d\n", nameValues[i].encodedSize, size);
1344 ok(!memcmp(buf, nameValues[i].encoded, size),
1345 "Got unexpected encoding\n");
1346 LocalFree(buf);
1349 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
1350 &embeddedNullNameValue.value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1351 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH) /* NT4/Win9x */,
1352 "Type %d: CryptEncodeObjectEx failed: %08x\n",
1353 embeddedNullNameValue.value.dwValueType, GetLastError());
1354 if (ret)
1356 ok(size == embeddedNullNameValue.encodedSize,
1357 "Expected size %d, got %d\n", embeddedNullNameValue.encodedSize, size);
1358 ok(!memcmp(buf, embeddedNullNameValue.encoded, size),
1359 "Got unexpected encoding\n");
1360 LocalFree(buf);
1364 static void test_decodeNameValue(DWORD dwEncoding)
1366 int i;
1367 BYTE *buf = NULL;
1368 DWORD bufSize = 0;
1369 BOOL ret;
1371 for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
1373 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1374 nameValues[i].encoded, nameValues[i].encoded[1] + 2,
1375 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1376 &buf, &bufSize);
1377 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1378 nameValues[i].value.dwValueType, GetLastError());
1379 if (ret)
1381 compareNameValues(&nameValues[i].value,
1382 (const CERT_NAME_VALUE *)buf);
1383 LocalFree(buf);
1386 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
1387 embeddedNullNameValue.encoded, embeddedNullNameValue.encodedSize,
1388 CRYPT_DECODE_ALLOC_FLAG | CRYPT_DECODE_SHARE_OID_STRING_FLAG, NULL,
1389 &buf, &bufSize);
1390 ok(ret, "Value type %d: CryptDecodeObjectEx failed: %08x\n",
1391 embeddedNullNameValue.value.dwValueType, GetLastError());
1392 if (ret)
1394 CERT_NAME_VALUE rdnEncodedValue = { CERT_RDN_ENCODED_BLOB,
1395 { sizeof(ia5EmbeddedNull), ia5EmbeddedNull } };
1396 CERT_NAME_VALUE embeddedNullValue = { CERT_RDN_IA5_STRING,
1397 { sizeof(embedded_null) - 1, (BYTE *)embedded_null } };
1398 const CERT_NAME_VALUE *got = (const CERT_NAME_VALUE *)buf,
1399 *expected = NULL;
1401 /* Some Windows versions decode name values with embedded NULLs,
1402 * others leave them encoded, even with the same version of crypt32.
1403 * Accept either.
1405 ok(got->dwValueType == CERT_RDN_ENCODED_BLOB ||
1406 got->dwValueType == CERT_RDN_IA5_STRING,
1407 "Expected CERT_RDN_ENCODED_BLOB or CERT_RDN_IA5_STRING, got %d\n",
1408 got->dwValueType);
1409 if (got->dwValueType == CERT_RDN_ENCODED_BLOB)
1410 expected = &rdnEncodedValue;
1411 else if (got->dwValueType == CERT_RDN_IA5_STRING)
1412 expected = &embeddedNullValue;
1413 if (expected)
1415 ok(got->Value.cbData == expected->Value.cbData,
1416 "String type %d: unexpected data size, got %d, expected %d\n",
1417 got->dwValueType, got->Value.cbData, expected->Value.cbData);
1418 if (got->Value.cbData && got->Value.pbData)
1419 ok(!memcmp(got->Value.pbData, expected->Value.pbData,
1420 min(got->Value.cbData, expected->Value.cbData)),
1421 "String type %d: unexpected value\n", expected->dwValueType);
1423 LocalFree(buf);
1427 static const BYTE emptyURL[] = { 0x30, 0x02, 0x86, 0x00 };
1428 static const BYTE emptyURLExtraBytes[] = { 0x30, 0x02, 0x86, 0x00, 0, 0, 0 };
1429 static const WCHAR url[] = { 'h','t','t','p',':','/','/','w','i','n','e',
1430 'h','q','.','o','r','g',0 };
1431 static const BYTE encodedURL[] = { 0x30, 0x13, 0x86, 0x11, 0x68, 0x74,
1432 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e,
1433 0x6f, 0x72, 0x67 };
1434 static const WCHAR nihongoURL[] = { 'h','t','t','p',':','/','/',0x226f,
1435 0x575b, 0 };
1436 static const WCHAR dnsName[] = { 'w','i','n','e','h','q','.','o','r','g',0 };
1437 static const BYTE encodedDnsName[] = { 0x30, 0x0c, 0x82, 0x0a, 0x77, 0x69,
1438 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
1439 static const BYTE localhost[] = { 127, 0, 0, 1 };
1440 static const BYTE encodedIPAddr[] = { 0x30, 0x06, 0x87, 0x04, 0x7f, 0x00, 0x00,
1441 0x01 };
1442 static const unsigned char encodedCommonName[] = {
1443 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,'J','u','a','n',' ','L','a','n','g',0};
1444 static const BYTE encodedOidName[] = { 0x30,0x04,0x88,0x02,0x2a,0x03 };
1445 static const BYTE encodedDirectoryName[] = {
1446 0x30,0x19,0xa4,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
1447 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00 };
1449 static void test_encodeAltName(DWORD dwEncoding)
1451 CERT_ALT_NAME_INFO info = { 0 };
1452 CERT_ALT_NAME_ENTRY entry = { 0 };
1453 BYTE *buf = NULL;
1454 DWORD size = 0;
1455 BOOL ret;
1456 char oid[] = "1.2.3";
1458 /* Test with empty info */
1459 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1460 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1461 if (buf)
1463 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
1464 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
1465 LocalFree(buf);
1467 /* Test with an empty entry */
1468 info.cAltEntry = 1;
1469 info.rgAltEntry = &entry;
1470 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1471 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1472 ok(!ret && GetLastError() == E_INVALIDARG,
1473 "Expected E_INVALIDARG, got %08x\n", GetLastError());
1474 /* Test with an empty pointer */
1475 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
1476 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1477 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1478 if (buf)
1480 ok(size == sizeof(emptyURL), "Wrong size %d\n", size);
1481 ok(!memcmp(buf, emptyURL, size), "Unexpected value\n");
1482 LocalFree(buf);
1484 /* Test with a real URL */
1485 U(entry).pwszURL = (LPWSTR)url;
1486 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1487 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1488 if (buf)
1490 ok(size == sizeof(encodedURL), "Wrong size %d\n", size);
1491 ok(!memcmp(buf, encodedURL, size), "Unexpected value\n");
1492 LocalFree(buf);
1494 /* Now with the URL containing an invalid IA5 char */
1495 U(entry).pwszURL = (LPWSTR)nihongoURL;
1496 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1497 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1498 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
1499 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
1500 /* The first invalid character is at index 7 */
1501 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
1502 "Expected invalid char at index 7, got %d\n",
1503 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
1504 /* Now with the URL missing a scheme */
1505 U(entry).pwszURL = (LPWSTR)dnsName;
1506 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1507 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1508 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1509 if (buf)
1511 /* This succeeds, but it shouldn't, so don't worry about conforming */
1512 LocalFree(buf);
1514 /* Now with a DNS name */
1515 entry.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
1516 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1517 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1518 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1519 if (buf)
1521 ok(size == sizeof(encodedDnsName), "Wrong size %d\n", size);
1522 ok(!memcmp(buf, encodedDnsName, size), "Unexpected value\n");
1523 LocalFree(buf);
1525 /* Test with an IP address */
1526 entry.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
1527 U(entry).IPAddress.cbData = sizeof(localhost);
1528 U(entry).IPAddress.pbData = (LPBYTE)localhost;
1529 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1530 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1531 if (buf)
1533 ok(size == sizeof(encodedIPAddr), "Wrong size %d\n", size);
1534 ok(!memcmp(buf, encodedIPAddr, size), "Unexpected value\n");
1535 LocalFree(buf);
1537 /* Test with OID */
1538 entry.dwAltNameChoice = CERT_ALT_NAME_REGISTERED_ID;
1539 U(entry).pszRegisteredID = oid;
1540 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1541 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1542 if (buf)
1544 ok(size == sizeof(encodedOidName), "Wrong size %d\n", size);
1545 ok(!memcmp(buf, encodedOidName, size), "Unexpected value\n");
1546 LocalFree(buf);
1548 /* Test with directory name */
1549 entry.dwAltNameChoice = CERT_ALT_NAME_DIRECTORY_NAME;
1550 U(entry).DirectoryName.cbData = sizeof(encodedCommonName);
1551 U(entry).DirectoryName.pbData = (LPBYTE)encodedCommonName;
1552 ret = pCryptEncodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, &info,
1553 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1554 if (buf)
1556 ok(size == sizeof(encodedDirectoryName), "Wrong size %d\n", size);
1557 ok(!memcmp(buf, encodedDirectoryName, size), "Unexpected value\n");
1558 LocalFree(buf);
1562 static void test_decodeAltName(DWORD dwEncoding)
1564 static const BYTE unimplementedType[] = { 0x30, 0x06, 0x85, 0x04, 0x7f,
1565 0x00, 0x00, 0x01 };
1566 static const BYTE bogusType[] = { 0x30, 0x06, 0x89, 0x04, 0x7f, 0x00, 0x00,
1567 0x01 };
1568 static const BYTE dns_embedded_null[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1569 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1570 static const BYTE dns_embedded_bell[] = { 0x30,0x10,0x82,0x0e,0x66,0x6f,
1571 0x6f,0x2e,0x63,0x6f,0x6d,0x07,0x62,0x61,0x64,0x64,0x69,0x65 };
1572 static const BYTE url_embedded_null[] = { 0x30,0x10,0x86,0x0e,0x66,0x6f,
1573 0x6f,0x2e,0x63,0x6f,0x6d,0x00,0x62,0x61,0x64,0x64,0x69,0x65 };
1574 BOOL ret;
1575 BYTE *buf = NULL;
1576 DWORD bufSize = 0;
1577 CERT_ALT_NAME_INFO *info;
1579 /* Test some bogus ones first */
1580 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1581 unimplementedType, sizeof(unimplementedType), CRYPT_DECODE_ALLOC_FLAG,
1582 NULL, &buf, &bufSize);
1583 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
1584 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1585 "Expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
1586 GetLastError());
1587 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1588 bogusType, sizeof(bogusType), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
1589 &bufSize);
1590 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
1591 GetLastError() == OSS_DATA_ERROR /* Win9x */),
1592 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
1593 GetLastError());
1594 /* Now expected cases */
1595 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptySequence,
1596 emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1597 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1598 if (buf)
1600 info = (CERT_ALT_NAME_INFO *)buf;
1602 ok(info->cAltEntry == 0, "Expected 0 entries, got %d\n",
1603 info->cAltEntry);
1604 LocalFree(buf);
1606 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, emptyURL,
1607 emptyURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1608 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1609 if (buf)
1611 info = (CERT_ALT_NAME_INFO *)buf;
1613 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1614 info->cAltEntry);
1615 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1616 "Expected CERT_ALT_NAME_URL, got %d\n",
1617 info->rgAltEntry[0].dwAltNameChoice);
1618 ok(U(info->rgAltEntry[0]).pwszURL == NULL || !*U(info->rgAltEntry[0]).pwszURL,
1619 "Expected empty URL\n");
1620 LocalFree(buf);
1622 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1623 emptyURLExtraBytes, sizeof(emptyURLExtraBytes), 0, NULL, NULL, &bufSize);
1624 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1625 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedURL,
1626 encodedURL[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1627 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1628 if (buf)
1630 info = (CERT_ALT_NAME_INFO *)buf;
1632 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1633 info->cAltEntry);
1634 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_URL,
1635 "Expected CERT_ALT_NAME_URL, got %d\n",
1636 info->rgAltEntry[0].dwAltNameChoice);
1637 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszURL, url), "Unexpected URL\n");
1638 LocalFree(buf);
1640 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedDnsName,
1641 encodedDnsName[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1642 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1643 if (buf)
1645 info = (CERT_ALT_NAME_INFO *)buf;
1647 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1648 info->cAltEntry);
1649 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1650 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1651 info->rgAltEntry[0].dwAltNameChoice);
1652 ok(!lstrcmpW(U(info->rgAltEntry[0]).pwszDNSName, dnsName),
1653 "Unexpected DNS name\n");
1654 LocalFree(buf);
1656 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedIPAddr,
1657 encodedIPAddr[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1658 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1659 if (buf)
1661 info = (CERT_ALT_NAME_INFO *)buf;
1663 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1664 info->cAltEntry);
1665 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_IP_ADDRESS,
1666 "Expected CERT_ALT_NAME_IP_ADDRESS, got %d\n",
1667 info->rgAltEntry[0].dwAltNameChoice);
1668 ok(U(info->rgAltEntry[0]).IPAddress.cbData == sizeof(localhost),
1669 "Unexpected IP address length %d\n",
1670 U(info->rgAltEntry[0]).IPAddress.cbData);
1671 ok(!memcmp(U(info->rgAltEntry[0]).IPAddress.pbData, localhost,
1672 sizeof(localhost)), "Unexpected IP address value\n");
1673 LocalFree(buf);
1675 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME, encodedOidName,
1676 sizeof(encodedOidName), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1677 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1678 if (buf)
1680 info = (CERT_ALT_NAME_INFO *)buf;
1682 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1683 info->cAltEntry);
1684 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_REGISTERED_ID,
1685 "Expected CERT_ALT_NAME_REGISTERED_ID, got %d\n",
1686 info->rgAltEntry[0].dwAltNameChoice);
1687 ok(!strcmp(U(info->rgAltEntry[0]).pszRegisteredID, "1.2.3"),
1688 "Expected OID 1.2.3, got %s\n", U(info->rgAltEntry[0]).pszRegisteredID);
1689 LocalFree(buf);
1691 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1692 encodedDirectoryName, sizeof(encodedDirectoryName),
1693 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1694 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1695 if (buf)
1697 info = (CERT_ALT_NAME_INFO *)buf;
1699 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1700 info->cAltEntry);
1701 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DIRECTORY_NAME,
1702 "Expected CERT_ALT_NAME_DIRECTORY_NAME, got %d\n",
1703 info->rgAltEntry[0].dwAltNameChoice);
1704 ok(U(info->rgAltEntry[0]).DirectoryName.cbData ==
1705 sizeof(encodedCommonName), "Unexpected directory name length %d\n",
1706 U(info->rgAltEntry[0]).DirectoryName.cbData);
1707 ok(!memcmp(U(info->rgAltEntry[0]).DirectoryName.pbData,
1708 encodedCommonName, sizeof(encodedCommonName)),
1709 "Unexpected directory name value\n");
1710 LocalFree(buf);
1712 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1713 dns_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1714 NULL, &buf, &bufSize);
1715 /* Fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned about the
1716 * particular failure, just that it doesn't decode.
1717 * It succeeds on (broken) Windows versions that haven't addressed
1718 * embedded NULLs in alternate names.
1720 ok(!ret || broken(ret), "expected failure\n");
1721 /* An embedded bell character is allowed, however. */
1722 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1723 dns_embedded_bell, sizeof(dns_embedded_bell), CRYPT_DECODE_ALLOC_FLAG,
1724 NULL, &buf, &bufSize);
1725 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1726 if (ret)
1728 info = (CERT_ALT_NAME_INFO *)buf;
1730 ok(info->cAltEntry == 1, "Expected 1 entries, got %d\n",
1731 info->cAltEntry);
1732 ok(info->rgAltEntry[0].dwAltNameChoice == CERT_ALT_NAME_DNS_NAME,
1733 "Expected CERT_ALT_NAME_DNS_NAME, got %d\n",
1734 info->rgAltEntry[0].dwAltNameChoice);
1735 LocalFree(buf);
1737 ret = pCryptDecodeObjectEx(dwEncoding, X509_ALTERNATE_NAME,
1738 url_embedded_null, sizeof(dns_embedded_null), CRYPT_DECODE_ALLOC_FLAG,
1739 NULL, &buf, &bufSize);
1740 /* Again, fails on WinXP with CRYPT_E_ASN1_RULE. I'm not too concerned
1741 * about the particular failure, just that it doesn't decode.
1742 * It succeeds on (broken) Windows versions that haven't addressed
1743 * embedded NULLs in alternate names.
1745 ok(!ret || broken(ret), "expected failure\n");
1748 struct UnicodeExpectedError
1750 DWORD valueType;
1751 LPCWSTR str;
1752 DWORD errorIndex;
1753 DWORD error;
1756 static const WCHAR oneW[] = { '1',0 };
1757 static const WCHAR aW[] = { 'a',0 };
1758 static const WCHAR quoteW[] = { '"', 0 };
1760 static struct UnicodeExpectedError unicodeErrors[] = {
1761 { CERT_RDN_ANY_TYPE, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1762 { CERT_RDN_ENCODED_BLOB, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1763 { CERT_RDN_OCTET_STRING, oneW, 0, CRYPT_E_NOT_CHAR_STRING },
1764 { CERT_RDN_NUMERIC_STRING, aW, 0, CRYPT_E_INVALID_NUMERIC_STRING },
1765 { CERT_RDN_PRINTABLE_STRING, quoteW, 0, CRYPT_E_INVALID_PRINTABLE_STRING },
1766 { CERT_RDN_IA5_STRING, nihongoURL, 7, CRYPT_E_INVALID_IA5_STRING },
1769 struct UnicodeExpectedResult
1771 DWORD valueType;
1772 LPCWSTR str;
1773 CRYPT_DATA_BLOB encoded;
1776 static BYTE oneNumeric[] = { 0x12, 0x01, 0x31 };
1777 static BYTE onePrintable[] = { 0x13, 0x01, 0x31 };
1778 static BYTE oneTeletex[] = { 0x14, 0x01, 0x31 };
1779 static BYTE oneVideotex[] = { 0x15, 0x01, 0x31 };
1780 static BYTE oneIA5[] = { 0x16, 0x01, 0x31 };
1781 static BYTE oneGraphic[] = { 0x19, 0x01, 0x31 };
1782 static BYTE oneVisible[] = { 0x1a, 0x01, 0x31 };
1783 static BYTE oneUniversal[] = { 0x1c, 0x04, 0x00, 0x00, 0x00, 0x31 };
1784 static BYTE oneGeneral[] = { 0x1b, 0x01, 0x31 };
1785 static BYTE oneBMP[] = { 0x1e, 0x02, 0x00, 0x31 };
1786 static BYTE oneUTF8[] = { 0x0c, 0x01, 0x31 };
1787 static BYTE nihongoT61[] = { 0x14,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6f,
1788 0x5b };
1789 static BYTE nihongoGeneral[] = { 0x1b,0x09,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1790 0x6f,0x5b };
1791 static BYTE nihongoBMP[] = { 0x1e,0x12,0x00,0x68,0x00,0x74,0x00,0x74,0x00,0x70,
1792 0x00,0x3a,0x00,0x2f,0x00,0x2f,0x22,0x6f,0x57,0x5b };
1793 static BYTE nihongoUTF8[] = { 0x0c,0x0d,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
1794 0xe2,0x89,0xaf,0xe5,0x9d,0x9b };
1796 static struct UnicodeExpectedResult unicodeResults[] = {
1797 { CERT_RDN_NUMERIC_STRING, oneW, { sizeof(oneNumeric), oneNumeric } },
1798 { CERT_RDN_PRINTABLE_STRING, oneW, { sizeof(onePrintable), onePrintable } },
1799 { CERT_RDN_TELETEX_STRING, oneW, { sizeof(oneTeletex), oneTeletex } },
1800 { CERT_RDN_VIDEOTEX_STRING, oneW, { sizeof(oneVideotex), oneVideotex } },
1801 { CERT_RDN_IA5_STRING, oneW, { sizeof(oneIA5), oneIA5 } },
1802 { CERT_RDN_GRAPHIC_STRING, oneW, { sizeof(oneGraphic), oneGraphic } },
1803 { CERT_RDN_VISIBLE_STRING, oneW, { sizeof(oneVisible), oneVisible } },
1804 { CERT_RDN_UNIVERSAL_STRING, oneW, { sizeof(oneUniversal), oneUniversal } },
1805 { CERT_RDN_GENERAL_STRING, oneW, { sizeof(oneGeneral), oneGeneral } },
1806 { CERT_RDN_BMP_STRING, oneW, { sizeof(oneBMP), oneBMP } },
1807 { CERT_RDN_UTF8_STRING, oneW, { sizeof(oneUTF8), oneUTF8 } },
1808 { CERT_RDN_BMP_STRING, nihongoURL, { sizeof(nihongoBMP), nihongoBMP } },
1809 { CERT_RDN_UTF8_STRING, nihongoURL, { sizeof(nihongoUTF8), nihongoUTF8 } },
1812 static struct UnicodeExpectedResult unicodeWeirdness[] = {
1813 { CERT_RDN_TELETEX_STRING, nihongoURL, { sizeof(nihongoT61), nihongoT61 } },
1814 { CERT_RDN_GENERAL_STRING, nihongoURL, { sizeof(nihongoGeneral), nihongoGeneral } },
1817 static void test_encodeUnicodeNameValue(DWORD dwEncoding)
1819 BYTE *buf = NULL;
1820 DWORD size = 0, i;
1821 BOOL ret;
1822 CERT_NAME_VALUE value;
1824 if (0)
1826 /* Crashes on win9x */
1827 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, NULL,
1828 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1829 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
1830 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
1832 /* Have to have a string of some sort */
1833 value.dwValueType = 0; /* aka CERT_RDN_ANY_TYPE */
1834 value.Value.pbData = NULL;
1835 value.Value.cbData = 0;
1836 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1837 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1838 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1839 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1840 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1841 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1842 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1843 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1844 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1845 value.dwValueType = CERT_RDN_ANY_TYPE;
1846 value.Value.pbData = (LPBYTE)oneW;
1847 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1848 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1849 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1850 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1851 value.Value.cbData = sizeof(oneW);
1852 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1853 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1854 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1855 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1856 /* An encoded string with specified length isn't good enough either */
1857 value.dwValueType = CERT_RDN_ENCODED_BLOB;
1858 value.Value.pbData = oneUniversal;
1859 value.Value.cbData = sizeof(oneUniversal);
1860 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1861 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1862 ok(!ret && GetLastError() == CRYPT_E_NOT_CHAR_STRING,
1863 "Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
1864 /* More failure checking */
1865 value.Value.cbData = 0;
1866 for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
1868 value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
1869 value.dwValueType = unicodeErrors[i].valueType;
1870 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1871 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1872 ok(!ret && GetLastError() == unicodeErrors[i].error,
1873 "Value type %d: expected %08x, got %08x\n", value.dwValueType,
1874 unicodeErrors[i].error, GetLastError());
1875 ok(size == unicodeErrors[i].errorIndex,
1876 "Expected error index %d, got %d\n", unicodeErrors[i].errorIndex,
1877 size);
1879 /* cbData can be zero if the string is NULL-terminated */
1880 value.Value.cbData = 0;
1881 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1883 value.Value.pbData = (LPBYTE)unicodeResults[i].str;
1884 value.dwValueType = unicodeResults[i].valueType;
1885 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1886 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1887 ok(ret || broken(GetLastError() == OSS_PDU_MISMATCH /* Win9x */),
1888 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1889 if (buf)
1891 ok(size == unicodeResults[i].encoded.cbData,
1892 "Value type %d: expected size %d, got %d\n",
1893 value.dwValueType, unicodeResults[i].encoded.cbData, size);
1894 ok(!memcmp(unicodeResults[i].encoded.pbData, buf, size),
1895 "Value type %d: unexpected value\n", value.dwValueType);
1896 LocalFree(buf);
1899 /* These "encode," but they do so by truncating each unicode character
1900 * rather than properly encoding it. Kept separate from the proper results,
1901 * because the encoded forms won't decode to their original strings.
1903 for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
1905 value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
1906 value.dwValueType = unicodeWeirdness[i].valueType;
1907 ret = pCryptEncodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE, &value,
1908 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
1909 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
1910 if (buf)
1912 ok(size == unicodeWeirdness[i].encoded.cbData,
1913 "Value type %d: expected size %d, got %d\n",
1914 value.dwValueType, unicodeWeirdness[i].encoded.cbData, size);
1915 ok(!memcmp(unicodeWeirdness[i].encoded.pbData, buf, size),
1916 "Value type %d: unexpected value\n", value.dwValueType);
1917 LocalFree(buf);
1922 static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
1924 if (n <= 0) return 0;
1925 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
1926 return *str1 - *str2;
1929 static void test_decodeUnicodeNameValue(DWORD dwEncoding)
1931 DWORD i;
1933 for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
1935 BYTE *buf = NULL;
1936 BOOL ret;
1937 DWORD size = 0;
1939 ret = pCryptDecodeObjectEx(dwEncoding, X509_UNICODE_NAME_VALUE,
1940 unicodeResults[i].encoded.pbData, unicodeResults[i].encoded.cbData,
1941 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
1942 ok(ret || broken(GetLastError() == CRYPT_E_NOT_CHAR_STRING /* Win9x */),
1943 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
1944 if (ret && buf)
1946 PCERT_NAME_VALUE value = (PCERT_NAME_VALUE)buf;
1948 ok(value->dwValueType == unicodeResults[i].valueType,
1949 "Expected value type %d, got %d\n", unicodeResults[i].valueType,
1950 value->dwValueType);
1951 ok(!strncmpW((LPWSTR)value->Value.pbData, unicodeResults[i].str,
1952 value->Value.cbData / sizeof(WCHAR)),
1953 "Unexpected decoded value for index %d (value type %d)\n", i,
1954 unicodeResults[i].valueType);
1955 LocalFree(buf);
1960 struct encodedOctets
1962 const BYTE *val;
1963 const BYTE *encoded;
1966 static const unsigned char bin46[] = { 'h','i',0 };
1967 static const unsigned char bin47[] = { 0x04,0x02,'h','i',0 };
1968 static const unsigned char bin48[] = {
1969 's','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1970 static const unsigned char bin49[] = {
1971 0x04,0x0f,'s','o','m','e','l','o','n','g',0xff,'s','t','r','i','n','g',0 };
1972 static const unsigned char bin50[] = { 0 };
1973 static const unsigned char bin51[] = { 0x04,0x00,0 };
1975 static const struct encodedOctets octets[] = {
1976 { bin46, bin47 },
1977 { bin48, bin49 },
1978 { bin50, bin51 },
1981 static void test_encodeOctets(DWORD dwEncoding)
1983 CRYPT_DATA_BLOB blob;
1984 DWORD i;
1986 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
1988 BYTE *buf = NULL;
1989 BOOL ret;
1990 DWORD bufSize = 0;
1992 blob.cbData = strlen((const char*)octets[i].val);
1993 blob.pbData = (BYTE*)octets[i].val;
1994 ret = pCryptEncodeObjectEx(dwEncoding, X509_OCTET_STRING, &blob,
1995 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
1996 ok(ret, "CryptEncodeObjectEx failed: %d\n", GetLastError());
1997 if (buf)
1999 ok(buf[0] == 4,
2000 "Got unexpected type %d for octet string (expected 4)\n", buf[0]);
2001 ok(buf[1] == octets[i].encoded[1], "Got length %d, expected %d\n",
2002 buf[1], octets[i].encoded[1]);
2003 ok(!memcmp(buf + 1, octets[i].encoded + 1,
2004 octets[i].encoded[1] + 1), "Got unexpected value\n");
2005 LocalFree(buf);
2010 static void test_decodeOctets(DWORD dwEncoding)
2012 DWORD i;
2014 for (i = 0; i < sizeof(octets) / sizeof(octets[0]); i++)
2016 BYTE *buf = NULL;
2017 BOOL ret;
2018 DWORD bufSize = 0;
2020 ret = pCryptDecodeObjectEx(dwEncoding, X509_OCTET_STRING,
2021 octets[i].encoded, octets[i].encoded[1] + 2,
2022 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2023 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2024 ok(bufSize >= sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1],
2025 "Expected size >= %d, got %d\n",
2026 (int)sizeof(CRYPT_DATA_BLOB) + octets[i].encoded[1], bufSize);
2027 ok(buf != NULL, "Expected allocated buffer\n");
2028 if (buf)
2030 CRYPT_DATA_BLOB *blob = (CRYPT_DATA_BLOB *)buf;
2032 if (blob->cbData)
2033 ok(!memcmp(blob->pbData, octets[i].val, blob->cbData),
2034 "Unexpected value\n");
2035 LocalFree(buf);
2040 static const BYTE bytesToEncode[] = { 0xff, 0xff };
2042 struct encodedBits
2044 DWORD cUnusedBits;
2045 const BYTE *encoded;
2046 DWORD cbDecoded;
2047 const BYTE *decoded;
2050 static const unsigned char bin52[] = { 0x03,0x03,0x00,0xff,0xff };
2051 static const unsigned char bin53[] = { 0xff,0xff };
2052 static const unsigned char bin54[] = { 0x03,0x03,0x01,0xff,0xfe };
2053 static const unsigned char bin55[] = { 0xff,0xfe };
2054 static const unsigned char bin56[] = { 0x03,0x02,0x01,0xfe };
2055 static const unsigned char bin57[] = { 0xfe };
2056 static const unsigned char bin58[] = { 0x03,0x01,0x00 };
2058 static const struct encodedBits bits[] = {
2059 /* normal test cases */
2060 { 0, bin52, 2, bin53 },
2061 { 1, bin54, 2, bin55 },
2062 /* strange test case, showing cUnusedBits >= 8 is allowed */
2063 { 9, bin56, 1, bin57 },
2066 static void test_encodeBits(DWORD dwEncoding)
2068 DWORD i;
2070 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2072 CRYPT_BIT_BLOB blob;
2073 BOOL ret;
2074 BYTE *buf = NULL;
2075 DWORD bufSize = 0;
2077 blob.cbData = sizeof(bytesToEncode);
2078 blob.pbData = (BYTE *)bytesToEncode;
2079 blob.cUnusedBits = bits[i].cUnusedBits;
2080 ret = pCryptEncodeObjectEx(dwEncoding, X509_BITS, &blob,
2081 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2082 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2083 if (buf)
2085 ok(bufSize == bits[i].encoded[1] + 2,
2086 "%d: Got unexpected size %d, expected %d\n", i, bufSize,
2087 bits[i].encoded[1] + 2);
2088 ok(!memcmp(buf, bits[i].encoded, bits[i].encoded[1] + 2),
2089 "%d: Unexpected value\n", i);
2090 LocalFree(buf);
2095 static void test_decodeBits(DWORD dwEncoding)
2097 static const BYTE ber[] = "\x03\x02\x01\xff";
2098 static const BYTE berDecoded = 0xfe;
2099 DWORD i;
2100 BOOL ret;
2101 BYTE *buf = NULL;
2102 DWORD bufSize = 0;
2104 /* normal cases */
2105 for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
2107 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
2108 bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2109 &bufSize);
2110 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2111 if (buf)
2113 CRYPT_BIT_BLOB *blob;
2115 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + bits[i].cbDecoded,
2116 "Got unexpected size %d\n", bufSize);
2117 blob = (CRYPT_BIT_BLOB *)buf;
2118 ok(blob->cbData == bits[i].cbDecoded,
2119 "Got unexpected length %d, expected %d\n", blob->cbData,
2120 bits[i].cbDecoded);
2121 if (blob->cbData && bits[i].cbDecoded)
2122 ok(!memcmp(blob->pbData, bits[i].decoded, bits[i].cbDecoded),
2123 "Unexpected value\n");
2124 LocalFree(buf);
2127 /* special case: check that something that's valid in BER but not in DER
2128 * decodes successfully
2130 ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, ber, ber[1] + 2,
2131 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2132 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2133 if (buf)
2135 CRYPT_BIT_BLOB *blob;
2137 ok(bufSize >= sizeof(CRYPT_BIT_BLOB) + sizeof(berDecoded),
2138 "Got unexpected size %d\n", bufSize);
2139 blob = (CRYPT_BIT_BLOB *)buf;
2140 ok(blob->cbData == sizeof(berDecoded),
2141 "Got unexpected length %d\n", blob->cbData);
2142 if (blob->cbData)
2143 ok(*blob->pbData == berDecoded, "Unexpected value\n");
2144 LocalFree(buf);
2148 struct Constraints2
2150 CERT_BASIC_CONSTRAINTS2_INFO info;
2151 const BYTE *encoded;
2154 static const unsigned char bin59[] = { 0x30,0x00 };
2155 static const unsigned char bin60[] = { 0x30,0x03,0x01,0x01,0xff };
2156 static const unsigned char bin61[] = { 0x30,0x03,0x02,0x01,0x00 };
2157 static const unsigned char bin62[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2158 static const struct Constraints2 constraints2[] = {
2159 /* empty constraints */
2160 { { FALSE, FALSE, 0}, bin59 },
2161 /* can be a CA */
2162 { { TRUE, FALSE, 0}, bin60 },
2163 /* has path length constraints set (MSDN implies fCA needs to be TRUE as well,
2164 * but that's not the case
2166 { { FALSE, TRUE, 0}, bin61 },
2167 /* can be a CA and has path length constraints set */
2168 { { TRUE, TRUE, 1}, bin62 },
2171 static const BYTE emptyConstraint[] = { 0x30, 0x03, 0x03, 0x01, 0x00 };
2172 static const BYTE encodedDomainName[] = { 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11,
2173 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16,
2174 0x03, 0x6f, 0x72, 0x67, 0x30, 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93,
2175 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2176 static const BYTE constraintWithDomainName[] = { 0x30, 0x32, 0x03, 0x01, 0x00,
2177 0x30, 0x2d, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
2178 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x6f, 0x72, 0x67, 0x30,
2179 0x14, 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19,
2180 0x16, 0x06, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71 };
2182 static void test_encodeBasicConstraints(DWORD dwEncoding)
2184 DWORD i, bufSize = 0;
2185 CERT_BASIC_CONSTRAINTS_INFO info = { { 0 } };
2186 CERT_NAME_BLOB nameBlob = { sizeof(encodedDomainName),
2187 (LPBYTE)encodedDomainName };
2188 BOOL ret;
2189 BYTE *buf = NULL;
2191 /* First test with the simpler info2 */
2192 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2194 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2195 &constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2196 &bufSize);
2197 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2198 if (buf)
2200 ok(bufSize == constraints2[i].encoded[1] + 2,
2201 "Expected %d bytes, got %d\n", constraints2[i].encoded[1] + 2,
2202 bufSize);
2203 ok(!memcmp(buf, constraints2[i].encoded,
2204 constraints2[i].encoded[1] + 2), "Unexpected value\n");
2205 LocalFree(buf);
2208 /* Now test with more complex basic constraints */
2209 info.SubjectType.cbData = 0;
2210 info.fPathLenConstraint = FALSE;
2211 info.cSubtreesConstraint = 0;
2212 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2213 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2214 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2215 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2216 if (buf)
2218 ok(bufSize == sizeof(emptyConstraint), "Wrong size %d\n", bufSize);
2219 ok(!memcmp(buf, emptyConstraint, sizeof(emptyConstraint)),
2220 "Unexpected value\n");
2221 LocalFree(buf);
2223 /* None of the certs I examined had any subtree constraint, but I test one
2224 * anyway just in case.
2226 info.cSubtreesConstraint = 1;
2227 info.rgSubtreesConstraint = &nameBlob;
2228 ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS, &info,
2229 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2230 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2231 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2232 if (buf)
2234 ok(bufSize == sizeof(constraintWithDomainName), "Wrong size %d\n", bufSize);
2235 ok(!memcmp(buf, constraintWithDomainName,
2236 sizeof(constraintWithDomainName)), "Unexpected value\n");
2237 LocalFree(buf);
2239 /* FIXME: test encoding with subject type. */
2242 static const unsigned char bin63[] = { 0x30,0x06,0x01,0x01,0x01,0x02,0x01,0x01 };
2244 static void test_decodeBasicConstraints(DWORD dwEncoding)
2246 static const BYTE inverted[] = { 0x30, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01,
2247 0xff };
2248 static const struct Constraints2 badBool = { { TRUE, TRUE, 1 }, bin63 };
2249 DWORD i;
2250 BOOL ret;
2251 BYTE *buf = NULL;
2252 DWORD bufSize = 0;
2254 /* First test with simpler info2 */
2255 for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
2257 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2258 constraints2[i].encoded, constraints2[i].encoded[1] + 2,
2259 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2260 ok(ret, "CryptDecodeObjectEx failed for item %d: %08x\n", i,
2261 GetLastError());
2262 if (buf)
2264 CERT_BASIC_CONSTRAINTS2_INFO *info =
2265 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2267 ok(!memcmp(info, &constraints2[i].info, sizeof(*info)),
2268 "Unexpected value for item %d\n", i);
2269 LocalFree(buf);
2272 /* Check with the order of encoded elements inverted */
2273 buf = (PBYTE)1;
2274 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2275 inverted, inverted[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2276 &bufSize);
2277 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2278 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2279 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2280 GetLastError());
2281 ok(!buf, "Expected buf to be set to NULL\n");
2282 /* Check with a non-DER bool */
2283 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2284 badBool.encoded, badBool.encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
2285 &buf, &bufSize);
2286 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2287 if (buf)
2289 CERT_BASIC_CONSTRAINTS2_INFO *info =
2290 (CERT_BASIC_CONSTRAINTS2_INFO *)buf;
2292 ok(!memcmp(info, &badBool.info, sizeof(*info)), "Unexpected value\n");
2293 LocalFree(buf);
2295 /* Check with a non-basic constraints value */
2296 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
2297 encodedCommonName, encodedCommonName[1] + 2,
2298 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2299 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2300 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2301 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2302 GetLastError());
2303 /* Now check with the more complex CERT_BASIC_CONSTRAINTS_INFO */
2304 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2305 emptyConstraint, sizeof(emptyConstraint), CRYPT_DECODE_ALLOC_FLAG, NULL,
2306 &buf, &bufSize);
2307 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2308 if (buf)
2310 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2312 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2313 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2314 ok(info->cSubtreesConstraint == 0, "Expected no subtree constraints\n");
2315 LocalFree(buf);
2317 ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS,
2318 constraintWithDomainName, sizeof(constraintWithDomainName),
2319 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2320 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2321 if (buf)
2323 CERT_BASIC_CONSTRAINTS_INFO *info = (CERT_BASIC_CONSTRAINTS_INFO *)buf;
2325 ok(info->SubjectType.cbData == 0, "Expected no subject type\n");
2326 ok(!info->fPathLenConstraint, "Expected no path length constraint\n");
2327 ok(info->cSubtreesConstraint == 1, "Expected a subtree constraint\n");
2328 if (info->cSubtreesConstraint && info->rgSubtreesConstraint)
2330 ok(info->rgSubtreesConstraint[0].cbData ==
2331 sizeof(encodedDomainName), "Wrong size %d\n",
2332 info->rgSubtreesConstraint[0].cbData);
2333 ok(!memcmp(info->rgSubtreesConstraint[0].pbData, encodedDomainName,
2334 sizeof(encodedDomainName)), "Unexpected value\n");
2336 LocalFree(buf);
2340 /* These are terrible public keys of course, I'm just testing encoding */
2341 static const BYTE modulus1[] = { 0,0,0,1,1,1,1,1 };
2342 static const BYTE modulus2[] = { 1,1,1,1,1,0,0,0 };
2343 static const BYTE modulus3[] = { 0x80,1,1,1,1,0,0,0 };
2344 static const BYTE modulus4[] = { 1,1,1,1,1,0,0,0x80 };
2345 static const BYTE mod1_encoded[] = { 0x30,0x0f,0x02,0x08,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x02,0x03,0x01,0x00,0x01 };
2346 static const BYTE mod2_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2347 static const BYTE mod3_encoded[] = { 0x30,0x0c,0x02,0x05,0x01,0x01,0x01,0x01,0x80,0x02,0x03,0x01,0x00,0x01 };
2348 static const BYTE mod4_encoded[] = { 0x30,0x10,0x02,0x09,0x00,0x80,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x03,0x01,0x00,0x01 };
2350 struct EncodedRSAPubKey
2352 const BYTE *modulus;
2353 size_t modulusLen;
2354 const BYTE *encoded;
2355 size_t decodedModulusLen;
2358 struct EncodedRSAPubKey rsaPubKeys[] = {
2359 { modulus1, sizeof(modulus1), mod1_encoded, sizeof(modulus1) },
2360 { modulus2, sizeof(modulus2), mod2_encoded, 5 },
2361 { modulus3, sizeof(modulus3), mod3_encoded, 5 },
2362 { modulus4, sizeof(modulus4), mod4_encoded, 8 },
2365 static void test_encodeRsaPublicKey(DWORD dwEncoding)
2367 BYTE toEncode[sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) + sizeof(modulus1)];
2368 BLOBHEADER *hdr = (BLOBHEADER *)toEncode;
2369 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(toEncode + sizeof(BLOBHEADER));
2370 BOOL ret;
2371 BYTE *buf = NULL;
2372 DWORD bufSize = 0, i;
2374 /* Try with a bogus blob type */
2375 hdr->bType = 2;
2376 hdr->bVersion = CUR_BLOB_VERSION;
2377 hdr->reserved = 0;
2378 hdr->aiKeyAlg = CALG_RSA_KEYX;
2379 rsaPubKey->magic = 0x31415352;
2380 rsaPubKey->bitlen = sizeof(modulus1) * 8;
2381 rsaPubKey->pubexp = 65537;
2382 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY), modulus1,
2383 sizeof(modulus1));
2385 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2386 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2387 ok(!ret && GetLastError() == E_INVALIDARG,
2388 "Expected E_INVALIDARG, got %08x\n", GetLastError());
2389 /* Now with a bogus reserved field */
2390 hdr->bType = PUBLICKEYBLOB;
2391 hdr->reserved = 1;
2392 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2393 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2394 if (buf)
2396 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2397 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2398 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2399 LocalFree(buf);
2401 /* Now with a bogus blob version */
2402 hdr->reserved = 0;
2403 hdr->bVersion = 0;
2404 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2405 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2406 if (buf)
2408 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2409 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2410 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2411 LocalFree(buf);
2413 /* And with a bogus alg ID */
2414 hdr->bVersion = CUR_BLOB_VERSION;
2415 hdr->aiKeyAlg = CALG_DES;
2416 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2417 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2418 if (buf)
2420 ok(bufSize == rsaPubKeys[0].encoded[1] + 2,
2421 "Expected size %d, got %d\n", rsaPubKeys[0].encoded[1] + 2, bufSize);
2422 ok(!memcmp(buf, rsaPubKeys[0].encoded, bufSize), "Unexpected value\n");
2423 LocalFree(buf);
2425 /* Check a couple of RSA-related OIDs */
2426 hdr->aiKeyAlg = CALG_RSA_KEYX;
2427 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_RSA,
2428 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2429 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2430 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2431 ret = pCryptEncodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2432 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2433 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2434 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2435 /* Finally, all valid */
2436 hdr->aiKeyAlg = CALG_RSA_KEYX;
2437 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2439 memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2440 rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
2441 ret = pCryptEncodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2442 toEncode, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2443 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2444 if (buf)
2446 ok(bufSize == rsaPubKeys[i].encoded[1] + 2,
2447 "Expected size %d, got %d\n", rsaPubKeys[i].encoded[1] + 2,
2448 bufSize);
2449 ok(!memcmp(buf, rsaPubKeys[i].encoded, bufSize),
2450 "Unexpected value\n");
2451 LocalFree(buf);
2456 static void test_decodeRsaPublicKey(DWORD dwEncoding)
2458 DWORD i;
2459 LPBYTE buf = NULL;
2460 DWORD bufSize = 0;
2461 BOOL ret;
2463 /* Try with a bad length */
2464 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2465 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1],
2466 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2467 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
2468 GetLastError() == OSS_MORE_INPUT /* Win9x/NT4 */),
2469 "Expected CRYPT_E_ASN1_EOD or OSS_MORE_INPUT, got %08x\n",
2470 GetLastError());
2471 /* Try with a couple of RSA-related OIDs */
2472 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_RSA,
2473 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2474 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2475 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2476 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2477 ret = pCryptDecodeObjectEx(dwEncoding, szOID_RSA_SHA1RSA,
2478 rsaPubKeys[0].encoded, rsaPubKeys[0].encoded[1] + 2,
2479 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2480 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
2481 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
2482 /* Now try success cases */
2483 for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
2485 bufSize = 0;
2486 ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
2487 rsaPubKeys[i].encoded, rsaPubKeys[i].encoded[1] + 2,
2488 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2489 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2490 if (buf)
2492 BLOBHEADER *hdr = (BLOBHEADER *)buf;
2493 RSAPUBKEY *rsaPubKey = (RSAPUBKEY *)(buf + sizeof(BLOBHEADER));
2495 ok(bufSize >= sizeof(BLOBHEADER) + sizeof(RSAPUBKEY) +
2496 rsaPubKeys[i].decodedModulusLen,
2497 "Wrong size %d\n", bufSize);
2498 ok(hdr->bType == PUBLICKEYBLOB,
2499 "Expected type PUBLICKEYBLOB (%d), got %d\n", PUBLICKEYBLOB,
2500 hdr->bType);
2501 ok(hdr->bVersion == CUR_BLOB_VERSION,
2502 "Expected version CUR_BLOB_VERSION (%d), got %d\n",
2503 CUR_BLOB_VERSION, hdr->bVersion);
2504 ok(hdr->reserved == 0, "Expected reserved 0, got %d\n",
2505 hdr->reserved);
2506 ok(hdr->aiKeyAlg == CALG_RSA_KEYX,
2507 "Expected CALG_RSA_KEYX, got %08x\n", hdr->aiKeyAlg);
2508 ok(rsaPubKey->magic == 0x31415352,
2509 "Expected magic RSA1, got %08x\n", rsaPubKey->magic);
2510 ok(rsaPubKey->bitlen == rsaPubKeys[i].decodedModulusLen * 8,
2511 "Wrong bit len %d\n", rsaPubKey->bitlen);
2512 ok(rsaPubKey->pubexp == 65537, "Expected pubexp 65537, got %d\n",
2513 rsaPubKey->pubexp);
2514 ok(!memcmp(buf + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
2515 rsaPubKeys[i].modulus, rsaPubKeys[i].decodedModulusLen),
2516 "Unexpected modulus\n");
2517 LocalFree(buf);
2522 static const BYTE intSequence[] = { 0x30, 0x1b, 0x02, 0x01, 0x01, 0x02, 0x01,
2523 0x7f, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02,
2524 0x02, 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2526 static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
2527 0x36, 0x30, 0x36, 0x31, 0x36, 0x31, 0x30, 0x30, 0x30, 0x5a, 0x02, 0x01, 0x7f,
2528 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x01, 0x00, 0x02, 0x01, 0x80, 0x02, 0x02,
2529 0xff, 0x7f, 0x02, 0x04, 0xba, 0xdd, 0xf0, 0x0d };
2531 static void test_encodeSequenceOfAny(DWORD dwEncoding)
2533 CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
2534 CRYPT_SEQUENCE_OF_ANY seq;
2535 DWORD i;
2536 BOOL ret;
2537 BYTE *buf = NULL;
2538 DWORD bufSize = 0;
2540 /* Encode a homogeneous sequence */
2541 for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
2543 blobs[i].cbData = ints[i].encoded[1] + 2;
2544 blobs[i].pbData = (BYTE *)ints[i].encoded;
2546 seq.cValue = sizeof(ints) / sizeof(ints[0]);
2547 seq.rgValue = blobs;
2549 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2550 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2551 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2552 if (buf)
2554 ok(bufSize == sizeof(intSequence), "Wrong size %d\n", bufSize);
2555 ok(!memcmp(buf, intSequence, intSequence[1] + 2), "Unexpected value\n");
2556 LocalFree(buf);
2558 /* Change the type of the first element in the sequence, and give it
2559 * another go
2561 blobs[0].cbData = times[0].encodedTime[1] + 2;
2562 blobs[0].pbData = (BYTE *)times[0].encodedTime;
2563 ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
2564 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2565 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2566 if (buf)
2568 ok(bufSize == sizeof(mixedSequence), "Wrong size %d\n", bufSize);
2569 ok(!memcmp(buf, mixedSequence, mixedSequence[1] + 2),
2570 "Unexpected value\n");
2571 LocalFree(buf);
2575 static void test_decodeSequenceOfAny(DWORD dwEncoding)
2577 BOOL ret;
2578 BYTE *buf = NULL;
2579 DWORD bufSize = 0;
2581 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, intSequence,
2582 intSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2583 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2584 if (buf)
2586 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2587 DWORD i;
2589 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2590 "Wrong elements %d\n", seq->cValue);
2591 for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
2593 ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
2594 "Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
2595 seq->rgValue[i].cbData);
2596 ok(!memcmp(seq->rgValue[i].pbData, ints[i].encoded,
2597 ints[i].encoded[1] + 2), "Unexpected value\n");
2599 LocalFree(buf);
2601 ret = pCryptDecodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, mixedSequence,
2602 mixedSequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
2603 &bufSize);
2604 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2605 if (buf)
2607 CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
2609 ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
2610 "Wrong elements %d\n", seq->cValue);
2611 /* Just check the first element since it's all that changed */
2612 ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
2613 "Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
2614 seq->rgValue[0].cbData);
2615 ok(!memcmp(seq->rgValue[0].pbData, times[0].encodedTime,
2616 times[0].encodedTime[1] + 2), "Unexpected value\n");
2617 LocalFree(buf);
2621 struct encodedExtensions
2623 CERT_EXTENSIONS exts;
2624 const BYTE *encoded;
2627 static BYTE crit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2628 static BYTE noncrit_ext_data[] = { 0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2629 static CHAR oid_basic_constraints2[] = szOID_BASIC_CONSTRAINTS2;
2630 static CERT_EXTENSION criticalExt =
2631 { oid_basic_constraints2, TRUE, { 8, crit_ext_data } };
2632 static CERT_EXTENSION nonCriticalExt =
2633 { oid_basic_constraints2, FALSE, { 8, noncrit_ext_data } };
2634 static CHAR oid_short[] = "1.1";
2635 static CERT_EXTENSION extWithShortOid =
2636 { oid_short, FALSE, { 0, NULL } };
2638 static const BYTE ext0[] = { 0x30,0x00 };
2639 static const BYTE ext1[] = { 0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
2640 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2641 static const BYTE ext2[] = { 0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,
2642 0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2643 static const BYTE ext3[] = { 0x30,0x07,0x30,0x05,0x06,0x01,0x29,0x04,0x00 };
2645 static const struct encodedExtensions exts[] = {
2646 { { 0, NULL }, ext0 },
2647 { { 1, &criticalExt }, ext1 },
2648 { { 1, &nonCriticalExt }, ext2 },
2649 { { 1, &extWithShortOid }, ext3 }
2652 static void test_encodeExtensions(DWORD dwEncoding)
2654 DWORD i;
2656 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2658 BOOL ret;
2659 BYTE *buf = NULL;
2660 DWORD bufSize = 0;
2662 ret = pCryptEncodeObjectEx(dwEncoding, X509_EXTENSIONS, &exts[i].exts,
2663 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2664 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2665 if (buf)
2667 ok(bufSize == exts[i].encoded[1] + 2,
2668 "Expected %d bytes, got %d\n", exts[i].encoded[1] + 2, bufSize);
2669 ok(!memcmp(buf, exts[i].encoded, exts[i].encoded[1] + 2),
2670 "Unexpected value\n");
2671 LocalFree(buf);
2676 static void test_decodeExtensions(DWORD dwEncoding)
2678 DWORD i;
2680 for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
2682 BOOL ret;
2683 BYTE *buf = NULL;
2684 DWORD bufSize = 0;
2686 ret = pCryptDecodeObjectEx(dwEncoding, X509_EXTENSIONS,
2687 exts[i].encoded, exts[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2688 NULL, &buf, &bufSize);
2689 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2690 if (buf)
2692 CERT_EXTENSIONS *ext = (CERT_EXTENSIONS *)buf;
2693 DWORD j;
2695 ok(ext->cExtension == exts[i].exts.cExtension,
2696 "Expected %d extensions, see %d\n", exts[i].exts.cExtension,
2697 ext->cExtension);
2698 for (j = 0; j < min(ext->cExtension, exts[i].exts.cExtension); j++)
2700 ok(!strcmp(ext->rgExtension[j].pszObjId,
2701 exts[i].exts.rgExtension[j].pszObjId),
2702 "Expected OID %s, got %s\n",
2703 exts[i].exts.rgExtension[j].pszObjId,
2704 ext->rgExtension[j].pszObjId);
2705 ok(!memcmp(ext->rgExtension[j].Value.pbData,
2706 exts[i].exts.rgExtension[j].Value.pbData,
2707 exts[i].exts.rgExtension[j].Value.cbData),
2708 "Unexpected value\n");
2710 LocalFree(buf);
2715 /* MS encodes public key info with a NULL if the algorithm identifier's
2716 * parameters are empty. However, when encoding an algorithm in a CERT_INFO,
2717 * it encodes them by omitting the algorithm parameters. It accepts either
2718 * form for decoding.
2720 struct encodedPublicKey
2722 CERT_PUBLIC_KEY_INFO info;
2723 const BYTE *encoded;
2724 const BYTE *encodedNoNull;
2725 CERT_PUBLIC_KEY_INFO decoded;
2728 static const BYTE aKey[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
2729 0xe, 0xf };
2730 static const BYTE params[] = { 0x02, 0x01, 0x01 };
2732 static const unsigned char bin64[] = {
2733 0x30,0x0b,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x03,0x01,0x00};
2734 static const unsigned char bin65[] = {
2735 0x30,0x09,0x30,0x04,0x06,0x02,0x2a,0x03,0x03,0x01,0x00};
2736 static const unsigned char bin66[] = {
2737 0x30,0x0f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x01,0x00};
2738 static const unsigned char bin67[] = {
2739 0x30,0x0d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x01,0x00};
2740 static const unsigned char bin68[] = {
2741 0x30,0x1f,0x30,0x0a,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x05,0x00,0x03,0x11,0x00,0x00,0x01,
2742 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2743 static const unsigned char bin69[] = {
2744 0x30,0x1d,0x30,0x08,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x03,0x11,0x00,0x00,0x01,
2745 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
2746 static const unsigned char bin70[] = {
2747 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2748 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2749 0x0f};
2750 static const unsigned char bin71[] = {
2751 0x30,0x20,0x30,0x0b,0x06,0x06,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x01,0x01,
2752 0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,
2753 0x0f};
2754 static unsigned char bin72[] = { 0x05,0x00};
2756 static CHAR oid_bogus[] = "1.2.3",
2757 oid_rsa[] = szOID_RSA;
2759 static const struct encodedPublicKey pubKeys[] = {
2760 /* with a bogus OID */
2761 { { { oid_bogus, { 0, NULL } }, { 0, NULL, 0 } },
2762 bin64, bin65,
2763 { { oid_bogus, { 2, bin72 } }, { 0, NULL, 0 } } },
2764 /* some normal keys */
2765 { { { oid_rsa, { 0, NULL } }, { 0, NULL, 0} },
2766 bin66, bin67,
2767 { { oid_rsa, { 2, bin72 } }, { 0, NULL, 0 } } },
2768 { { { oid_rsa, { 0, NULL } }, { sizeof(aKey), (BYTE *)aKey, 0} },
2769 bin68, bin69,
2770 { { oid_rsa, { 2, bin72 } }, { sizeof(aKey), (BYTE *)aKey, 0} } },
2771 /* with add'l parameters--note they must be DER-encoded */
2772 { { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2773 (BYTE *)aKey, 0 } },
2774 bin70, bin71,
2775 { { oid_rsa, { sizeof(params), (BYTE *)params } }, { sizeof(aKey),
2776 (BYTE *)aKey, 0 } } },
2779 static void test_encodePublicKeyInfo(DWORD dwEncoding)
2781 DWORD i;
2783 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2785 BOOL ret;
2786 BYTE *buf = NULL;
2787 DWORD bufSize = 0;
2789 ret = pCryptEncodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2790 &pubKeys[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
2791 &bufSize);
2792 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
2793 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
2794 if (buf)
2796 ok(bufSize == pubKeys[i].encoded[1] + 2,
2797 "Expected %d bytes, got %d\n", pubKeys[i].encoded[1] + 2, bufSize);
2798 if (bufSize == pubKeys[i].encoded[1] + 2)
2799 ok(!memcmp(buf, pubKeys[i].encoded, pubKeys[i].encoded[1] + 2),
2800 "Unexpected value\n");
2801 LocalFree(buf);
2806 static void comparePublicKeyInfo(const CERT_PUBLIC_KEY_INFO *expected,
2807 const CERT_PUBLIC_KEY_INFO *got)
2809 ok(!strcmp(expected->Algorithm.pszObjId, got->Algorithm.pszObjId),
2810 "Expected OID %s, got %s\n", expected->Algorithm.pszObjId,
2811 got->Algorithm.pszObjId);
2812 ok(expected->Algorithm.Parameters.cbData ==
2813 got->Algorithm.Parameters.cbData,
2814 "Expected parameters of %d bytes, got %d\n",
2815 expected->Algorithm.Parameters.cbData, got->Algorithm.Parameters.cbData);
2816 if (expected->Algorithm.Parameters.cbData)
2817 ok(!memcmp(expected->Algorithm.Parameters.pbData,
2818 got->Algorithm.Parameters.pbData, got->Algorithm.Parameters.cbData),
2819 "Unexpected algorithm parameters\n");
2820 ok(expected->PublicKey.cbData == got->PublicKey.cbData,
2821 "Expected public key of %d bytes, got %d\n",
2822 expected->PublicKey.cbData, got->PublicKey.cbData);
2823 if (expected->PublicKey.cbData)
2824 ok(!memcmp(expected->PublicKey.pbData, got->PublicKey.pbData,
2825 got->PublicKey.cbData), "Unexpected public key value\n");
2828 static void test_decodePublicKeyInfo(DWORD dwEncoding)
2830 static const BYTE bogusPubKeyInfo[] = { 0x30, 0x22, 0x30, 0x0d, 0x06, 0x06,
2831 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03,
2832 0x11, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
2833 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
2834 DWORD i;
2835 BOOL ret;
2836 BYTE *buf = NULL;
2837 DWORD bufSize = 0;
2839 for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
2841 /* The NULL form decodes to the decoded member */
2842 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2843 pubKeys[i].encoded, pubKeys[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2844 NULL, &buf, &bufSize);
2845 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2846 if (buf)
2848 comparePublicKeyInfo(&pubKeys[i].decoded,
2849 (CERT_PUBLIC_KEY_INFO *)buf);
2850 LocalFree(buf);
2852 /* The non-NULL form decodes to the original */
2853 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2854 pubKeys[i].encodedNoNull, pubKeys[i].encodedNoNull[1] + 2,
2855 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &bufSize);
2856 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
2857 if (buf)
2859 comparePublicKeyInfo(&pubKeys[i].info, (CERT_PUBLIC_KEY_INFO *)buf);
2860 LocalFree(buf);
2863 /* Test with bogus (not valid DER) parameters */
2864 ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
2865 bogusPubKeyInfo, bogusPubKeyInfo[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
2866 NULL, &buf, &bufSize);
2867 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
2868 GetLastError() == OSS_DATA_ERROR /* Win9x */),
2869 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
2870 GetLastError());
2873 static const BYTE v1Cert[] = { 0x30, 0x33, 0x02, 0x00, 0x30, 0x02, 0x06, 0x00,
2874 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
2875 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30,
2876 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x07, 0x30,
2877 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2878 static const BYTE v2Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x01, 0x02,
2879 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2880 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2881 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2882 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2883 static const BYTE v3Cert[] = { 0x30, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02,
2884 0x00, 0x30, 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31,
2885 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f,
2886 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
2887 0x30, 0x5a, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00 };
2888 static const BYTE v4Cert[] = {
2889 0x30,0x38,0xa0,0x03,0x02,0x01,0x03,0x02,0x00,0x30,0x02,0x06,0x00,0x30,0x22,
2890 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
2891 0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,
2892 0x30,0x30,0x30,0x5a,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00 };
2893 static const BYTE v1CertWithConstraints[] = { 0x30, 0x4b, 0x02, 0x00, 0x30,
2894 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2895 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2896 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2897 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2898 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2899 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2900 static const BYTE v1CertWithSerial[] = { 0x30, 0x4c, 0x02, 0x01, 0x01, 0x30,
2901 0x02, 0x06, 0x00, 0x30, 0x22, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31,
2902 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36,
2903 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a,
2904 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3, 0x16, 0x30, 0x14,
2905 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30,
2906 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2907 static const BYTE bigCert[] = { 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
2908 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
2909 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22,
2910 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30,
2911 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30,
2912 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30,
2913 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20,
2914 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01,
2915 0x00, 0xa3, 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
2916 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01 };
2917 static const BYTE v1CertWithPubKey[] = {
2918 0x30,0x81,0x95,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2919 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2920 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2921 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2922 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2923 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2924 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2925 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2926 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,
2927 0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,
2928 0x01,0x01 };
2929 static const BYTE v1CertWithPubKeyNoNull[] = {
2930 0x30,0x81,0x93,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2931 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2932 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2933 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2934 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2935 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2936 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2937 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2938 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,
2939 0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
2940 static const BYTE v1CertWithSubjectKeyId[] = {
2941 0x30,0x7b,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
2942 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2943 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
2944 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
2945 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
2946 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
2947 0x00,0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0xa3,0x17,0x30,0x15,0x30,
2948 0x13,0x06,0x03,0x55,0x1d,0x0e,0x04,0x0c,0x04,0x0a,0x4a,0x75,0x61,0x6e,0x20,
2949 0x4c,0x61,0x6e,0x67,0x00 };
2950 static const BYTE v1CertWithIssuerUniqueId[] = {
2951 0x30,0x38,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,
2952 0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,
2953 0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
2954 0x30,0x07,0x30,0x02,0x06,0x00,0x03,0x01,0x00,0x81,0x02,0x00,0x01 };
2955 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueId[] = {
2956 0x30,0x81,0x99,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2957 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2958 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2959 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2960 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2961 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2962 0x67,0x00,0x30,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2963 0x01,0x01,0x05,0x00,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2964 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,
2965 0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,
2966 0x01,0x01,0xff,0x02,0x01,0x01 };
2967 static const BYTE v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull[] = {
2968 0x30,0x81,0x97,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,
2969 0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,
2970 0x6e,0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,
2971 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
2972 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,
2973 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
2974 0x67,0x00,0x30,0x20,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
2975 0x01,0x01,0x03,0x11,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
2976 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x81,0x02,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,
2977 0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,
2978 0xff,0x02,0x01,0x01 };
2980 static const BYTE serialNum[] = { 0x01 };
2982 static void test_encodeCertToBeSigned(DWORD dwEncoding)
2984 BOOL ret;
2985 BYTE *buf = NULL;
2986 DWORD size = 0;
2987 CERT_INFO info = { 0 };
2988 static char oid_rsa_rsa[] = szOID_RSA_RSA;
2989 static char oid_subject_key_identifier[] = szOID_SUBJECT_KEY_IDENTIFIER;
2990 CERT_EXTENSION ext;
2992 if (0)
2994 /* Test with NULL pvStructInfo (crashes on win9x) */
2995 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL,
2996 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
2997 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
2998 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3000 /* Test with a V1 cert */
3001 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3002 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3003 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3004 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3005 if (buf)
3007 ok(size == v1Cert[1] + 2, "Expected size %d, got %d\n",
3008 v1Cert[1] + 2, size);
3009 ok(!memcmp(buf, v1Cert, size), "Got unexpected value\n");
3010 LocalFree(buf);
3012 /* Test v2 cert */
3013 info.dwVersion = CERT_V2;
3014 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3015 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3016 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3017 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3018 if (buf)
3020 ok(size == sizeof(v2Cert), "Wrong size %d\n", size);
3021 ok(!memcmp(buf, v2Cert, size), "Got unexpected value\n");
3022 LocalFree(buf);
3024 /* Test v3 cert */
3025 info.dwVersion = CERT_V3;
3026 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3027 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3028 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3029 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3030 if (buf)
3032 ok(size == sizeof(v3Cert), "Wrong size %d\n", size);
3033 ok(!memcmp(buf, v3Cert, size), "Got unexpected value\n");
3034 LocalFree(buf);
3036 /* A v4 cert? */
3037 info.dwVersion = 3; /* Not a typo, CERT_V3 is 2 */
3038 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3039 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3040 if (buf)
3042 ok(size == sizeof(v4Cert), "Wrong size %d\n", size);
3043 ok(!memcmp(buf, v4Cert, size), "Unexpected value\n");
3044 LocalFree(buf);
3046 /* see if a V1 cert can have basic constraints set (RFC3280 says no, but
3047 * API doesn't prevent it)
3049 info.dwVersion = CERT_V1;
3050 info.cExtension = 1;
3051 info.rgExtension = &criticalExt;
3052 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3053 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3054 ok(ret || GetLastError() == OSS_BAD_PTR /* Win9x */,
3055 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3056 if (buf)
3058 ok(size == sizeof(v1CertWithConstraints), "Wrong size %d\n", size);
3059 ok(!memcmp(buf, v1CertWithConstraints, size), "Got unexpected value\n");
3060 LocalFree(buf);
3062 /* test v1 cert with a serial number */
3063 info.SerialNumber.cbData = sizeof(serialNum);
3064 info.SerialNumber.pbData = (BYTE *)serialNum;
3065 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3066 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3067 if (buf)
3069 ok(size == sizeof(v1CertWithSerial), "Wrong size %d\n", size);
3070 ok(!memcmp(buf, v1CertWithSerial, size), "Got unexpected value\n");
3071 LocalFree(buf);
3073 /* Test v1 cert with an issuer name, serial number, and issuer unique id */
3074 info.dwVersion = CERT_V1;
3075 info.cExtension = 0;
3076 info.IssuerUniqueId.cbData = sizeof(serialNum);
3077 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3078 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3079 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3080 ok(ret || broken(GetLastError() == OSS_BAD_PTR /* Win98 */),
3081 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3082 if (buf)
3084 ok(size == sizeof(v1CertWithIssuerUniqueId), "Wrong size %d\n", size);
3085 ok(!memcmp(buf, v1CertWithIssuerUniqueId, size),
3086 "Got unexpected value\n");
3087 LocalFree(buf);
3089 /* Test v1 cert with an issuer name, a subject name, and a serial number */
3090 info.IssuerUniqueId.cbData = 0;
3091 info.IssuerUniqueId.pbData = NULL;
3092 info.cExtension = 1;
3093 info.rgExtension = &criticalExt;
3094 info.Issuer.cbData = sizeof(encodedCommonName);
3095 info.Issuer.pbData = (BYTE *)encodedCommonName;
3096 info.Subject.cbData = sizeof(encodedCommonName);
3097 info.Subject.pbData = (BYTE *)encodedCommonName;
3098 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3099 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3100 if (buf)
3102 ok(size == sizeof(bigCert), "Wrong size %d\n", size);
3103 ok(!memcmp(buf, bigCert, size), "Got unexpected value\n");
3104 LocalFree(buf);
3106 /* Add a public key */
3107 info.SubjectPublicKeyInfo.Algorithm.pszObjId = oid_rsa_rsa;
3108 info.SubjectPublicKeyInfo.PublicKey.cbData = sizeof(aKey);
3109 info.SubjectPublicKeyInfo.PublicKey.pbData = (LPBYTE)aKey;
3110 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3111 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3112 if (buf)
3114 ok(size == sizeof(v1CertWithPubKey) ||
3115 size == sizeof(v1CertWithPubKeyNoNull), "Wrong size %d\n", size);
3116 if (size == sizeof(v1CertWithPubKey))
3117 ok(!memcmp(buf, v1CertWithPubKey, size), "Got unexpected value\n");
3118 else if (size == sizeof(v1CertWithPubKeyNoNull))
3119 ok(!memcmp(buf, v1CertWithPubKeyNoNull, size),
3120 "Got unexpected value\n");
3121 LocalFree(buf);
3123 /* Again add an issuer unique id */
3124 info.IssuerUniqueId.cbData = sizeof(serialNum);
3125 info.IssuerUniqueId.pbData = (BYTE *)serialNum;
3126 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3127 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3128 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3129 if (buf)
3131 ok(size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId) ||
3132 size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull),
3133 "Wrong size %d\n", size);
3134 if (size == sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId))
3135 ok(!memcmp(buf, v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3136 size), "unexpected value\n");
3137 else if (size ==
3138 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull))
3139 ok(!memcmp(buf,
3140 v1CertWithSubjectIssuerSerialAndIssuerUniqueIdNoNull, size),
3141 "unexpected value\n");
3142 LocalFree(buf);
3144 /* Remove the public key, and add a subject key identifier extension */
3145 info.IssuerUniqueId.cbData = 0;
3146 info.IssuerUniqueId.pbData = NULL;
3147 info.SubjectPublicKeyInfo.Algorithm.pszObjId = NULL;
3148 info.SubjectPublicKeyInfo.PublicKey.cbData = 0;
3149 info.SubjectPublicKeyInfo.PublicKey.pbData = NULL;
3150 ext.pszObjId = oid_subject_key_identifier;
3151 ext.fCritical = FALSE;
3152 ext.Value.cbData = sizeof(octetCommonNameValue);
3153 ext.Value.pbData = octetCommonNameValue;
3154 info.cExtension = 1;
3155 info.rgExtension = &ext;
3156 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, &info,
3157 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3158 if (buf)
3160 ok(size == sizeof(v1CertWithSubjectKeyId), "Wrong size %d\n", size);
3161 ok(!memcmp(buf, v1CertWithSubjectKeyId, size), "Unexpected value\n");
3162 LocalFree(buf);
3166 static void test_decodeCertToBeSigned(DWORD dwEncoding)
3168 static const BYTE *corruptCerts[] = { v1Cert, v2Cert, v3Cert, v4Cert,
3169 v1CertWithConstraints, v1CertWithSerial, v1CertWithIssuerUniqueId };
3170 BOOL ret;
3171 BYTE *buf = NULL;
3172 DWORD size = 0, i;
3174 /* Test with NULL pbEncoded */
3175 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 0,
3176 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3177 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
3178 GetLastError() == OSS_BAD_ARG /* Win9x */),
3179 "Expected CRYPT_E_ASN1_EOD or OSS_BAD_ARG, got %08x\n", GetLastError());
3180 if (0)
3182 /* Crashes on win9x */
3183 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, NULL, 1,
3184 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3185 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3186 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3188 /* The following certs all fail with CRYPT_E_ASN1_CORRUPT or
3189 * CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
3190 * serial number, an issuer, a subject, and a public key.
3192 for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
3194 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3195 corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3196 &buf, &size);
3197 ok(!ret, "Expected failure\n");
3199 /* The following succeeds, even though v1 certs are not allowed to have
3200 * extensions.
3202 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3203 v1CertWithSubjectKeyId, sizeof(v1CertWithSubjectKeyId),
3204 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3205 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3206 if (ret)
3208 CERT_INFO *info = (CERT_INFO *)buf;
3210 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3211 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3212 info->dwVersion);
3213 ok(info->cExtension == 1, "expected 1 extension, got %d\n",
3214 info->cExtension);
3215 LocalFree(buf);
3217 /* The following also succeeds, even though V1 certs are not allowed to
3218 * have issuer unique ids.
3220 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3221 v1CertWithSubjectIssuerSerialAndIssuerUniqueId,
3222 sizeof(v1CertWithSubjectIssuerSerialAndIssuerUniqueId),
3223 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3224 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3225 if (ret)
3227 CERT_INFO *info = (CERT_INFO *)buf;
3229 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3230 ok(info->dwVersion == CERT_V1, "expected CERT_V1, got %d\n",
3231 info->dwVersion);
3232 ok(info->IssuerUniqueId.cbData == sizeof(serialNum),
3233 "unexpected issuer unique id size %d\n", info->IssuerUniqueId.cbData);
3234 ok(!memcmp(info->IssuerUniqueId.pbData, serialNum, sizeof(serialNum)),
3235 "unexpected issuer unique id value\n");
3236 LocalFree(buf);
3238 /* Now check with serial number, subject and issuer specified */
3239 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, bigCert,
3240 sizeof(bigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3241 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3242 if (buf)
3244 CERT_INFO *info = (CERT_INFO *)buf;
3246 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3247 ok(info->SerialNumber.cbData == 1,
3248 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3249 ok(*info->SerialNumber.pbData == *serialNum,
3250 "Expected serial number %d, got %d\n", *serialNum,
3251 *info->SerialNumber.pbData);
3252 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3253 "Wrong size %d\n", info->Issuer.cbData);
3254 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3255 "Unexpected issuer\n");
3256 ok(info->Subject.cbData == sizeof(encodedCommonName),
3257 "Wrong size %d\n", info->Subject.cbData);
3258 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3259 info->Subject.cbData), "Unexpected subject\n");
3260 LocalFree(buf);
3262 /* Check again with pub key specified */
3263 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
3264 v1CertWithPubKey, sizeof(v1CertWithPubKey), CRYPT_DECODE_ALLOC_FLAG, NULL,
3265 &buf, &size);
3266 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3267 if (buf)
3269 CERT_INFO *info = (CERT_INFO *)buf;
3271 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3272 ok(info->SerialNumber.cbData == 1,
3273 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3274 ok(*info->SerialNumber.pbData == *serialNum,
3275 "Expected serial number %d, got %d\n", *serialNum,
3276 *info->SerialNumber.pbData);
3277 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3278 "Wrong size %d\n", info->Issuer.cbData);
3279 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3280 "Unexpected issuer\n");
3281 ok(info->Subject.cbData == sizeof(encodedCommonName),
3282 "Wrong size %d\n", info->Subject.cbData);
3283 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3284 info->Subject.cbData), "Unexpected subject\n");
3285 ok(!strcmp(info->SubjectPublicKeyInfo.Algorithm.pszObjId,
3286 szOID_RSA_RSA), "Expected szOID_RSA_RSA, got %s\n",
3287 info->SubjectPublicKeyInfo.Algorithm.pszObjId);
3288 ok(info->SubjectPublicKeyInfo.PublicKey.cbData == sizeof(aKey),
3289 "Wrong size %d\n", info->SubjectPublicKeyInfo.PublicKey.cbData);
3290 ok(!memcmp(info->SubjectPublicKeyInfo.PublicKey.pbData, aKey,
3291 sizeof(aKey)), "Unexpected public key\n");
3292 LocalFree(buf);
3296 static const BYTE hash[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd,
3297 0xe, 0xf };
3299 static const BYTE signedBigCert[] = {
3300 0x30, 0x81, 0x93, 0x30, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06, 0x00, 0x30,
3301 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a,
3302 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x30, 0x22, 0x18, 0x0f,
3303 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3304 0x30, 0x5a, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30,
3305 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06,
3306 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61,
3307 0x6e, 0x67, 0x00, 0x30, 0x07, 0x30, 0x02, 0x06, 0x00, 0x03, 0x01, 0x00, 0xa3,
3308 0x16, 0x30, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff,
3309 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3310 0x00, 0x03, 0x11, 0x00, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07,
3311 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
3313 static void test_encodeCert(DWORD dwEncoding)
3315 /* Note the SignatureAlgorithm must match that in the encoded cert. Note
3316 * also that bigCert is a NULL-terminated string, so don't count its
3317 * last byte (otherwise the signed cert won't decode.)
3319 CERT_SIGNED_CONTENT_INFO info = { { sizeof(bigCert), (BYTE *)bigCert },
3320 { NULL, { 0, NULL } }, { sizeof(hash), (BYTE *)hash, 0 } };
3321 BOOL ret;
3322 BYTE *buf = NULL;
3323 DWORD bufSize = 0;
3325 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT, &info,
3326 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &bufSize);
3327 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3328 if (buf)
3330 ok(bufSize == sizeof(signedBigCert), "Wrong size %d\n", bufSize);
3331 ok(!memcmp(buf, signedBigCert, bufSize), "Unexpected cert\n");
3332 LocalFree(buf);
3336 static void test_decodeCert(DWORD dwEncoding)
3338 BOOL ret;
3339 BYTE *buf = NULL;
3340 DWORD size = 0;
3342 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT, signedBigCert,
3343 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3344 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3345 if (buf)
3347 CERT_SIGNED_CONTENT_INFO *info = (CERT_SIGNED_CONTENT_INFO *)buf;
3349 ok(info->ToBeSigned.cbData == sizeof(bigCert),
3350 "Wrong cert size %d\n", info->ToBeSigned.cbData);
3351 ok(!memcmp(info->ToBeSigned.pbData, bigCert, info->ToBeSigned.cbData),
3352 "Unexpected cert\n");
3353 ok(info->Signature.cbData == sizeof(hash),
3354 "Wrong signature size %d\n", info->Signature.cbData);
3355 ok(!memcmp(info->Signature.pbData, hash, info->Signature.cbData),
3356 "Unexpected signature\n");
3357 LocalFree(buf);
3359 /* A signed cert decodes as a CERT_INFO too */
3360 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED, signedBigCert,
3361 sizeof(signedBigCert), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3362 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3363 if (buf)
3365 CERT_INFO *info = (CERT_INFO *)buf;
3367 ok(size >= sizeof(CERT_INFO), "Wrong size %d\n", size);
3368 ok(info->SerialNumber.cbData == 1,
3369 "Expected serial number size 1, got %d\n", info->SerialNumber.cbData);
3370 ok(*info->SerialNumber.pbData == *serialNum,
3371 "Expected serial number %d, got %d\n", *serialNum,
3372 *info->SerialNumber.pbData);
3373 ok(info->Issuer.cbData == sizeof(encodedCommonName),
3374 "Wrong size %d\n", info->Issuer.cbData);
3375 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
3376 "Unexpected issuer\n");
3377 ok(info->Subject.cbData == sizeof(encodedCommonName),
3378 "Wrong size %d\n", info->Subject.cbData);
3379 ok(!memcmp(info->Subject.pbData, encodedCommonName,
3380 info->Subject.cbData), "Unexpected subject\n");
3381 LocalFree(buf);
3385 static const BYTE emptyDistPoint[] = { 0x30, 0x02, 0x30, 0x00 };
3386 static const BYTE distPointWithUrl[] = { 0x30, 0x19, 0x30, 0x17, 0xa0, 0x15,
3387 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69,
3388 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3389 static const BYTE distPointWithReason[] = { 0x30, 0x06, 0x30, 0x04, 0x81, 0x02,
3390 0x00, 0x03 };
3391 static const BYTE distPointWithIssuer[] = { 0x30, 0x17, 0x30, 0x15, 0xa2, 0x13,
3392 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65,
3393 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67 };
3394 static const BYTE distPointWithUrlAndIssuer[] = { 0x30, 0x2e, 0x30, 0x2c, 0xa0,
3395 0x15, 0xa0, 0x13, 0x86, 0x11, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77,
3396 0x69, 0x6e, 0x65, 0x68, 0x71, 0x2e, 0x6f, 0x72, 0x67, 0xa2, 0x13, 0x86, 0x11,
3397 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x69, 0x6e, 0x65, 0x68, 0x71,
3398 0x2e, 0x6f, 0x72, 0x67 };
3399 static const BYTE crlReason = CRL_REASON_KEY_COMPROMISE |
3400 CRL_REASON_AFFILIATION_CHANGED;
3402 static void test_encodeCRLDistPoints(DWORD dwEncoding)
3404 CRL_DIST_POINTS_INFO info = { 0 };
3405 CRL_DIST_POINT point = { { 0 } };
3406 CERT_ALT_NAME_ENTRY entry = { 0 };
3407 BOOL ret;
3408 BYTE *buf = NULL;
3409 DWORD size = 0;
3411 /* Test with an empty info */
3412 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3413 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3414 ok(!ret && GetLastError() == E_INVALIDARG,
3415 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3416 /* Test with one empty dist point */
3417 info.cDistPoint = 1;
3418 info.rgDistPoint = &point;
3419 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3420 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3421 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3422 if (buf)
3424 ok(size == sizeof(emptyDistPoint), "Wrong size %d\n", size);
3425 ok(!memcmp(buf, emptyDistPoint, size), "Unexpected value\n");
3426 LocalFree(buf);
3428 /* A dist point with an invalid name */
3429 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3430 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3431 U(entry).pwszURL = (LPWSTR)nihongoURL;
3432 U(point.DistPointName).FullName.cAltEntry = 1;
3433 U(point.DistPointName).FullName.rgAltEntry = &entry;
3434 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3435 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3436 ok(!ret && GetLastError() == CRYPT_E_INVALID_IA5_STRING,
3437 "Expected CRYPT_E_INVALID_IA5_STRING, got %08x\n", GetLastError());
3438 /* The first invalid character is at index 7 */
3439 ok(GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size) == 7,
3440 "Expected invalid char at index 7, got %d\n",
3441 GET_CERT_ALT_NAME_VALUE_ERR_INDEX(size));
3442 /* A dist point with (just) a valid name */
3443 U(entry).pwszURL = (LPWSTR)url;
3444 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3445 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3446 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3447 if (buf)
3449 ok(size == sizeof(distPointWithUrl), "Wrong size %d\n", size);
3450 ok(!memcmp(buf, distPointWithUrl, size), "Unexpected value\n");
3451 LocalFree(buf);
3453 /* A dist point with (just) reason flags */
3454 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_NO_NAME;
3455 point.ReasonFlags.cbData = sizeof(crlReason);
3456 point.ReasonFlags.pbData = (LPBYTE)&crlReason;
3457 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3458 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3459 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3460 if (buf)
3462 ok(size == sizeof(distPointWithReason), "Wrong size %d\n", size);
3463 ok(!memcmp(buf, distPointWithReason, size), "Unexpected value\n");
3464 LocalFree(buf);
3466 /* A dist point with just an issuer */
3467 point.ReasonFlags.cbData = 0;
3468 point.CRLIssuer.cAltEntry = 1;
3469 point.CRLIssuer.rgAltEntry = &entry;
3470 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3471 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3472 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3473 if (buf)
3475 ok(size == sizeof(distPointWithIssuer), "Wrong size %d\n", size);
3476 ok(!memcmp(buf, distPointWithIssuer, size), "Unexpected value\n");
3477 LocalFree(buf);
3479 /* A dist point with both a name and an issuer */
3480 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3481 ret = pCryptEncodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS, &info,
3482 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3483 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3484 if (buf)
3486 ok(size == sizeof(distPointWithUrlAndIssuer),
3487 "Wrong size %d\n", size);
3488 ok(!memcmp(buf, distPointWithUrlAndIssuer, size), "Unexpected value\n");
3489 LocalFree(buf);
3493 static void test_decodeCRLDistPoints(DWORD dwEncoding)
3495 BOOL ret;
3496 BYTE *buf = NULL;
3497 DWORD size = 0;
3498 PCRL_DIST_POINTS_INFO info;
3499 PCRL_DIST_POINT point;
3500 PCERT_ALT_NAME_ENTRY entry;
3502 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3503 emptyDistPoint, emptyDistPoint[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3504 &buf, &size);
3505 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3506 if (ret)
3508 info = (PCRL_DIST_POINTS_INFO)buf;
3509 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3510 "Wrong size %d\n", size);
3511 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3512 info->cDistPoint);
3513 point = info->rgDistPoint;
3514 ok(point->DistPointName.dwDistPointNameChoice == CRL_DIST_POINT_NO_NAME,
3515 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3516 point->DistPointName.dwDistPointNameChoice);
3517 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3518 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3519 LocalFree(buf);
3521 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3522 distPointWithUrl, distPointWithUrl[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3523 &buf, &size);
3524 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3525 if (ret)
3527 info = (PCRL_DIST_POINTS_INFO)buf;
3528 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3529 "Wrong size %d\n", size);
3530 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3531 info->cDistPoint);
3532 point = info->rgDistPoint;
3533 ok(point->DistPointName.dwDistPointNameChoice ==
3534 CRL_DIST_POINT_FULL_NAME,
3535 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3536 point->DistPointName.dwDistPointNameChoice);
3537 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3538 "Expected 1 name entry, got %d\n",
3539 U(point->DistPointName).FullName.cAltEntry);
3540 entry = U(point->DistPointName).FullName.rgAltEntry;
3541 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3542 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3543 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3544 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3545 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3546 LocalFree(buf);
3548 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3549 distPointWithReason, distPointWithReason[1] + 2, CRYPT_DECODE_ALLOC_FLAG,
3550 NULL, &buf, &size);
3551 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3552 if (ret)
3554 info = (PCRL_DIST_POINTS_INFO)buf;
3555 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3556 "Wrong size %d\n", size);
3557 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3558 info->cDistPoint);
3559 point = info->rgDistPoint;
3560 ok(point->DistPointName.dwDistPointNameChoice ==
3561 CRL_DIST_POINT_NO_NAME,
3562 "Expected CRL_DIST_POINT_NO_NAME, got %d\n",
3563 point->DistPointName.dwDistPointNameChoice);
3564 ok(point->ReasonFlags.cbData == sizeof(crlReason),
3565 "Expected reason length\n");
3566 ok(!memcmp(point->ReasonFlags.pbData, &crlReason, sizeof(crlReason)),
3567 "Unexpected reason\n");
3568 ok(point->CRLIssuer.cAltEntry == 0, "Expected no issuer\n");
3569 LocalFree(buf);
3571 ret = pCryptDecodeObjectEx(dwEncoding, X509_CRL_DIST_POINTS,
3572 distPointWithUrlAndIssuer, distPointWithUrlAndIssuer[1] + 2,
3573 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3574 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3575 if (ret)
3577 info = (PCRL_DIST_POINTS_INFO)buf;
3578 ok(size >= sizeof(CRL_DIST_POINTS_INFO) + sizeof(CRL_DIST_POINT),
3579 "Wrong size %d\n", size);
3580 ok(info->cDistPoint == 1, "Expected 1 dist points, got %d\n",
3581 info->cDistPoint);
3582 point = info->rgDistPoint;
3583 ok(point->DistPointName.dwDistPointNameChoice ==
3584 CRL_DIST_POINT_FULL_NAME,
3585 "Expected CRL_DIST_POINT_FULL_NAME, got %d\n",
3586 point->DistPointName.dwDistPointNameChoice);
3587 ok(U(point->DistPointName).FullName.cAltEntry == 1,
3588 "Expected 1 name entry, got %d\n",
3589 U(point->DistPointName).FullName.cAltEntry);
3590 entry = U(point->DistPointName).FullName.rgAltEntry;
3591 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3592 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3593 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3594 ok(point->ReasonFlags.cbData == 0, "Expected no reason\n");
3595 ok(point->CRLIssuer.cAltEntry == 1,
3596 "Expected 1 issuer entry, got %d\n", point->CRLIssuer.cAltEntry);
3597 entry = point->CRLIssuer.rgAltEntry;
3598 ok(entry->dwAltNameChoice == CERT_ALT_NAME_URL,
3599 "Expected CERT_ALT_NAME_URL, got %d\n", entry->dwAltNameChoice);
3600 ok(!lstrcmpW(U(*entry).pwszURL, url), "Unexpected name\n");
3601 LocalFree(buf);
3605 static const BYTE badFlagsIDP[] = { 0x30,0x06,0x81,0x01,0xff,0x82,0x01,0xff };
3606 static const BYTE emptyNameIDP[] = { 0x30,0x04,0xa0,0x02,0xa0,0x00 };
3607 static const BYTE urlIDP[] = { 0x30,0x17,0xa0,0x15,0xa0,0x13,0x86,0x11,0x68,
3608 0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,
3609 0x67 };
3611 static void test_encodeCRLIssuingDistPoint(DWORD dwEncoding)
3613 BOOL ret;
3614 BYTE *buf = NULL;
3615 DWORD size = 0;
3616 CRL_ISSUING_DIST_POINT point = { { 0 } };
3617 CERT_ALT_NAME_ENTRY entry;
3619 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, NULL,
3620 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3621 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3623 skip("no X509_ISSUING_DIST_POINT encode support\n");
3624 return;
3626 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3627 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3628 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3629 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3630 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3631 if (buf)
3633 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
3634 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
3635 LocalFree(buf);
3637 /* nonsensical flags */
3638 point.fOnlyContainsUserCerts = TRUE;
3639 point.fOnlyContainsCACerts = TRUE;
3640 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3641 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3642 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3643 if (buf)
3645 ok(size == sizeof(badFlagsIDP), "Unexpected size %d\n", size);
3646 ok(!memcmp(buf, badFlagsIDP, size), "Unexpected value\n");
3647 LocalFree(buf);
3649 /* unimplemented name type */
3650 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3651 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_ISSUER_RDN_NAME;
3652 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3653 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3654 ok(!ret && GetLastError() == E_INVALIDARG,
3655 "Expected E_INVALIDARG, got %08x\n", GetLastError());
3656 /* empty name */
3657 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3658 U(point.DistPointName).FullName.cAltEntry = 0;
3659 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3660 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3661 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3662 if (buf)
3664 ok(size == sizeof(emptyNameIDP), "Unexpected size %d\n", size);
3665 ok(!memcmp(buf, emptyNameIDP, size), "Unexpected value\n");
3666 LocalFree(buf);
3668 /* name with URL entry */
3669 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3670 U(entry).pwszURL = (LPWSTR)url;
3671 U(point.DistPointName).FullName.cAltEntry = 1;
3672 U(point.DistPointName).FullName.rgAltEntry = &entry;
3673 ret = pCryptEncodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT, &point,
3674 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3675 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3676 if (buf)
3678 ok(size == sizeof(urlIDP), "Unexpected size %d\n", size);
3679 ok(!memcmp(buf, urlIDP, size), "Unexpected value\n");
3680 LocalFree(buf);
3684 static void compareAltNameEntry(const CERT_ALT_NAME_ENTRY *expected,
3685 const CERT_ALT_NAME_ENTRY *got)
3687 ok(expected->dwAltNameChoice == got->dwAltNameChoice,
3688 "Expected name choice %d, got %d\n", expected->dwAltNameChoice,
3689 got->dwAltNameChoice);
3690 if (expected->dwAltNameChoice == got->dwAltNameChoice)
3692 switch (got->dwAltNameChoice)
3694 case CERT_ALT_NAME_RFC822_NAME:
3695 case CERT_ALT_NAME_DNS_NAME:
3696 case CERT_ALT_NAME_EDI_PARTY_NAME:
3697 case CERT_ALT_NAME_URL:
3698 case CERT_ALT_NAME_REGISTERED_ID:
3699 ok((!U(*expected).pwszURL && !U(*got).pwszURL) ||
3700 (!U(*expected).pwszURL && !lstrlenW(U(*got).pwszURL)) ||
3701 (!U(*got).pwszURL && !lstrlenW(U(*expected).pwszURL)) ||
3702 !lstrcmpW(U(*expected).pwszURL, U(*got).pwszURL),
3703 "Unexpected name\n");
3704 break;
3705 case CERT_ALT_NAME_X400_ADDRESS:
3706 case CERT_ALT_NAME_DIRECTORY_NAME:
3707 case CERT_ALT_NAME_IP_ADDRESS:
3708 ok(U(*got).IPAddress.cbData == U(*expected).IPAddress.cbData,
3709 "Unexpected IP address length %d\n", U(*got).IPAddress.cbData);
3710 ok(!memcmp(U(*got).IPAddress.pbData, U(*got).IPAddress.pbData,
3711 U(*got).IPAddress.cbData), "Unexpected value\n");
3712 break;
3717 static void compareAltNameInfo(const CERT_ALT_NAME_INFO *expected,
3718 const CERT_ALT_NAME_INFO *got)
3720 DWORD i;
3722 ok(expected->cAltEntry == got->cAltEntry, "Expected %d entries, got %d\n",
3723 expected->cAltEntry, got->cAltEntry);
3724 for (i = 0; i < min(expected->cAltEntry, got->cAltEntry); i++)
3725 compareAltNameEntry(&expected->rgAltEntry[i], &got->rgAltEntry[i]);
3728 static void compareDistPointName(const CRL_DIST_POINT_NAME *expected,
3729 const CRL_DIST_POINT_NAME *got)
3731 ok(got->dwDistPointNameChoice == expected->dwDistPointNameChoice,
3732 "Unexpected name choice %d\n", got->dwDistPointNameChoice);
3733 if (got->dwDistPointNameChoice == CRL_DIST_POINT_FULL_NAME)
3734 compareAltNameInfo(&(U(*expected).FullName), &(U(*got).FullName));
3737 static void compareCRLIssuingDistPoints(const CRL_ISSUING_DIST_POINT *expected,
3738 const CRL_ISSUING_DIST_POINT *got)
3740 compareDistPointName(&expected->DistPointName, &got->DistPointName);
3741 ok(got->fOnlyContainsUserCerts == expected->fOnlyContainsUserCerts,
3742 "Unexpected fOnlyContainsUserCerts\n");
3743 ok(got->fOnlyContainsCACerts == expected->fOnlyContainsCACerts,
3744 "Unexpected fOnlyContainsCACerts\n");
3745 ok(got->OnlySomeReasonFlags.cbData == expected->OnlySomeReasonFlags.cbData,
3746 "Unexpected reason flags\n");
3747 ok(got->fIndirectCRL == expected->fIndirectCRL,
3748 "Unexpected fIndirectCRL\n");
3751 static void test_decodeCRLIssuingDistPoint(DWORD dwEncoding)
3753 BOOL ret;
3754 BYTE *buf = NULL;
3755 DWORD size = 0;
3756 CRL_ISSUING_DIST_POINT point = { { 0 } };
3758 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3759 emptySequence, emptySequence[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3760 &buf, &size);
3761 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
3763 skip("no X509_ISSUING_DIST_POINT decode support\n");
3764 return;
3766 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3767 if (ret)
3769 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3770 LocalFree(buf);
3772 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3773 badFlagsIDP, badFlagsIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3774 &buf, &size);
3775 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3776 if (ret)
3778 point.fOnlyContainsUserCerts = point.fOnlyContainsCACerts = TRUE;
3779 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3780 LocalFree(buf);
3782 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3783 emptyNameIDP, emptyNameIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
3784 &buf, &size);
3785 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3786 if (ret)
3788 point.fOnlyContainsCACerts = point.fOnlyContainsUserCerts = FALSE;
3789 point.DistPointName.dwDistPointNameChoice = CRL_DIST_POINT_FULL_NAME;
3790 U(point.DistPointName).FullName.cAltEntry = 0;
3791 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3792 LocalFree(buf);
3794 ret = pCryptDecodeObjectEx(dwEncoding, X509_ISSUING_DIST_POINT,
3795 urlIDP, urlIDP[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
3796 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
3797 if (ret)
3799 CERT_ALT_NAME_ENTRY entry;
3801 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
3802 U(entry).pwszURL = (LPWSTR)url;
3803 U(point.DistPointName).FullName.cAltEntry = 1;
3804 U(point.DistPointName).FullName.rgAltEntry = &entry;
3805 compareCRLIssuingDistPoints(&point, (PCRL_ISSUING_DIST_POINT)buf);
3806 LocalFree(buf);
3810 static const BYTE v1CRL[] = { 0x30, 0x15, 0x30, 0x02, 0x06, 0x00, 0x18, 0x0f,
3811 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3812 0x30, 0x5a };
3813 static const BYTE v2CRL[] = { 0x30, 0x18, 0x02, 0x01, 0x01, 0x30, 0x02, 0x06,
3814 0x00, 0x18, 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30,
3815 0x30, 0x30, 0x30, 0x30, 0x5a };
3816 static const BYTE v1CRLWithIssuer[] = { 0x30, 0x2c, 0x30, 0x02, 0x06, 0x00,
3817 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a,
3818 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f, 0x31,
3819 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
3820 0x5a };
3821 static const BYTE v1CRLWithIssuerAndEmptyEntry[] = { 0x30, 0x43, 0x30, 0x02,
3822 0x06, 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03,
3823 0x13, 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18,
3824 0x0f, 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30,
3825 0x30, 0x30, 0x5a, 0x30, 0x15, 0x30, 0x13, 0x02, 0x00, 0x18, 0x0f, 0x31, 0x36,
3826 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3827 static const BYTE v1CRLWithIssuerAndEntry[] = { 0x30, 0x44, 0x30, 0x02, 0x06,
3828 0x00, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
3829 0x0a, 0x4a, 0x75, 0x61, 0x6e, 0x20, 0x4c, 0x61, 0x6e, 0x67, 0x00, 0x18, 0x0f,
3830 0x31, 0x36, 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30,
3831 0x30, 0x5a, 0x30, 0x16, 0x30, 0x14, 0x02, 0x01, 0x01, 0x18, 0x0f, 0x31, 0x36,
3832 0x30, 0x31, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a };
3833 static const BYTE v1CRLWithEntryExt[] = { 0x30,0x5a,0x30,0x02,0x06,0x00,0x30,
3834 0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,
3835 0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
3836 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x2c,0x30,0x2a,0x02,0x01,
3837 0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,
3838 0x30,0x30,0x5a,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,
3839 0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3840 static const BYTE v1CRLWithExt[] = { 0x30,0x5c,0x30,0x02,0x06,0x00,0x30,0x15,
3841 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
3842 0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3843 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,0x02,0x01,0x01,
3844 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
3845 0x30,0x5a,0xa0,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,
3846 0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3847 static const BYTE v2CRLWithExt[] = { 0x30,0x5c,0x02,0x01,0x01,0x30,0x02,0x06,
3848 0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,
3849 0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,
3850 0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x16,0x30,0x14,
3851 0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,
3852 0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,0x03,0x55,0x1d,
3853 0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3854 static const BYTE v2CRLWithIssuingDistPoint[] = { 0x30,0x5c,0x02,0x01,0x01,
3855 0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,
3856 0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x18,0x0f,0x31,
3857 0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,
3858 0x16,0x30,0x14,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
3859 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0xa0,0x13,0x30,0x11,0x30,0x0f,0x06,
3860 0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01 };
3862 static void test_encodeCRLToBeSigned(DWORD dwEncoding)
3864 BOOL ret;
3865 BYTE *buf = NULL;
3866 static CHAR oid_issuing_dist_point[] = szOID_ISSUING_DIST_POINT;
3867 DWORD size = 0;
3868 CRL_INFO info = { 0 };
3869 CRL_ENTRY entry = { { 0 }, { 0 }, 0, 0 };
3870 CERT_EXTENSION ext;
3872 /* Test with a V1 CRL */
3873 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3874 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3875 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3876 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3877 if (buf)
3879 ok(size == sizeof(v1CRL), "Wrong size %d\n", size);
3880 ok(!memcmp(buf, v1CRL, size), "Got unexpected value\n");
3881 LocalFree(buf);
3883 /* Test v2 CRL */
3884 info.dwVersion = CRL_V2;
3885 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3886 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3887 ok(ret || broken(GetLastError() == OSS_DATA_ERROR /* Win9x */),
3888 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3889 if (buf)
3891 ok(size == v2CRL[1] + 2, "Expected size %d, got %d\n",
3892 v2CRL[1] + 2, size);
3893 ok(!memcmp(buf, v2CRL, size), "Got unexpected value\n");
3894 LocalFree(buf);
3896 /* v1 CRL with a name */
3897 info.dwVersion = CRL_V1;
3898 info.Issuer.cbData = sizeof(encodedCommonName);
3899 info.Issuer.pbData = (BYTE *)encodedCommonName;
3900 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3901 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3902 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3903 if (buf)
3905 ok(size == sizeof(v1CRLWithIssuer), "Wrong size %d\n", size);
3906 ok(!memcmp(buf, v1CRLWithIssuer, size), "Got unexpected value\n");
3907 LocalFree(buf);
3909 if (0)
3911 /* v1 CRL with a name and a NULL entry pointer (crashes on win9x) */
3912 info.cCRLEntry = 1;
3913 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3914 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3915 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
3916 "Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
3918 /* now set an empty entry */
3919 info.cCRLEntry = 1;
3920 info.rgCRLEntry = &entry;
3921 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3922 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3923 if (buf)
3925 ok(size == sizeof(v1CRLWithIssuerAndEmptyEntry),
3926 "Wrong size %d\n", size);
3927 ok(!memcmp(buf, v1CRLWithIssuerAndEmptyEntry, size),
3928 "Got unexpected value\n");
3929 LocalFree(buf);
3931 /* an entry with a serial number */
3932 entry.SerialNumber.cbData = sizeof(serialNum);
3933 entry.SerialNumber.pbData = (BYTE *)serialNum;
3934 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3935 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3936 if (buf)
3938 ok(size == sizeof(v1CRLWithIssuerAndEntry),
3939 "Wrong size %d\n", size);
3940 ok(!memcmp(buf, v1CRLWithIssuerAndEntry, size),
3941 "Got unexpected value\n");
3942 LocalFree(buf);
3944 /* an entry with an extension */
3945 entry.cExtension = 1;
3946 entry.rgExtension = &criticalExt;
3947 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3948 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3949 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3950 if (buf)
3952 ok(size == sizeof(v1CRLWithEntryExt), "Wrong size %d\n", size);
3953 ok(!memcmp(buf, v1CRLWithEntryExt, size), "Got unexpected value\n");
3954 LocalFree(buf);
3956 /* a CRL with an extension */
3957 entry.cExtension = 0;
3958 info.cExtension = 1;
3959 info.rgExtension = &criticalExt;
3960 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3961 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3962 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3963 if (buf)
3965 ok(size == sizeof(v1CRLWithExt), "Wrong size %d\n", size);
3966 ok(!memcmp(buf, v1CRLWithExt, size), "Got unexpected value\n");
3967 LocalFree(buf);
3969 /* a v2 CRL with an extension, this time non-critical */
3970 info.dwVersion = CRL_V2;
3971 info.rgExtension = &nonCriticalExt;
3972 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3973 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3974 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3975 if (buf)
3977 ok(size == sizeof(v2CRLWithExt), "Wrong size %d\n", size);
3978 ok(!memcmp(buf, v2CRLWithExt, size), "Got unexpected value\n");
3979 LocalFree(buf);
3981 /* a v2 CRL with an issuing dist point extension */
3982 ext.pszObjId = oid_issuing_dist_point;
3983 ext.fCritical = TRUE;
3984 ext.Value.cbData = sizeof(urlIDP);
3985 ext.Value.pbData = (LPBYTE)urlIDP;
3986 entry.rgExtension = &ext;
3987 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED, &info,
3988 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
3989 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
3990 if (buf)
3992 ok(size == sizeof(v2CRLWithIssuingDistPoint), "Wrong size %d\n", size);
3993 ok(!memcmp(buf, v2CRLWithIssuingDistPoint, size), "Unexpected value\n");
3994 LocalFree(buf);
3998 static const BYTE verisignCRL[] = { 0x30, 0x82, 0x01, 0xb1, 0x30, 0x82, 0x01,
3999 0x1a, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
4000 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x30, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06,
4001 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65,
4002 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x0e, 0x56,
4003 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e,
4004 0x31, 0x33, 0x30, 0x31, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, 0x65,
4005 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72,
4006 0x63, 0x69, 0x61, 0x6c, 0x20, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65,
4007 0x20, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x73, 0x20, 0x43,
4008 0x41, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x33, 0x32, 0x34, 0x30, 0x30, 0x30, 0x30,
4009 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, 0x34, 0x30, 0x31, 0x30, 0x37, 0x32, 0x33,
4010 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x69, 0x30, 0x21, 0x02, 0x10, 0x1b, 0x51,
4011 0x90, 0xf7, 0x37, 0x24, 0x39, 0x9c, 0x92, 0x54, 0xcd, 0x42, 0x46, 0x37, 0x99,
4012 0x6a, 0x17, 0x0d, 0x30, 0x31, 0x30, 0x31, 0x33, 0x30, 0x30, 0x30, 0x30, 0x31,
4013 0x32, 0x34, 0x5a, 0x30, 0x21, 0x02, 0x10, 0x75, 0x0e, 0x40, 0xff, 0x97, 0xf0,
4014 0x47, 0xed, 0xf5, 0x56, 0xc7, 0x08, 0x4e, 0xb1, 0xab, 0xfd, 0x17, 0x0d, 0x30,
4015 0x31, 0x30, 0x31, 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x34, 0x39, 0x5a, 0x30,
4016 0x21, 0x02, 0x10, 0x77, 0xe6, 0x5a, 0x43, 0x59, 0x93, 0x5d, 0x5f, 0x7a, 0x75,
4017 0x80, 0x1a, 0xcd, 0xad, 0xc2, 0x22, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x38, 0x33,
4018 0x31, 0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x5a, 0xa0, 0x1a, 0x30, 0x18, 0x30,
4019 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06,
4020 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x0d, 0x06,
4021 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, 0x05, 0x00, 0x03,
4022 0x81, 0x81, 0x00, 0x18, 0x2c, 0xe8, 0xfc, 0x16, 0x6d, 0x91, 0x4a, 0x3d, 0x88,
4023 0x54, 0x48, 0x5d, 0xb8, 0x11, 0xbf, 0x64, 0xbb, 0xf9, 0xda, 0x59, 0x19, 0xdd,
4024 0x0e, 0x65, 0xab, 0xc0, 0x0c, 0xfa, 0x67, 0x7e, 0x21, 0x1e, 0x83, 0x0e, 0xcf,
4025 0x9b, 0x89, 0x8a, 0xcf, 0x0c, 0x4b, 0xc1, 0x39, 0x9d, 0xe7, 0x6a, 0xac, 0x46,
4026 0x74, 0x6a, 0x91, 0x62, 0x22, 0x0d, 0xc4, 0x08, 0xbd, 0xf5, 0x0a, 0x90, 0x7f,
4027 0x06, 0x21, 0x3d, 0x7e, 0xa7, 0xaa, 0x5e, 0xcd, 0x22, 0x15, 0xe6, 0x0c, 0x75,
4028 0x8e, 0x6e, 0xad, 0xf1, 0x84, 0xe4, 0x22, 0xb4, 0x30, 0x6f, 0xfb, 0x64, 0x8f,
4029 0xd7, 0x80, 0x43, 0xf5, 0x19, 0x18, 0x66, 0x1d, 0x72, 0xa3, 0xe3, 0x94, 0x82,
4030 0x28, 0x52, 0xa0, 0x06, 0x4e, 0xb1, 0xc8, 0x92, 0x0c, 0x97, 0xbe, 0x15, 0x07,
4031 0xab, 0x7a, 0xc9, 0xea, 0x08, 0x67, 0x43, 0x4d, 0x51, 0x63, 0x3b, 0x9c, 0x9c,
4032 0xcd };
4033 static const BYTE verisignCRLWithLotsOfEntries[] = {
4034 0x30,0x82,0x1d,0xbd,0x30,0x82,0x1d,0x26,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,
4035 0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,0x30,0x61,0x31,0x11,0x30,0x0f,0x06,
4036 0x03,0x55,0x04,0x07,0x13,0x08,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x31,
4037 0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0a,0x13,0x0e,0x56,0x65,0x72,0x69,0x53,
4038 0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31,0x06,0x03,
4039 0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20,0x43,
4040 0x6f,0x6d,0x6d,0x65,0x72,0x63,0x69,0x61,0x6c,0x20,0x53,0x6f,0x66,0x74,0x77,
4041 0x61,0x72,0x65,0x20,0x50,0x75,0x62,0x6c,0x69,0x73,0x68,0x65,0x72,0x73,0x20,
4042 0x43,0x41,0x17,0x0d,0x30,0x34,0x30,0x33,0x33,0x31,0x30,0x30,0x30,0x30,0x30,
4043 0x30,0x5a,0x17,0x0d,0x30,0x34,0x30,0x35,0x33,0x31,0x32,0x33,0x35,0x39,0x35,
4044 0x39,0x5a,0x30,0x82,0x1c,0x92,0x30,0x21,0x02,0x10,0x01,0x22,0xb8,0xb2,0xf3,
4045 0x76,0x42,0xcc,0x48,0x71,0xb6,0x11,0xbf,0xd1,0xcf,0xda,0x17,0x0d,0x30,0x32,
4046 0x30,0x34,0x31,0x35,0x31,0x35,0x34,0x30,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,
4047 0x01,0x83,0x93,0xfb,0x96,0xde,0x1d,0x89,0x4e,0xc3,0x47,0x9c,0xe1,0x60,0x13,
4048 0x63,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x31,0x33,0x35,0x37,0x35,0x38,
4049 0x5a,0x30,0x21,0x02,0x10,0x01,0xdc,0xdb,0x63,0xd4,0xc9,0x9f,0x31,0xb8,0x16,
4050 0xf9,0x2c,0xf5,0xb1,0x08,0x8e,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4051 0x37,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x02,0x1a,0xa6,0xaf,0x94,
4052 0x71,0xf0,0x07,0x6e,0xf1,0x17,0xe4,0xd4,0x17,0x82,0xdb,0x17,0x0d,0x30,0x32,
4053 0x30,0x37,0x31,0x39,0x32,0x31,0x32,0x38,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4054 0x02,0x4c,0xe8,0x9d,0xfd,0x5f,0x77,0x4d,0x4b,0xf5,0x79,0x8b,0xb1,0x08,0x67,
4055 0xac,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x36,0x31,0x36,0x35,0x30,
4056 0x5a,0x30,0x21,0x02,0x10,0x02,0x59,0xae,0x6c,0x4c,0x21,0xf1,0x59,0x49,0x87,
4057 0xb0,0x95,0xf9,0x65,0xf3,0x20,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x39,0x30,
4058 0x38,0x30,0x34,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x03,0x3c,0x41,0x0e,0x2f,
4059 0x42,0x5c,0x32,0x2c,0xb1,0x35,0xfe,0xe7,0x61,0x97,0xa5,0x17,0x0d,0x30,0x32,
4060 0x30,0x34,0x32,0x34,0x31,0x39,0x34,0x37,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,
4061 0x03,0x4e,0x68,0xfa,0x8b,0xb2,0x8e,0xb9,0x72,0xea,0x72,0xe5,0x3b,0x15,0xac,
4062 0x8b,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x35,0x31,0x35,0x31,
4063 0x5a,0x30,0x21,0x02,0x10,0x03,0xc9,0xa8,0xe3,0x48,0xb0,0x5f,0xcf,0x08,0xee,
4064 0xb9,0x93,0xf9,0xe9,0xaf,0x0c,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x38,0x31,
4065 0x33,0x34,0x39,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x04,0x9b,0x23,0x6a,0x37,
4066 0x5c,0x06,0x98,0x0a,0x31,0xc8,0x86,0xdc,0x3a,0x95,0xcc,0x17,0x0d,0x30,0x32,
4067 0x31,0x30,0x30,0x31,0x32,0x32,0x31,0x30,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4068 0x06,0x08,0xba,0xc7,0xac,0xf8,0x5a,0x7c,0xa1,0xf4,0x25,0x85,0xbb,0x4e,0x8c,
4069 0x4f,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x33,0x30,0x37,0x35,0x37,0x31,0x34,
4070 0x5a,0x30,0x21,0x02,0x10,0x07,0x66,0x22,0x4a,0x4a,0x9d,0xff,0x6e,0xb5,0x11,
4071 0x0b,0xa9,0x94,0xfc,0x68,0x20,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,
4072 0x31,0x34,0x30,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x07,0x8f,0xa1,0x4d,0xb5,
4073 0xfc,0x0c,0xc6,0x42,0x72,0x88,0x37,0x76,0x29,0x44,0x31,0x17,0x0d,0x30,0x32,
4074 0x30,0x33,0x31,0x35,0x32,0x30,0x31,0x39,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,
4075 0x07,0xb9,0xd9,0x42,0x19,0x81,0xc4,0xfd,0x49,0x4f,0x72,0xce,0xf2,0xf8,0x6d,
4076 0x76,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x35,0x31,0x35,0x33,0x37,0x31,0x39,
4077 0x5a,0x30,0x21,0x02,0x10,0x08,0x6e,0xf9,0x6c,0x7f,0xbf,0xbc,0xc8,0x86,0x70,
4078 0x62,0x3f,0xe9,0xc4,0x2f,0x2b,0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x38,0x30,
4079 0x30,0x32,0x38,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x09,0x08,0xe4,0xaa,0xf5,
4080 0x2d,0x2b,0xc0,0x15,0x9e,0x00,0x8b,0x3f,0x97,0x93,0xf9,0x17,0x0d,0x30,0x33,
4081 0x30,0x32,0x31,0x32,0x32,0x32,0x30,0x30,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,
4082 0x09,0x13,0x0a,0x4f,0x0f,0x88,0xe5,0x50,0x05,0xc3,0x5f,0xf4,0xff,0x15,0x39,
4083 0xdd,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x38,0x31,0x31,0x33,0x30,
4084 0x5a,0x30,0x21,0x02,0x10,0x09,0x8d,0xdd,0x37,0xda,0xe7,0x84,0x03,0x9d,0x98,
4085 0x96,0xf8,0x88,0x3a,0x55,0xca,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,
4086 0x33,0x33,0x35,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x0a,0x35,0x0c,0xd7,0xf4,
4087 0x53,0xe6,0xc1,0x4e,0xf2,0x2a,0xd3,0xce,0xf8,0x7c,0xe7,0x17,0x0d,0x30,0x32,
4088 0x30,0x38,0x30,0x32,0x32,0x32,0x32,0x34,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4089 0x0b,0x9c,0xb8,0xf8,0xfb,0x35,0x38,0xf2,0x91,0xfd,0xa1,0xe9,0x69,0x4a,0xb1,
4090 0x24,0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x38,0x30,0x31,0x30,0x32,0x32,0x32,
4091 0x5a,0x30,0x21,0x02,0x10,0x0c,0x2f,0x7f,0x32,0x15,0xe0,0x2f,0x74,0xfa,0x05,
4092 0x22,0x67,0xbc,0x8a,0x2d,0xd0,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,
4093 0x39,0x30,0x37,0x35,0x34,0x5a,0x30,0x21,0x02,0x10,0x0c,0x32,0x5b,0x78,0x32,
4094 0xc6,0x7c,0xd8,0xdd,0x25,0x91,0x22,0x4d,0x84,0x0a,0x94,0x17,0x0d,0x30,0x32,
4095 0x30,0x33,0x31,0x38,0x31,0x32,0x33,0x39,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,
4096 0x0d,0x76,0x36,0xb9,0x1c,0x72,0xb7,0x9d,0xdf,0xa5,0x35,0x82,0xc5,0xa8,0xf7,
4097 0xbb,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x32,0x31,0x34,0x32,0x31,0x31,
4098 0x5a,0x30,0x21,0x02,0x10,0x0f,0x28,0x79,0x98,0x56,0xb8,0xa5,0x5e,0xeb,0x79,
4099 0x5f,0x1b,0xed,0x0b,0x86,0x76,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x30,
4100 0x31,0x31,0x30,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x0f,0x80,0x3c,0x24,0xf4,
4101 0x62,0x27,0x24,0xbe,0x6a,0x74,0x9c,0x18,0x8e,0x4b,0x3b,0x17,0x0d,0x30,0x32,
4102 0x31,0x31,0x32,0x30,0x31,0x37,0x31,0x31,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,
4103 0x0f,0xf2,0xa7,0x8c,0x80,0x9c,0xbe,0x2f,0xc8,0xa9,0xeb,0xfe,0x94,0x86,0x5a,
4104 0x5c,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x30,0x31,0x39,0x35,0x38,0x34,0x35,
4105 0x5a,0x30,0x21,0x02,0x10,0x10,0x45,0x13,0x35,0x45,0xf3,0xc6,0x02,0x8d,0x8d,
4106 0x18,0xb1,0xc4,0x0a,0x7a,0x18,0x17,0x0d,0x30,0x32,0x30,0x34,0x32,0x36,0x31,
4107 0x37,0x33,0x32,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x10,0x79,0xb1,0x71,0x1b,
4108 0x26,0x98,0x92,0x08,0x1e,0x3c,0xe4,0x8b,0x29,0x37,0xf9,0x17,0x0d,0x30,0x32,
4109 0x30,0x33,0x32,0x38,0x31,0x36,0x33,0x32,0x35,0x35,0x5a,0x30,0x21,0x02,0x10,
4110 0x11,0x38,0x80,0x77,0xcb,0x6b,0xe5,0xd6,0xa7,0xf2,0x99,0xa1,0xc8,0xe9,0x40,
4111 0x25,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x39,0x31,0x32,0x32,0x34,0x31,0x37,
4112 0x5a,0x30,0x21,0x02,0x10,0x11,0x7a,0xc3,0x82,0xfe,0x74,0x36,0x11,0x21,0xd6,
4113 0x92,0x86,0x09,0xdf,0xe6,0xf3,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x31,
4114 0x35,0x31,0x31,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x11,0xab,0x8e,0x21,0x28,
4115 0x7f,0x6d,0xf2,0xc1,0xc8,0x40,0x3e,0xa5,0xde,0x98,0xd3,0x17,0x0d,0x30,0x32,
4116 0x30,0x35,0x30,0x32,0x31,0x38,0x34,0x34,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,
4117 0x12,0x3c,0x38,0xae,0x3f,0x64,0x53,0x3a,0xf7,0xbc,0x6c,0x27,0xe2,0x9c,0x65,
4118 0x75,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x33,0x30,0x38,0x35,0x39,
4119 0x5a,0x30,0x21,0x02,0x10,0x12,0x88,0xb6,0x6c,0x9b,0xcf,0xe7,0x50,0x92,0xd2,
4120 0x87,0x63,0x8f,0xb7,0xa6,0xe3,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x32,
4121 0x30,0x35,0x35,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x12,0x95,0x4e,0xb6,0x8f,
4122 0x3a,0x19,0x6a,0x16,0x73,0x4f,0x6e,0x15,0xba,0xa5,0xe7,0x17,0x0d,0x30,0x32,
4123 0x30,0x36,0x31,0x37,0x31,0x38,0x35,0x36,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,
4124 0x13,0x37,0x0b,0x41,0x8c,0x31,0x43,0x1c,0x27,0xaa,0xe1,0x83,0x0f,0x99,0x21,
4125 0xcd,0x17,0x0d,0x30,0x32,0x30,0x37,0x32,0x32,0x31,0x32,0x31,0x37,0x31,0x36,
4126 0x5a,0x30,0x21,0x02,0x10,0x14,0x7a,0x29,0x0a,0x09,0x38,0xf4,0x53,0x28,0x33,
4127 0x6f,0x37,0x07,0x23,0x12,0x10,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x30,
4128 0x32,0x30,0x30,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x15,0x04,0x81,0x1e,0xe2,
4129 0x6f,0xf0,0xd8,0xdd,0x12,0x55,0x05,0x66,0x51,0x6e,0x1a,0x17,0x0d,0x30,0x32,
4130 0x30,0x33,0x31,0x33,0x31,0x30,0x35,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,
4131 0x15,0x30,0x0d,0x8a,0xbd,0x0e,0x89,0x0e,0x66,0x4f,0x49,0x93,0xa2,0x8f,0xbc,
4132 0x2e,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x30,0x36,0x34,0x32,0x32,0x33,
4133 0x5a,0x30,0x21,0x02,0x10,0x16,0xbe,0x64,0xd6,0x4f,0x90,0xf4,0xf7,0x2b,0xc8,
4134 0xca,0x67,0x5c,0x82,0x13,0xe8,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x31,
4135 0x39,0x30,0x39,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x18,0x51,0x9c,0xe4,0x48,
4136 0x62,0x06,0xfe,0xb8,0x2d,0x93,0xb7,0xc9,0xc9,0x1b,0x4e,0x17,0x0d,0x30,0x32,
4137 0x30,0x34,0x31,0x37,0x30,0x35,0x30,0x30,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,
4138 0x19,0x82,0xdb,0x39,0x74,0x00,0x38,0x36,0x59,0xf6,0xcc,0xc1,0x23,0x8d,0x40,
4139 0xe9,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,0x37,0x35,0x34,0x35,0x34,
4140 0x5a,0x30,0x21,0x02,0x10,0x1b,0x51,0x90,0xf7,0x37,0x24,0x39,0x9c,0x92,0x54,
4141 0xcd,0x42,0x46,0x37,0x99,0x6a,0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x30,0x30,
4142 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x1b,0xe4,0xb2,0xbb,0xb6,
4143 0x74,0x5d,0x6b,0x8b,0x04,0xb6,0xa0,0x1b,0x35,0xeb,0x29,0x17,0x0d,0x30,0x32,
4144 0x30,0x39,0x32,0x35,0x32,0x30,0x31,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,
4145 0x1c,0x1d,0xd5,0x2a,0xf6,0xaa,0xfd,0xbb,0x47,0xc2,0x73,0x36,0xcf,0x53,0xbd,
4146 0x81,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x30,0x33,0x34,0x32,
4147 0x5a,0x30,0x21,0x02,0x10,0x1c,0xb0,0x5a,0x1f,0xfd,0xa6,0x98,0xf6,0x46,0xf9,
4148 0x32,0x10,0x9e,0xef,0x52,0x8e,0x17,0x0d,0x30,0x32,0x30,0x36,0x32,0x37,0x31,
4149 0x33,0x30,0x33,0x32,0x32,0x5a,0x30,0x21,0x02,0x10,0x1d,0x01,0xfc,0xa7,0xdd,
4150 0xb4,0x0c,0x64,0xbd,0x65,0x45,0xe6,0xbf,0x1c,0x7e,0x90,0x17,0x0d,0x30,0x32,
4151 0x30,0x32,0x32,0x31,0x30,0x34,0x32,0x30,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,
4152 0x1e,0x4d,0xc9,0xc6,0x6e,0x57,0xda,0x8a,0x07,0x97,0x70,0xfa,0xee,0x9c,0xc5,
4153 0x58,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x39,0x32,0x32,0x33,0x34,0x32,0x31,
4154 0x5a,0x30,0x21,0x02,0x10,0x1e,0xbb,0x9b,0x28,0x61,0x50,0x7f,0x12,0x30,0xfb,
4155 0x02,0xb5,0xe1,0xb0,0x7e,0x9d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x36,0x30,
4156 0x30,0x30,0x34,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x1f,0x5a,0x64,0xc9,0xa5,
4157 0x51,0x8c,0xe2,0x2d,0x50,0x83,0xc2,0x4c,0x7c,0xe7,0x85,0x17,0x0d,0x30,0x32,
4158 0x30,0x38,0x32,0x34,0x30,0x36,0x33,0x31,0x32,0x38,0x5a,0x30,0x21,0x02,0x10,
4159 0x1f,0xc2,0x4e,0xd0,0xac,0x52,0xd3,0x39,0x18,0x6d,0xd0,0x0f,0x23,0xd7,0x45,
4160 0x72,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x31,0x39,0x31,0x35,0x34,0x32,
4161 0x5a,0x30,0x20,0x02,0x0f,0x24,0x60,0x7a,0x8e,0x0e,0x86,0xa4,0x88,0x68,0xaf,
4162 0xd9,0x0c,0x6b,0xba,0xff,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x35,
4163 0x31,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x20,0x41,0x73,0xbb,0x72,0x88,
4164 0x6e,0x4b,0x1c,0xb6,0x70,0x02,0x67,0xaa,0x3b,0x3d,0x17,0x0d,0x30,0x32,0x30,
4165 0x39,0x30,0x33,0x31,0x37,0x30,0x36,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x20,
4166 0x6e,0x0d,0xdc,0x8c,0xa4,0xac,0xf7,0x08,0x77,0x5c,0x80,0xf9,0xa3,0x68,0x92,
4167 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x30,0x35,0x37,0x31,0x36,0x5a,
4168 0x30,0x21,0x02,0x10,0x21,0xe4,0x6b,0x98,0x47,0x91,0xe6,0x02,0xdf,0xb2,0x45,
4169 0xbc,0x31,0x37,0xa0,0x7c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x32,0x33,
4170 0x32,0x33,0x31,0x33,0x5a,0x30,0x21,0x02,0x10,0x22,0x00,0x95,0x70,0x79,0xf9,
4171 0x9c,0x34,0x91,0xbb,0x84,0xb9,0x91,0xde,0x22,0x55,0x17,0x0d,0x30,0x32,0x30,
4172 0x32,0x31,0x33,0x30,0x36,0x35,0x39,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x22,
4173 0xf9,0x67,0x4f,0xcd,0x29,0xc6,0xdc,0xc8,0x22,0x6e,0xe9,0x0a,0xa1,0x48,0x5a,
4174 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x30,0x30,0x34,0x33,0x32,0x36,0x5a,
4175 0x30,0x21,0x02,0x10,0x24,0xa3,0xa7,0xd0,0xb8,0x1d,0x1c,0xf7,0xe6,0x1f,0x6e,
4176 0xba,0xc9,0x98,0x59,0xed,0x17,0x0d,0x30,0x33,0x30,0x37,0x32,0x34,0x32,0x30,
4177 0x35,0x38,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x24,0xef,0x89,0xa1,0x30,0x4f,
4178 0x51,0x63,0xfe,0xdb,0xdb,0x64,0x6e,0x4c,0x5a,0x81,0x17,0x0d,0x30,0x32,0x30,
4179 0x37,0x30,0x33,0x30,0x39,0x32,0x31,0x31,0x37,0x5a,0x30,0x21,0x02,0x10,0x25,
4180 0x08,0xe5,0xac,0xdd,0x6f,0x74,0x44,0x51,0x1a,0xf5,0xdb,0xf8,0xba,0x25,0xe0,
4181 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x39,0x30,0x34,0x31,0x36,0x32,0x32,0x5a,
4182 0x30,0x21,0x02,0x10,0x25,0x81,0xe8,0x18,0x60,0x88,0xbc,0x1a,0xe9,0x14,0x84,
4183 0xed,0xd4,0x62,0xf5,0x47,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x33,0x30,0x31,
4184 0x35,0x37,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x26,0xe5,0x5c,0xab,0x16,0xec,
4185 0x61,0x38,0x49,0x2c,0xd2,0xb1,0x48,0x89,0xd5,0x47,0x17,0x0d,0x30,0x32,0x30,
4186 0x33,0x31,0x33,0x31,0x38,0x30,0x30,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x27,
4187 0xbe,0xda,0x7f,0x4f,0x1f,0x6c,0x76,0x09,0xc0,0x9a,0xaf,0xd4,0x68,0xe2,0x16,
4188 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x30,0x31,0x38,0x33,0x32,0x33,0x30,0x5a,
4189 0x30,0x21,0x02,0x10,0x28,0x89,0xd0,0xb3,0xb5,0xc4,0x56,0x36,0x9b,0x3e,0x81,
4190 0x1a,0x21,0x56,0xaa,0x42,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x34,0x31,0x31,
4191 0x30,0x33,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x28,0xab,0x93,0x06,0xb1,0x1e,
4192 0x05,0xe0,0xe1,0x25,0x75,0xc7,0x74,0xcb,0x55,0xa6,0x17,0x0d,0x30,0x33,0x30,
4193 0x31,0x32,0x34,0x31,0x39,0x34,0x38,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x29,
4194 0xe9,0x3b,0x44,0x8d,0xc3,0x4b,0x80,0x17,0xda,0xe4,0x1c,0x43,0x96,0x83,0x59,
4195 0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x37,0x32,0x31,0x34,0x33,0x33,0x39,0x5a,
4196 0x30,0x21,0x02,0x10,0x2a,0x08,0x64,0x2b,0x48,0xe2,0x17,0x89,0x6a,0x0c,0xf9,
4197 0x7e,0x10,0x66,0x8f,0xe7,0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x39,0x31,0x38,
4198 0x33,0x35,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x2a,0x44,0xee,0x91,0x5d,0xe3,
4199 0xa5,0x2b,0x09,0xf3,0x56,0x59,0xe0,0x8f,0x25,0x22,0x17,0x0d,0x30,0x32,0x30,
4200 0x32,0x32,0x31,0x31,0x39,0x33,0x31,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x2a,
4201 0x8b,0x4e,0xa5,0xb6,0x06,0xc8,0x48,0x3b,0x0e,0x71,0x1e,0x6b,0xf4,0x16,0xc1,
4202 0x17,0x0d,0x30,0x32,0x30,0x34,0x33,0x30,0x30,0x39,0x32,0x31,0x31,0x38,0x5a,
4203 0x30,0x21,0x02,0x10,0x2b,0x03,0xfc,0x2f,0xc2,0x8e,0x38,0x29,0x6f,0xa1,0x0f,
4204 0xe9,0x47,0x1b,0x35,0xd7,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x32,0x30,
4205 0x31,0x38,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,0x48,0xf7,0xd6,0xd5,0x71,
4206 0xc0,0xd1,0xbd,0x6a,0x00,0x65,0x1d,0x2d,0xa9,0xdd,0x17,0x0d,0x30,0x32,0x30,
4207 0x33,0x30,0x36,0x31,0x37,0x32,0x30,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x2c,
4208 0xbf,0x84,0x1d,0xe4,0x58,0x32,0x79,0x32,0x10,0x37,0xde,0xd7,0x94,0xff,0x85,
4209 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x39,0x30,0x32,0x32,0x35,0x5a,
4210 0x30,0x21,0x02,0x10,0x2d,0x03,0x54,0x35,0x54,0x45,0x2c,0x6d,0x39,0xf0,0x1b,
4211 0x74,0x68,0xde,0xcf,0x93,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x33,
4212 0x32,0x33,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,0x24,0x94,0x34,0x19,0x92,
4213 0xb1,0xf2,0x37,0x9d,0x6e,0xc5,0x35,0x93,0xdd,0xf0,0x17,0x0d,0x30,0x32,0x30,
4214 0x33,0x31,0x35,0x31,0x37,0x31,0x37,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2d,
4215 0x47,0x24,0x61,0x87,0x91,0xba,0x2e,0xf2,0xf7,0x92,0x21,0xf3,0x1b,0x8b,0x1e,
4216 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x32,0x33,0x30,0x38,0x32,0x32,0x5a,
4217 0x30,0x21,0x02,0x10,0x2d,0x84,0xc2,0xb1,0x01,0xa1,0x3a,0x6f,0xb0,0x30,0x13,
4218 0x76,0x5a,0x69,0xec,0x41,0x17,0x0d,0x30,0x32,0x30,0x37,0x31,0x35,0x31,0x37,
4219 0x32,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x2d,0xd5,0x26,0xc3,0xcd,0x01,
4220 0xce,0xfd,0x67,0xb8,0x08,0xac,0x5a,0x70,0xc4,0x34,0x17,0x0d,0x30,0x32,0x30,
4221 0x32,0x32,0x37,0x30,0x34,0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x2e,
4222 0x2b,0x0a,0x94,0x4d,0xf1,0xa4,0x37,0xb7,0xa3,0x9b,0x4b,0x96,0x26,0xa8,0xe3,
4223 0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x39,0x30,0x36,0x32,0x38,0x32,0x38,0x5a,
4224 0x30,0x21,0x02,0x10,0x2e,0x31,0x30,0xc1,0x2e,0x16,0x31,0xd9,0x2b,0x0a,0x70,
4225 0xca,0x3f,0x31,0x73,0x62,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x39,0x30,0x31,
4226 0x34,0x39,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x2e,0xbd,0x6d,0xdf,0xce,0x20,
4227 0x6f,0xe7,0xa8,0xf4,0xf3,0x25,0x9c,0xc3,0xc1,0x12,0x17,0x0d,0x30,0x32,0x30,
4228 0x39,0x32,0x30,0x31,0x33,0x35,0x34,0x34,0x32,0x5a,0x30,0x21,0x02,0x10,0x2f,
4229 0x56,0x16,0x22,0xba,0x87,0xd5,0xfd,0xff,0xe6,0xb0,0xdd,0x3c,0x08,0x26,0x2c,
4230 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x33,0x31,0x37,0x35,0x33,0x31,0x31,0x5a,
4231 0x30,0x21,0x02,0x10,0x30,0x3e,0x77,0x7b,0xec,0xcb,0x89,0x2c,0x15,0x55,0x7f,
4232 0x20,0xf2,0x33,0xc1,0x1e,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x32,0x33,
4233 0x35,0x30,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x30,0x59,0x6c,0xaa,0x5f,0xd3,
4234 0xac,0x50,0x86,0x2c,0xc4,0xfa,0x3c,0x48,0x50,0xd1,0x17,0x0d,0x30,0x32,0x30,
4235 0x32,0x32,0x31,0x30,0x34,0x31,0x39,0x33,0x35,0x5a,0x30,0x21,0x02,0x10,0x30,
4236 0xce,0x9a,0xf1,0xfa,0x17,0xfa,0xf5,0x4c,0xbc,0x52,0x8a,0xf4,0x26,0x2b,0x7b,
4237 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x31,0x31,0x39,0x31,0x32,0x33,0x39,0x5a,
4238 0x30,0x21,0x02,0x10,0x31,0x16,0x4a,0x6a,0x2e,0x6d,0x34,0x4d,0xd2,0x40,0xf0,
4239 0x5f,0x47,0xe6,0x5b,0x47,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x32,0x31,0x37,
4240 0x33,0x38,0x35,0x32,0x5a,0x30,0x21,0x02,0x10,0x31,0xdb,0x97,0x5b,0x06,0x63,
4241 0x0b,0xd8,0xfe,0x06,0xb3,0xf5,0xf9,0x64,0x0a,0x59,0x17,0x0d,0x30,0x32,0x30,
4242 0x32,0x31,0x32,0x31,0x35,0x35,0x39,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x32,
4243 0xbc,0xeb,0x0c,0xca,0x65,0x06,0x3f,0xa4,0xd5,0x4a,0x56,0x46,0x7c,0x22,0x09,
4244 0x17,0x0d,0x30,0x32,0x30,0x38,0x31,0x36,0x30,0x37,0x33,0x33,0x35,0x35,0x5a,
4245 0x30,0x21,0x02,0x10,0x33,0x17,0xef,0xe1,0x89,0xec,0x11,0x25,0x15,0x8f,0x3b,
4246 0x67,0x7a,0x64,0x0b,0x50,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x31,0x37,
4247 0x30,0x33,0x34,0x36,0x5a,0x30,0x21,0x02,0x10,0x34,0x24,0xa0,0xd2,0x00,0x61,
4248 0xeb,0xd3,0x9a,0xa7,0x2a,0x66,0xb4,0x82,0x23,0x77,0x17,0x0d,0x30,0x32,0x30,
4249 0x33,0x31,0x35,0x32,0x32,0x34,0x33,0x33,0x39,0x5a,0x30,0x21,0x02,0x10,0x34,
4250 0xa8,0x16,0x67,0xa5,0x1b,0xa3,0x31,0x11,0x5e,0x26,0xc8,0x3f,0x21,0x38,0xbe,
4251 0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x31,0x32,0x31,0x31,0x36,0x32,0x31,0x5a,
4252 0x30,0x21,0x02,0x10,0x36,0x3a,0xbe,0x05,0x55,0x52,0x93,0x4f,0x32,0x5f,0x30,
4253 0x63,0xc0,0xd4,0x50,0xdf,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x31,
4254 0x34,0x36,0x31,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,0x19,0xcc,0xa5,0x9d,0x85,
4255 0x05,0x56,0xe1,0x63,0x42,0x4b,0x0d,0x3c,0xbf,0xd6,0x17,0x0d,0x30,0x33,0x30,
4256 0x31,0x30,0x38,0x31,0x38,0x35,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x37,
4257 0x2f,0xfd,0x2b,0xec,0x4d,0x94,0x35,0x51,0xf4,0x07,0x2a,0xf5,0x0b,0x97,0xc4,
4258 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x33,0x31,0x39,0x31,0x38,0x30,0x31,0x5a,
4259 0x30,0x21,0x02,0x10,0x37,0x83,0xf5,0x1e,0x7e,0xf4,0x5f,0xad,0x1f,0x0c,0x55,
4260 0x86,0x30,0x02,0x54,0xc1,0x17,0x0d,0x30,0x33,0x30,0x31,0x30,0x38,0x32,0x30,
4261 0x30,0x33,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x38,0x32,0x3e,0x50,0x2b,0x36,
4262 0x93,0x01,0x32,0x0a,0x59,0x8c,0xce,0xad,0xa0,0xeb,0x17,0x0d,0x30,0x32,0x30,
4263 0x34,0x33,0x30,0x32,0x31,0x32,0x34,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3a,
4264 0x62,0xd8,0x64,0xd3,0x85,0xd5,0x61,0x1d,0x9d,0x3f,0x61,0x25,0xe9,0x3a,0x1d,
4265 0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x35,0x31,0x39,0x31,0x36,0x5a,
4266 0x30,0x21,0x02,0x10,0x3a,0x97,0x36,0xb1,0x26,0x14,0x73,0x50,0xa3,0xcc,0x3f,
4267 0xd0,0x3b,0x83,0x99,0xc9,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x31,0x30,0x33,
4268 0x32,0x39,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x3b,0x87,0x3e,0x20,0xbe,0x97,
4269 0xff,0xa7,0x6b,0x2b,0x5f,0xff,0x9a,0x7f,0x4c,0x95,0x17,0x0d,0x30,0x32,0x30,
4270 0x37,0x30,0x33,0x30,0x30,0x33,0x31,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x3b,
4271 0xba,0xe5,0xf2,0x23,0x99,0xc6,0xd7,0xae,0xe2,0x98,0x0d,0xa4,0x13,0x5c,0xd4,
4272 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x34,0x31,0x39,0x32,0x38,0x34,0x35,0x5a,
4273 0x30,0x21,0x02,0x10,0x3b,0xc2,0x7c,0xf0,0xbd,0xd2,0x9a,0x6f,0x97,0xdd,0x76,
4274 0xbc,0xa9,0x6c,0x45,0x0d,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,
4275 0x34,0x32,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x3b,0xc5,0xda,0x41,0x64,0x7a,
4276 0x37,0x8e,0x9f,0x7f,0x1f,0x9b,0x25,0x0a,0xb4,0xda,0x17,0x0d,0x30,0x32,0x30,
4277 0x33,0x30,0x36,0x31,0x33,0x32,0x34,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x3c,
4278 0x1b,0xf1,0x9a,0x48,0xb0,0xb8,0xa0,0x45,0xd5,0x8f,0x0f,0x57,0x90,0xc2,0xcd,
4279 0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x38,0x30,0x36,0x34,0x33,0x32,0x33,0x5a,
4280 0x30,0x21,0x02,0x10,0x3d,0x15,0x48,0x80,0xb4,0xfe,0x51,0x7e,0xed,0x46,0xae,
4281 0x51,0xfd,0x47,0x73,0xde,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x37,0x30,0x39,
4282 0x32,0x30,0x30,0x38,0x5a,0x30,0x21,0x02,0x10,0x3d,0x61,0x4e,0x87,0xea,0x39,
4283 0x02,0xf3,0x1e,0x3e,0x56,0x5c,0x0e,0x3b,0xa7,0xe3,0x17,0x0d,0x30,0x32,0x31,
4284 0x30,0x32,0x39,0x31,0x39,0x35,0x34,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x3d,
4285 0xdd,0x61,0x92,0x82,0x69,0x6b,0x01,0x79,0x0e,0xef,0x96,0x12,0xa3,0x76,0x80,
4286 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x31,0x32,0x32,0x32,0x34,0x31,0x36,0x5a,
4287 0x30,0x21,0x02,0x10,0x3e,0x0e,0x14,0x71,0x55,0xf3,0x48,0x09,0x1b,0x56,0x3b,
4288 0x91,0x7a,0x7d,0xec,0xc9,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x31,0x32,0x31,
4289 0x34,0x35,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x3e,0x23,0x00,0x1f,0x9b,0xbd,
4290 0xe8,0xb1,0xf0,0x06,0x67,0xa6,0x70,0x42,0x2e,0xc3,0x17,0x0d,0x30,0x32,0x30,
4291 0x38,0x30,0x38,0x31,0x32,0x32,0x31,0x33,0x32,0x5a,0x30,0x21,0x02,0x10,0x41,
4292 0x91,0x1a,0x8c,0xde,0x2d,0xb3,0xeb,0x79,0x1d,0xc7,0x99,0x99,0xbe,0x0c,0x0e,
4293 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x35,0x31,0x39,0x31,0x38,0x35,0x34,0x5a,
4294 0x30,0x21,0x02,0x10,0x41,0xa8,0xd7,0x9c,0x10,0x5e,0x5a,0xac,0x16,0x7f,0x93,
4295 0xaa,0xd1,0x83,0x34,0x55,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x31,0x32,
4296 0x35,0x33,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x42,0x88,0x96,0xb0,0x7b,0x28,
4297 0xa2,0xfa,0x2f,0x91,0x73,0x58,0xa7,0x1e,0x53,0x7c,0x17,0x0d,0x30,0x33,0x30,
4298 0x33,0x30,0x31,0x30,0x39,0x34,0x33,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x42,
4299 0x93,0x2f,0xd2,0x54,0xd3,0x94,0xd0,0x41,0x6a,0x2e,0x33,0x8b,0x81,0xb4,0x3c,
4300 0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x30,0x30,0x34,0x38,0x34,0x36,0x5a,
4301 0x30,0x21,0x02,0x10,0x44,0x24,0xdd,0xba,0x85,0xfd,0x3e,0xb2,0xb8,0x17,0x74,
4302 0xfd,0x9d,0x5c,0x0c,0xbd,0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x31,0x31,0x36,
4303 0x30,0x39,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x45,0x02,0x18,0x7d,0x39,0x9c,
4304 0xb9,0x14,0xfb,0x10,0x37,0x96,0xf4,0xc1,0xdd,0x2f,0x17,0x0d,0x30,0x32,0x30,
4305 0x32,0x31,0x31,0x31,0x31,0x31,0x31,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x45,
4306 0x16,0xbc,0x31,0x0b,0x4e,0x87,0x0a,0xcc,0xe3,0xd5,0x14,0x16,0x33,0x11,0x83,
4307 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x30,0x32,0x32,0x30,0x31,0x37,0x5a,
4308 0x30,0x21,0x02,0x10,0x46,0x16,0x36,0xde,0x3f,0xef,0x8c,0xfa,0x67,0x53,0x12,
4309 0xcc,0x76,0x63,0xd6,0xdd,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x31,0x36,
4310 0x35,0x39,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x46,0x5f,0x85,0xa3,0xa4,0x98,
4311 0x3c,0x40,0x63,0xf6,0x1c,0xf7,0xc2,0xbe,0xfd,0x0e,0x17,0x0d,0x30,0x32,0x30,
4312 0x34,0x30,0x39,0x31,0x35,0x33,0x30,0x30,0x35,0x5a,0x30,0x21,0x02,0x10,0x47,
4313 0x20,0xc2,0xd8,0x85,0x85,0x54,0x39,0xcd,0xf2,0x10,0xf0,0xa7,0x88,0x52,0x75,
4314 0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x30,0x32,0x32,0x32,0x35,0x32,0x37,0x5a,
4315 0x30,0x21,0x02,0x10,0x47,0x42,0x6e,0xa2,0xab,0xc5,0x33,0x5d,0x50,0x44,0x0b,
4316 0x88,0x97,0x84,0x59,0x4c,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x35,0x31,0x34,
4317 0x30,0x35,0x31,0x39,0x5a,0x30,0x21,0x02,0x10,0x49,0x20,0x3f,0xa8,0x6e,0x81,
4318 0xc8,0x3b,0x26,0x05,0xf4,0xa7,0x9b,0x5a,0x81,0x60,0x17,0x0d,0x30,0x32,0x30,
4319 0x37,0x31,0x31,0x31,0x37,0x35,0x30,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x49,
4320 0x8b,0x6f,0x05,0xfb,0xcb,0xf4,0x5a,0xaf,0x09,0x47,0xb1,0x04,0xc5,0xe3,0x51,
4321 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x32,0x31,0x37,0x34,0x38,0x30,0x38,0x5a,
4322 0x30,0x21,0x02,0x10,0x49,0xb2,0xc3,0x7a,0xbf,0x75,0x2a,0xb3,0x13,0xae,0x53,
4323 0xc6,0xcb,0x45,0x5a,0x3e,0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x35,0x32,0x31,
4324 0x33,0x35,0x33,0x37,0x5a,0x30,0x21,0x02,0x10,0x4b,0xca,0xc3,0xab,0x0a,0xc5,
4325 0xcd,0x90,0xa2,0xbe,0x43,0xfe,0xdd,0x06,0xe1,0x45,0x17,0x0d,0x30,0x32,0x30,
4326 0x37,0x32,0x30,0x31,0x37,0x33,0x32,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x4c,
4327 0x00,0xcc,0x73,0xd5,0x74,0x61,0x62,0x92,0x52,0xff,0xde,0x5b,0xc1,0x55,0xbd,
4328 0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x36,0x31,0x34,0x30,0x31,0x35,0x31,0x5a,
4329 0x30,0x21,0x02,0x10,0x4c,0x59,0xc1,0xc3,0x56,0x40,0x27,0xd4,0x22,0x0e,0x37,
4330 0xf6,0x5f,0x26,0x50,0xc5,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x30,0x39,
4331 0x35,0x37,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x4c,0xca,0x12,0x59,0x46,0xf9,
4332 0x2b,0xc6,0x7d,0x33,0x78,0x40,0x2c,0x3b,0x7a,0x0c,0x17,0x0d,0x30,0x32,0x30,
4333 0x35,0x33,0x30,0x32,0x30,0x32,0x34,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x4d,
4334 0x57,0x51,0x35,0x9b,0xe5,0x41,0x2c,0x69,0x66,0xc7,0x21,0xec,0xc6,0x29,0x32,
4335 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x30,0x34,0x33,0x35,0x35,0x36,0x5a,
4336 0x30,0x21,0x02,0x10,0x4e,0x85,0xab,0x9e,0x17,0x54,0xe7,0x42,0x0f,0x8c,0xa1,
4337 0x65,0x96,0x88,0x53,0x54,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x38,0x30,0x30,
4338 0x31,0x38,0x35,0x33,0x5a,0x30,0x21,0x02,0x10,0x50,0x3d,0xed,0xac,0x21,0x86,
4339 0x66,0x5d,0xa5,0x1a,0x13,0xee,0xfc,0xa7,0x0b,0xc6,0x17,0x0d,0x30,0x32,0x30,
4340 0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x34,0x39,0x5a,0x30,0x21,0x02,0x10,0x50,
4341 0xa3,0x81,0x9c,0xcb,0x22,0xe4,0x0f,0x80,0xcb,0x7a,0xec,0x35,0xf8,0x73,0x82,
4342 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x35,0x31,0x36,0x35,0x39,0x35,0x39,0x5a,
4343 0x30,0x21,0x02,0x10,0x51,0x28,0x73,0x26,0x17,0xcf,0x10,0x6e,0xeb,0x4a,0x03,
4344 0x74,0xa3,0x35,0xe5,0x60,0x17,0x0d,0x30,0x33,0x30,0x36,0x31,0x33,0x31,0x30,
4345 0x30,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x51,0x52,0xff,0xdc,0x69,0x6b,
4346 0x1f,0x1f,0xff,0x7c,0xb1,0x7f,0x03,0x90,0xa9,0x6b,0x17,0x0d,0x30,0x32,0x30,
4347 0x36,0x31,0x34,0x31,0x36,0x30,0x34,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x52,
4348 0xd9,0x53,0x69,0x9f,0xec,0xab,0xdd,0x5d,0x2a,0x2f,0xaa,0x57,0x86,0xb9,0x1f,
4349 0x17,0x0d,0x30,0x32,0x30,0x38,0x33,0x30,0x32,0x33,0x34,0x36,0x34,0x33,0x5a,
4350 0x30,0x21,0x02,0x10,0x54,0x46,0xa8,0x8f,0x69,0x2e,0x02,0xf4,0xb4,0xb2,0x69,
4351 0xda,0xbd,0x40,0x02,0xe0,0x17,0x0d,0x30,0x32,0x30,0x33,0x32,0x36,0x30,0x31,
4352 0x35,0x36,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x54,0xb5,0x81,0x73,0xb5,0x7c,
4353 0x6d,0xba,0x5c,0x99,0x0d,0xff,0x0a,0x4d,0xee,0xef,0x17,0x0d,0x30,0x32,0x30,
4354 0x37,0x32,0x34,0x31,0x36,0x33,0x39,0x35,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,
4355 0x91,0x41,0x20,0x9f,0x57,0x6f,0x42,0x53,0x4e,0x19,0xcc,0xe4,0xc8,0x52,0x4a,
4356 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x38,0x32,0x33,0x32,0x34,0x30,0x30,0x5a,
4357 0x30,0x21,0x02,0x10,0x57,0xc6,0xdc,0xa0,0xed,0xbf,0x77,0xdd,0x7e,0x18,0x68,
4358 0x83,0x57,0x0c,0x2a,0x4f,0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x31,0x31,0x34,
4359 0x30,0x36,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x57,0xed,0xe2,0x5b,0xe2,0x62,
4360 0x3f,0x98,0xe1,0xf5,0x4d,0x30,0xa4,0x0e,0xdf,0xdf,0x17,0x0d,0x30,0x32,0x30,
4361 0x36,0x30,0x39,0x30,0x31,0x34,0x37,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x58,
4362 0x47,0xd9,0xbd,0x83,0x1a,0x63,0x6f,0xb7,0x63,0x7f,0x4a,0x56,0x5e,0x8e,0x4d,
4363 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x35,0x31,0x37,0x32,0x33,0x30,0x33,0x5a,
4364 0x30,0x21,0x02,0x10,0x58,0xc6,0x62,0x99,0x80,0xe6,0x0c,0x4f,0x00,0x8b,0x25,
4365 0x38,0x93,0xe6,0x18,0x10,0x17,0x0d,0x30,0x32,0x30,0x36,0x30,0x36,0x30,0x37,
4366 0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x59,0x52,0x09,0x0e,0x99,0xf3,
4367 0xa9,0xe5,0x2f,0xed,0xa9,0xb2,0xd8,0x61,0xe7,0xea,0x17,0x0d,0x30,0x32,0x30,
4368 0x36,0x32,0x36,0x31,0x34,0x31,0x38,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x59,
4369 0x5c,0xaa,0xfb,0xbe,0xfb,0x73,0xd1,0xf4,0xab,0xc8,0xe3,0x3d,0x01,0x04,0xdd,
4370 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x37,0x32,0x32,0x32,0x30,0x31,0x30,0x5a,
4371 0x30,0x21,0x02,0x10,0x59,0x97,0x59,0xa7,0x3d,0xb0,0xd9,0x7e,0xff,0x2a,0xcb,
4372 0x31,0xcc,0x66,0xf3,0x85,0x17,0x0d,0x30,0x32,0x30,0x38,0x32,0x32,0x30,0x30,
4373 0x35,0x35,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x59,0xdd,0x45,0x36,0x61,0xd9,
4374 0x3e,0xe9,0xff,0xbd,0xad,0x2e,0xbf,0x9a,0x5d,0x98,0x17,0x0d,0x30,0x32,0x30,
4375 0x37,0x30,0x32,0x32,0x30,0x34,0x30,0x30,0x33,0x5a,0x30,0x21,0x02,0x10,0x5a,
4376 0x4b,0x48,0x18,0xa9,0x2a,0x9c,0xd5,0x91,0x2f,0x4f,0xa4,0xf8,0xb3,0x1b,0x4d,
4377 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x34,0x32,0x33,0x33,0x33,0x31,0x32,0x5a,
4378 0x30,0x21,0x02,0x10,0x5a,0xdf,0x32,0x0d,0x64,0xeb,0x9b,0xd2,0x11,0xe2,0x58,
4379 0x50,0xbe,0x93,0x0c,0x65,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x35,0x31,0x37,
4380 0x30,0x37,0x32,0x31,0x5a,0x30,0x21,0x02,0x10,0x5b,0x23,0xbf,0xbb,0xc4,0xb3,
4381 0xf4,0x02,0xe9,0xcb,0x10,0x9e,0xee,0xa5,0x3f,0xcd,0x17,0x0d,0x30,0x32,0x30,
4382 0x33,0x32,0x39,0x31,0x36,0x32,0x36,0x35,0x39,0x5a,0x30,0x21,0x02,0x10,0x5b,
4383 0x51,0xbc,0x38,0xbf,0xaf,0x9f,0x27,0xa9,0xc7,0xed,0x25,0xd0,0x8d,0xec,0x2e,
4384 0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x38,0x31,0x30,0x32,0x35,0x32,0x30,0x5a,
4385 0x30,0x21,0x02,0x10,0x5c,0x29,0x7f,0x46,0x61,0xdd,0x47,0x90,0x82,0x91,0xbd,
4386 0x79,0x22,0x6a,0x98,0x38,0x17,0x0d,0x30,0x32,0x31,0x31,0x30,0x38,0x31,0x35,
4387 0x35,0x34,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x5e,0x38,0xf7,0x5b,0x00,0xf1,
4388 0xef,0x1c,0xb6,0xff,0xd5,0x5c,0x74,0xfb,0x95,0x5d,0x17,0x0d,0x30,0x32,0x31,
4389 0x31,0x32,0x33,0x30,0x31,0x34,0x39,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x5e,
4390 0x88,0xbe,0xb6,0xb4,0xb2,0xaa,0xb0,0x92,0xf3,0xf6,0xc2,0xbc,0x72,0x21,0xca,
4391 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x34,0x30,0x37,0x31,0x32,0x31,0x30,0x5a,
4392 0x30,0x21,0x02,0x10,0x5f,0x59,0xa0,0xbb,0xaf,0x26,0xc8,0xc1,0xb4,0x04,0x3a,
4393 0xbb,0xfc,0x4c,0x75,0xa5,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x36,0x31,0x35,
4394 0x35,0x31,0x32,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,0x81,0x08,0x0f,0xa0,0xcd,
4395 0x44,0x73,0x23,0x58,0x8e,0x49,0x9f,0xb5,0x08,0x35,0x17,0x0d,0x30,0x32,0x30,
4396 0x36,0x31,0x39,0x31,0x34,0x31,0x37,0x34,0x33,0x5a,0x30,0x21,0x02,0x10,0x5f,
4397 0xba,0x1f,0x8f,0xb2,0x23,0x56,0xdd,0xbc,0xa6,0x72,0xb0,0x99,0x13,0xb5,0xb2,
4398 0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x36,0x30,0x38,0x34,0x37,0x31,0x30,0x5a,
4399 0x30,0x21,0x02,0x10,0x60,0x09,0xd5,0xb7,0x6b,0xf1,0x16,0x4a,0xfa,0xd0,0xa5,
4400 0x4c,0x8e,0xdd,0x02,0xcb,0x17,0x0d,0x30,0x32,0x30,0x36,0x31,0x37,0x31,0x36,
4401 0x31,0x32,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x60,0x1d,0x19,0xd8,0x55,0xd5,
4402 0x14,0xd5,0xff,0x03,0x0d,0xad,0x5c,0x07,0x4c,0xe7,0x17,0x0d,0x30,0x32,0x30,
4403 0x37,0x31,0x35,0x32,0x33,0x30,0x31,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x60,
4404 0x24,0x67,0xc3,0x0b,0xad,0x53,0x8f,0xce,0x89,0x05,0xb5,0x87,0xaf,0x7c,0xe4,
4405 0x17,0x0d,0x30,0x32,0x31,0x30,0x30,0x38,0x32,0x30,0x33,0x38,0x35,0x32,0x5a,
4406 0x30,0x21,0x02,0x10,0x60,0x5c,0xf3,0x3d,0x22,0x23,0x39,0x3f,0xe6,0x21,0x09,
4407 0xfd,0xdd,0x77,0xc2,0x8f,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x32,0x31,0x37,
4408 0x32,0x37,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x60,0xa2,0x5e,0xbf,0x07,0x83,
4409 0xa3,0x18,0x56,0x18,0x48,0x63,0xa7,0xfd,0xc7,0x63,0x17,0x0d,0x30,0x32,0x30,
4410 0x35,0x30,0x39,0x31,0x39,0x35,0x32,0x32,0x37,0x5a,0x30,0x21,0x02,0x10,0x60,
4411 0xc2,0xad,0xa8,0x0e,0xf9,0x9a,0x66,0x5d,0xa2,0x75,0x04,0x5e,0x5c,0x71,0xc2,
4412 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x32,0x31,0x33,0x33,0x36,0x31,0x37,0x5a,
4413 0x30,0x21,0x02,0x10,0x60,0xdb,0x1d,0x37,0x34,0xf6,0x02,0x9d,0x68,0x1b,0x70,
4414 0xf1,0x13,0x00,0x2f,0x80,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x38,0x30,0x39,
4415 0x35,0x35,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x61,0xf0,0x38,0xea,0xbc,0x17,
4416 0x0d,0x11,0xd2,0x89,0xee,0x87,0x50,0x57,0xa0,0xed,0x17,0x0d,0x30,0x33,0x30,
4417 0x31,0x32,0x39,0x31,0x37,0x34,0x31,0x34,0x34,0x5a,0x30,0x21,0x02,0x10,0x61,
4418 0xfa,0x9b,0xeb,0x58,0xf9,0xe5,0xa5,0x9e,0x79,0xa8,0x3d,0x79,0xac,0x35,0x97,
4419 0x17,0x0d,0x30,0x32,0x31,0x30,0x31,0x30,0x32,0x30,0x31,0x36,0x33,0x37,0x5a,
4420 0x30,0x21,0x02,0x10,0x62,0x44,0x57,0x24,0x41,0xc0,0x89,0x3f,0x5b,0xd2,0xbd,
4421 0xe7,0x2f,0x75,0x41,0xfa,0x17,0x0d,0x30,0x32,0x30,0x38,0x30,0x38,0x31,0x38,
4422 0x33,0x30,0x31,0x35,0x5a,0x30,0x21,0x02,0x10,0x62,0x51,0x3a,0x2d,0x8d,0x82,
4423 0x39,0x65,0xfe,0xf6,0x8a,0xc8,0x4e,0x29,0x91,0xfd,0x17,0x0d,0x30,0x32,0x30,
4424 0x39,0x32,0x36,0x30,0x30,0x35,0x34,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x62,
4425 0x52,0x49,0x49,0xf2,0x51,0x67,0x7a,0xe2,0xee,0xc9,0x0c,0x23,0x11,0x3d,0xb2,
4426 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x38,0x30,0x36,0x35,0x35,0x5a,
4427 0x30,0x21,0x02,0x10,0x63,0x52,0xbd,0xdc,0xb7,0xbf,0xbb,0x90,0x6c,0x82,0xee,
4428 0xb5,0xa3,0x9f,0xd8,0xc9,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x31,0x31,0x36,
4429 0x33,0x30,0x35,0x38,0x5a,0x30,0x21,0x02,0x10,0x63,0x5e,0x6b,0xe9,0xea,0x3d,
4430 0xd6,0x3b,0xc3,0x4d,0x09,0xc3,0x13,0xdb,0xdd,0xbc,0x17,0x0d,0x30,0x33,0x30,
4431 0x36,0x30,0x32,0x31,0x34,0x34,0x37,0x33,0x36,0x5a,0x30,0x21,0x02,0x10,0x63,
4432 0xda,0x0b,0xd5,0x13,0x1e,0x98,0x83,0x32,0xa2,0x3a,0x4b,0xdf,0x8c,0x89,0x86,
4433 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x35,0x30,0x38,0x30,0x38,0x31,0x33,0x5a,
4434 0x30,0x21,0x02,0x10,0x64,0xfe,0xf0,0x1a,0x3a,0xed,0x89,0xf8,0xb5,0x34,0xd3,
4435 0x1e,0x0f,0xce,0x0d,0xce,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x38,0x32,0x31,
4436 0x30,0x36,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x65,0xa7,0x49,0xd8,0x37,0x22,
4437 0x4b,0x4a,0xe5,0xcf,0xa3,0xfe,0xd6,0x3b,0xc0,0x67,0x17,0x0d,0x30,0x32,0x31,
4438 0x32,0x30,0x34,0x31,0x37,0x31,0x34,0x31,0x36,0x5a,0x30,0x21,0x02,0x10,0x65,
4439 0xc9,0x9e,0x47,0x76,0x98,0x0d,0x9e,0x57,0xe4,0xae,0xc5,0x1c,0x3e,0xf2,0xe7,
4440 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x33,0x31,0x34,0x30,0x38,0x31,0x38,0x5a,
4441 0x30,0x21,0x02,0x10,0x65,0xe0,0x7b,0xc5,0x74,0xe4,0xab,0x01,0x4f,0xa3,0x5e,
4442 0xd6,0xeb,0xcd,0xd5,0x69,0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x33,0x31,0x37,
4443 0x32,0x34,0x30,0x36,0x5a,0x30,0x21,0x02,0x10,0x66,0x51,0xb7,0xe5,0x62,0xb7,
4444 0xe3,0x31,0xc0,0xee,0xf2,0xe8,0xfe,0x84,0x6a,0x4e,0x17,0x0d,0x30,0x32,0x30,
4445 0x39,0x30,0x36,0x31,0x33,0x32,0x33,0x33,0x33,0x5a,0x30,0x21,0x02,0x10,0x67,
4446 0x7c,0x76,0xac,0x66,0x5a,0x6b,0x41,0x5c,0x07,0x83,0x02,0xd6,0xd9,0x63,0xc0,
4447 0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x38,0x31,0x33,0x35,0x35,0x31,0x30,0x5a,
4448 0x30,0x21,0x02,0x10,0x68,0x67,0xde,0xb3,0xaa,0x20,0xcf,0x4b,0x34,0xa5,0xe0,
4449 0xc8,0xc0,0xc5,0xc9,0xa4,0x17,0x0d,0x30,0x32,0x30,0x33,0x31,0x32,0x30,0x31,
4450 0x30,0x39,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x69,0x23,0x34,0x5d,0x75,0x04,
4451 0xdc,0x99,0xbd,0xce,0x8d,0x21,0xb4,0x6b,0x10,0xfc,0x17,0x0d,0x30,0x32,0x30,
4452 0x39,0x30,0x33,0x31,0x33,0x31,0x39,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x69,
4453 0x9f,0x20,0x31,0xd1,0x3f,0xfa,0x1e,0x70,0x2e,0x37,0xd5,0x9a,0x8c,0x0a,0x16,
4454 0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x30,0x30,0x39,0x30,0x31,0x33,0x35,0x5a,
4455 0x30,0x21,0x02,0x10,0x6a,0x94,0xd6,0x25,0xd0,0x67,0xe4,0x4d,0x79,0x2b,0xc6,
4456 0xd5,0xc9,0x4a,0x7f,0xc6,0x17,0x0d,0x30,0x32,0x30,0x32,0x31,0x31,0x31,0x39,
4457 0x31,0x35,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x6b,0x5c,0xa4,0x45,0x5b,0xe9,
4458 0xcf,0xe7,0x3b,0x29,0xb1,0x32,0xd7,0xa1,0x04,0x3d,0x17,0x0d,0x30,0x32,0x31,
4459 0x30,0x31,0x38,0x31,0x35,0x34,0x33,0x34,0x38,0x5a,0x30,0x21,0x02,0x10,0x6b,
4460 0xc0,0x7d,0x4f,0x18,0xfe,0xb7,0x07,0xe8,0x56,0x9a,0x6c,0x40,0x0f,0x36,0x53,
4461 0x17,0x0d,0x30,0x32,0x30,0x39,0x32,0x36,0x32,0x31,0x30,0x31,0x32,0x36,0x5a,
4462 0x30,0x21,0x02,0x10,0x6b,0xe1,0xdd,0x36,0x3b,0xec,0xe0,0xa9,0xf5,0x92,0x7e,
4463 0x33,0xbf,0xed,0x48,0x46,0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x37,0x31,0x34,
4464 0x34,0x32,0x33,0x31,0x5a,0x30,0x21,0x02,0x10,0x6c,0xac,0xeb,0x37,0x2b,0x6a,
4465 0x42,0xe2,0xca,0xc8,0xd2,0xda,0xb8,0xb9,0x82,0x6a,0x17,0x0d,0x30,0x32,0x30,
4466 0x33,0x30,0x31,0x31,0x34,0x32,0x38,0x33,0x34,0x5a,0x30,0x21,0x02,0x10,0x6d,
4467 0x98,0x1b,0xb4,0x76,0xd1,0x62,0x59,0xa1,0x3c,0xee,0xd2,0x21,0xd8,0xdf,0x4c,
4468 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x34,0x31,0x37,0x35,0x36,0x31,0x32,0x5a,
4469 0x30,0x21,0x02,0x10,0x6d,0xdd,0x0b,0x5a,0x3c,0x9c,0xab,0xd3,0x3b,0xd9,0x16,
4470 0xec,0x69,0x74,0xfb,0x9a,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x32,0x31,0x32,
4471 0x32,0x36,0x33,0x38,0x5a,0x30,0x21,0x02,0x10,0x6e,0xde,0xfd,0x89,0x36,0xae,
4472 0xa0,0x41,0x8d,0x5c,0xec,0x2e,0x90,0x31,0xf8,0x9a,0x17,0x0d,0x30,0x32,0x30,
4473 0x34,0x30,0x38,0x32,0x32,0x33,0x36,0x31,0x32,0x5a,0x30,0x21,0x02,0x10,0x6f,
4474 0xb2,0x6b,0x4c,0x48,0xca,0xfe,0xe6,0x69,0x9a,0x06,0x63,0xc4,0x32,0x96,0xc1,
4475 0x17,0x0d,0x30,0x33,0x30,0x31,0x31,0x37,0x31,0x37,0x32,0x37,0x32,0x35,0x5a,
4476 0x30,0x21,0x02,0x10,0x70,0x0b,0xe1,0xee,0x44,0x89,0x51,0x52,0x65,0x27,0x2c,
4477 0x2d,0x34,0x7c,0xe0,0x8d,0x17,0x0d,0x30,0x32,0x30,0x39,0x31,0x38,0x30,0x30,
4478 0x33,0x36,0x30,0x30,0x5a,0x30,0x21,0x02,0x10,0x70,0x2d,0xc0,0xa6,0xb8,0xa5,
4479 0xa0,0xda,0x48,0x59,0xb3,0x96,0x34,0x80,0xc8,0x25,0x17,0x0d,0x30,0x32,0x30,
4480 0x38,0x33,0x30,0x31,0x34,0x30,0x31,0x30,0x31,0x5a,0x30,0x21,0x02,0x10,0x70,
4481 0xe1,0xd9,0x92,0xcd,0x76,0x42,0x63,0x51,0x6e,0xcd,0x8c,0x09,0x29,0x17,0x48,
4482 0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x37,0x31,0x31,0x31,0x30,0x34,0x31,0x5a,
4483 0x30,0x21,0x02,0x10,0x72,0x38,0xe4,0x91,0x6a,0x7a,0x8a,0xf3,0xbf,0xf0,0xd8,
4484 0xe0,0xa4,0x70,0x8d,0xa8,0x17,0x0d,0x30,0x32,0x30,0x33,0x30,0x34,0x31,0x39,
4485 0x30,0x36,0x34,0x30,0x5a,0x30,0x21,0x02,0x10,0x72,0x97,0xa1,0xd8,0x9c,0x3b,
4486 0x00,0xc2,0xc4,0x26,0x2d,0x06,0x2b,0x29,0x76,0x4e,0x17,0x0d,0x30,0x32,0x30,
4487 0x36,0x31,0x38,0x31,0x35,0x30,0x39,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x72,
4488 0xd2,0x23,0x9b,0xf2,0x33,0xe9,0x7c,0xcf,0xb6,0xa9,0x41,0xd5,0x0e,0x5c,0x39,
4489 0x17,0x0d,0x30,0x33,0x30,0x34,0x30,0x39,0x31,0x37,0x30,0x32,0x32,0x39,0x5a,
4490 0x30,0x21,0x02,0x10,0x74,0x5c,0x9c,0xf9,0xaa,0xc3,0xfa,0x94,0x3c,0x25,0x39,
4491 0x65,0x44,0x95,0x13,0xf1,0x17,0x0d,0x30,0x32,0x30,0x37,0x30,0x39,0x32,0x33,
4492 0x35,0x33,0x32,0x30,0x5a,0x30,0x21,0x02,0x10,0x74,0x98,0x7f,0x68,0xad,0x17,
4493 0x92,0x93,0xf2,0x65,0x94,0x0c,0x33,0xe6,0xbd,0x49,0x17,0x0d,0x30,0x32,0x30,
4494 0x34,0x32,0x33,0x30,0x37,0x34,0x34,0x31,0x38,0x5a,0x30,0x21,0x02,0x10,0x75,
4495 0x0e,0x40,0xff,0x97,0xf0,0x47,0xed,0xf5,0x56,0xc7,0x08,0x4e,0xb1,0xab,0xfd,
4496 0x17,0x0d,0x30,0x31,0x30,0x31,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,
4497 0x30,0x21,0x02,0x10,0x75,0x26,0x51,0x59,0x65,0xb7,0x33,0x32,0x5f,0xe6,0xcd,
4498 0xaa,0x30,0x65,0x78,0xe0,0x17,0x0d,0x30,0x32,0x30,0x35,0x31,0x36,0x31,0x38,
4499 0x32,0x34,0x35,0x36,0x5a,0x30,0x21,0x02,0x10,0x76,0x13,0x6f,0xbf,0xc8,0xde,
4500 0xd9,0x36,0x30,0x39,0xcc,0x85,0x8f,0x00,0x2f,0x19,0x17,0x0d,0x30,0x32,0x30,
4501 0x33,0x31,0x34,0x30,0x39,0x34,0x38,0x32,0x34,0x5a,0x30,0x21,0x02,0x10,0x76,
4502 0x52,0x78,0x89,0x44,0xfa,0xc1,0xb3,0xd7,0xc9,0x4c,0xb3,0x32,0x95,0xaf,0x03,
4503 0x17,0x0d,0x30,0x32,0x31,0x31,0x31,0x34,0x31,0x39,0x31,0x35,0x34,0x33,0x5a,
4504 0x30,0x21,0x02,0x10,0x77,0x5d,0x4c,0x40,0xd9,0x8d,0xfa,0xc8,0x9a,0x24,0x8d,
4505 0x47,0x10,0x90,0x4a,0x0a,0x17,0x0d,0x30,0x32,0x30,0x35,0x30,0x39,0x30,0x31,
4506 0x31,0x33,0x30,0x32,0x5a,0x30,0x21,0x02,0x10,0x77,0xe6,0x5a,0x43,0x59,0x93,
4507 0x5d,0x5f,0x7a,0x75,0x80,0x1a,0xcd,0xad,0xc2,0x22,0x17,0x0d,0x30,0x30,0x30,
4508 0x38,0x33,0x31,0x31,0x38,0x32,0x32,0x35,0x30,0x5a,0x30,0x21,0x02,0x10,0x78,
4509 0x19,0xf1,0xb6,0x87,0x83,0xaf,0xdf,0x60,0x8d,0x9a,0x64,0x0d,0xec,0xe0,0x51,
4510 0x17,0x0d,0x30,0x32,0x30,0x35,0x32,0x30,0x31,0x37,0x32,0x38,0x31,0x36,0x5a,
4511 0x30,0x21,0x02,0x10,0x78,0x64,0x65,0x8f,0x82,0x79,0xdb,0xa5,0x1c,0x47,0x10,
4512 0x1d,0x72,0x23,0x66,0x52,0x17,0x0d,0x30,0x33,0x30,0x31,0x32,0x34,0x31,0x38,
4513 0x34,0x35,0x34,0x37,0x5a,0x30,0x21,0x02,0x10,0x78,0x64,0xe1,0xc0,0x69,0x8f,
4514 0x3a,0xc7,0x8b,0x23,0xe3,0x29,0xb1,0xee,0xa9,0x41,0x17,0x0d,0x30,0x32,0x30,
4515 0x35,0x30,0x38,0x31,0x37,0x34,0x36,0x32,0x36,0x5a,0x30,0x21,0x02,0x10,0x78,
4516 0x79,0x89,0x61,0x12,0x67,0x64,0x14,0xfd,0x08,0xcc,0xb3,0x05,0x55,0xc0,0x67,
4517 0x17,0x0d,0x30,0x32,0x30,0x34,0x30,0x32,0x31,0x33,0x31,0x38,0x35,0x33,0x5a,
4518 0x30,0x21,0x02,0x10,0x78,0x8a,0x56,0x22,0x08,0xce,0x42,0xee,0xd1,0xa3,0x79,
4519 0x10,0x14,0xfd,0x3a,0x36,0x17,0x0d,0x30,0x33,0x30,0x32,0x30,0x35,0x31,0x36,
4520 0x35,0x33,0x32,0x39,0x5a,0x30,0x21,0x02,0x10,0x7a,0xa0,0x6c,0xba,0x33,0x02,
4521 0xac,0x5f,0xf5,0x0b,0xb6,0x77,0x61,0xef,0x77,0x09,0x17,0x0d,0x30,0x32,0x30,
4522 0x32,0x32,0x38,0x31,0x37,0x35,0x35,0x31,0x31,0x5a,0x30,0x21,0x02,0x10,0x7b,
4523 0x91,0x33,0x66,0x6c,0xf0,0xd4,0xe3,0x9d,0xf6,0x88,0x29,0x9b,0xf7,0xd0,0xea,
4524 0x17,0x0d,0x30,0x32,0x31,0x31,0x32,0x30,0x32,0x32,0x31,0x36,0x34,0x39,0x5a,
4525 0x30,0x21,0x02,0x10,0x7c,0xef,0xf2,0x0a,0x08,0xae,0x10,0x57,0x1e,0xde,0xdc,
4526 0xd6,0x63,0x76,0xb0,0x5d,0x17,0x0d,0x30,0x32,0x30,0x32,0x32,0x36,0x31,0x30,
4527 0x32,0x32,0x33,0x30,0x5a,0x30,0x21,0x02,0x10,0x7f,0x76,0xef,0x69,0xeb,0xf5,
4528 0x3f,0x53,0x2e,0xaa,0xa5,0xed,0xde,0xc0,0xb4,0x06,0x17,0x0d,0x30,0x32,0x30,
4529 0x35,0x30,0x31,0x30,0x33,0x33,0x33,0x30,0x37,0x5a,0x30,0x21,0x02,0x10,0x7f,
4530 0xcb,0x6b,0x99,0x91,0xd0,0x76,0xe1,0x3c,0x0e,0x67,0x15,0xc4,0xd4,0x4d,0x7b,
4531 0x17,0x0d,0x30,0x32,0x30,0x34,0x31,0x30,0x32,0x31,0x31,0x38,0x34,0x30,0x5a,
4532 0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x04,0x05,0x00,
4533 0x03,0x81,0x81,0x00,0x5c,0xb9,0xb3,0xbe,0xd3,0xd6,0x73,0xa3,0xfe,0x4a,0xb2,
4534 0x21,0x80,0xea,0xaa,0x05,0x61,0x14,0x1d,0x67,0xb1,0xdf,0xa6,0xf9,0x42,0x08,
4535 0x0d,0x59,0x62,0x9c,0x11,0x5f,0x0e,0x92,0xc5,0xc6,0xae,0x74,0x64,0xc7,0x84,
4536 0x3e,0x64,0x43,0xd2,0xec,0xbb,0xe1,0x9b,0x52,0x74,0x57,0xcf,0x96,0xef,0x68,
4537 0x02,0x7a,0x7b,0x36,0xb7,0xc6,0x9a,0x5f,0xca,0x9c,0x37,0x47,0xc8,0x3a,0x5c,
4538 0x34,0x35,0x3b,0x4b,0xca,0x20,0x77,0x44,0x68,0x07,0x02,0x34,0x46,0xaa,0x0f,
4539 0xd0,0x4d,0xd9,0x47,0xf4,0xb3,0x2d,0xb1,0x44,0xa5,0x69,0xa9,0x85,0x13,0x43,
4540 0xcd,0xcc,0x1d,0x9a,0xe6,0x2d,0xfd,0x9f,0xdc,0x2f,0x83,0xbb,0x8c,0xe2,0x8c,
4541 0x61,0xc0,0x99,0x16,0x71,0x05,0xb6,0x25,0x14,0x64,0x4f,0x30 };
4543 static void test_decodeCRLToBeSigned(DWORD dwEncoding)
4545 static const BYTE *corruptCRLs[] = { v1CRL, v2CRL };
4546 BOOL ret;
4547 BYTE *buf = NULL;
4548 DWORD size = 0, i;
4550 for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
4552 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4553 corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4554 &buf, &size);
4555 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4556 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4557 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4558 GetLastError());
4560 /* at a minimum, a CRL must contain an issuer: */
4561 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4562 v1CRLWithIssuer, v1CRLWithIssuer[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
4563 &buf, &size);
4564 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4565 if (buf)
4567 CRL_INFO *info = (CRL_INFO *)buf;
4569 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4570 ok(info->cCRLEntry == 0, "Expected 0 CRL entries, got %d\n",
4571 info->cCRLEntry);
4572 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4573 "Wrong issuer size %d\n", info->Issuer.cbData);
4574 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4575 "Unexpected issuer\n");
4576 LocalFree(buf);
4578 /* check decoding with an empty CRL entry */
4579 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4580 v1CRLWithIssuerAndEmptyEntry, v1CRLWithIssuerAndEmptyEntry[1] + 2,
4581 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4582 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
4583 GetLastError() == OSS_DATA_ERROR /* Win9x */),
4584 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %08x\n",
4585 GetLastError());
4586 /* with a real CRL entry */
4587 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4588 v1CRLWithIssuerAndEntry, v1CRLWithIssuerAndEntry[1] + 2,
4589 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4590 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4591 if (buf)
4593 CRL_INFO *info = (CRL_INFO *)buf;
4594 CRL_ENTRY *entry;
4596 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4597 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4598 info->cCRLEntry);
4599 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4600 entry = info->rgCRLEntry;
4601 ok(entry->SerialNumber.cbData == 1,
4602 "Expected serial number size 1, got %d\n",
4603 entry->SerialNumber.cbData);
4604 ok(*entry->SerialNumber.pbData == *serialNum,
4605 "Expected serial number %d, got %d\n", *serialNum,
4606 *entry->SerialNumber.pbData);
4607 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4608 "Wrong issuer size %d\n", info->Issuer.cbData);
4609 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4610 "Unexpected issuer\n");
4611 LocalFree(buf);
4613 /* a real CRL from verisign that has extensions */
4614 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4615 verisignCRL, sizeof(verisignCRL), CRYPT_DECODE_ALLOC_FLAG,
4616 NULL, &buf, &size);
4617 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4618 if (buf)
4620 CRL_INFO *info = (CRL_INFO *)buf;
4621 CRL_ENTRY *entry;
4623 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4624 ok(info->cCRLEntry == 3, "Expected 3 CRL entries, got %d\n",
4625 info->cCRLEntry);
4626 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4627 entry = info->rgCRLEntry;
4628 ok(info->cExtension == 2, "Expected 2 extensions, got %d\n",
4629 info->cExtension);
4630 LocalFree(buf);
4632 /* another real CRL from verisign that has lots of entries */
4633 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4634 verisignCRLWithLotsOfEntries, sizeof(verisignCRLWithLotsOfEntries),
4635 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4636 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4637 if (buf)
4639 CRL_INFO *info = (CRL_INFO *)buf;
4641 ok(size >= sizeof(CRL_INFO), "Got size %d\n", size);
4642 ok(info->cCRLEntry == 209, "Expected 209 CRL entries, got %d\n",
4643 info->cCRLEntry);
4644 ok(info->cExtension == 0, "Expected 0 extensions, got %d\n",
4645 info->cExtension);
4646 LocalFree(buf);
4648 /* and finally, with an extension */
4649 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4650 v1CRLWithExt, sizeof(v1CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4651 NULL, &buf, &size);
4652 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4653 if (buf)
4655 CRL_INFO *info = (CRL_INFO *)buf;
4656 CRL_ENTRY *entry;
4658 ok(size >= sizeof(CRL_INFO), "Wrong size %d\n", size);
4659 ok(info->cCRLEntry == 1, "Expected 1 CRL entries, got %d\n",
4660 info->cCRLEntry);
4661 ok(info->rgCRLEntry != NULL, "Expected a valid CRL entry array\n");
4662 entry = info->rgCRLEntry;
4663 ok(entry->SerialNumber.cbData == 1,
4664 "Expected serial number size 1, got %d\n",
4665 entry->SerialNumber.cbData);
4666 ok(*entry->SerialNumber.pbData == *serialNum,
4667 "Expected serial number %d, got %d\n", *serialNum,
4668 *entry->SerialNumber.pbData);
4669 ok(info->Issuer.cbData == sizeof(encodedCommonName),
4670 "Wrong issuer size %d\n", info->Issuer.cbData);
4671 ok(!memcmp(info->Issuer.pbData, encodedCommonName, info->Issuer.cbData),
4672 "Unexpected issuer\n");
4673 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4674 info->cExtension);
4675 LocalFree(buf);
4677 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4678 v2CRLWithExt, sizeof(v2CRLWithExt), CRYPT_DECODE_ALLOC_FLAG,
4679 NULL, &buf, &size);
4680 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4681 if (buf)
4683 CRL_INFO *info = (CRL_INFO *)buf;
4685 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4686 info->cExtension);
4687 LocalFree(buf);
4689 /* And again, with an issuing dist point */
4690 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
4691 v2CRLWithIssuingDistPoint, sizeof(v2CRLWithIssuingDistPoint),
4692 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4693 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4694 if (buf)
4696 CRL_INFO *info = (CRL_INFO *)buf;
4698 ok(info->cExtension == 1, "Expected 1 extensions, got %d\n",
4699 info->cExtension);
4700 LocalFree(buf);
4704 static const LPCSTR keyUsages[] = { szOID_PKIX_KP_CODE_SIGNING,
4705 szOID_PKIX_KP_CLIENT_AUTH, szOID_RSA_RSA };
4706 static const BYTE encodedUsage[] = {
4707 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03,
4708 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09,
4709 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 };
4711 static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
4713 BOOL ret;
4714 BYTE *buf = NULL;
4715 DWORD size = 0;
4716 CERT_ENHKEY_USAGE usage;
4718 /* Test with empty usage */
4719 usage.cUsageIdentifier = 0;
4720 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4721 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4722 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4723 if (buf)
4725 ok(size == sizeof(emptySequence), "Wrong size %d\n", size);
4726 ok(!memcmp(buf, emptySequence, size), "Got unexpected value\n");
4727 LocalFree(buf);
4729 /* Test with a few usages */
4730 usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
4731 usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
4732 ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
4733 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4734 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4735 if (buf)
4737 ok(size == sizeof(encodedUsage), "Wrong size %d\n", size);
4738 ok(!memcmp(buf, encodedUsage, size), "Got unexpected value\n");
4739 LocalFree(buf);
4743 static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
4745 BOOL ret;
4746 LPBYTE buf = NULL;
4747 DWORD size = 0;
4749 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4750 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4751 &buf, &size);
4752 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4753 if (buf)
4755 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4757 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4758 "Wrong size %d\n", size);
4759 ok(usage->cUsageIdentifier == 0, "Expected 0 CRL entries, got %d\n",
4760 usage->cUsageIdentifier);
4761 LocalFree(buf);
4763 ret = pCryptDecodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE,
4764 encodedUsage, sizeof(encodedUsage), CRYPT_DECODE_ALLOC_FLAG, NULL,
4765 &buf, &size);
4766 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4767 if (buf)
4769 CERT_ENHKEY_USAGE *usage = (CERT_ENHKEY_USAGE *)buf;
4770 DWORD i;
4772 ok(size >= sizeof(CERT_ENHKEY_USAGE),
4773 "Wrong size %d\n", size);
4774 ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
4775 "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
4776 for (i = 0; i < usage->cUsageIdentifier; i++)
4777 ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
4778 "Expected OID %s, got %s\n", keyUsages[i],
4779 usage->rgpszUsageIdentifier[i]);
4780 LocalFree(buf);
4784 static BYTE keyId[] = { 1,2,3,4 };
4785 static const BYTE authorityKeyIdWithId[] = {
4786 0x30,0x06,0x80,0x04,0x01,0x02,0x03,0x04 };
4787 static const BYTE authorityKeyIdWithIssuer[] = { 0x30,0x19,0xa1,0x17,0x30,0x15,
4788 0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,
4789 0x20,0x4c,0x61,0x6e,0x67,0x00 };
4790 static const BYTE authorityKeyIdWithSerial[] = { 0x30,0x03,0x82,0x01,0x01 };
4792 static void test_encodeAuthorityKeyId(DWORD dwEncoding)
4794 CERT_AUTHORITY_KEY_ID_INFO info = { { 0 } };
4795 BOOL ret;
4796 BYTE *buf = NULL;
4797 DWORD size = 0;
4799 /* Test with empty id */
4800 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4801 CRYPT_ENCODE_ALLOC_FLAG, NULL, &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);
4809 /* With just a key id */
4810 info.KeyId.cbData = sizeof(keyId);
4811 info.KeyId.pbData = keyId;
4812 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4813 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4814 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4815 if (buf)
4817 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n", size);
4818 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4819 LocalFree(buf);
4821 /* With just an issuer */
4822 info.KeyId.cbData = 0;
4823 info.CertIssuer.cbData = sizeof(encodedCommonName);
4824 info.CertIssuer.pbData = (BYTE *)encodedCommonName;
4825 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4826 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4827 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4828 if (buf)
4830 ok(size == sizeof(authorityKeyIdWithIssuer), "Unexpected size %d\n",
4831 size);
4832 ok(!memcmp(buf, authorityKeyIdWithIssuer, size), "Unexpected value\n");
4833 LocalFree(buf);
4835 /* With just a serial number */
4836 info.CertIssuer.cbData = 0;
4837 info.CertSerialNumber.cbData = sizeof(serialNum);
4838 info.CertSerialNumber.pbData = (BYTE *)serialNum;
4839 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID, &info,
4840 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4841 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4842 if (buf)
4844 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4845 size);
4846 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4847 LocalFree(buf);
4851 static void test_decodeAuthorityKeyId(DWORD dwEncoding)
4853 BOOL ret;
4854 LPBYTE buf = NULL;
4855 DWORD size = 0;
4857 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4858 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
4859 &buf, &size);
4860 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4861 if (buf)
4863 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4865 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4866 size);
4867 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4868 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4869 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4870 LocalFree(buf);
4872 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4873 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
4874 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4875 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4876 if (buf)
4878 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4880 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4881 size);
4882 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
4883 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
4884 "Unexpected key id\n");
4885 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4886 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4887 LocalFree(buf);
4889 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4890 authorityKeyIdWithIssuer, sizeof(authorityKeyIdWithIssuer),
4891 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4892 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4893 if (buf)
4895 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4897 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4898 size);
4899 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4900 ok(info->CertIssuer.cbData == sizeof(encodedCommonName),
4901 "Unexpected issuer len\n");
4902 ok(!memcmp(info->CertIssuer.pbData, encodedCommonName,
4903 sizeof(encodedCommonName)), "Unexpected issuer\n");
4904 ok(info->CertSerialNumber.cbData == 0, "Expected no serial number\n");
4905 LocalFree(buf);
4907 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID,
4908 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
4909 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
4910 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
4911 if (buf)
4913 CERT_AUTHORITY_KEY_ID_INFO *info = (CERT_AUTHORITY_KEY_ID_INFO *)buf;
4915 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID_INFO), "Unexpected size %d\n",
4916 size);
4917 ok(info->KeyId.cbData == 0, "Expected no key id\n");
4918 ok(info->CertIssuer.cbData == 0, "Expected no issuer name\n");
4919 ok(info->CertSerialNumber.cbData == sizeof(serialNum),
4920 "Unexpected serial number len\n");
4921 ok(!memcmp(info->CertSerialNumber.pbData, serialNum, sizeof(serialNum)),
4922 "Unexpected serial number\n");
4923 LocalFree(buf);
4927 static const BYTE authorityKeyIdWithIssuerUrl[] = { 0x30,0x15,0xa1,0x13,0x86,
4928 0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,
4929 0x6f,0x72,0x67 };
4931 static void test_encodeAuthorityKeyId2(DWORD dwEncoding)
4933 CERT_AUTHORITY_KEY_ID2_INFO info = { { 0 } };
4934 CERT_ALT_NAME_ENTRY entry = { 0 };
4935 BOOL ret;
4936 BYTE *buf = NULL;
4937 DWORD size = 0;
4939 /* Test with empty id */
4940 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4941 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4942 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4943 if (buf)
4945 ok(size == sizeof(emptySequence), "Unexpected size %d\n", size);
4946 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
4947 LocalFree(buf);
4949 /* With just a key id */
4950 info.KeyId.cbData = sizeof(keyId);
4951 info.KeyId.pbData = keyId;
4952 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4953 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4954 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4955 if (buf)
4957 ok(size == sizeof(authorityKeyIdWithId), "Unexpected size %d\n",
4958 size);
4959 ok(!memcmp(buf, authorityKeyIdWithId, size), "Unexpected value\n");
4960 LocalFree(buf);
4962 /* With a bogus issuer name */
4963 info.KeyId.cbData = 0;
4964 info.AuthorityCertIssuer.cAltEntry = 1;
4965 info.AuthorityCertIssuer.rgAltEntry = &entry;
4966 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4967 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4968 ok(!ret && GetLastError() == E_INVALIDARG,
4969 "Expected E_INVALIDARG, got %08x\n", GetLastError());
4970 /* With an issuer name */
4971 entry.dwAltNameChoice = CERT_ALT_NAME_URL;
4972 U(entry).pwszURL = (LPWSTR)url;
4973 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4974 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4975 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4976 if (buf)
4978 ok(size == sizeof(authorityKeyIdWithIssuerUrl), "Unexpected size %d\n",
4979 size);
4980 ok(!memcmp(buf, authorityKeyIdWithIssuerUrl, size),
4981 "Unexpected value\n");
4982 LocalFree(buf);
4984 /* With just a serial number */
4985 info.AuthorityCertIssuer.cAltEntry = 0;
4986 info.AuthorityCertSerialNumber.cbData = sizeof(serialNum);
4987 info.AuthorityCertSerialNumber.pbData = (BYTE *)serialNum;
4988 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2, &info,
4989 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
4990 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
4991 if (buf)
4993 ok(size == sizeof(authorityKeyIdWithSerial), "Unexpected size %d\n",
4994 size);
4995 ok(!memcmp(buf, authorityKeyIdWithSerial, size), "Unexpected value\n");
4996 LocalFree(buf);
5000 static void test_decodeAuthorityKeyId2(DWORD dwEncoding)
5002 BOOL ret;
5003 LPBYTE buf = NULL;
5004 DWORD size = 0;
5006 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5007 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5008 &buf, &size);
5009 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5010 if (buf)
5012 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5014 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5015 size);
5016 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5017 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5018 "Expected no issuer name entries\n");
5019 ok(info->AuthorityCertSerialNumber.cbData == 0,
5020 "Expected no serial number\n");
5021 LocalFree(buf);
5023 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5024 authorityKeyIdWithId, sizeof(authorityKeyIdWithId),
5025 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5026 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5027 if (buf)
5029 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5031 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5032 size);
5033 ok(info->KeyId.cbData == sizeof(keyId), "Unexpected key id len\n");
5034 ok(!memcmp(info->KeyId.pbData, keyId, sizeof(keyId)),
5035 "Unexpected key id\n");
5036 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5037 "Expected no issuer name entries\n");
5038 ok(info->AuthorityCertSerialNumber.cbData == 0,
5039 "Expected no serial number\n");
5040 LocalFree(buf);
5042 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5043 authorityKeyIdWithIssuerUrl, sizeof(authorityKeyIdWithIssuerUrl),
5044 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5045 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5046 if (buf)
5048 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5050 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5051 size);
5052 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5053 ok(info->AuthorityCertIssuer.cAltEntry == 1,
5054 "Expected 1 issuer entry, got %d\n",
5055 info->AuthorityCertIssuer.cAltEntry);
5056 ok(info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice ==
5057 CERT_ALT_NAME_URL, "Expected CERT_ALT_NAME_URL, got %d\n",
5058 info->AuthorityCertIssuer.rgAltEntry[0].dwAltNameChoice);
5059 ok(!lstrcmpW(U(info->AuthorityCertIssuer.rgAltEntry[0]).pwszURL,
5060 url), "Unexpected URL\n");
5061 ok(info->AuthorityCertSerialNumber.cbData == 0,
5062 "Expected no serial number\n");
5063 LocalFree(buf);
5065 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_KEY_ID2,
5066 authorityKeyIdWithSerial, sizeof(authorityKeyIdWithSerial),
5067 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5068 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5069 if (buf)
5071 CERT_AUTHORITY_KEY_ID2_INFO *info = (CERT_AUTHORITY_KEY_ID2_INFO *)buf;
5073 ok(size >= sizeof(CERT_AUTHORITY_KEY_ID2_INFO), "Unexpected size %d\n",
5074 size);
5075 ok(info->KeyId.cbData == 0, "Expected no key id\n");
5076 ok(info->AuthorityCertIssuer.cAltEntry == 0,
5077 "Expected no issuer name entries\n");
5078 ok(info->AuthorityCertSerialNumber.cbData == sizeof(serialNum),
5079 "Unexpected serial number len\n");
5080 ok(!memcmp(info->AuthorityCertSerialNumber.pbData, serialNum,
5081 sizeof(serialNum)), "Unexpected serial number\n");
5082 LocalFree(buf);
5086 static const BYTE authorityInfoAccessWithUrl[] = {
5087 0x30,0x19,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5088 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
5089 static const BYTE authorityInfoAccessWithUrlAndIPAddr[] = {
5090 0x30,0x29,0x30,0x17,0x06,0x02,0x2a,0x03,0x86,0x11,0x68,0x74,0x74,0x70,0x3a,
5091 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67,0x30,0x0e,0x06,
5092 0x02,0x2d,0x06,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5094 static void test_encodeAuthorityInfoAccess(DWORD dwEncoding)
5096 static char oid1[] = "1.2.3";
5097 static char oid2[] = "1.5.6";
5098 BOOL ret;
5099 BYTE *buf = NULL;
5100 DWORD size = 0;
5101 CERT_ACCESS_DESCRIPTION accessDescription[2];
5102 CERT_AUTHORITY_INFO_ACCESS aia;
5104 memset(accessDescription, 0, sizeof(accessDescription));
5105 aia.cAccDescr = 0;
5106 aia.rgAccDescr = NULL;
5107 /* Having no access descriptions is allowed */
5108 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5109 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5110 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5111 if (buf)
5113 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
5114 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
5115 LocalFree(buf);
5116 buf = NULL;
5118 /* It can't have an empty access method */
5119 aia.cAccDescr = 1;
5120 aia.rgAccDescr = accessDescription;
5121 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5122 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5123 ok(!ret && (GetLastError() == E_INVALIDARG ||
5124 GetLastError() == OSS_LIMITED /* Win9x */),
5125 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
5126 /* It can't have an empty location */
5127 accessDescription[0].pszAccessMethod = oid1;
5128 SetLastError(0xdeadbeef);
5129 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5130 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5131 ok(!ret && GetLastError() == E_INVALIDARG,
5132 "expected E_INVALIDARG, got %08x\n", GetLastError());
5133 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5134 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5135 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5136 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5137 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5138 if (buf)
5140 ok(size == sizeof(authorityInfoAccessWithUrl), "unexpected size %d\n",
5141 size);
5142 ok(!memcmp(buf, authorityInfoAccessWithUrl, size),
5143 "unexpected value\n");
5144 LocalFree(buf);
5145 buf = NULL;
5147 accessDescription[1].pszAccessMethod = oid2;
5148 accessDescription[1].AccessLocation.dwAltNameChoice =
5149 CERT_ALT_NAME_IP_ADDRESS;
5150 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5151 sizeof(encodedIPAddr);
5152 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5153 (LPBYTE)encodedIPAddr;
5154 aia.cAccDescr = 2;
5155 ret = pCryptEncodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS, &aia,
5156 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5157 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5158 if (buf)
5160 ok(size == sizeof(authorityInfoAccessWithUrlAndIPAddr),
5161 "unexpected size %d\n", size);
5162 ok(!memcmp(buf, authorityInfoAccessWithUrlAndIPAddr, size),
5163 "unexpected value\n");
5164 LocalFree(buf);
5165 buf = NULL;
5169 static void compareAuthorityInfoAccess(LPCSTR header,
5170 const CERT_AUTHORITY_INFO_ACCESS *expected,
5171 const CERT_AUTHORITY_INFO_ACCESS *got)
5173 DWORD i;
5175 ok(expected->cAccDescr == got->cAccDescr,
5176 "%s: expected %d access descriptions, got %d\n", header,
5177 expected->cAccDescr, got->cAccDescr);
5178 for (i = 0; i < expected->cAccDescr; i++)
5180 ok(!strcmp(expected->rgAccDescr[i].pszAccessMethod,
5181 got->rgAccDescr[i].pszAccessMethod), "%s[%d]: expected %s, got %s\n",
5182 header, i, expected->rgAccDescr[i].pszAccessMethod,
5183 got->rgAccDescr[i].pszAccessMethod);
5184 compareAltNameEntry(&expected->rgAccDescr[i].AccessLocation,
5185 &got->rgAccDescr[i].AccessLocation);
5189 static void test_decodeAuthorityInfoAccess(DWORD dwEncoding)
5191 static char oid1[] = "1.2.3";
5192 static char oid2[] = "1.5.6";
5193 BOOL ret;
5194 LPBYTE buf = NULL;
5195 DWORD size = 0;
5197 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5198 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
5199 &buf, &size);
5200 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5201 if (buf)
5203 CERT_AUTHORITY_INFO_ACCESS aia = { 0, NULL };
5205 compareAuthorityInfoAccess("empty AIA", &aia,
5206 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5207 LocalFree(buf);
5208 buf = NULL;
5210 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5211 authorityInfoAccessWithUrl, sizeof(authorityInfoAccessWithUrl),
5212 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5213 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5214 if (buf)
5216 CERT_ACCESS_DESCRIPTION accessDescription;
5217 CERT_AUTHORITY_INFO_ACCESS aia;
5219 accessDescription.pszAccessMethod = oid1;
5220 accessDescription.AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5221 U(accessDescription.AccessLocation).pwszURL = (LPWSTR)url;
5222 aia.cAccDescr = 1;
5223 aia.rgAccDescr = &accessDescription;
5224 compareAuthorityInfoAccess("AIA with URL", &aia,
5225 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5226 LocalFree(buf);
5227 buf = NULL;
5229 ret = pCryptDecodeObjectEx(dwEncoding, X509_AUTHORITY_INFO_ACCESS,
5230 authorityInfoAccessWithUrlAndIPAddr,
5231 sizeof(authorityInfoAccessWithUrlAndIPAddr), CRYPT_DECODE_ALLOC_FLAG,
5232 NULL, &buf, &size);
5233 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5234 if (buf)
5236 CERT_ACCESS_DESCRIPTION accessDescription[2];
5237 CERT_AUTHORITY_INFO_ACCESS aia;
5239 accessDescription[0].pszAccessMethod = oid1;
5240 accessDescription[0].AccessLocation.dwAltNameChoice = CERT_ALT_NAME_URL;
5241 U(accessDescription[0].AccessLocation).pwszURL = (LPWSTR)url;
5242 accessDescription[1].pszAccessMethod = oid2;
5243 accessDescription[1].AccessLocation.dwAltNameChoice =
5244 CERT_ALT_NAME_IP_ADDRESS;
5245 U(accessDescription[1].AccessLocation).IPAddress.cbData =
5246 sizeof(encodedIPAddr);
5247 U(accessDescription[1].AccessLocation).IPAddress.pbData =
5248 (LPBYTE)encodedIPAddr;
5249 aia.cAccDescr = 2;
5250 aia.rgAccDescr = accessDescription;
5251 compareAuthorityInfoAccess("AIA with URL and IP addr", &aia,
5252 (CERT_AUTHORITY_INFO_ACCESS *)buf);
5253 LocalFree(buf);
5254 buf = NULL;
5258 static const BYTE emptyCTL[] = {
5259 0x30,0x17,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5260 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5261 static const BYTE emptyCTLWithVersion1[] = {
5262 0x30,0x1a,0x02,0x01,0x01,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5263 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5264 static const BYTE ctlWithUsageIdentifier[] = {
5265 0x30,0x1b,0x30,0x04,0x06,0x02,0x2a,0x03,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,
5266 0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5267 static const BYTE ctlWithListIdentifier[] = {
5268 0x30,0x1a,0x30,0x00,0x04,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5269 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5270 static const BYTE ctlWithSequenceNumber[] = {
5271 0x30,0x1a,0x30,0x00,0x02,0x01,0x01,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,
5272 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5273 static const BYTE ctlWithThisUpdate[] = {
5274 0x30,0x15,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5275 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5276 static const BYTE ctlWithThisAndNextUpdate[] = {
5277 0x30,0x24,0x30,0x00,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5278 0x30,0x30,0x30,0x5a,0x17,0x0d,0x30,0x35,0x30,0x36,0x30,0x36,0x31,0x36,0x31,
5279 0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00 };
5280 static const BYTE ctlWithAlgId[] = {
5281 0x30,0x1b,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5282 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
5283 static const BYTE ctlWithBogusEntry[] = {
5284 0x30,0x29,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5285 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x10,0x30,0x0e,0x04,
5286 0x01,0x01,0x31,0x09,0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,0x01 };
5287 static const BYTE ctlWithOneEntry[] = {
5288 0x30,0x2a,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5289 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x11,0x30,0x0f,0x04,
5290 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00 };
5291 static const BYTE ctlWithTwoEntries[] = {
5292 0x30,0x41,0x30,0x00,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5293 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x02,0x06,0x00,0x30,0x28,0x30,0x0f,0x04,
5294 0x01,0x01,0x31,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x31,0x02,0x30,0x00,0x30,
5295 0x15,0x04,0x01,0x01,0x31,0x10,0x30,0x0e,0x06,0x02,0x2d,0x06,0x31,0x08,0x30,
5296 0x06,0x87,0x04,0x7f,0x00,0x00,0x01 };
5298 static void test_encodeCTL(DWORD dwEncoding)
5300 static char oid1[] = "1.2.3";
5301 static char oid2[] = "1.5.6";
5302 char *pOid1 = oid1;
5303 BOOL ret;
5304 BYTE *buf = NULL;
5305 DWORD size = 0;
5306 CTL_INFO info;
5307 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5308 CTL_ENTRY ctlEntry[2];
5309 CRYPT_ATTRIBUTE attr1, attr2;
5310 CRYPT_ATTR_BLOB value1, value2;
5312 memset(&info, 0, sizeof(info));
5313 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5314 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5315 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5316 if (buf)
5318 ok(size == sizeof(emptyCTL), "unexpected size %d\n", size);
5319 ok(!memcmp(buf, emptyCTL, size), "unexpected value\n");
5320 LocalFree(buf);
5321 buf = NULL;
5323 info.dwVersion = 1;
5324 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5325 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5326 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5327 if (buf)
5329 ok(size == sizeof(emptyCTLWithVersion1), "unexpected size %d\n", size);
5330 ok(!memcmp(buf, emptyCTLWithVersion1, size), "unexpected value\n");
5331 LocalFree(buf);
5332 buf = NULL;
5334 info.dwVersion = 0;
5335 info.SubjectUsage.cUsageIdentifier = 1;
5336 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5337 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5338 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5339 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5340 if (buf)
5342 ok(size == sizeof(ctlWithUsageIdentifier), "unexpected size %d\n",
5343 size);
5344 ok(!memcmp(buf, ctlWithUsageIdentifier, size), "unexpected value\n");
5345 LocalFree(buf);
5346 buf = NULL;
5348 info.SubjectUsage.cUsageIdentifier = 0;
5349 info.ListIdentifier.cbData = sizeof(serialNum);
5350 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5351 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5352 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5353 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5354 if (buf)
5356 ok(size == sizeof(ctlWithListIdentifier), "unexpected size %d\n", size);
5357 ok(!memcmp(buf, ctlWithListIdentifier, size), "unexpected value\n");
5358 LocalFree(buf);
5359 buf = NULL;
5361 info.ListIdentifier.cbData = 0;
5362 info.SequenceNumber.cbData = sizeof(serialNum);
5363 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5364 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5365 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5366 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5367 if (buf)
5369 ok(size == sizeof(ctlWithSequenceNumber), "unexpected size %d\n",
5370 size);
5371 ok(!memcmp(buf, ctlWithSequenceNumber, size), "unexpected value\n");
5372 LocalFree(buf);
5373 buf = NULL;
5375 info.SequenceNumber.cbData = 0;
5376 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5377 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5378 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5379 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5380 if (buf)
5382 ok(size == sizeof(ctlWithThisUpdate), "unexpected size %d\n", size);
5383 ok(!memcmp(buf, ctlWithThisUpdate, size), "unexpected value\n");
5384 LocalFree(buf);
5385 buf = NULL;
5387 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5388 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5389 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5390 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5391 if (buf)
5393 ok(size == sizeof(ctlWithThisAndNextUpdate), "unexpected size %d\n",
5394 size);
5395 ok(!memcmp(buf, ctlWithThisAndNextUpdate, size), "unexpected value\n");
5396 LocalFree(buf);
5397 buf = NULL;
5399 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5400 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5401 info.SubjectAlgorithm.pszObjId = oid2;
5402 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5403 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5404 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5405 if (buf)
5407 ok(size == sizeof(ctlWithAlgId), "unexpected size %d\n", size);
5408 ok(!memcmp(buf, ctlWithAlgId, size), "unexpected value\n");
5409 LocalFree(buf);
5410 buf = NULL;
5412 /* The value is supposed to be asn.1 encoded, so this'll fail to decode
5413 * (see tests below) but it'll encode fine.
5415 info.SubjectAlgorithm.pszObjId = NULL;
5416 value1.cbData = sizeof(serialNum);
5417 value1.pbData = (LPBYTE)serialNum;
5418 attr1.pszObjId = oid1;
5419 attr1.cValue = 1;
5420 attr1.rgValue = &value1;
5421 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5422 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5423 ctlEntry[0].cAttribute = 1;
5424 ctlEntry[0].rgAttribute = &attr1;
5425 info.cCTLEntry = 1;
5426 info.rgCTLEntry = ctlEntry;
5427 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5428 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5429 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5430 if (buf)
5432 ok(size == sizeof(ctlWithBogusEntry), "unexpected size %d\n", size);
5433 ok(!memcmp(buf, ctlWithBogusEntry, size), "unexpected value\n");
5434 LocalFree(buf);
5435 buf = NULL;
5437 value1.cbData = sizeof(emptySequence);
5438 value1.pbData = (LPBYTE)emptySequence;
5439 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5440 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5441 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5442 if (buf)
5444 ok(size == sizeof(ctlWithOneEntry), "unexpected size %d\n", size);
5445 ok(!memcmp(buf, ctlWithOneEntry, size), "unexpected value\n");
5446 LocalFree(buf);
5447 buf = NULL;
5449 value2.cbData = sizeof(encodedIPAddr);
5450 value2.pbData = (LPBYTE)encodedIPAddr;
5451 attr2.pszObjId = oid2;
5452 attr2.cValue = 1;
5453 attr2.rgValue = &value2;
5454 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5455 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5456 ctlEntry[1].cAttribute = 1;
5457 ctlEntry[1].rgAttribute = &attr2;
5458 info.cCTLEntry = 2;
5459 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CTL, &info,
5460 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5461 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
5462 if (buf)
5464 ok(size == sizeof(ctlWithTwoEntries), "unexpected size %d\n", size);
5465 ok(!memcmp(buf, ctlWithTwoEntries, size), "unexpected value\n");
5466 LocalFree(buf);
5467 buf = NULL;
5471 static void compareCTLInfo(LPCSTR header, const CTL_INFO *expected,
5472 const CTL_INFO *got)
5474 DWORD i, j, k;
5476 ok(expected->dwVersion == got->dwVersion,
5477 "%s: expected version %d, got %d\n", header, expected->dwVersion,
5478 got->dwVersion);
5479 ok(expected->SubjectUsage.cUsageIdentifier ==
5480 got->SubjectUsage.cUsageIdentifier,
5481 "%s: expected %d usage identifiers, got %d\n", header,
5482 expected->SubjectUsage.cUsageIdentifier,
5483 got->SubjectUsage.cUsageIdentifier);
5484 for (i = 0; i < expected->SubjectUsage.cUsageIdentifier; i++)
5485 ok(!strcmp(expected->SubjectUsage.rgpszUsageIdentifier[i],
5486 got->SubjectUsage.rgpszUsageIdentifier[i]),
5487 "%s[%d]: expected %s, got %s\n", header, i,
5488 expected->SubjectUsage.rgpszUsageIdentifier[i],
5489 got->SubjectUsage.rgpszUsageIdentifier[i]);
5490 ok(expected->ListIdentifier.cbData == got->ListIdentifier.cbData,
5491 "%s: expected list identifier of %d bytes, got %d\n", header,
5492 expected->ListIdentifier.cbData, got->ListIdentifier.cbData);
5493 if (expected->ListIdentifier.cbData)
5494 ok(!memcmp(expected->ListIdentifier.pbData, got->ListIdentifier.pbData,
5495 expected->ListIdentifier.cbData),
5496 "%s: unexpected list identifier value\n", header);
5497 ok(expected->SequenceNumber.cbData == got->SequenceNumber.cbData,
5498 "%s: expected sequence number of %d bytes, got %d\n", header,
5499 expected->SequenceNumber.cbData, got->SequenceNumber.cbData);
5500 if (expected->SequenceNumber.cbData)
5501 ok(!memcmp(expected->SequenceNumber.pbData, got->SequenceNumber.pbData,
5502 expected->SequenceNumber.cbData),
5503 "%s: unexpected sequence number value\n", header);
5504 ok(!memcmp(&expected->ThisUpdate, &got->ThisUpdate, sizeof(FILETIME)),
5505 "%s: expected this update = (%d, %d), got (%d, %d)\n", header,
5506 expected->ThisUpdate.dwLowDateTime, expected->ThisUpdate.dwHighDateTime,
5507 got->ThisUpdate.dwLowDateTime, got->ThisUpdate.dwHighDateTime);
5508 ok(!memcmp(&expected->NextUpdate, &got->NextUpdate, sizeof(FILETIME)),
5509 "%s: expected next update = (%d, %d), got (%d, %d)\n", header,
5510 expected->NextUpdate.dwLowDateTime, expected->NextUpdate.dwHighDateTime,
5511 got->NextUpdate.dwLowDateTime, got->NextUpdate.dwHighDateTime);
5512 if (expected->SubjectAlgorithm.pszObjId &&
5513 *expected->SubjectAlgorithm.pszObjId && !got->SubjectAlgorithm.pszObjId)
5514 ok(0, "%s: expected subject algorithm %s, got NULL\n", header,
5515 expected->SubjectAlgorithm.pszObjId);
5516 if (expected->SubjectAlgorithm.pszObjId && got->SubjectAlgorithm.pszObjId)
5517 ok(!strcmp(expected->SubjectAlgorithm.pszObjId,
5518 got->SubjectAlgorithm.pszObjId),
5519 "%s: expected subject algorithm %s, got %s\n", header,
5520 expected->SubjectAlgorithm.pszObjId, got->SubjectAlgorithm.pszObjId);
5521 ok(expected->SubjectAlgorithm.Parameters.cbData ==
5522 got->SubjectAlgorithm.Parameters.cbData,
5523 "%s: expected subject algorithm parameters of %d bytes, got %d\n", header,
5524 expected->SubjectAlgorithm.Parameters.cbData,
5525 got->SubjectAlgorithm.Parameters.cbData);
5526 if (expected->SubjectAlgorithm.Parameters.cbData)
5527 ok(!memcmp(expected->SubjectAlgorithm.Parameters.pbData,
5528 got->SubjectAlgorithm.Parameters.pbData,
5529 expected->SubjectAlgorithm.Parameters.cbData),
5530 "%s: unexpected subject algorithm parameter value\n", header);
5531 ok(expected->cCTLEntry == got->cCTLEntry,
5532 "%s: expected %d CTL entries, got %d\n", header, expected->cCTLEntry,
5533 got->cCTLEntry);
5534 for (i = 0; i < expected->cCTLEntry; i++)
5536 ok(expected->rgCTLEntry[i].SubjectIdentifier.cbData ==
5537 got->rgCTLEntry[i].SubjectIdentifier.cbData,
5538 "%s[%d]: expected subject identifier of %d bytes, got %d\n",
5539 header, i, expected->rgCTLEntry[i].SubjectIdentifier.cbData,
5540 got->rgCTLEntry[i].SubjectIdentifier.cbData);
5541 if (expected->rgCTLEntry[i].SubjectIdentifier.cbData)
5542 ok(!memcmp(expected->rgCTLEntry[i].SubjectIdentifier.pbData,
5543 got->rgCTLEntry[i].SubjectIdentifier.pbData,
5544 expected->rgCTLEntry[i].SubjectIdentifier.cbData),
5545 "%s[%d]: unexpected subject identifier value\n",
5546 header, i);
5547 for (j = 0; j < expected->rgCTLEntry[i].cAttribute; j++)
5549 ok(!strcmp(expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5550 got->rgCTLEntry[i].rgAttribute[j].pszObjId),
5551 "%s[%d][%d]: expected attribute OID %s, got %s\n", header, i, j,
5552 expected->rgCTLEntry[i].rgAttribute[j].pszObjId,
5553 got->rgCTLEntry[i].rgAttribute[j].pszObjId);
5554 for (k = 0; k < expected->rgCTLEntry[i].rgAttribute[j].cValue; k++)
5556 ok(expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData ==
5557 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5558 "%s[%d][%d][%d]: expected value of %d bytes, got %d\n",
5559 header, i, j, k,
5560 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData,
5561 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData);
5562 if (expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData)
5563 ok(!memcmp(
5564 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5565 got->rgCTLEntry[i].rgAttribute[j].rgValue[k].pbData,
5566 expected->rgCTLEntry[i].rgAttribute[j].rgValue[k].cbData),
5567 "%s[%d][%d][%d]: unexpected value\n",
5568 header, i, j, k);
5572 ok(expected->cExtension == got->cExtension,
5573 "%s: expected %d extensions, got %d\n", header, expected->cExtension,
5574 got->cExtension);
5575 for (i = 0; i < expected->cExtension; i++)
5577 ok(!strcmp(expected->rgExtension[i].pszObjId,
5578 got->rgExtension[i].pszObjId), "%s[%d]: expected %s, got %s\n",
5579 header, i, expected->rgExtension[i].pszObjId,
5580 got->rgExtension[i].pszObjId);
5581 ok(expected->rgExtension[i].fCritical == got->rgExtension[i].fCritical,
5582 "%s[%d]: expected fCritical = %d, got %d\n", header, i,
5583 expected->rgExtension[i].fCritical, got->rgExtension[i].fCritical);
5584 ok(expected->rgExtension[i].Value.cbData ==
5585 got->rgExtension[i].Value.cbData,
5586 "%s[%d]: expected extension value to have %d bytes, got %d\n",
5587 header, i, expected->rgExtension[i].Value.cbData,
5588 got->rgExtension[i].Value.cbData);
5589 if (expected->rgExtension[i].Value.cbData)
5590 ok(!memcmp(expected->rgExtension[i].Value.pbData,
5591 got->rgExtension[i].Value.pbData,
5592 expected->rgExtension[i].Value.cbData),
5593 "%s[%d]: unexpected extension value\n", header, i);
5597 static const BYTE signedCTL[] = {
5598 0x30,0x81,0xc7,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,
5599 0x81,0xb9,0x30,0x81,0xb6,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,
5600 0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x28,0x06,0x09,0x2a,0x86,
5601 0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x1b,0x04,0x19,0x30,0x17,0x30,0x00,
5602 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5603 0x30,0x5a,0x30,0x02,0x06,0x00,0x31,0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,
5604 0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,
5605 0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,
5606 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
5607 0x00,0x04,0x40,0xca,0xd8,0x32,0xd1,0xbd,0x97,0x61,0x54,0xd6,0x80,0xcf,0x0d,
5608 0xbd,0xa2,0x42,0xc7,0xca,0x37,0x91,0x7d,0x9d,0xac,0x8c,0xdf,0x05,0x8a,0x39,
5609 0xc6,0x07,0xc1,0x37,0xe6,0xb9,0xd1,0x0d,0x26,0xec,0xa5,0xb0,0x8a,0x51,0x26,
5610 0x2b,0x4f,0x73,0x44,0x86,0x83,0x5e,0x2b,0x6e,0xcc,0xf8,0x1b,0x85,0x53,0xe9,
5611 0x7a,0x80,0x8f,0x6b,0x42,0x19,0x93 };
5612 static const BYTE signedCTLWithCTLInnerContent[] = {
5613 0x30,0x82,0x01,0x0f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,
5614 0xa0,0x82,0x01,0x00,0x30,0x81,0xfd,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,
5615 0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x30,0x06,0x09,
5616 0x2b,0x06,0x01,0x04,0x01,0x82,0x37,0x0a,0x01,0xa0,0x23,0x30,0x21,0x30,0x00,
5617 0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,
5618 0x30,0x5a,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,
5619 0x00,0x31,0x81,0xb5,0x30,0x81,0xb2,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,
5620 0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,
5621 0x4c,0x61,0x6e,0x67,0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,
5622 0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0xa0,0x3b,0x30,0x18,0x06,0x09,0x2a,0x86,
5623 0x48,0x86,0xf7,0x0d,0x01,0x09,0x03,0x31,0x0b,0x06,0x09,0x2b,0x06,0x01,0x04,
5624 0x01,0x82,0x37,0x0a,0x01,0x30,0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,
5625 0x01,0x09,0x04,0x31,0x12,0x04,0x10,0x54,0x71,0xbc,0xe1,0x56,0x31,0xa2,0xf9,
5626 0x65,0x70,0x34,0xf8,0xe2,0xe9,0xb4,0xf4,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
5627 0x40,0x2f,0x1b,0x9f,0x5a,0x4a,0x15,0x73,0xfa,0xb1,0x93,0x3d,0x09,0x52,0xdf,
5628 0x6b,0x98,0x4b,0x13,0x5e,0xe7,0xbf,0x65,0xf4,0x9c,0xc2,0xb1,0x77,0x09,0xb1,
5629 0x66,0x4d,0x72,0x0d,0xb1,0x1a,0x50,0x20,0xe0,0x57,0xa2,0x39,0xc7,0xcd,0x7f,
5630 0x8e,0xe7,0x5f,0x76,0x2b,0xd1,0x6a,0x82,0xb3,0x30,0x25,0x61,0xf6,0x25,0x23,
5631 0x57,0x6c,0x0b,0x47,0xb8 };
5633 static void test_decodeCTL(DWORD dwEncoding)
5635 static char oid1[] = "1.2.3";
5636 static char oid2[] = "1.5.6";
5637 static BYTE nullData[] = { 5,0 };
5638 char *pOid1 = oid1;
5639 BOOL ret;
5640 BYTE *buf = NULL;
5641 DWORD size = 0;
5642 CTL_INFO info;
5643 SYSTEMTIME thisUpdate = { 2005, 6, 1, 6, 16, 10, 0, 0 };
5644 CTL_ENTRY ctlEntry[2];
5645 CRYPT_ATTRIBUTE attr1, attr2;
5646 CRYPT_ATTR_BLOB value1, value2;
5648 memset(&info, 0, sizeof(info));
5649 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTL, sizeof(emptyCTL),
5650 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5651 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5652 if (buf)
5654 compareCTLInfo("empty CTL", &info, (CTL_INFO *)buf);
5655 LocalFree(buf);
5656 buf = NULL;
5658 info.dwVersion = 1;
5659 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, emptyCTLWithVersion1,
5660 sizeof(emptyCTLWithVersion1), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
5661 &size);
5662 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5663 if (buf)
5665 compareCTLInfo("v1 CTL", &info, (CTL_INFO *)buf);
5666 LocalFree(buf);
5667 buf = NULL;
5669 info.dwVersion = 0;
5670 info.SubjectUsage.cUsageIdentifier = 1;
5671 info.SubjectUsage.rgpszUsageIdentifier = &pOid1;
5672 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithUsageIdentifier,
5673 sizeof(ctlWithUsageIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL,
5674 &buf, &size);
5675 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5676 if (buf)
5678 compareCTLInfo("CTL with usage identifier", &info, (CTL_INFO *)buf);
5679 LocalFree(buf);
5680 buf = NULL;
5682 info.SubjectUsage.cUsageIdentifier = 0;
5683 info.ListIdentifier.cbData = sizeof(serialNum);
5684 info.ListIdentifier.pbData = (LPBYTE)serialNum;
5685 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithListIdentifier,
5686 sizeof(ctlWithListIdentifier), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5687 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5688 if (buf)
5690 compareCTLInfo("CTL with list identifier", &info, (CTL_INFO *)buf);
5691 LocalFree(buf);
5692 buf = NULL;
5694 info.ListIdentifier.cbData = 0;
5695 info.SequenceNumber.cbData = sizeof(serialNum);
5696 info.SequenceNumber.pbData = (LPBYTE)serialNum;
5697 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithSequenceNumber,
5698 sizeof(ctlWithSequenceNumber), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5699 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5700 if (buf)
5702 compareCTLInfo("CTL with sequence number", &info, (CTL_INFO *)buf);
5703 LocalFree(buf);
5704 buf = NULL;
5706 info.SequenceNumber.cbData = 0;
5707 SystemTimeToFileTime(&thisUpdate, &info.ThisUpdate);
5708 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisUpdate,
5709 sizeof(ctlWithThisUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5710 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5711 if (buf)
5713 compareCTLInfo("CTL with this update", &info, (CTL_INFO *)buf);
5714 LocalFree(buf);
5715 buf = NULL;
5717 SystemTimeToFileTime(&thisUpdate, &info.NextUpdate);
5718 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithThisAndNextUpdate,
5719 sizeof(ctlWithThisAndNextUpdate), CRYPT_DECODE_ALLOC_FLAG, NULL,
5720 &buf, &size);
5721 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5722 if (buf)
5724 compareCTLInfo("CTL with this and next update", &info, (CTL_INFO *)buf);
5725 LocalFree(buf);
5726 buf = NULL;
5728 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5729 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5730 info.SubjectAlgorithm.pszObjId = oid2;
5731 info.SubjectAlgorithm.Parameters.cbData = sizeof(nullData);
5732 info.SubjectAlgorithm.Parameters.pbData = nullData;
5733 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithAlgId,
5734 sizeof(ctlWithAlgId), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5735 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5736 if (buf)
5738 compareCTLInfo("CTL with algorithm identifier", &info, (CTL_INFO *)buf);
5739 LocalFree(buf);
5740 buf = NULL;
5742 SetLastError(0xdeadbeef);
5743 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithBogusEntry,
5744 sizeof(ctlWithBogusEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5745 ok(!ret &&
5746 (GetLastError() == CRYPT_E_ASN1_EOD ||
5747 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
5748 GetLastError() == OSS_MORE_INPUT), /* Win9x */
5749 "expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %08x\n",
5750 GetLastError());
5751 info.SubjectAlgorithm.Parameters.cbData = 0;
5752 info.ThisUpdate.dwLowDateTime = info.ThisUpdate.dwHighDateTime = 0;
5753 info.NextUpdate.dwLowDateTime = info.NextUpdate.dwHighDateTime = 0;
5754 info.SubjectAlgorithm.pszObjId = oid2;
5755 info.SubjectAlgorithm.pszObjId = NULL;
5756 value1.cbData = sizeof(emptySequence);
5757 value1.pbData = (LPBYTE)emptySequence;
5758 attr1.pszObjId = oid1;
5759 attr1.cValue = 1;
5760 attr1.rgValue = &value1;
5761 ctlEntry[0].SubjectIdentifier.cbData = sizeof(serialNum);
5762 ctlEntry[0].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5763 ctlEntry[0].cAttribute = 1;
5764 ctlEntry[0].rgAttribute = &attr1;
5765 info.cCTLEntry = 1;
5766 info.rgCTLEntry = ctlEntry;
5767 SetLastError(0xdeadbeef);
5768 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithOneEntry,
5769 sizeof(ctlWithOneEntry), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5770 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5771 if (buf)
5773 compareCTLInfo("CTL with one entry", &info, (CTL_INFO *)buf);
5774 LocalFree(buf);
5775 buf = NULL;
5777 value2.cbData = sizeof(encodedIPAddr);
5778 value2.pbData = (LPBYTE)encodedIPAddr;
5779 attr2.pszObjId = oid2;
5780 attr2.cValue = 1;
5781 attr2.rgValue = &value2;
5782 ctlEntry[1].SubjectIdentifier.cbData = sizeof(serialNum);
5783 ctlEntry[1].SubjectIdentifier.pbData = (LPBYTE)serialNum;
5784 ctlEntry[1].cAttribute = 1;
5785 ctlEntry[1].rgAttribute = &attr2;
5786 info.cCTLEntry = 2;
5787 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, ctlWithTwoEntries,
5788 sizeof(ctlWithTwoEntries), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5789 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
5790 if (buf)
5792 compareCTLInfo("CTL with two entries", &info, (CTL_INFO *)buf);
5793 LocalFree(buf);
5794 buf = NULL;
5796 /* A signed CTL isn't decodable, even if the inner content is a CTL */
5797 SetLastError(0xdeadbeef);
5798 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL, signedCTL,
5799 sizeof(signedCTL), CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5800 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5801 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5802 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5803 GetLastError());
5804 SetLastError(0xdeadbeef);
5805 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CTL,
5806 signedCTLWithCTLInnerContent, sizeof(signedCTLWithCTLInnerContent),
5807 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5808 ok(!ret && (GetLastError() == CRYPT_E_ASN1_BADTAG ||
5809 GetLastError() == OSS_DATA_ERROR /* Win9x */),
5810 "expected CRYPT_E_ASN1_BADTAG or OSS_DATA_ERROR, got %08x\n",
5811 GetLastError());
5814 static const BYTE emptyPKCSContentInfo[] = { 0x30,0x04,0x06,0x02,0x2a,0x03 };
5815 static const BYTE emptyPKCSContentInfoExtraBytes[] = { 0x30,0x04,0x06,0x02,0x2a,
5816 0x03,0,0,0,0,0,0 };
5817 static const BYTE bogusPKCSContentInfo[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,
5818 0xa0,0x01,0x01 };
5819 static const BYTE intPKCSContentInfo[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0xa0,
5820 0x03,0x02,0x01,0x01 };
5821 static BYTE bogusDER[] = { 1 };
5823 static void test_encodePKCSContentInfo(DWORD dwEncoding)
5825 BOOL ret;
5826 BYTE *buf = NULL;
5827 DWORD size = 0;
5828 CRYPT_CONTENT_INFO info = { 0 };
5829 char oid1[] = "1.2.3";
5831 if (0)
5833 /* Crashes on win9x */
5834 SetLastError(0xdeadbeef);
5835 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, NULL,
5836 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5837 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
5838 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
5840 SetLastError(0xdeadbeef);
5841 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5842 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5843 ok(!ret && (GetLastError() == E_INVALIDARG ||
5844 GetLastError() == OSS_LIMITED /* Win9x */),
5845 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
5846 info.pszObjId = oid1;
5847 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5848 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5849 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
5850 if (buf)
5852 ok(size == sizeof(emptyPKCSContentInfo), "Unexpected size %d\n", size);
5853 ok(!memcmp(buf, emptyPKCSContentInfo, size), "Unexpected value\n");
5854 LocalFree(buf);
5856 info.Content.pbData = bogusDER;
5857 info.Content.cbData = sizeof(bogusDER);
5858 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5859 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5860 ok(ret, "CryptEncodeObjectEx failed; %x\n", GetLastError());
5861 if (buf)
5863 ok(size == sizeof(bogusPKCSContentInfo), "Unexpected size %d\n", size);
5864 ok(!memcmp(buf, bogusPKCSContentInfo, size), "Unexpected value\n");
5865 LocalFree(buf);
5867 info.Content.pbData = (BYTE *)ints[0].encoded;
5868 info.Content.cbData = ints[0].encoded[1] + 2;
5869 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, &info,
5870 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5871 if (buf)
5873 ok(size == sizeof(intPKCSContentInfo), "Unexpected size %d\n", size);
5874 ok(!memcmp(buf, intPKCSContentInfo, size), "Unexpected value\n");
5875 LocalFree(buf);
5879 static const BYTE indefiniteSignedPKCSContent[] = {
5880 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x02,0xa0,0x80,
5881 0x30,0x80,0x02,0x01,0x01,0x31,0x0e,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,
5882 0xf7,0x0d,0x02,0x05,0x05,0x00,0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,
5883 0x0d,0x01,0x07,0x01,0xa0,0x80,0x24,0x80,0x04,0x04,0x01,0x02,0x03,0x04,0x04,
5884 0x04,0x01,0x02,0x03,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0x81,0xd2,0x30,
5885 0x81,0xcf,0x02,0x01,0x01,0x30,0x02,0x06,0x00,0x30,0x15,0x31,0x13,0x30,0x11,
5886 0x06,0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
5887 0x67,0x00,0x30,0x22,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,0x31,0x30,
5888 0x30,0x30,0x30,0x30,0x30,0x5a,0x18,0x0f,0x31,0x36,0x30,0x31,0x30,0x31,0x30,
5889 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5890 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5891 0x00,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,
5892 0x01,0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0xe2,0x54,0x3a,0xa7,
5893 0x83,0xb1,0x27,0x14,0x3e,0x59,0xbb,0xb4,0x53,0xe6,0x1f,0xe7,0x5d,0xf1,0x21,
5894 0x68,0xad,0x85,0x53,0xdb,0x6b,0x1e,0xeb,0x65,0x97,0x03,0x86,0x60,0xde,0xf3,
5895 0x6c,0x38,0x75,0xe0,0x4c,0x61,0xbb,0xbc,0x62,0x17,0xa9,0xcd,0x79,0x3f,0x21,
5896 0x4e,0x96,0xcb,0x0e,0xdc,0x61,0x94,0x30,0x18,0x10,0x6b,0xd0,0x1c,0x10,0x79,
5897 0x02,0x03,0x01,0x00,0x01,0xa3,0x16,0x30,0x14,0x30,0x12,0x06,0x03,0x55,0x1d,
5898 0x13,0x01,0x01,0xff,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x01,0x31,
5899 0x77,0x30,0x75,0x02,0x01,0x01,0x30,0x1a,0x30,0x15,0x31,0x13,0x30,0x11,0x06,
5900 0x03,0x55,0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,
5901 0x00,0x02,0x01,0x01,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,
5902 0x05,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x40,0x57,0xba,0xe0,0xad,
5903 0xfe,0x36,0x8d,0xb3,0x88,0xa2,0x8d,0x84,0x82,0x52,0x09,0x09,0xd9,0xf0,0xb8,
5904 0x04,0xfa,0xb5,0x51,0x0b,0x2b,0x2e,0xd5,0x72,0x3e,0x3d,0x13,0x8a,0x51,0xc3,
5905 0x71,0x65,0x9a,0x52,0xf2,0x8f,0xb2,0x5b,0x39,0x28,0xb3,0x29,0x36,0xa5,0x8d,
5906 0xe3,0x55,0x71,0x91,0xf9,0x2a,0xd1,0xb8,0xaa,0x52,0xb8,0x22,0x3a,0xeb,0x61,
5907 0x00,0x00,0x00,0x00,0x00,0x00 };
5909 static void test_decodePKCSContentInfo(DWORD dwEncoding)
5911 BOOL ret;
5912 LPBYTE buf = NULL;
5913 DWORD size = 0;
5914 CRYPT_CONTENT_INFO *info;
5916 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5917 emptyPKCSContentInfo, sizeof(emptyPKCSContentInfo),
5918 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5919 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5920 if (buf)
5922 info = (CRYPT_CONTENT_INFO *)buf;
5924 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5925 info->pszObjId);
5926 ok(info->Content.cbData == 0, "Expected no data, got %d\n",
5927 info->Content.cbData);
5928 LocalFree(buf);
5930 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5931 emptyPKCSContentInfoExtraBytes, sizeof(emptyPKCSContentInfoExtraBytes),
5932 0, NULL, NULL, &size);
5933 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5934 SetLastError(0xdeadbeef);
5935 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5936 bogusPKCSContentInfo, sizeof(bogusPKCSContentInfo),
5937 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5938 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
5939 * I doubt an app depends on that.
5941 ok((!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
5942 GetLastError() == CRYPT_E_ASN1_CORRUPT)) || broken(ret),
5943 "Expected CRYPT_E_ASN1_EOD or CRYPT_E_ASN1_CORRUPT, got %x\n",
5944 GetLastError());
5945 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5946 intPKCSContentInfo, sizeof(intPKCSContentInfo),
5947 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5948 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5949 if (buf)
5951 info = (CRYPT_CONTENT_INFO *)buf;
5953 ok(!strcmp(info->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
5954 info->pszObjId);
5955 ok(info->Content.cbData == ints[0].encoded[1] + 2,
5956 "Unexpected size %d\n", info->Content.cbData);
5957 ok(!memcmp(info->Content.pbData, ints[0].encoded,
5958 info->Content.cbData), "Unexpected value\n");
5959 LocalFree(buf);
5961 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO,
5962 indefiniteSignedPKCSContent, sizeof(indefiniteSignedPKCSContent),
5963 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
5964 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
5965 if (buf)
5967 info = (CRYPT_CONTENT_INFO *)buf;
5969 ok(!strcmp(info->pszObjId, szOID_RSA_signedData),
5970 "Expected %s, got %s\n", szOID_RSA_signedData, info->pszObjId);
5971 ok(info->Content.cbData == 392, "Expected 392, got %d\n",
5972 info->Content.cbData);
5973 LocalFree(buf);
5977 static const BYTE emptyPKCSAttr[] = { 0x30,0x06,0x06,0x02,0x2a,0x03,0x31,
5978 0x00 };
5979 static const BYTE bogusPKCSAttr[] = { 0x30,0x07,0x06,0x02,0x2a,0x03,0x31,0x01,
5980 0x01 };
5981 static const BYTE intPKCSAttr[] = { 0x30,0x09,0x06,0x02,0x2a,0x03,0x31,0x03,
5982 0x02,0x01,0x01 };
5984 static void test_encodePKCSAttribute(DWORD dwEncoding)
5986 CRYPT_ATTRIBUTE attr = { 0 };
5987 BOOL ret;
5988 LPBYTE buf = NULL;
5989 DWORD size = 0;
5990 CRYPT_ATTR_BLOB blob;
5991 char oid[] = "1.2.3";
5993 if (0)
5995 /* Crashes on win9x */
5996 SetLastError(0xdeadbeef);
5997 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, NULL,
5998 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
5999 ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
6000 "Expected STATUS_ACCESS_VIOLATION, got %x\n", GetLastError());
6002 SetLastError(0xdeadbeef);
6003 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6004 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6005 ok(!ret && (GetLastError() == E_INVALIDARG ||
6006 GetLastError() == OSS_LIMITED /* Win9x */),
6007 "Expected E_INVALIDARG or OSS_LIMITED, got %x\n", GetLastError());
6008 attr.pszObjId = oid;
6009 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6010 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6011 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6012 if (buf)
6014 ok(size == sizeof(emptyPKCSAttr), "Unexpected size %d\n", size);
6015 ok(!memcmp(buf, emptyPKCSAttr, size), "Unexpected value\n");
6016 LocalFree(buf);
6018 blob.cbData = sizeof(bogusDER);
6019 blob.pbData = bogusDER;
6020 attr.cValue = 1;
6021 attr.rgValue = &blob;
6022 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6023 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6024 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6025 if (buf)
6027 ok(size == sizeof(bogusPKCSAttr), "Unexpected size %d\n", size);
6028 ok(!memcmp(buf, bogusPKCSAttr, size), "Unexpected value\n");
6029 LocalFree(buf);
6031 blob.pbData = (BYTE *)ints[0].encoded;
6032 blob.cbData = ints[0].encoded[1] + 2;
6033 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTE, &attr,
6034 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6035 if (buf)
6037 ok(size == sizeof(intPKCSAttr), "Unexpected size %d\n", size);
6038 ok(!memcmp(buf, intPKCSAttr, size), "Unexpected value\n");
6039 LocalFree(buf);
6043 static void test_decodePKCSAttribute(DWORD dwEncoding)
6045 BOOL ret;
6046 LPBYTE buf = NULL;
6047 DWORD size = 0;
6048 CRYPT_ATTRIBUTE *attr;
6050 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6051 emptyPKCSAttr, sizeof(emptyPKCSAttr),
6052 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6053 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6054 if (buf)
6056 attr = (CRYPT_ATTRIBUTE *)buf;
6058 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6059 attr->pszObjId);
6060 ok(attr->cValue == 0, "Expected no value, got %d\n", attr->cValue);
6061 LocalFree(buf);
6063 SetLastError(0xdeadbeef);
6064 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6065 bogusPKCSAttr, sizeof(bogusPKCSAttr),
6066 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6067 /* Native fails with CRYPT_E_ASN1_EOD, accept also CRYPT_E_ASN1_CORRUPT as
6068 * I doubt an app depends on that.
6070 ok(!ret && (GetLastError() == CRYPT_E_ASN1_EOD ||
6071 GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6072 GetLastError() == OSS_MORE_INPUT /* Win9x */),
6073 "Expected CRYPT_E_ASN1_EOD, CRYPT_E_ASN1_CORRUPT, or OSS_MORE_INPUT, got %x\n",
6074 GetLastError());
6075 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTE,
6076 intPKCSAttr, sizeof(intPKCSAttr),
6077 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6078 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6079 if (buf)
6081 attr = (CRYPT_ATTRIBUTE *)buf;
6083 ok(!strcmp(attr->pszObjId, "1.2.3"), "Expected 1.2.3, got %s\n",
6084 attr->pszObjId);
6085 ok(attr->cValue == 1, "Expected 1 value, got %d\n", attr->cValue);
6086 ok(attr->rgValue[0].cbData == ints[0].encoded[1] + 2,
6087 "Unexpected size %d\n", attr->rgValue[0].cbData);
6088 ok(!memcmp(attr->rgValue[0].pbData, ints[0].encoded,
6089 attr->rgValue[0].cbData), "Unexpected value\n");
6090 LocalFree(buf);
6094 static const BYTE emptyPKCSAttributes[] = { 0x31,0x00 };
6095 static const BYTE singlePKCSAttributes[] = { 0x31,0x08,0x30,0x06,0x06,0x02,
6096 0x2a,0x03,0x31,0x00 };
6097 static const BYTE doublePKCSAttributes[] = { 0x31,0x13,0x30,0x06,0x06,0x02,
6098 0x2a,0x03,0x31,0x00,0x30,0x09,0x06,0x02,0x2d,0x06,0x31,0x03,0x02,0x01,0x01 };
6100 static void test_encodePKCSAttributes(DWORD dwEncoding)
6102 CRYPT_ATTRIBUTES attributes = { 0 };
6103 CRYPT_ATTRIBUTE attr[2] = { { 0 } };
6104 CRYPT_ATTR_BLOB blob;
6105 BOOL ret;
6106 LPBYTE buf = NULL;
6107 DWORD size = 0;
6108 char oid1[] = "1.2.3", oid2[] = "1.5.6";
6110 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6111 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6112 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6113 if (buf)
6115 ok(size == sizeof(emptyPKCSAttributes), "Unexpected size %d\n", size);
6116 ok(!memcmp(buf, emptyPKCSAttributes, size), "Unexpected value\n");
6117 LocalFree(buf);
6119 attributes.cAttr = 1;
6120 attributes.rgAttr = attr;
6121 SetLastError(0xdeadbeef);
6122 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6123 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6124 ok(!ret && (GetLastError() == E_INVALIDARG ||
6125 GetLastError() == OSS_LIMITED /* Win9x */),
6126 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6127 attr[0].pszObjId = oid1;
6128 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6129 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6130 if (buf)
6132 ok(size == sizeof(singlePKCSAttributes), "Unexpected size %d\n", size);
6133 ok(!memcmp(buf, singlePKCSAttributes, size), "Unexpected value\n");
6134 LocalFree(buf);
6136 attr[1].pszObjId = oid2;
6137 attr[1].cValue = 1;
6138 attr[1].rgValue = &blob;
6139 blob.pbData = (BYTE *)ints[0].encoded;
6140 blob.cbData = ints[0].encoded[1] + 2;
6141 attributes.cAttr = 2;
6142 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_ATTRIBUTES, &attributes,
6143 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6144 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6145 if (buf)
6147 ok(size == sizeof(doublePKCSAttributes), "Unexpected size %d\n", size);
6148 ok(!memcmp(buf, doublePKCSAttributes, size), "Unexpected value\n");
6149 LocalFree(buf);
6153 static void test_decodePKCSAttributes(DWORD dwEncoding)
6155 BOOL ret;
6156 LPBYTE buf = NULL;
6157 DWORD size = 0;
6158 CRYPT_ATTRIBUTES *attributes;
6160 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6161 emptyPKCSAttributes, sizeof(emptyPKCSAttributes),
6162 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6163 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6164 if (buf)
6166 attributes = (CRYPT_ATTRIBUTES *)buf;
6167 ok(attributes->cAttr == 0, "Expected no attributes, got %d\n",
6168 attributes->cAttr);
6169 LocalFree(buf);
6171 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6172 singlePKCSAttributes, sizeof(singlePKCSAttributes),
6173 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6174 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6175 if (buf)
6177 attributes = (CRYPT_ATTRIBUTES *)buf;
6178 ok(attributes->cAttr == 1, "Expected 1 attribute, got %d\n",
6179 attributes->cAttr);
6180 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6181 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6182 ok(attributes->rgAttr[0].cValue == 0,
6183 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6184 LocalFree(buf);
6186 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_ATTRIBUTES,
6187 doublePKCSAttributes, sizeof(doublePKCSAttributes),
6188 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6189 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6190 if (buf)
6192 attributes = (CRYPT_ATTRIBUTES *)buf;
6193 ok(attributes->cAttr == 2, "Expected 2 attributes, got %d\n",
6194 attributes->cAttr);
6195 ok(!strcmp(attributes->rgAttr[0].pszObjId, "1.2.3"),
6196 "Expected 1.2.3, got %s\n", attributes->rgAttr[0].pszObjId);
6197 ok(attributes->rgAttr[0].cValue == 0,
6198 "Expected no attributes, got %d\n", attributes->rgAttr[0].cValue);
6199 ok(!strcmp(attributes->rgAttr[1].pszObjId, "1.5.6"),
6200 "Expected 1.5.6, got %s\n", attributes->rgAttr[1].pszObjId);
6201 ok(attributes->rgAttr[1].cValue == 1,
6202 "Expected 1 attribute, got %d\n", attributes->rgAttr[1].cValue);
6203 ok(attributes->rgAttr[1].rgValue[0].cbData == ints[0].encoded[1] + 2,
6204 "Unexpected size %d\n", attributes->rgAttr[1].rgValue[0].cbData);
6205 ok(!memcmp(attributes->rgAttr[1].rgValue[0].pbData, ints[0].encoded,
6206 attributes->rgAttr[1].rgValue[0].cbData), "Unexpected value\n");
6207 LocalFree(buf);
6211 static const BYTE singleCapability[] = {
6212 0x30,0x06,0x30,0x04,0x06,0x02,0x2d,0x06 };
6213 static const BYTE twoCapabilities[] = {
6214 0x30,0x0c,0x30,0x04,0x06,0x02,0x2d,0x06,0x30,0x04,0x06,0x02,0x2a,0x03 };
6215 static const BYTE singleCapabilitywithNULL[] = {
6216 0x30,0x08,0x30,0x06,0x06,0x02,0x2d,0x06,0x05,0x00 };
6218 static void test_encodePKCSSMimeCapabilities(DWORD dwEncoding)
6220 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6221 BOOL ret;
6222 LPBYTE buf = NULL;
6223 DWORD size = 0;
6224 CRYPT_SMIME_CAPABILITY capability[2];
6225 CRYPT_SMIME_CAPABILITIES capabilities;
6227 /* An empty capabilities is allowed */
6228 capabilities.cCapability = 0;
6229 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6230 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6231 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6232 if (buf)
6234 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
6235 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
6236 LocalFree(buf);
6238 /* A non-empty capabilities with an empty capability (lacking an OID) is
6239 * not allowed
6241 capability[0].pszObjId = NULL;
6242 capability[0].Parameters.cbData = 0;
6243 capabilities.cCapability = 1;
6244 capabilities.rgCapability = capability;
6245 SetLastError(0xdeadbeef);
6246 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6247 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6248 ok(!ret && (GetLastError() == E_INVALIDARG ||
6249 GetLastError() == OSS_LIMITED /* Win9x */),
6250 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6251 capability[0].pszObjId = oid1;
6252 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6253 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6254 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6255 if (buf)
6257 ok(size == sizeof(singleCapability), "unexpected size %d\n", size);
6258 ok(!memcmp(buf, singleCapability, size), "unexpected value\n");
6259 LocalFree(buf);
6261 capability[1].pszObjId = oid2;
6262 capability[1].Parameters.cbData = 0;
6263 capabilities.cCapability = 2;
6264 ret = pCryptEncodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6265 &capabilities, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6266 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
6267 if (buf)
6269 ok(size == sizeof(twoCapabilities), "unexpected size %d\n", size);
6270 ok(!memcmp(buf, twoCapabilities, size), "unexpected value\n");
6271 LocalFree(buf);
6275 static void compareSMimeCapabilities(LPCSTR header,
6276 const CRYPT_SMIME_CAPABILITIES *expected, const CRYPT_SMIME_CAPABILITIES *got)
6278 DWORD i;
6280 ok(got->cCapability == expected->cCapability,
6281 "%s: expected %d capabilities, got %d\n", header, expected->cCapability,
6282 got->cCapability);
6283 for (i = 0; i < expected->cCapability; i++)
6285 ok(!strcmp(expected->rgCapability[i].pszObjId,
6286 got->rgCapability[i].pszObjId), "%s[%d]: expected %s, got %s\n",
6287 header, i, expected->rgCapability[i].pszObjId,
6288 got->rgCapability[i].pszObjId);
6289 ok(expected->rgCapability[i].Parameters.cbData ==
6290 got->rgCapability[i].Parameters.cbData,
6291 "%s[%d]: expected %d bytes, got %d\n", header, i,
6292 expected->rgCapability[i].Parameters.cbData,
6293 got->rgCapability[i].Parameters.cbData);
6294 if (expected->rgCapability[i].Parameters.cbData)
6295 ok(!memcmp(expected->rgCapability[i].Parameters.pbData,
6296 got->rgCapability[i].Parameters.pbData,
6297 expected->rgCapability[i].Parameters.cbData),
6298 "%s[%d]: unexpected value\n", header, i);
6302 static void test_decodePKCSSMimeCapabilities(DWORD dwEncoding)
6304 static char oid1[] = "1.5.6", oid2[] = "1.2.3";
6305 BOOL ret;
6306 DWORD size = 0;
6307 CRYPT_SMIME_CAPABILITY capability[2];
6308 CRYPT_SMIME_CAPABILITIES capabilities, *ptr;
6310 SetLastError(0xdeadbeef);
6311 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6312 emptySequence, sizeof(emptySequence),
6313 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6314 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6315 if (ret)
6317 capabilities.cCapability = 0;
6318 compareSMimeCapabilities("empty capabilities", &capabilities, ptr);
6319 LocalFree(ptr);
6321 SetLastError(0xdeadbeef);
6322 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6323 singleCapability, sizeof(singleCapability), CRYPT_DECODE_ALLOC_FLAG, NULL,
6324 &ptr, &size);
6325 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6326 if (ret)
6328 capability[0].pszObjId = oid1;
6329 capability[0].Parameters.cbData = 0;
6330 capabilities.cCapability = 1;
6331 capabilities.rgCapability = capability;
6332 compareSMimeCapabilities("single capability", &capabilities, ptr);
6333 LocalFree(ptr);
6335 SetLastError(0xdeadbeef);
6336 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6337 singleCapabilitywithNULL, sizeof(singleCapabilitywithNULL),
6338 CRYPT_DECODE_ALLOC_FLAG, NULL, &ptr, &size);
6339 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6340 if (ret)
6342 BYTE NULLparam[] = {0x05, 0x00};
6343 capability[0].pszObjId = oid1;
6344 capability[0].Parameters.cbData = 2;
6345 capability[0].Parameters.pbData = NULLparam;
6346 capabilities.cCapability = 1;
6347 capabilities.rgCapability = capability;
6348 compareSMimeCapabilities("single capability with NULL", &capabilities,
6349 ptr);
6350 LocalFree(ptr);
6352 SetLastError(0xdeadbeef);
6353 ret = pCryptDecodeObjectEx(dwEncoding, PKCS_SMIME_CAPABILITIES,
6354 twoCapabilities, sizeof(twoCapabilities), CRYPT_DECODE_ALLOC_FLAG, NULL,
6355 &ptr, &size);
6356 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
6357 if (ret)
6359 capability[0].Parameters.cbData = 0;
6360 capability[1].pszObjId = oid2;
6361 capability[1].Parameters.cbData = 0;
6362 capabilities.cCapability = 2;
6363 compareSMimeCapabilities("two capabilities", &capabilities, ptr);
6364 LocalFree(ptr);
6368 static BYTE encodedCommonNameNoNull[] = { 0x30,0x14,0x31,0x12,0x30,0x10,
6369 0x06,0x03,0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,
6370 0x67 };
6371 static const BYTE minimalPKCSSigner[] = {
6372 0x30,0x2b,0x02,0x01,0x00,0x30,0x18,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6373 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6374 0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6375 static const BYTE PKCSSignerWithSerial[] = {
6376 0x30,0x2c,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6377 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6378 0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,0x04,0x06,0x00,0x05,0x00,0x04,
6379 0x00 };
6380 static const BYTE PKCSSignerWithHashAlgo[] = {
6381 0x30,0x2e,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6382 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6383 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x04,0x06,0x00,0x05,
6384 0x00,0x04,0x00 };
6385 static const BYTE PKCSSignerWithHashAndEncryptionAlgo[] = {
6386 0x30,0x30,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6387 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6388 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6389 0x06,0x05,0x00,0x04,0x00 };
6390 static const BYTE PKCSSignerWithHash[] = {
6391 0x30,0x40,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6392 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6393 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0x30,0x06,0x06,0x02,0x2d,
6394 0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
6395 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6396 static const BYTE PKCSSignerWithAuthAttr[] = {
6397 0x30,0x62,0x02,0x01,0x00,0x30,0x19,0x30,0x14,0x31,0x12,0x30,0x10,0x06,0x03,
6398 0x55,0x04,0x03,0x13,0x09,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x02,
6399 0x01,0x01,0x30,0x06,0x06,0x02,0x2a,0x03,0x05,0x00,0xa0,0x20,0x30,0x1e,0x06,
6400 0x03,0x55,0x04,0x03,0x31,0x17,0x30,0x15,0x31,0x13,0x30,0x11,0x06,0x03,0x55,
6401 0x04,0x03,0x13,0x0a,0x4a,0x75,0x61,0x6e,0x20,0x4c,0x61,0x6e,0x67,0x00,0x30,
6402 0x06,0x06,0x02,0x2d,0x06,0x05,0x00,0x04,0x10,0x00,0x01,0x02,0x03,0x04,0x05,
6403 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
6405 static void test_encodePKCSSignerInfo(DWORD dwEncoding)
6407 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6408 BOOL ret;
6409 LPBYTE buf = NULL;
6410 DWORD size = 0;
6411 CMSG_SIGNER_INFO info = { 0 };
6412 char oid_common_name[] = szOID_COMMON_NAME;
6413 CRYPT_ATTR_BLOB commonName = { sizeof(encodedCommonName),
6414 (LPBYTE)encodedCommonName };
6415 CRYPT_ATTRIBUTE attr = { oid_common_name, 1, &commonName };
6417 SetLastError(0xdeadbeef);
6418 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6419 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6420 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6422 skip("no PKCS7_SIGNER_INFO encode support\n");
6423 return;
6425 ok(!ret && (GetLastError() == E_INVALIDARG ||
6426 GetLastError() == OSS_LIMITED /* Win9x */),
6427 "Expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
6428 /* To be encoded, a signer must have an issuer at least, and the encoding
6429 * must include PKCS_7_ASN_ENCODING. (That isn't enough to be decoded,
6430 * see decoding tests.)
6432 info.Issuer.cbData = sizeof(encodedCommonNameNoNull);
6433 info.Issuer.pbData = encodedCommonNameNoNull;
6434 SetLastError(0xdeadbeef);
6435 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6436 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6437 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6438 ok(!ret && GetLastError() == E_INVALIDARG,
6439 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6440 else
6442 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6443 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6444 if (buf)
6446 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6447 if (size == sizeof(minimalPKCSSigner))
6448 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6449 else
6450 ok(0, "Unexpected value\n");
6451 LocalFree(buf);
6454 info.SerialNumber.cbData = sizeof(serialNum);
6455 info.SerialNumber.pbData = (BYTE *)serialNum;
6456 SetLastError(0xdeadbeef);
6457 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6458 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6459 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6460 ok(!ret && GetLastError() == E_INVALIDARG,
6461 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6462 else
6464 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6465 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6466 if (buf)
6468 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6469 size);
6470 if (size == sizeof(PKCSSignerWithSerial))
6471 ok(!memcmp(buf, PKCSSignerWithSerial, size),
6472 "Unexpected value\n");
6473 else
6474 ok(0, "Unexpected value\n");
6475 LocalFree(buf);
6478 info.HashAlgorithm.pszObjId = oid1;
6479 SetLastError(0xdeadbeef);
6480 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6481 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6482 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6483 ok(!ret && GetLastError() == E_INVALIDARG,
6484 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6485 else
6487 ok(ret || broken(GetLastError() == OSS_LIMITED /* Win9x */),
6488 "CryptEncodeObjectEx failed: %x\n", GetLastError());
6489 if (buf)
6491 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6492 size);
6493 if (size == sizeof(PKCSSignerWithHashAlgo))
6494 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6495 "Unexpected value\n");
6496 else
6497 ok(0, "Unexpected value\n");
6498 LocalFree(buf);
6501 info.HashEncryptionAlgorithm.pszObjId = oid2;
6502 SetLastError(0xdeadbeef);
6503 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6504 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6505 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6506 ok(!ret && GetLastError() == E_INVALIDARG,
6507 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6508 else
6510 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6511 if (buf)
6513 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6514 "Unexpected size %d\n", size);
6515 if (size == sizeof(PKCSSignerWithHashAndEncryptionAlgo))
6516 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6517 "Unexpected value\n");
6518 else
6519 ok(0, "Unexpected value\n");
6520 LocalFree(buf);
6523 info.EncryptedHash.cbData = sizeof(hash);
6524 info.EncryptedHash.pbData = (BYTE *)hash;
6525 SetLastError(0xdeadbeef);
6526 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6527 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6528 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6529 ok(!ret && GetLastError() == E_INVALIDARG,
6530 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6531 else
6533 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6534 if (buf)
6536 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6537 size);
6538 if (size == sizeof(PKCSSignerWithHash))
6539 ok(!memcmp(buf, PKCSSignerWithHash, size),
6540 "Unexpected value\n");
6541 else
6542 ok(0, "Unexpected value\n");
6543 LocalFree(buf);
6546 info.AuthAttrs.cAttr = 1;
6547 info.AuthAttrs.rgAttr = &attr;
6548 SetLastError(0xdeadbeef);
6549 ret = pCryptEncodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO, &info,
6550 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6551 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6552 ok(!ret && GetLastError() == E_INVALIDARG,
6553 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6554 else
6556 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6557 if (buf)
6559 ok(size == sizeof(PKCSSignerWithAuthAttr), "Unexpected size %d\n",
6560 size);
6561 if (size == sizeof(PKCSSignerWithAuthAttr))
6562 ok(!memcmp(buf, PKCSSignerWithAuthAttr, size),
6563 "Unexpected value\n");
6564 else
6565 ok(0, "Unexpected value\n");
6566 LocalFree(buf);
6571 static void test_decodePKCSSignerInfo(DWORD dwEncoding)
6573 BOOL ret;
6574 LPBYTE buf = NULL;
6575 DWORD size = 0;
6576 CMSG_SIGNER_INFO *info;
6578 /* A PKCS signer can't be decoded without a serial number. */
6579 SetLastError(0xdeadbeef);
6580 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6581 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6582 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6583 ok(!ret && (GetLastError() == CRYPT_E_ASN1_CORRUPT ||
6584 GetLastError() == OSS_DATA_ERROR /* Win9x */),
6585 "Expected CRYPT_E_ASN1_CORRUPT or OSS_DATA_ERROR, got %x\n",
6586 GetLastError());
6587 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6588 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6589 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6590 ok(ret || broken(GetLastError() == OSS_DATA_ERROR),
6591 "CryptDecodeObjectEx failed: %x\n", GetLastError());
6592 if (buf)
6594 info = (CMSG_SIGNER_INFO *)buf;
6595 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6596 info->dwVersion);
6597 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6598 "Unexpected size %d\n", info->Issuer.cbData);
6599 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6600 info->Issuer.cbData), "Unexpected value\n");
6601 ok(info->SerialNumber.cbData == sizeof(serialNum),
6602 "Unexpected size %d\n", info->SerialNumber.cbData);
6603 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6604 "Unexpected value\n");
6605 LocalFree(buf);
6607 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6608 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6609 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6610 if (buf)
6612 info = (CMSG_SIGNER_INFO *)buf;
6613 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6614 info->dwVersion);
6615 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6616 "Unexpected size %d\n", info->Issuer.cbData);
6617 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6618 info->Issuer.cbData), "Unexpected value\n");
6619 ok(info->SerialNumber.cbData == sizeof(serialNum),
6620 "Unexpected size %d\n", info->SerialNumber.cbData);
6621 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6622 "Unexpected value\n");
6623 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6624 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6625 LocalFree(buf);
6627 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6628 PKCSSignerWithHashAndEncryptionAlgo,
6629 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6630 NULL, &buf, &size);
6631 if (buf)
6633 info = (CMSG_SIGNER_INFO *)buf;
6634 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6635 info->dwVersion);
6636 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6637 "Unexpected size %d\n", info->Issuer.cbData);
6638 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6639 info->Issuer.cbData), "Unexpected value\n");
6640 ok(info->SerialNumber.cbData == sizeof(serialNum),
6641 "Unexpected size %d\n", info->SerialNumber.cbData);
6642 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6643 "Unexpected value\n");
6644 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6645 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6646 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6647 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6648 LocalFree(buf);
6650 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6651 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6652 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6653 if (buf)
6655 info = (CMSG_SIGNER_INFO *)buf;
6656 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6657 info->dwVersion);
6658 ok(info->Issuer.cbData == sizeof(encodedCommonNameNoNull),
6659 "Unexpected size %d\n", info->Issuer.cbData);
6660 ok(!memcmp(info->Issuer.pbData, encodedCommonNameNoNull,
6661 info->Issuer.cbData), "Unexpected value\n");
6662 ok(info->SerialNumber.cbData == sizeof(serialNum),
6663 "Unexpected size %d\n", info->SerialNumber.cbData);
6664 ok(!memcmp(info->SerialNumber.pbData, serialNum, sizeof(serialNum)),
6665 "Unexpected value\n");
6666 ok(!strcmp(info->HashAlgorithm.pszObjId, "1.2.3"),
6667 "Expected 1.2.3, got %s\n", info->HashAlgorithm.pszObjId);
6668 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, "1.5.6"),
6669 "Expected 1.5.6, got %s\n", info->HashEncryptionAlgorithm.pszObjId);
6670 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
6671 info->EncryptedHash.cbData);
6672 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
6673 "Unexpected value\n");
6674 LocalFree(buf);
6676 ret = pCryptDecodeObjectEx(dwEncoding, PKCS7_SIGNER_INFO,
6677 PKCSSignerWithAuthAttr, sizeof(PKCSSignerWithAuthAttr),
6678 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6679 if (buf)
6681 info = (CMSG_SIGNER_INFO *)buf;
6682 ok(info->AuthAttrs.cAttr == 1, "Expected 1 attribute, got %d\n",
6683 info->AuthAttrs.cAttr);
6684 ok(!strcmp(info->AuthAttrs.rgAttr[0].pszObjId, szOID_COMMON_NAME),
6685 "Expected %s, got %s\n", szOID_COMMON_NAME,
6686 info->AuthAttrs.rgAttr[0].pszObjId);
6687 ok(info->AuthAttrs.rgAttr[0].cValue == 1, "Expected 1 value, got %d\n",
6688 info->AuthAttrs.rgAttr[0].cValue);
6689 ok(info->AuthAttrs.rgAttr[0].rgValue[0].cbData ==
6690 sizeof(encodedCommonName), "Unexpected size %d\n",
6691 info->AuthAttrs.rgAttr[0].rgValue[0].cbData);
6692 ok(!memcmp(info->AuthAttrs.rgAttr[0].rgValue[0].pbData,
6693 encodedCommonName, sizeof(encodedCommonName)), "Unexpected value\n");
6694 LocalFree(buf);
6698 static const BYTE CMSSignerWithKeyId[] = {
6699 0x30,0x14,0x02,0x01,0x00,0x80,0x01,0x01,0x30,0x04,0x06,0x00,0x05,0x00,0x30,
6700 0x04,0x06,0x00,0x05,0x00,0x04,0x00 };
6702 static void test_encodeCMSSignerInfo(DWORD dwEncoding)
6704 BOOL ret;
6705 LPBYTE buf = NULL;
6706 DWORD size = 0;
6707 CMSG_CMS_SIGNER_INFO info = { 0 };
6708 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6710 SetLastError(0xdeadbeef);
6711 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6712 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6713 ok(!ret, "Expected failure, got %d\n", ret);
6714 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6716 skip("no CMS_SIGNER_INFO encode support\n");
6717 return;
6719 ok(GetLastError() == E_INVALIDARG,
6720 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6721 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6722 SetLastError(0xdeadbeef);
6723 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6724 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6725 ok(!ret, "Expected failure, got %d\n", ret);
6726 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6728 skip("no CMS_SIGNER_INFO encode support\n");
6729 return;
6731 ok(GetLastError() == E_INVALIDARG,
6732 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6733 /* To be encoded, a signer must have a valid cert ID, where a valid ID may
6734 * be a key id or a issuer serial number with at least the issuer set, and
6735 * the encoding must include PKCS_7_ASN_ENCODING.
6736 * (That isn't enough to be decoded, see decoding tests.)
6738 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6739 sizeof(encodedCommonNameNoNull);
6740 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6741 SetLastError(0xdeadbeef);
6742 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6743 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6744 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6745 ok(!ret && GetLastError() == E_INVALIDARG,
6746 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6747 else
6749 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6750 if (buf)
6752 ok(size == sizeof(minimalPKCSSigner), "Unexpected size %d\n", size);
6753 ok(!memcmp(buf, minimalPKCSSigner, size), "Unexpected value\n");
6754 LocalFree(buf);
6757 U(info.SignerId).IssuerSerialNumber.SerialNumber.cbData = sizeof(serialNum);
6758 U(info.SignerId).IssuerSerialNumber.SerialNumber.pbData = (BYTE *)serialNum;
6759 SetLastError(0xdeadbeef);
6760 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6761 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6762 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6763 ok(!ret && GetLastError() == E_INVALIDARG,
6764 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6765 else
6767 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6768 if (buf)
6770 ok(size == sizeof(PKCSSignerWithSerial), "Unexpected size %d\n",
6771 size);
6772 ok(!memcmp(buf, PKCSSignerWithSerial, size), "Unexpected value\n");
6773 LocalFree(buf);
6776 info.SignerId.dwIdChoice = CERT_ID_KEY_IDENTIFIER;
6777 U(info.SignerId).KeyId.cbData = sizeof(serialNum);
6778 U(info.SignerId).KeyId.pbData = (BYTE *)serialNum;
6779 SetLastError(0xdeadbeef);
6780 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6781 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6782 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6783 ok(!ret && GetLastError() == E_INVALIDARG,
6784 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6785 else
6787 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6788 if (buf)
6790 ok(size == sizeof(CMSSignerWithKeyId), "Unexpected size %d\n",
6791 size);
6792 ok(!memcmp(buf, CMSSignerWithKeyId, size), "Unexpected value\n");
6793 LocalFree(buf);
6796 /* While a CERT_ID can have a hash type, that's not allowed in CMS, where
6797 * only the IssuerAndSerialNumber and SubjectKeyIdentifier types are allowed
6798 * (see RFC 3852, section 5.3.)
6800 info.SignerId.dwIdChoice = CERT_ID_SHA1_HASH;
6801 U(info.SignerId).HashId.cbData = sizeof(hash);
6802 U(info.SignerId).HashId.pbData = (BYTE *)hash;
6803 SetLastError(0xdeadbeef);
6804 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6805 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6806 ok(!ret && GetLastError() == E_INVALIDARG,
6807 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6808 /* Now with a hash algo */
6809 info.SignerId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER;
6810 U(info.SignerId).IssuerSerialNumber.Issuer.cbData =
6811 sizeof(encodedCommonNameNoNull);
6812 U(info.SignerId).IssuerSerialNumber.Issuer.pbData = encodedCommonNameNoNull;
6813 info.HashAlgorithm.pszObjId = oid1;
6814 SetLastError(0xdeadbeef);
6815 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6816 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6817 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6818 ok(!ret && GetLastError() == E_INVALIDARG,
6819 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6820 else
6822 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6823 if (buf)
6825 ok(size == sizeof(PKCSSignerWithHashAlgo), "Unexpected size %d\n",
6826 size);
6827 ok(!memcmp(buf, PKCSSignerWithHashAlgo, size),
6828 "Unexpected value\n");
6829 LocalFree(buf);
6832 info.HashEncryptionAlgorithm.pszObjId = oid2;
6833 SetLastError(0xdeadbeef);
6834 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6835 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6836 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6837 ok(!ret && GetLastError() == E_INVALIDARG,
6838 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6839 else
6841 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6842 if (buf)
6844 ok(size == sizeof(PKCSSignerWithHashAndEncryptionAlgo),
6845 "Unexpected size %d\n", size);
6846 ok(!memcmp(buf, PKCSSignerWithHashAndEncryptionAlgo, size),
6847 "Unexpected value\n");
6848 LocalFree(buf);
6851 info.EncryptedHash.cbData = sizeof(hash);
6852 info.EncryptedHash.pbData = (BYTE *)hash;
6853 SetLastError(0xdeadbeef);
6854 ret = pCryptEncodeObjectEx(dwEncoding, CMS_SIGNER_INFO, &info,
6855 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
6856 if (!(dwEncoding & PKCS_7_ASN_ENCODING))
6857 ok(!ret && GetLastError() == E_INVALIDARG,
6858 "Expected E_INVALIDARG, got %08x\n", GetLastError());
6859 else
6861 ok(ret, "CryptEncodeObjectEx failed: %x\n", GetLastError());
6862 if (buf)
6864 ok(size == sizeof(PKCSSignerWithHash), "Unexpected size %d\n",
6865 size);
6866 ok(!memcmp(buf, PKCSSignerWithHash, size), "Unexpected value\n");
6867 LocalFree(buf);
6872 static void test_decodeCMSSignerInfo(DWORD dwEncoding)
6874 BOOL ret;
6875 LPBYTE buf = NULL;
6876 DWORD size = 0;
6877 CMSG_CMS_SIGNER_INFO *info;
6878 static char oid1[] = "1.2.3", oid2[] = "1.5.6";
6880 /* A CMS signer can't be decoded without a serial number. */
6881 SetLastError(0xdeadbeef);
6882 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6883 minimalPKCSSigner, sizeof(minimalPKCSSigner),
6884 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6885 ok(!ret, "expected failure\n");
6886 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
6888 skip("no CMS_SIGNER_INFO decode support\n");
6889 return;
6891 ok(GetLastError() == CRYPT_E_ASN1_CORRUPT,
6892 "Expected CRYPT_E_ASN1_CORRUPT, got %x\n", GetLastError());
6893 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6894 PKCSSignerWithSerial, sizeof(PKCSSignerWithSerial),
6895 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6896 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6897 if (buf)
6899 info = (CMSG_CMS_SIGNER_INFO *)buf;
6900 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6901 info->dwVersion);
6902 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6903 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6904 info->SignerId.dwIdChoice);
6905 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6906 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6907 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6908 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6909 encodedCommonNameNoNull,
6910 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6911 "Unexpected value\n");
6912 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6913 sizeof(serialNum), "Unexpected size %d\n",
6914 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6915 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6916 serialNum, sizeof(serialNum)), "Unexpected value\n");
6917 LocalFree(buf);
6919 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6920 PKCSSignerWithHashAlgo, sizeof(PKCSSignerWithHashAlgo),
6921 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6922 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6923 if (buf)
6925 info = (CMSG_CMS_SIGNER_INFO *)buf;
6926 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6927 info->dwVersion);
6928 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6929 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6930 info->SignerId.dwIdChoice);
6931 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6932 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6933 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6934 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6935 encodedCommonNameNoNull,
6936 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6937 "Unexpected value\n");
6938 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6939 sizeof(serialNum), "Unexpected size %d\n",
6940 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6941 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6942 serialNum, sizeof(serialNum)), "Unexpected value\n");
6943 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6944 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6945 LocalFree(buf);
6947 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6948 PKCSSignerWithHashAndEncryptionAlgo,
6949 sizeof(PKCSSignerWithHashAndEncryptionAlgo), CRYPT_DECODE_ALLOC_FLAG,
6950 NULL, &buf, &size);
6951 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6952 if (buf)
6954 info = (CMSG_CMS_SIGNER_INFO *)buf;
6955 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6956 info->dwVersion);
6957 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6958 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6959 info->SignerId.dwIdChoice);
6960 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6961 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6962 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6963 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6964 encodedCommonNameNoNull,
6965 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6966 "Unexpected value\n");
6967 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6968 sizeof(serialNum), "Unexpected size %d\n",
6969 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
6970 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
6971 serialNum, sizeof(serialNum)), "Unexpected value\n");
6972 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
6973 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
6974 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
6975 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
6976 LocalFree(buf);
6978 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
6979 PKCSSignerWithHash, sizeof(PKCSSignerWithHash),
6980 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
6981 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
6982 if (buf)
6984 info = (CMSG_CMS_SIGNER_INFO *)buf;
6985 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
6986 info->dwVersion);
6987 ok(info->SignerId.dwIdChoice == CERT_ID_ISSUER_SERIAL_NUMBER,
6988 "Expected CERT_ID_ISSUER_SERIAL_NUMBER, got %d\n",
6989 info->SignerId.dwIdChoice);
6990 ok(U(info->SignerId).IssuerSerialNumber.Issuer.cbData ==
6991 sizeof(encodedCommonNameNoNull), "Unexpected size %d\n",
6992 U(info->SignerId).IssuerSerialNumber.Issuer.cbData);
6993 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.Issuer.pbData,
6994 encodedCommonNameNoNull,
6995 U(info->SignerId).IssuerSerialNumber.Issuer.cbData),
6996 "Unexpected value\n");
6997 ok(U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData ==
6998 sizeof(serialNum), "Unexpected size %d\n",
6999 U(info->SignerId).IssuerSerialNumber.SerialNumber.cbData);
7000 ok(!memcmp(U(info->SignerId).IssuerSerialNumber.SerialNumber.pbData,
7001 serialNum, sizeof(serialNum)), "Unexpected value\n");
7002 ok(!strcmp(info->HashAlgorithm.pszObjId, oid1),
7003 "Expected %s, got %s\n", oid1, info->HashAlgorithm.pszObjId);
7004 ok(!strcmp(info->HashEncryptionAlgorithm.pszObjId, oid2),
7005 "Expected %s, got %s\n", oid2, info->HashEncryptionAlgorithm.pszObjId);
7006 ok(info->EncryptedHash.cbData == sizeof(hash), "Unexpected size %d\n",
7007 info->EncryptedHash.cbData);
7008 ok(!memcmp(info->EncryptedHash.pbData, hash, sizeof(hash)),
7009 "Unexpected value\n");
7010 LocalFree(buf);
7012 ret = pCryptDecodeObjectEx(dwEncoding, CMS_SIGNER_INFO,
7013 CMSSignerWithKeyId, sizeof(CMSSignerWithKeyId),
7014 CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
7015 ok(ret, "CryptDecodeObjectEx failed: %x\n", GetLastError());
7016 if (buf)
7018 info = (CMSG_CMS_SIGNER_INFO *)buf;
7019 ok(info->dwVersion == 0, "Expected version 0, got %d\n",
7020 info->dwVersion);
7021 ok(info->SignerId.dwIdChoice == CERT_ID_KEY_IDENTIFIER,
7022 "Expected CERT_ID_KEY_IDENTIFIER, got %d\n",
7023 info->SignerId.dwIdChoice);
7024 ok(U(info->SignerId).KeyId.cbData == sizeof(serialNum),
7025 "Unexpected size %d\n", U(info->SignerId).KeyId.cbData);
7026 ok(!memcmp(U(info->SignerId).KeyId.pbData, serialNum, sizeof(serialNum)),
7027 "Unexpected value\n");
7028 LocalFree(buf);
7032 static BYTE emptyDNSPermittedConstraints[] = {
7033 0x30,0x06,0xa0,0x04,0x30,0x02,0x82,0x00 };
7034 static BYTE emptyDNSExcludedConstraints[] = {
7035 0x30,0x06,0xa1,0x04,0x30,0x02,0x82,0x00 };
7036 static BYTE DNSExcludedConstraints[] = {
7037 0x30,0x17,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,
7038 0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7039 static BYTE permittedAndExcludedConstraints[] = {
7040 0x30,0x25,0xa0,0x0c,0x30,0x0a,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7041 0x01,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,
7042 0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7043 static BYTE permittedAndExcludedWithMinConstraints[] = {
7044 0x30,0x28,0xa0,0x0f,0x30,0x0d,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7045 0x01,0x80,0x01,0x05,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,0x74,0x70,0x3a,
7046 0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7047 static BYTE permittedAndExcludedWithMinMaxConstraints[] = {
7048 0x30,0x2b,0xa0,0x12,0x30,0x10,0x87,0x08,0x30,0x06,0x87,0x04,0x7f,0x00,0x00,
7049 0x01,0x80,0x01,0x05,0x81,0x01,0x03,0xa1,0x15,0x30,0x13,0x82,0x11,0x68,0x74,
7050 0x74,0x70,0x3a,0x2f,0x2f,0x77,0x69,0x6e,0x65,0x68,0x71,0x2e,0x6f,0x72,0x67 };
7052 static void test_encodeNameConstraints(DWORD dwEncoding)
7054 BOOL ret;
7055 CERT_NAME_CONSTRAINTS_INFO constraints = { 0 };
7056 CERT_GENERAL_SUBTREE permitted = { { 0 } };
7057 CERT_GENERAL_SUBTREE excluded = { { 0 } };
7058 LPBYTE buf;
7059 DWORD size;
7061 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7062 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7063 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7065 skip("no X509_NAME_CONSTRAINTS encode support\n");
7066 return;
7068 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7069 if (ret)
7071 ok(size == sizeof(emptySequence), "Unexpected size\n");
7072 ok(!memcmp(buf, emptySequence, size), "Unexpected value\n");
7073 LocalFree(buf);
7075 constraints.cPermittedSubtree = 1;
7076 constraints.rgPermittedSubtree = &permitted;
7077 SetLastError(0xdeadbeef);
7078 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7079 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7080 ok(!ret && GetLastError() == E_INVALIDARG,
7081 "Expected E_INVALIDARG, got %08x\n", GetLastError());
7082 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7083 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7084 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7085 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7086 if (ret)
7088 ok(size == sizeof(emptyDNSPermittedConstraints), "Unexpected size\n");
7089 ok(!memcmp(buf, emptyDNSPermittedConstraints, size),
7090 "Unexpected value\n");
7091 LocalFree(buf);
7093 constraints.cPermittedSubtree = 0;
7094 constraints.cExcludedSubtree = 1;
7095 constraints.rgExcludedSubtree = &excluded;
7096 excluded.Base.dwAltNameChoice = CERT_ALT_NAME_DNS_NAME;
7097 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7098 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7099 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7100 if (ret)
7102 ok(size == sizeof(emptyDNSExcludedConstraints), "Unexpected size\n");
7103 ok(!memcmp(buf, emptyDNSExcludedConstraints, size),
7104 "Unexpected value\n");
7105 LocalFree(buf);
7107 U(excluded.Base).pwszURL = (LPWSTR)url;
7108 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7109 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7110 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7111 if (ret)
7113 ok(size == sizeof(DNSExcludedConstraints), "Unexpected size\n");
7114 ok(!memcmp(buf, DNSExcludedConstraints, size),
7115 "Unexpected value\n");
7116 LocalFree(buf);
7118 permitted.Base.dwAltNameChoice = CERT_ALT_NAME_IP_ADDRESS;
7119 U(permitted.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7120 U(permitted.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7121 constraints.cPermittedSubtree = 1;
7122 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7123 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7124 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7125 if (ret)
7127 ok(size == sizeof(permittedAndExcludedConstraints),
7128 "Unexpected size\n");
7129 ok(!memcmp(buf, permittedAndExcludedConstraints, size),
7130 "Unexpected value\n");
7131 LocalFree(buf);
7133 permitted.dwMinimum = 5;
7134 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7135 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7136 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7137 if (ret)
7139 ok(size == sizeof(permittedAndExcludedWithMinConstraints),
7140 "Unexpected size\n");
7141 ok(!memcmp(buf, permittedAndExcludedWithMinConstraints, size),
7142 "Unexpected value\n");
7143 LocalFree(buf);
7145 permitted.fMaximum = TRUE;
7146 permitted.dwMaximum = 3;
7147 SetLastError(0xdeadbeef);
7148 ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS, &constraints,
7149 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7150 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7151 if (ret)
7153 ok(size == sizeof(permittedAndExcludedWithMinMaxConstraints),
7154 "Unexpected size\n");
7155 ok(!memcmp(buf, permittedAndExcludedWithMinMaxConstraints, size),
7156 "Unexpected value\n");
7157 LocalFree(buf);
7161 struct EncodedNameConstraints
7163 CRYPT_DATA_BLOB encoded;
7164 CERT_NAME_CONSTRAINTS_INFO constraints;
7167 static CERT_GENERAL_SUBTREE emptyDNSSubtree = {
7168 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7169 static CERT_GENERAL_SUBTREE DNSSubtree = {
7170 { CERT_ALT_NAME_DNS_NAME, { 0 } }, 0 };
7171 static CERT_GENERAL_SUBTREE IPAddressSubtree = {
7172 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 0 };
7173 static CERT_GENERAL_SUBTREE IPAddressWithMinSubtree = {
7174 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, 0 };
7175 static CERT_GENERAL_SUBTREE IPAddressWithMinMaxSubtree = {
7176 { CERT_ALT_NAME_IP_ADDRESS, { 0 } }, 5, TRUE, 3 };
7178 struct EncodedNameConstraints encodedNameConstraints[] = {
7179 { { sizeof(emptySequence), (LPBYTE)emptySequence }, { 0 } },
7180 { { sizeof(emptyDNSPermittedConstraints), emptyDNSPermittedConstraints },
7181 { 1, &emptyDNSSubtree, 0, NULL } },
7182 { { sizeof(emptyDNSExcludedConstraints), emptyDNSExcludedConstraints },
7183 { 0, NULL, 1, &emptyDNSSubtree } },
7184 { { sizeof(DNSExcludedConstraints), DNSExcludedConstraints },
7185 { 0, NULL, 1, &DNSSubtree } },
7186 { { sizeof(permittedAndExcludedConstraints), permittedAndExcludedConstraints },
7187 { 1, &IPAddressSubtree, 1, &DNSSubtree } },
7188 { { sizeof(permittedAndExcludedWithMinConstraints),
7189 permittedAndExcludedWithMinConstraints },
7190 { 1, &IPAddressWithMinSubtree, 1, &DNSSubtree } },
7191 { { sizeof(permittedAndExcludedWithMinMaxConstraints),
7192 permittedAndExcludedWithMinMaxConstraints },
7193 { 1, &IPAddressWithMinMaxSubtree, 1, &DNSSubtree } },
7196 static void test_decodeNameConstraints(DWORD dwEncoding)
7198 BOOL ret;
7199 DWORD i;
7200 CERT_NAME_CONSTRAINTS_INFO *constraints;
7202 U(DNSSubtree.Base).pwszURL = (LPWSTR)url;
7203 U(IPAddressSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7204 U(IPAddressSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7205 U(IPAddressWithMinSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7206 U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7207 U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
7208 U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
7209 for (i = 0;
7210 i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
7211 i++)
7213 DWORD size;
7215 ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_CONSTRAINTS,
7216 encodedNameConstraints[i].encoded.pbData,
7217 encodedNameConstraints[i].encoded.cbData,
7218 CRYPT_DECODE_ALLOC_FLAG, NULL, &constraints, &size);
7219 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7221 skip("no X509_NAME_CONSTRAINTS decode support\n");
7222 return;
7224 ok(ret, "%d: CryptDecodeObjectEx failed: %08x\n", i, GetLastError());
7225 if (ret)
7227 DWORD j;
7229 if (constraints->cPermittedSubtree !=
7230 encodedNameConstraints[i].constraints.cPermittedSubtree)
7231 fprintf(stderr, "%d: expected %d permitted, got %d\n", i,
7232 encodedNameConstraints[i].constraints.cPermittedSubtree,
7233 constraints->cPermittedSubtree);
7234 if (constraints->cPermittedSubtree ==
7235 encodedNameConstraints[i].constraints.cPermittedSubtree)
7237 for (j = 0; j < constraints->cPermittedSubtree; j++)
7239 compareAltNameEntry(&constraints->rgPermittedSubtree[j].Base,
7240 &encodedNameConstraints[i].constraints.rgPermittedSubtree[j].Base);
7243 if (constraints->cExcludedSubtree !=
7244 encodedNameConstraints[i].constraints.cExcludedSubtree)
7245 fprintf(stderr, "%d: expected %d excluded, got %d\n", i,
7246 encodedNameConstraints[i].constraints.cExcludedSubtree,
7247 constraints->cExcludedSubtree);
7248 if (constraints->cExcludedSubtree ==
7249 encodedNameConstraints[i].constraints.cExcludedSubtree)
7251 for (j = 0; j < constraints->cExcludedSubtree; j++)
7253 compareAltNameEntry(&constraints->rgExcludedSubtree[j].Base,
7254 &encodedNameConstraints[i].constraints.rgExcludedSubtree[j].Base);
7257 LocalFree(constraints);
7262 static WCHAR noticeText[] = { 'T','h','i','s',' ','i','s',' ','a',' ',
7263 'n','o','t','i','c','e',0 };
7264 static const BYTE noticeWithDisplayText[] = {
7265 0x30,0x22,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,0x00,
7266 0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,0x74,
7267 0x00,0x69,0x00,0x63,0x00,0x65
7269 static char org[] = "Wine";
7270 static int noticeNumbers[] = { 2,3 };
7271 static BYTE noticeWithReference[] = {
7272 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7273 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7274 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7275 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7278 static void test_encodePolicyQualifierUserNotice(DWORD dwEncoding)
7280 BOOL ret;
7281 LPBYTE buf;
7282 DWORD size;
7283 CERT_POLICY_QUALIFIER_USER_NOTICE notice;
7284 CERT_POLICY_QUALIFIER_NOTICE_REFERENCE reference;
7286 memset(&notice, 0, sizeof(notice));
7287 ret = pCryptEncodeObjectEx(dwEncoding,
7288 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7289 NULL, &buf, &size);
7290 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7292 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE encode support\n");
7293 return;
7295 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7296 if (ret)
7298 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7299 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7300 LocalFree(buf);
7302 notice.pszDisplayText = noticeText;
7303 ret = pCryptEncodeObjectEx(dwEncoding,
7304 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7305 NULL, &buf, &size);
7306 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7307 if (ret)
7309 ok(sizeof(noticeWithDisplayText) == size, "unexpected size %d\n", size);
7310 ok(!memcmp(buf, noticeWithDisplayText, size), "unexpected value\n");
7311 LocalFree(buf);
7313 reference.pszOrganization = org;
7314 reference.cNoticeNumbers = 2;
7315 reference.rgNoticeNumbers = noticeNumbers;
7316 notice.pNoticeReference = &reference;
7317 ret = pCryptEncodeObjectEx(dwEncoding,
7318 X509_PKIX_POLICY_QUALIFIER_USERNOTICE, &notice, CRYPT_ENCODE_ALLOC_FLAG,
7319 NULL, &buf, &size);
7320 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7321 if (ret)
7323 ok(sizeof(noticeWithReference) == size, "unexpected size %d\n", size);
7324 ok(!memcmp(buf, noticeWithReference, size), "unexpected value\n");
7325 LocalFree(buf);
7329 static void test_decodePolicyQualifierUserNotice(DWORD dwEncoding)
7331 BOOL ret;
7332 CERT_POLICY_QUALIFIER_USER_NOTICE *notice;
7333 DWORD size;
7335 ret = pCryptDecodeObjectEx(dwEncoding,
7336 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7337 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7338 &notice, &size);
7339 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7341 skip("no X509_PKIX_POLICY_QUALIFIER_USERNOTICE decode support\n");
7342 return;
7344 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7345 if (ret)
7347 ok(notice->pszDisplayText == NULL, "unexpected display text\n");
7348 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7349 LocalFree(notice);
7351 ret = pCryptDecodeObjectEx(dwEncoding,
7352 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7353 noticeWithDisplayText, sizeof(noticeWithDisplayText),
7354 CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size);
7355 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7356 if (ret)
7358 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7359 "unexpected display text\n");
7360 ok(notice->pNoticeReference == NULL, "unexpected notice reference\n");
7361 LocalFree(notice);
7363 ret = pCryptDecodeObjectEx(dwEncoding,
7364 X509_PKIX_POLICY_QUALIFIER_USERNOTICE,
7365 noticeWithReference, sizeof(noticeWithReference),
7366 CRYPT_DECODE_ALLOC_FLAG, NULL, &notice, &size);
7367 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7368 if (ret)
7370 ok(!lstrcmpW(notice->pszDisplayText, noticeText),
7371 "unexpected display text\n");
7372 ok(notice->pNoticeReference != NULL, "expected a notice reference\n");
7373 if (notice->pNoticeReference)
7375 ok(!strcmp(notice->pNoticeReference->pszOrganization, org),
7376 "unexpected organization %s\n",
7377 notice->pNoticeReference->pszOrganization);
7378 ok(notice->pNoticeReference->cNoticeNumbers == 2,
7379 "expected 2 notice numbers, got %d\n",
7380 notice->pNoticeReference->cNoticeNumbers);
7381 ok(notice->pNoticeReference->rgNoticeNumbers[0] == noticeNumbers[0],
7382 "unexpected notice number %d\n",
7383 notice->pNoticeReference->rgNoticeNumbers[0]);
7384 ok(notice->pNoticeReference->rgNoticeNumbers[1] == noticeNumbers[1],
7385 "unexpected notice number %d\n",
7386 notice->pNoticeReference->rgNoticeNumbers[1]);
7388 LocalFree(notice);
7392 static char oid_any_policy[] = "2.5.29.32.0";
7393 static const BYTE policiesWithAnyPolicy[] = {
7394 0x30,0x08,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00
7396 static char oid1[] = "1.2.3";
7397 static char oid_user_notice[] = "1.3.6.1.5.5.7.2.2";
7398 static const BYTE twoPolicies[] = {
7399 0x30,0x50,0x30,0x06,0x06,0x04,0x55,0x1d,0x20,0x00,0x30,0x46,0x06,0x02,0x2a,
7400 0x03,0x30,0x40,0x30,0x3e,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x02,0x02,
7401 0x30,0x32,0x30,0x0e,0x16,0x04,0x57,0x69,0x6e,0x65,0x30,0x06,0x02,0x01,0x02,
7402 0x02,0x01,0x03,0x1e,0x20,0x00,0x54,0x00,0x68,0x00,0x69,0x00,0x73,0x00,0x20,
7403 0x00,0x69,0x00,0x73,0x00,0x20,0x00,0x61,0x00,0x20,0x00,0x6e,0x00,0x6f,0x00,
7404 0x74,0x00,0x69,0x00,0x63,0x00,0x65
7407 static void test_encodeCertPolicies(DWORD dwEncoding)
7409 BOOL ret;
7410 CERT_POLICIES_INFO info;
7411 CERT_POLICY_INFO policy[2];
7412 CERT_POLICY_QUALIFIER_INFO qualifier;
7413 LPBYTE buf;
7414 DWORD size;
7416 memset(&info, 0, sizeof(info));
7417 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7418 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7419 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7420 if (ret)
7422 ok(sizeof(emptySequence) == size, "unexpected size %d\n", size);
7423 ok(!memcmp(buf, emptySequence, size), "unexpected value\n");
7424 LocalFree(buf);
7426 memset(policy, 0, sizeof(policy));
7427 info.cPolicyInfo = 1;
7428 info.rgPolicyInfo = policy;
7429 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7430 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7431 ok(!ret && (GetLastError() == E_INVALIDARG ||
7432 GetLastError() == OSS_LIMITED /* Win9x/NT4 */),
7433 "expected E_INVALIDARG or OSS_LIMITED, got %08x\n", GetLastError());
7434 policy[0].pszPolicyIdentifier = oid_any_policy;
7435 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7436 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7437 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7438 if (ret)
7440 ok(sizeof(policiesWithAnyPolicy) == size, "unexpected size %d\n", size);
7441 ok(!memcmp(buf, policiesWithAnyPolicy, size), "unexpected value\n");
7442 LocalFree(buf);
7444 policy[1].pszPolicyIdentifier = oid1;
7445 memset(&qualifier, 0, sizeof(qualifier));
7446 qualifier.pszPolicyQualifierId = oid_user_notice;
7447 qualifier.Qualifier.cbData = sizeof(noticeWithReference);
7448 qualifier.Qualifier.pbData = noticeWithReference;
7449 policy[1].cPolicyQualifier = 1;
7450 policy[1].rgPolicyQualifier = &qualifier;
7451 info.cPolicyInfo = 2;
7452 ret = pCryptEncodeObjectEx(dwEncoding, X509_CERT_POLICIES, &info,
7453 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7454 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7455 if (ret)
7457 ok(sizeof(twoPolicies) == size, "unexpected size %d\n", size);
7458 ok(!memcmp(buf, twoPolicies, size), "unexpected value\n");
7459 LocalFree(buf);
7463 static void test_decodeCertPolicies(DWORD dwEncoding)
7465 BOOL ret;
7466 CERT_POLICIES_INFO *info;
7467 DWORD size;
7469 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7470 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7471 &info, &size);
7472 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7473 if (ret)
7475 ok(info->cPolicyInfo == 0, "unexpected policy info %d\n",
7476 info->cPolicyInfo);
7477 LocalFree(info);
7479 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7480 policiesWithAnyPolicy, sizeof(policiesWithAnyPolicy),
7481 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7482 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7483 if (ret)
7485 ok(info->cPolicyInfo == 1, "unexpected policy info %d\n",
7486 info->cPolicyInfo);
7487 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7488 "unexpected policy id %s\n",
7489 info->rgPolicyInfo[0].pszPolicyIdentifier);
7490 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7491 "unexpected policy qualifier count %d\n",
7492 info->rgPolicyInfo[0].cPolicyQualifier);
7493 LocalFree(info);
7495 ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_POLICIES,
7496 twoPolicies, sizeof(twoPolicies),
7497 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7498 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7499 if (ret)
7501 ok(info->cPolicyInfo == 2, "unexpected policy info %d\n",
7502 info->cPolicyInfo);
7503 ok(!strcmp(info->rgPolicyInfo[0].pszPolicyIdentifier, oid_any_policy),
7504 "unexpected policy id %s\n",
7505 info->rgPolicyInfo[0].pszPolicyIdentifier);
7506 ok(info->rgPolicyInfo[0].cPolicyQualifier == 0,
7507 "unexpected policy qualifier count %d\n",
7508 info->rgPolicyInfo[0].cPolicyQualifier);
7509 ok(!strcmp(info->rgPolicyInfo[1].pszPolicyIdentifier, oid1),
7510 "unexpected policy id %s\n",
7511 info->rgPolicyInfo[1].pszPolicyIdentifier);
7512 ok(info->rgPolicyInfo[1].cPolicyQualifier == 1,
7513 "unexpected policy qualifier count %d\n",
7514 info->rgPolicyInfo[1].cPolicyQualifier);
7515 ok(!strcmp(
7516 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId,
7517 oid_user_notice), "unexpected policy qualifier id %s\n",
7518 info->rgPolicyInfo[1].rgPolicyQualifier[0].pszPolicyQualifierId);
7519 ok(info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData ==
7520 sizeof(noticeWithReference), "unexpected qualifier size %d\n",
7521 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.cbData);
7522 ok(!memcmp(
7523 info->rgPolicyInfo[1].rgPolicyQualifier[0].Qualifier.pbData,
7524 noticeWithReference, sizeof(noticeWithReference)),
7525 "unexpected qualifier value\n");
7526 LocalFree(info);
7530 static const BYTE policyMappingWithOneMapping[] = {
7531 0x30,0x0a,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04 };
7532 static const BYTE policyMappingWithTwoMappings[] = {
7533 0x30,0x14,0x30,0x08,0x06,0x02,0x2a,0x03,0x06,0x02,0x53,0x04,0x30,0x08,0x06,
7534 0x02,0x2b,0x04,0x06,0x02,0x55,0x06 };
7535 static const LPCSTR mappingOids[] = { X509_POLICY_MAPPINGS,
7536 szOID_POLICY_MAPPINGS, szOID_LEGACY_POLICY_MAPPINGS };
7538 static void test_encodeCertPolicyMappings(DWORD dwEncoding)
7540 static char oid2[] = "2.3.4";
7541 static char oid3[] = "1.3.4";
7542 static char oid4[] = "2.5.6";
7543 BOOL ret;
7544 CERT_POLICY_MAPPINGS_INFO info = { 0 };
7545 CERT_POLICY_MAPPING mapping[2];
7546 LPBYTE buf;
7547 DWORD size, i;
7549 /* Each of the mapping OIDs is equivalent, so check with all of them */
7550 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
7552 memset(&info, 0, sizeof(info));
7553 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7554 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7555 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7556 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7557 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7559 win_skip("no policy mappings support\n");
7560 return;
7562 if (ret)
7564 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7565 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7566 "unexpected value\n");
7567 LocalFree(buf);
7569 mapping[0].pszIssuerDomainPolicy = NULL;
7570 mapping[0].pszSubjectDomainPolicy = NULL;
7571 info.cPolicyMapping = 1;
7572 info.rgPolicyMapping = mapping;
7573 SetLastError(0xdeadbeef);
7574 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7575 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7576 ok(!ret && GetLastError() == E_INVALIDARG,
7577 "expected E_INVALIDARG, got %08x\n", GetLastError());
7578 mapping[0].pszIssuerDomainPolicy = oid1;
7579 mapping[0].pszSubjectDomainPolicy = oid2;
7580 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7581 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7582 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7583 if (ret)
7585 ok(size == sizeof(policyMappingWithOneMapping),
7586 "unexpected size %d\n", size);
7587 ok(!memcmp(buf, policyMappingWithOneMapping, size),
7588 "unexpected value\n");
7589 LocalFree(buf);
7591 mapping[1].pszIssuerDomainPolicy = oid3;
7592 mapping[1].pszSubjectDomainPolicy = oid4;
7593 info.cPolicyMapping = 2;
7594 ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
7595 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7596 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7597 if (ret)
7599 ok(size == sizeof(policyMappingWithTwoMappings),
7600 "unexpected size %d\n", size);
7601 ok(!memcmp(buf, policyMappingWithTwoMappings, size),
7602 "unexpected value\n");
7603 LocalFree(buf);
7608 static void test_decodeCertPolicyMappings(DWORD dwEncoding)
7610 DWORD size, i;
7611 CERT_POLICY_MAPPINGS_INFO *info;
7612 BOOL ret;
7614 /* Each of the mapping OIDs is equivalent, so check with all of them */
7615 for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
7617 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7618 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7619 &info, &size);
7620 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7621 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7622 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7624 win_skip("no policy mappings support\n");
7625 return;
7627 if (ret)
7629 ok(info->cPolicyMapping == 0,
7630 "expected 0 policy mappings, got %d\n", info->cPolicyMapping);
7631 LocalFree(info);
7633 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7634 policyMappingWithOneMapping, sizeof(policyMappingWithOneMapping),
7635 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7636 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7637 if (ret)
7639 ok(info->cPolicyMapping == 1,
7640 "expected 1 policy mappings, got %d\n", info->cPolicyMapping);
7641 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7642 "unexpected issuer policy %s\n",
7643 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7644 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7645 "2.3.4"), "unexpected subject policy %s\n",
7646 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7647 LocalFree(info);
7649 ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
7650 policyMappingWithTwoMappings, sizeof(policyMappingWithTwoMappings),
7651 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7652 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7653 if (ret)
7655 ok(info->cPolicyMapping == 2,
7656 "expected 2 policy mappings, got %d\n", info->cPolicyMapping);
7657 ok(!strcmp(info->rgPolicyMapping[0].pszIssuerDomainPolicy, "1.2.3"),
7658 "unexpected issuer policy %s\n",
7659 info->rgPolicyMapping[0].pszIssuerDomainPolicy);
7660 ok(!strcmp(info->rgPolicyMapping[0].pszSubjectDomainPolicy,
7661 "2.3.4"), "unexpected subject policy %s\n",
7662 info->rgPolicyMapping[0].pszSubjectDomainPolicy);
7663 ok(!strcmp(info->rgPolicyMapping[1].pszIssuerDomainPolicy, "1.3.4"),
7664 "unexpected issuer policy %s\n",
7665 info->rgPolicyMapping[1].pszIssuerDomainPolicy);
7666 ok(!strcmp(info->rgPolicyMapping[1].pszSubjectDomainPolicy,
7667 "2.5.6"), "unexpected subject policy %s\n",
7668 info->rgPolicyMapping[1].pszSubjectDomainPolicy);
7669 LocalFree(info);
7674 static const BYTE policyConstraintsWithRequireExplicit[] = {
7675 0x30,0x03,0x80,0x01,0x00 };
7676 static const BYTE policyConstraintsWithInhibitMapping[] = {
7677 0x30,0x03,0x81,0x01,0x01 };
7678 static const BYTE policyConstraintsWithBoth[] = {
7679 0x30,0x06,0x80,0x01,0x01,0x81,0x01,0x01 };
7681 static void test_encodeCertPolicyConstraints(DWORD dwEncoding)
7683 CERT_POLICY_CONSTRAINTS_INFO info = { 0 };
7684 LPBYTE buf;
7685 DWORD size;
7686 BOOL ret;
7688 /* Even though RFC 5280 explicitly states CAs must not issue empty
7689 * policy constraints (section 4.2.1.11), the API doesn't prevent it.
7691 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7692 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7693 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7694 "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7695 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7697 win_skip("no policy constraints support\n");
7698 return;
7700 if (ret)
7702 ok(size == sizeof(emptySequence), "unexpected size %d\n", size);
7703 ok(!memcmp(buf, emptySequence, sizeof(emptySequence)),
7704 "unexpected value\n");
7705 LocalFree(buf);
7707 /* If fRequireExplicitPolicy is set but dwRequireExplicitPolicySkipCerts
7708 * is not, then a skip of 0 is encoded.
7710 info.fRequireExplicitPolicy = TRUE;
7711 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7712 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7713 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7714 if (ret)
7716 ok(size == sizeof(policyConstraintsWithRequireExplicit),
7717 "unexpected size %d\n", size);
7718 ok(!memcmp(buf, policyConstraintsWithRequireExplicit,
7719 sizeof(policyConstraintsWithRequireExplicit)), "unexpected value\n");
7720 LocalFree(buf);
7722 /* With inhibit policy mapping */
7723 info.fRequireExplicitPolicy = FALSE;
7724 info.dwRequireExplicitPolicySkipCerts = 0;
7725 info.fInhibitPolicyMapping = TRUE;
7726 info.dwInhibitPolicyMappingSkipCerts = 1;
7727 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7728 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7729 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7730 if (ret)
7732 ok(size == sizeof(policyConstraintsWithInhibitMapping),
7733 "unexpected size %d\n", size);
7734 ok(!memcmp(buf, policyConstraintsWithInhibitMapping,
7735 sizeof(policyConstraintsWithInhibitMapping)), "unexpected value\n");
7736 LocalFree(buf);
7738 /* And with both */
7739 info.fRequireExplicitPolicy = TRUE;
7740 info.dwRequireExplicitPolicySkipCerts = 1;
7741 ret = pCryptEncodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS, &info,
7742 CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
7743 ok(ret, "CryptEncodeObjectEx failed: %08x\n", GetLastError());
7744 if (ret)
7746 ok(size == sizeof(policyConstraintsWithBoth), "unexpected size %d\n",
7747 size);
7748 ok(!memcmp(buf, policyConstraintsWithBoth,
7749 sizeof(policyConstraintsWithBoth)), "unexpected value\n");
7750 LocalFree(buf);
7754 static void test_decodeCertPolicyConstraints(DWORD dwEncoding)
7756 CERT_POLICY_CONSTRAINTS_INFO *info;
7757 DWORD size;
7758 BOOL ret;
7760 /* Again, even though CAs must not issue such constraints, they can be
7761 * decoded.
7763 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7764 emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
7765 &info, &size);
7766 ok(ret || broken(GetLastError() == ERROR_FILE_NOT_FOUND),
7767 "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7768 if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
7770 win_skip("no policy mappings support\n");
7771 return;
7773 if (ret)
7775 ok(!info->fRequireExplicitPolicy,
7776 "expected require explicit = FALSE\n");
7777 ok(!info->fInhibitPolicyMapping,
7778 "expected implicit mapping = FALSE\n");
7779 LocalFree(info);
7781 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7782 policyConstraintsWithRequireExplicit,
7783 sizeof(policyConstraintsWithRequireExplicit), CRYPT_DECODE_ALLOC_FLAG,
7784 NULL, &info, &size);
7785 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7786 if (ret)
7788 ok(info->fRequireExplicitPolicy,
7789 "expected require explicit = TRUE\n");
7790 ok(info->dwRequireExplicitPolicySkipCerts == 0, "expected 0, got %d\n",
7791 info->dwRequireExplicitPolicySkipCerts);
7792 ok(!info->fInhibitPolicyMapping,
7793 "expected implicit mapping = FALSE\n");
7794 LocalFree(info);
7796 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7797 policyConstraintsWithInhibitMapping,
7798 sizeof(policyConstraintsWithInhibitMapping), CRYPT_DECODE_ALLOC_FLAG,
7799 NULL, &info, &size);
7800 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7801 if (ret)
7803 ok(!info->fRequireExplicitPolicy,
7804 "expected require explicit = FALSE\n");
7805 ok(info->fInhibitPolicyMapping,
7806 "expected implicit mapping = TRUE\n");
7807 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
7808 info->dwInhibitPolicyMappingSkipCerts);
7809 LocalFree(info);
7811 ret = pCryptDecodeObjectEx(dwEncoding, X509_POLICY_CONSTRAINTS,
7812 policyConstraintsWithBoth, sizeof(policyConstraintsWithBoth),
7813 CRYPT_DECODE_ALLOC_FLAG, NULL, &info, &size);
7814 ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
7815 if (ret)
7817 ok(info->fRequireExplicitPolicy,
7818 "expected require explicit = TRUE\n");
7819 ok(info->dwRequireExplicitPolicySkipCerts == 1, "expected 1, got %d\n",
7820 info->dwRequireExplicitPolicySkipCerts);
7821 ok(info->fInhibitPolicyMapping,
7822 "expected implicit mapping = TRUE\n");
7823 ok(info->dwInhibitPolicyMappingSkipCerts == 1, "expected 1, got %d\n",
7824 info->dwInhibitPolicyMappingSkipCerts);
7825 LocalFree(info);
7829 /* Free *pInfo with HeapFree */
7830 static void testExportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO *pInfo)
7832 BOOL ret;
7833 DWORD size = 0;
7834 HCRYPTKEY key;
7836 /* This crashes
7837 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, NULL);
7839 ret = CryptExportPublicKeyInfoEx(0, 0, 0, NULL, 0, NULL, NULL, &size);
7840 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7841 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7842 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, 0, NULL, 0, NULL, NULL,
7843 &size);
7844 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7845 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7846 ret = CryptExportPublicKeyInfoEx(0, 0, X509_ASN_ENCODING, NULL, 0, NULL,
7847 NULL, &size);
7848 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7849 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7850 ret = CryptExportPublicKeyInfoEx(0, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7851 0, NULL, NULL, &size);
7852 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7853 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7854 /* Test with no key */
7855 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING, NULL,
7856 0, NULL, NULL, &size);
7857 ok(!ret && GetLastError() == NTE_NO_KEY, "Expected NTE_NO_KEY, got %08x\n",
7858 GetLastError());
7859 ret = CryptGenKey(csp, AT_SIGNATURE, 0, &key);
7860 ok(ret, "CryptGenKey failed: %08x\n", GetLastError());
7861 if (ret)
7863 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE, X509_ASN_ENCODING,
7864 NULL, 0, NULL, NULL, &size);
7865 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n", GetLastError());
7866 *pInfo = HeapAlloc(GetProcessHeap(), 0, size);
7867 if (*pInfo)
7869 ret = CryptExportPublicKeyInfoEx(csp, AT_SIGNATURE,
7870 X509_ASN_ENCODING, NULL, 0, NULL, *pInfo, &size);
7871 ok(ret, "CryptExportPublicKeyInfoEx failed: %08x\n",
7872 GetLastError());
7873 if (ret)
7875 /* By default (we passed NULL as the OID) the OID is
7876 * szOID_RSA_RSA.
7878 ok(!strcmp((*pInfo)->Algorithm.pszObjId, szOID_RSA_RSA),
7879 "Expected %s, got %s\n", szOID_RSA_RSA,
7880 (*pInfo)->Algorithm.pszObjId);
7884 CryptDestroyKey(key);
7887 static const BYTE expiredCert[] = { 0x30, 0x82, 0x01, 0x33, 0x30, 0x81, 0xe2,
7888 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0xc4, 0xd7, 0x7f, 0x0e, 0x6f, 0xa6,
7889 0x8c, 0xaa, 0x47, 0x47, 0x40, 0xe7, 0xb7, 0x0b, 0x4a, 0x7f, 0x30, 0x09, 0x06,
7890 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7891 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7892 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7893 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x36, 0x39, 0x30, 0x31, 0x30, 0x31, 0x30,
7894 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30,
7895 0x31, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x1f, 0x31, 0x1d, 0x30,
7896 0x1b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x14, 0x61, 0x72, 0x69, 0x63, 0x40,
7897 0x63, 0x6f, 0x64, 0x65, 0x77, 0x65, 0x61, 0x76, 0x65, 0x72, 0x73, 0x2e, 0x63,
7898 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
7899 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
7900 0x00, 0xa1, 0xaf, 0x4a, 0xea, 0xa7, 0x83, 0x57, 0xc0, 0x37, 0x33, 0x7e, 0x29,
7901 0x5e, 0x0d, 0xfc, 0x44, 0x74, 0x3a, 0x1d, 0xc3, 0x1b, 0x1d, 0x96, 0xed, 0x4e,
7902 0xf4, 0x1b, 0x98, 0xec, 0x69, 0x1b, 0x04, 0xea, 0x25, 0xcf, 0xb3, 0x2a, 0xf5,
7903 0xd9, 0x22, 0xd9, 0x8d, 0x08, 0x39, 0x81, 0xc6, 0xe0, 0x4f, 0x12, 0x37, 0x2a,
7904 0x3f, 0x80, 0xa6, 0x6c, 0x67, 0x43, 0x3a, 0xdd, 0x95, 0x0c, 0xbb, 0x2f, 0x6b,
7905 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02,
7906 0x1d, 0x05, 0x00, 0x03, 0x41, 0x00, 0x8f, 0xa2, 0x5b, 0xd6, 0xdf, 0x34, 0xd0,
7907 0xa2, 0xa7, 0x47, 0xf1, 0x13, 0x79, 0xd3, 0xf3, 0x39, 0xbd, 0x4e, 0x2b, 0xa3,
7908 0xf4, 0x63, 0x37, 0xac, 0x5a, 0x0c, 0x5e, 0x4d, 0x0d, 0x54, 0x87, 0x4f, 0x31,
7909 0xfb, 0xa0, 0xce, 0x8f, 0x9a, 0x2f, 0x4d, 0x48, 0xc6, 0x84, 0x8d, 0xf5, 0x70,
7910 0x74, 0x17, 0xa5, 0xf3, 0x66, 0x47, 0x06, 0xd6, 0x64, 0x45, 0xbc, 0x52, 0xef,
7911 0x49, 0xe5, 0xf9, 0x65, 0xf3 };
7913 static void testImportPublicKey(HCRYPTPROV csp, PCERT_PUBLIC_KEY_INFO info)
7915 BOOL ret;
7916 HCRYPTKEY key;
7917 PCCERT_CONTEXT context;
7918 DWORD dwSize;
7919 ALG_ID ai;
7921 /* These crash
7922 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, NULL);
7923 ret = CryptImportPublicKeyInfoEx(0, 0, NULL, 0, 0, NULL, &key);
7924 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, NULL);
7925 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7926 NULL);
7928 ret = CryptImportPublicKeyInfoEx(0, 0, info, 0, 0, NULL, &key);
7929 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7930 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7931 ret = CryptImportPublicKeyInfoEx(csp, 0, info, 0, 0, NULL, &key);
7932 ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
7933 "Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
7934 ret = CryptImportPublicKeyInfoEx(0, X509_ASN_ENCODING, info, 0, 0, NULL,
7935 &key);
7936 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
7937 "Expected ERROR_INVALID_PARAMETER, got %08x\n", GetLastError());
7939 /* Export key with standard algorithm (CALG_RSA_KEYX) */
7940 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, 0, 0, NULL,
7941 &key);
7942 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7944 dwSize = sizeof(ai);
7945 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7946 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7947 if(ret)
7949 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7950 ok(ai == CALG_RSA_KEYX, "Default ALG_ID is %04x (expected CALG_RSA_KEYX)\n", ai);
7953 CryptDestroyKey(key);
7955 /* Repeat with forced algorithm */
7956 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING, info, CALG_RSA_SIGN, 0, NULL,
7957 &key);
7958 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7960 dwSize = sizeof(ai);
7961 CryptGetKeyParam(key, KP_ALGID, (LPVOID)&ai, &dwSize, 0);
7962 ok(ret, "CryptGetKeyParam failed: %08x\n", GetLastError());
7963 if(ret)
7965 ok(dwSize == sizeof(ai), "CryptGetKeyParam returned size %d\n",dwSize);
7966 ok(ai == CALG_RSA_SIGN, "ALG_ID is %04x (expected CALG_RSA_SIGN)\n", ai);
7969 CryptDestroyKey(key);
7971 /* Test importing a public key from a certificate context */
7972 context = CertCreateCertificateContext(X509_ASN_ENCODING, expiredCert,
7973 sizeof(expiredCert));
7974 ok(context != NULL, "CertCreateCertificateContext failed: %08x\n",
7975 GetLastError());
7976 if (context)
7978 ok(!strcmp(szOID_RSA_RSA,
7979 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId),
7980 "Expected %s, got %s\n", szOID_RSA_RSA,
7981 context->pCertInfo->SubjectPublicKeyInfo.Algorithm.pszObjId);
7982 ret = CryptImportPublicKeyInfoEx(csp, X509_ASN_ENCODING,
7983 &context->pCertInfo->SubjectPublicKeyInfo, 0, 0, NULL, &key);
7984 ok(ret, "CryptImportPublicKeyInfoEx failed: %08x\n", GetLastError());
7985 CryptDestroyKey(key);
7986 CertFreeCertificateContext(context);
7990 static const char cspName[] = "WineCryptTemp";
7992 static void testPortPublicKeyInfo(void)
7994 HCRYPTPROV csp;
7995 BOOL ret;
7996 PCERT_PUBLIC_KEY_INFO info = NULL;
7998 /* Just in case a previous run failed, delete this thing */
7999 CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
8000 CRYPT_DELETEKEYSET);
8001 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
8002 CRYPT_NEWKEYSET);
8004 testExportPublicKey(csp, &info);
8005 testImportPublicKey(csp, info);
8007 HeapFree(GetProcessHeap(), 0, info);
8008 CryptReleaseContext(csp, 0);
8009 ret = CryptAcquireContextA(&csp, cspName, MS_DEF_PROV, PROV_RSA_FULL,
8010 CRYPT_DELETEKEYSET);
8013 START_TEST(encode)
8015 static const DWORD encodings[] = { X509_ASN_ENCODING, PKCS_7_ASN_ENCODING,
8016 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING };
8017 HMODULE hCrypt32;
8018 DWORD i;
8020 hCrypt32 = GetModuleHandleA("crypt32.dll");
8021 pCryptDecodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptDecodeObjectEx");
8022 pCryptEncodeObjectEx = (void*)GetProcAddress(hCrypt32, "CryptEncodeObjectEx");
8023 if (!pCryptDecodeObjectEx || !pCryptEncodeObjectEx)
8025 win_skip("CryptDecodeObjectEx() is not available\n");
8026 return;
8029 for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
8031 test_encodeInt(encodings[i]);
8032 test_decodeInt(encodings[i]);
8033 test_encodeEnumerated(encodings[i]);
8034 test_decodeEnumerated(encodings[i]);
8035 test_encodeFiletime(encodings[i]);
8036 test_decodeFiletime(encodings[i]);
8037 test_encodeName(encodings[i]);
8038 test_decodeName(encodings[i]);
8039 test_encodeUnicodeName(encodings[i]);
8040 test_decodeUnicodeName(encodings[i]);
8041 test_encodeNameValue(encodings[i]);
8042 test_decodeNameValue(encodings[i]);
8043 test_encodeUnicodeNameValue(encodings[i]);
8044 test_decodeUnicodeNameValue(encodings[i]);
8045 test_encodeAltName(encodings[i]);
8046 test_decodeAltName(encodings[i]);
8047 test_encodeOctets(encodings[i]);
8048 test_decodeOctets(encodings[i]);
8049 test_encodeBits(encodings[i]);
8050 test_decodeBits(encodings[i]);
8051 test_encodeBasicConstraints(encodings[i]);
8052 test_decodeBasicConstraints(encodings[i]);
8053 test_encodeRsaPublicKey(encodings[i]);
8054 test_decodeRsaPublicKey(encodings[i]);
8055 test_encodeSequenceOfAny(encodings[i]);
8056 test_decodeSequenceOfAny(encodings[i]);
8057 test_encodeExtensions(encodings[i]);
8058 test_decodeExtensions(encodings[i]);
8059 test_encodePublicKeyInfo(encodings[i]);
8060 test_decodePublicKeyInfo(encodings[i]);
8061 test_encodeCertToBeSigned(encodings[i]);
8062 test_decodeCertToBeSigned(encodings[i]);
8063 test_encodeCert(encodings[i]);
8064 test_decodeCert(encodings[i]);
8065 test_encodeCRLDistPoints(encodings[i]);
8066 test_decodeCRLDistPoints(encodings[i]);
8067 test_encodeCRLIssuingDistPoint(encodings[i]);
8068 test_decodeCRLIssuingDistPoint(encodings[i]);
8069 test_encodeCRLToBeSigned(encodings[i]);
8070 test_decodeCRLToBeSigned(encodings[i]);
8071 test_encodeEnhancedKeyUsage(encodings[i]);
8072 test_decodeEnhancedKeyUsage(encodings[i]);
8073 test_encodeAuthorityKeyId(encodings[i]);
8074 test_decodeAuthorityKeyId(encodings[i]);
8075 test_encodeAuthorityKeyId2(encodings[i]);
8076 test_decodeAuthorityKeyId2(encodings[i]);
8077 test_encodeAuthorityInfoAccess(encodings[i]);
8078 test_decodeAuthorityInfoAccess(encodings[i]);
8079 test_encodeCTL(encodings[i]);
8080 test_decodeCTL(encodings[i]);
8081 test_encodePKCSContentInfo(encodings[i]);
8082 test_decodePKCSContentInfo(encodings[i]);
8083 test_encodePKCSAttribute(encodings[i]);
8084 test_decodePKCSAttribute(encodings[i]);
8085 test_encodePKCSAttributes(encodings[i]);
8086 test_decodePKCSAttributes(encodings[i]);
8087 test_encodePKCSSMimeCapabilities(encodings[i]);
8088 test_decodePKCSSMimeCapabilities(encodings[i]);
8089 test_encodePKCSSignerInfo(encodings[i]);
8090 test_decodePKCSSignerInfo(encodings[i]);
8091 test_encodeCMSSignerInfo(encodings[i]);
8092 test_decodeCMSSignerInfo(encodings[i]);
8093 test_encodeNameConstraints(encodings[i]);
8094 test_decodeNameConstraints(encodings[i]);
8095 test_encodePolicyQualifierUserNotice(encodings[i]);
8096 test_decodePolicyQualifierUserNotice(encodings[i]);
8097 test_encodeCertPolicies(encodings[i]);
8098 test_decodeCertPolicies(encodings[i]);
8099 test_encodeCertPolicyMappings(encodings[i]);
8100 test_decodeCertPolicyMappings(encodings[i]);
8101 test_encodeCertPolicyConstraints(encodings[i]);
8102 test_decodeCertPolicyConstraints(encodings[i]);
8104 testPortPublicKeyInfo();